1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 *
26 * Copyright 2017 Jason King.
27 * Copyright (c) 2017, Joyent, Inc.
28 */
29
30 #include <syslog.h>
31 #include <assert.h>
32 #include <string.h>
33 #include <ipsec_util.h>
34 #include <locale.h>
35 #include <security/cryptoki.h>
36 #include <pthread.h>
37 #include <sys/debug.h>
38 #include <note.h>
39 #include "pkcs11.h"
40 #include "defs.h"
41
42 /*
43 * per usr/src/lib/pkcs11/libpkcs11/common/metaGlobal.h, the metaslot
44 * is always slot 0
45 */
46 #define METASLOT_ID (0)
47
48 CK_INFO pkcs11_info = { 0 };
49 CK_SESSION_HANDLE p11h = CK_INVALID_HANDLE;
50
51 #define PKCS11_FUNC "func"
52 #define PKCS11_RC "errnum"
53 #define PKCS11_ERRMSG "err"
54
55 static void fmtstr(char *, size_t, CK_UTF8CHAR *, size_t);
56 static CK_RV pkcs11_callback_handler(CK_SESSION_HANDLE, CK_NOTIFICATION,
57 void *);
58 static void log_slotinfo(CK_SLOT_ID);
59
60 /*
61 * Locates the metaslot among the available slots. If the metaslot
62 * is inable to be located, we terminate.
63 */
64 void
65 pkcs11_init(void)
66 {
67 CK_RV rv = CKR_OK;
68 CK_ULONG nslot = 0;
69 CK_C_INITIALIZE_ARGS args = {
70 NULL_PTR, /* CreateMutex */
71 NULL_PTR, /* DestroyMutex */
72 NULL_PTR, /* LockMutex */
73 NULL_PTR, /* UnlockMutex */
74 CKF_OS_LOCKING_OK, /* flags */
75 NULL_PTR /* reserved */
76 };
77
78 if ((rv = C_Initialize(&args)) != CKR_OK) {
79 PKCS11ERR(fatal, log, "C_Initialize", rv);
80 exit(1);
81 }
82
83 if ((rv = C_GetInfo(&pkcs11_info)) != CKR_OK) {
84 PKCS11ERR(fatal, log, "C_Info", rv);
85 exit(1);
86 }
87
88 if ((rv = C_GetSlotList(CK_FALSE, NULL, &nslot)) != CKR_OK) {
89 PKCS11ERR(fatal, log, "C_GetSlotList", rv);
90 exit(1);
91 }
92
93 CK_SLOT_ID slots[nslot];
94
95 if ((rv = C_GetSlotList(CK_FALSE, slots, &nslot)) != CKR_OK) {
96 PKCS11ERR(fatal, log, "C_GetSlotList", rv);
97 exit(1);
98 }
99
100 {
101 char manf[33];
102 char libdesc[33];
103
104 fmtstr(manf, sizeof (manf), pkcs11_info.manufacturerID,
105 sizeof (pkcs11_info.manufacturerID));
106 fmtstr(libdesc, sizeof (libdesc),
107 pkcs11_info.libraryDescription,
108 sizeof (pkcs11_info.libraryDescription));
109
110 (void) bunyan_debug(log, "PKCS#11 provider info",
111 BUNYAN_T_STRING, "manufacturer", manf,
112 BUNYAN_T_UINT32, "version.major",
113 (uint32_t)pkcs11_info.cryptokiVersion.major,
114 BUNYAN_T_UINT32, "version.minor",
115 (uint32_t)pkcs11_info.cryptokiVersion.minor,
116 BUNYAN_T_UINT64, "flags",
117 (uint64_t)pkcs11_info.flags,
118 BUNYAN_T_STRING, "library", libdesc,
119 BUNYAN_T_UINT32, "lib.major",
120 (uint32_t)pkcs11_info.libraryVersion.major,
121 BUNYAN_T_UINT32, "lib.minor",
122 (uint32_t)pkcs11_info.libraryVersion.minor,
123 BUNYAN_T_UINT32, "numslots", nslot,
124 BUNYAN_T_END);
125 }
126
127 for (size_t i = 0; i < nslot; i++)
128 log_slotinfo(slots[i]);
129
130 rv = C_OpenSession(METASLOT_ID, CKF_SERIAL_SESSION, NULL,
131 pkcs11_callback_handler, &p11h);
132 if (rv != CKR_OK) {
133 PKCS11ERR(fatal, log, "C_OpenSession", rv);
134 exit(1);
135 }
136
137 (void) bunyan_trace(log, "PKCS#11 session opened",
138 BUNYAN_T_UINT64, "pkcs11 handle", (uint64_t)p11h,
139 BUNYAN_T_END);
140 }
141
142 static void
143 log_slotinfo(CK_SLOT_ID slot)
144 {
145 CK_SLOT_INFO info = { 0 };
146 char manuf[33]; /* sizeof info.manufacturerID NUL */
147 CK_RV rv;
148
149 rv = C_GetSlotInfo(slot, &info);
150 if (rv != CKR_OK) {
151 PKCS11ERR(error, log, "C_GetSlotInfo", rv);
152 return;
153 }
154
155 {
156 char desc[65]; /* sizeof info.description + NUL */
157 fmtstr(desc, sizeof (desc), info.slotDescription,
158 sizeof (info.slotDescription));
159 fmtstr(manuf, sizeof (manuf), info.manufacturerID,
160 sizeof (info.manufacturerID));
161
162 (void) bunyan_debug(log, "PKCS#11 slot Info",
163 BUNYAN_T_UINT64, "slot", (uint64_t)slot,
164 BUNYAN_T_STRING, "desc", desc,
165 BUNYAN_T_STRING, "manufacturer", manuf,
166 BUNYAN_T_UINT32, "hwversion.major",
167 (uint32_t)info.hardwareVersion.major,
168 BUNYAN_T_UINT32, "hwversion.minor",
169 (uint32_t)info.hardwareVersion.minor,
170 BUNYAN_T_UINT32, "fwversion.major",
171 (uint32_t)info.firmwareVersion.major,
172 BUNYAN_T_UINT32, "fwversion.minor",
173 (uint32_t)info.firmwareVersion.minor,
174 BUNYAN_T_UINT64, "flags", (uint64_t)info.flags,
175 BUNYAN_T_BOOLEAN, "present",
176 !!(info.flags & CKF_TOKEN_PRESENT),
177 BUNYAN_T_BOOLEAN, "removable",
178 !!(info.flags & CKF_REMOVABLE_DEVICE),
179 BUNYAN_T_BOOLEAN, "hwslot", !!(info.flags & CKF_HW_SLOT),
180 BUNYAN_T_END);
181 }
182
183 if (!(info.flags & CKF_TOKEN_PRESENT))
184 return;
185
186 CK_TOKEN_INFO tinfo = { 0 };
187 rv = C_GetTokenInfo(slot, &tinfo);
188 if (rv != CKR_OK)
189 PKCS11ERR(error, log, "C_GetTokenInfo", rv);
190
191 char label[33]; /* sizeof tinfo.label + NUL */
192 char model[17]; /* sizeof tinfo.model + NUL */
193 char serial[17]; /* sizeof tinfo.serialNumber + NUL */
194 char utctime[17]; /* sizeof tinfo.utsTime + NUL */
195
196 fmtstr(manuf, sizeof (manuf), tinfo.manufacturerID,
197 sizeof (tinfo.manufacturerID));
198 fmtstr(label, sizeof (label), tinfo.label, sizeof (tinfo.label));
199 fmtstr(model, sizeof (model), tinfo.model, sizeof (tinfo.model));
200 fmtstr(serial, sizeof (serial), tinfo.serialNumber,
201 sizeof (tinfo.serialNumber));
202 fmtstr(utctime, sizeof (utctime), tinfo.utcTime,
203 sizeof (tinfo.utcTime));
204
205 #define F(_inf, _flg) BUNYAN_T_BOOLEAN, #_flg, !!((_inf).flags & (_flg))
206
207 (void) bunyan_debug(log, "PKCS#11 token info",
208 BUNYAN_T_UINT32, "slot", (uint32_t)slot,
209 BUNYAN_T_STRING, "label", label,
210 BUNYAN_T_STRING, "manuf", manuf,
211 BUNYAN_T_STRING, "model", model,
212 BUNYAN_T_STRING, "serial", serial,
213 BUNYAN_T_UINT64, "flags", (uint64_t)tinfo.flags,
214 F(info, CKF_RNG),
215 F(info, CKF_WRITE_PROTECTED),
216 F(info, CKF_LOGIN_REQUIRED),
217 F(info, CKF_USER_PIN_INITIALIZED),
218 F(info, CKF_RESTORE_KEY_NOT_NEEDED),
219 F(info, CKF_CLOCK_ON_TOKEN),
220 F(info, CKF_PROTECTED_AUTHENTICATION_PATH),
221 F(info, CKF_DUAL_CRYPTO_OPERATIONS),
222 F(info, CKF_TOKEN_INITIALIZED),
223 F(info, CKF_SECONDARY_AUTHENTICATION),
224 F(info, CKF_USER_PIN_COUNT_LOW),
225 F(info, CKF_USER_PIN_FINAL_TRY),
226 F(info, CKF_USER_PIN_LOCKED),
227 F(info, CKF_USER_PIN_TO_BE_CHANGED),
228 F(info, CKF_SO_PIN_COUNT_LOW),
229 F(info, CKF_SO_PIN_FINAL_TRY),
230 F(info, CKF_SO_PIN_LOCKED),
231 F(info, CKF_SO_PIN_TO_BE_CHANGED),
232 F(info, CKF_ERROR_STATE),
233 BUNYAN_T_END);
234 #undef F
235 }
236
237 void
238 pkcs11_fini(void)
239 {
240 CK_RV rv;
241
242 rv = C_CloseSession(p11h);
243 if (rv != CKR_OK)
244 PKCS11ERR(error, log, "C_CloseSession", rv);
245
246 rv = C_Finalize(NULL_PTR);
247 if (rv != CKR_OK)
248 PKCS11ERR(error, log, "C_Finalize", rv);
249 }
250
251 /*
252 * We explicitly avoid using the default: case in these switch statements
253 * so that the addition of new IKEv2 encryption algs will cause compilation
254 * errors if they are not added to these functions.
255 */
256 CK_MECHANISM_TYPE
257 ikev2_encr_to_p11(ikev2_xf_encr_t encr)
258 {
259 switch (encr) {
260 case IKEV2_ENCR_NONE:
261 case IKEV2_ENCR_NULL_AES_GMAC:
262 case IKEV2_ENCR_NULL:
263 case IKEV2_ENCR_3IDEA:
264 case IKEV2_ENCR_XTS_AES:
265 INVALID("encr");
266 /*NOTREACHED*/
267 return (0);
268 case IKEV2_ENCR_DES_IV64:
269 case IKEV2_ENCR_DES:
270 case IKEV2_ENCR_DES_IV32:
271 return (CKM_DES_CBC);
272 case IKEV2_ENCR_3DES:
273 return (CKM_DES3_CBC);
274 case IKEV2_ENCR_RC5:
275 return (CKM_RC5_CBC);
276 case IKEV2_ENCR_IDEA:
277 return (CKM_IDEA_CBC);
278 case IKEV2_ENCR_CAST:
279 return (CKM_CAST5_CBC);
280 case IKEV2_ENCR_BLOWFISH:
281 return (CKM_BLOWFISH_CBC);
282 case IKEV2_ENCR_RC4:
283 return (CKM_RC4);
284 case IKEV2_ENCR_AES_CBC:
285 return (CKM_AES_CBC);
286 case IKEV2_ENCR_AES_CTR:
287 return (CKM_AES_CTR);
288 case IKEV2_ENCR_AES_CCM_8:
289 case IKEV2_ENCR_AES_CCM_12:
290 case IKEV2_ENCR_AES_CCM_16:
291 return (CKM_AES_CCM);
292 case IKEV2_ENCR_AES_GCM_8:
293 case IKEV2_ENCR_AES_GCM_12:
294 case IKEV2_ENCR_AES_GCM_16:
295 return (CKM_AES_GCM);
296 case IKEV2_ENCR_CAMELLIA_CBC:
297 return (CKM_CAMELLIA_CBC);
298 case IKEV2_ENCR_CAMELLIA_CTR:
299 return (CKM_CAMELLIA_CTR);
300 case IKEV2_ENCR_CAMELLIA_CCM_8:
301 case IKEV2_ENCR_CAMELLIA_CCM_12:
302 case IKEV2_ENCR_CAMELLIA_CCM_16:
303 return (CKM_CAMELLIA_CBC);
304 }
305 /*NOTREACHED*/
306 return (0);
307 }
308
309 size_t
310 ikev2_encr_block_size(ikev2_xf_encr_t encr)
311 {
312 switch (encr) {
313 case IKEV2_ENCR_NONE:
314 case IKEV2_ENCR_NULL:
315 case IKEV2_ENCR_NULL_AES_GMAC:
316 return (0);
317 case IKEV2_ENCR_DES_IV64:
318 case IKEV2_ENCR_DES:
319 case IKEV2_ENCR_DES_IV32:
320 case IKEV2_ENCR_3DES:
321 case IKEV2_ENCR_RC5:
322 case IKEV2_ENCR_RC4:
323 case IKEV2_ENCR_IDEA:
324 case IKEV2_ENCR_CAST:
325 case IKEV2_ENCR_BLOWFISH:
326 case IKEV2_ENCR_3IDEA:
327 return (8);
328 case IKEV2_ENCR_AES_CBC:
329 case IKEV2_ENCR_AES_CTR:
330 case IKEV2_ENCR_XTS_AES:
331 case IKEV2_ENCR_AES_CCM_8:
332 case IKEV2_ENCR_AES_CCM_12:
333 case IKEV2_ENCR_AES_CCM_16:
334 case IKEV2_ENCR_AES_GCM_8:
335 case IKEV2_ENCR_AES_GCM_12:
336 case IKEV2_ENCR_AES_GCM_16:
337 case IKEV2_ENCR_CAMELLIA_CBC:
338 case IKEV2_ENCR_CAMELLIA_CTR:
339 case IKEV2_ENCR_CAMELLIA_CCM_8:
340 case IKEV2_ENCR_CAMELLIA_CCM_12:
341 case IKEV2_ENCR_CAMELLIA_CCM_16:
342 return (16);
343 }
344 /*NOTREACHED*/
345 return (0);
346 }
347
348 size_t
349 ikev2_encr_iv_size(ikev2_xf_encr_t encr)
350 {
351 switch (encr) {
352 case IKEV2_ENCR_NONE:
353 case IKEV2_ENCR_NULL:
354 return (0);
355 case IKEV2_ENCR_DES_IV32:
356 return (4);
357 case IKEV2_ENCR_DES_IV64:
358 return (8);
359 default:
360 return (ikev2_encr_block_size(encr));
361 }
362 }
363
364 encr_modes_t
365 ikev2_encr_mode(ikev2_xf_encr_t encr)
366 {
367 switch (encr) {
368 case IKEV2_ENCR_NONE:
369 case IKEV2_ENCR_NULL:
370 case IKEV2_ENCR_NULL_AES_GMAC:
371 case IKEV2_ENCR_XTS_AES:
372 return (MODE_NONE);
373 case IKEV2_ENCR_DES_IV64:
374 case IKEV2_ENCR_DES:
375 case IKEV2_ENCR_DES_IV32:
376 case IKEV2_ENCR_3DES:
377 case IKEV2_ENCR_RC5:
378 case IKEV2_ENCR_RC4:
379 case IKEV2_ENCR_IDEA:
380 case IKEV2_ENCR_CAST:
381 case IKEV2_ENCR_BLOWFISH:
382 case IKEV2_ENCR_3IDEA:
383 case IKEV2_ENCR_AES_CBC:
384 case IKEV2_ENCR_CAMELLIA_CBC:
385 return (MODE_CBC);
386 case IKEV2_ENCR_AES_CTR:
387 case IKEV2_ENCR_CAMELLIA_CTR:
388 return (MODE_CTR);
389 case IKEV2_ENCR_AES_CCM_8:
390 case IKEV2_ENCR_AES_CCM_12:
391 case IKEV2_ENCR_AES_CCM_16:
392 case IKEV2_ENCR_CAMELLIA_CCM_8:
393 case IKEV2_ENCR_CAMELLIA_CCM_12:
394 case IKEV2_ENCR_CAMELLIA_CCM_16:
395 return (MODE_CCM);
396 case IKEV2_ENCR_AES_GCM_8:
397 case IKEV2_ENCR_AES_GCM_12:
398 case IKEV2_ENCR_AES_GCM_16:
399 return (MODE_GCM);
400 }
401 /*NOTREACHED*/
402 return (MODE_NONE);
403 }
404
405 CK_MECHANISM_TYPE
406 ikev2_auth_to_p11(ikev2_xf_auth_t auth)
407 {
408 switch (auth) {
409 case IKEV2_XF_AUTH_NONE:
410 return (0);
411 case IKEV2_XF_AUTH_HMAC_MD5_96:
412 return (CKM_MD5_HMAC);
413 case IKEV2_XF_AUTH_HMAC_SHA1_96:
414 return (CKM_SHA_1_HMAC);
415 case IKEV2_XF_AUTH_DES_MAC:
416 return (CKM_DES_MAC);
417 case IKEV2_XF_AUTH_KPDK_MD5:
418 return (CKM_MD5_HMAC); /* XXX: verify */
419 case IKEV2_XF_AUTH_AES_XCBC_96:
420 return (CKM_AES_XCBC_MAC_96);
421 case IKEV2_XF_AUTH_HMAC_MD5_128:
422 return (CKM_MD5_HMAC);
423 case IKEV2_XF_AUTH_HMAC_SHA1_160:
424 return (CKM_SHA_1_HMAC);
425 case IKEV2_XF_AUTH_AES_CMAC_96:
426 return (CKM_AES_CMAC);
427 case IKEV2_XF_AUTH_AES_128_GMAC:
428 case IKEV2_XF_AUTH_AES_192_GMAC:
429 case IKEV2_XF_AUTH_AES_256_GMAC:
430 return (CKM_AES_GMAC);
431 case IKEV2_XF_AUTH_HMAC_SHA2_256_128:
432 return (CKM_SHA256_HMAC);
433 case IKEV2_XF_AUTH_HMAC_SHA2_384_192:
434 return (CKM_SHA384_HMAC);
435 case IKEV2_XF_AUTH_HMAC_SHA2_512_256:
436 return (CKM_SHA512_HMAC);
437 }
438
439 /*NOTREACHED*/
440 return (0);
441 }
442
443 size_t
444 ikev2_auth_icv_size(ikev2_xf_encr_t encr, ikev2_xf_auth_t auth)
445 {
446 switch (encr) {
447 case IKEV2_ENCR_NONE:
448 case IKEV2_ENCR_NULL:
449 case IKEV2_ENCR_NULL_AES_GMAC:
450 case IKEV2_ENCR_DES_IV64:
451 case IKEV2_ENCR_DES:
452 case IKEV2_ENCR_DES_IV32:
453 case IKEV2_ENCR_3DES:
454 case IKEV2_ENCR_RC5:
455 case IKEV2_ENCR_RC4:
456 case IKEV2_ENCR_IDEA:
457 case IKEV2_ENCR_CAST:
458 case IKEV2_ENCR_BLOWFISH:
459 case IKEV2_ENCR_3IDEA:
460 case IKEV2_ENCR_AES_CBC:
461 case IKEV2_ENCR_AES_CTR:
462 case IKEV2_ENCR_XTS_AES:
463 case IKEV2_ENCR_CAMELLIA_CBC:
464 case IKEV2_ENCR_CAMELLIA_CTR:
465 break;
466 case IKEV2_ENCR_AES_CCM_8:
467 case IKEV2_ENCR_AES_GCM_8:
468 case IKEV2_ENCR_CAMELLIA_CCM_8:
469 ASSERT3S(auth, ==, IKEV2_XF_AUTH_NONE);
470 return (8);
471 case IKEV2_ENCR_AES_CCM_12:
472 case IKEV2_ENCR_AES_GCM_12:
473 case IKEV2_ENCR_CAMELLIA_CCM_12:
474 ASSERT3S(auth, ==, IKEV2_XF_AUTH_NONE);
475 return (12);
476 case IKEV2_ENCR_AES_CCM_16:
477 case IKEV2_ENCR_AES_GCM_16:
478 case IKEV2_ENCR_CAMELLIA_CCM_16:
479 ASSERT3S(auth, ==, IKEV2_XF_AUTH_NONE);
480 return (16);
481 }
482
483 switch (auth) {
484 case IKEV2_XF_AUTH_NONE:
485 return (0);
486 case IKEV2_XF_AUTH_HMAC_MD5_96:
487 case IKEV2_XF_AUTH_HMAC_SHA1_96:
488 case IKEV2_XF_AUTH_AES_XCBC_96:
489 case IKEV2_XF_AUTH_AES_CMAC_96:
490 return (12);
491 case IKEV2_XF_AUTH_DES_MAC: /* a guess */
492 case IKEV2_XF_AUTH_KPDK_MD5:
493 case IKEV2_XF_AUTH_HMAC_MD5_128:
494 case IKEV2_XF_AUTH_AES_128_GMAC:
495 case IKEV2_XF_AUTH_HMAC_SHA2_256_128:
496 return (16);
497 case IKEV2_XF_AUTH_HMAC_SHA1_160:
498 return (20);
499 case IKEV2_XF_AUTH_AES_192_GMAC:
500 case IKEV2_XF_AUTH_HMAC_SHA2_384_192:
501 return (24);
502 case IKEV2_XF_AUTH_AES_256_GMAC:
503 case IKEV2_XF_AUTH_HMAC_SHA2_512_256:
504 return (32);
505 }
506 /*NOTREACHED*/
507 return (0);
508 }
509
510 /*
511 * Destroy a PKCS#11 object with nicer error messages in case of failure.
512 */
513 void
514 pkcs11_destroy_obj(const char *name, CK_OBJECT_HANDLE_PTR objp,
515 bunyan_logger_t *l)
516 {
517 CK_RV ret;
518
519 if (objp == NULL || *objp == CK_INVALID_HANDLE)
520 return;
521
522 if ((ret = C_DestroyObject(p11h, *objp)) != CKR_OK) {
523 PKCS11ERR(error, (l == NULL) ? log : l, "C_DestroyObject", ret);
524 } else {
525 *objp = CK_INVALID_HANDLE;
526 }
527 }
528
529 /*
530 * Scatter/gather digest calculation. Upon failure, B_FALSE is returned.
531 */
532 boolean_t
533 pkcs11_digest(CK_MECHANISM_TYPE alg, const buf_t *restrict in, size_t n,
534 buf_t *restrict out, bunyan_logger_t *l)
535 {
536 CK_MECHANISM mech;
537 CK_RV ret;
538
539 mech.mechanism = alg;
540 mech.pParameter = NULL_PTR;
541 mech.ulParameterLen = 0;
542
543 if ((ret = C_DigestInit(p11h, &mech)) != CKR_OK) {
544 PKCS11ERR(error, l, "C_DigestInit", ret);
545 return (B_FALSE);
546 }
547
548 for (size_t i = 0; i < n; i++) {
549 ret = C_DigestUpdate(p11h, in[i].b_ptr, buf_left(&in[i]));
550 if (ret != CKR_OK) {
551 PKCS11ERR(error, l, "C_DigestUpdate", ret);
552 return (B_FALSE);
553 }
554 }
555
556 CK_ULONG len = out->b_len;
557
558 ret = C_DigestFinal(p11h, out->b_ptr, &len);
559 if (ret != CKR_OK) {
560 PKCS11ERR(error, l, "C_DigestFinal", ret);
561 return (B_FALSE);
562 }
563
564 if (len > buf_left(out)) {
565 bunyan_error(l, "Output buffer for C_Digest was too small",
566 BUNYAN_T_STRING, "func", __func__,
567 BUNYAN_T_STRING, "file", __FILE__,
568 BUNYAN_T_INT32, "line", __LINE__,
569 BUNYAN_T_UINT32, "outsz", (uint32_t)buf_left(out),
570 BUNYAN_T_UINT32, "digestsz", (uint32_t)len,
571 BUNYAN_T_END);
572 return (B_FALSE);
573 }
574
575 return (B_TRUE);
576 }
577
578 static CK_RV
579 pkcs11_callback_handler(CK_SESSION_HANDLE session, CK_NOTIFICATION surrender,
580 void *context)
581 {
582 _NOTE(ARGUNUSED(session, context));
583 VERIFY3U(surrender, ==, CKN_SURRENDER);
584
585 return (CKR_OK);
586 }
587
588 /*
589 * Sadly, string fields in PKCS#11 structs are not NUL-terminated and
590 * are space padded, so this converts it into a more traditional C-string
591 * with quoting so space padding is evident
592 */
593 static void
594 fmtstr(char *buf, size_t buflen, CK_UTF8CHAR *src, size_t srclen)
595 {
596 ASSERT3U(srclen + 1, <=, buflen);
597
598 (void) memset(buf, 0, buflen);
599 (void) memcpy(buf, src, srclen);
600
601 for (char *p = buf + strlen(buf) - 1; p >= buf && *p == ' '; p--)
602 *p = '\0';
603 }