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 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2018, Joyent, Inc.
24 */
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <strings.h>
29 #include <stdio.h>
30 #include <cryptoutil.h>
31 #include <errno.h>
32 #include <security/cryptoki.h>
33 #include <sys/crypto/common.h>
34 #include <sys/crypto/ioctl.h>
35 #include "kernelGlobal.h"
36 #include "kernelObject.h"
37 #include "kernelSlot.h"
38
39 #define ENCODE_ATTR(type, value, len) { \
40 cur_attr->oa_type = type; \
41 (void) memcpy(ptr, value, len); \
42 cur_attr->oa_value = ptr; \
43 cur_attr->oa_value_len = len; \
44 cur_attr++; \
45 }
46
47 #define MECH_HASH(type) (((uintptr_t)type) % KMECH_HASHTABLE_SIZE)
48 /*
49 * Serialize writes to the hash table. We don't need a per bucket lock as
50 * there are only a few writes and we don't need the lock for reads.
51 */
52 pthread_mutex_t mechhash_mutex = PTHREAD_MUTEX_INITIALIZER;
53
54 static CK_RV
kmech_hash_insert(CK_MECHANISM_TYPE type,crypto_mech_type_t kmech)55 kmech_hash_insert(CK_MECHANISM_TYPE type, crypto_mech_type_t kmech)
56 {
57 uint_t h;
58 kmh_elem_t *elem, *cur;
59
60 elem = malloc(sizeof (kmh_elem_t));
61 if (elem == NULL)
62 return (CKR_HOST_MEMORY);
63
64 h = MECH_HASH(type);
65 elem->type = type;
66 elem->kmech = kmech;
67
68 (void) pthread_mutex_lock(&mechhash_mutex);
69 for (cur = kernel_mechhash[h]; cur != NULL; cur = cur->knext) {
70 if (type == cur->type) {
71 /* Some other thread beat us to it. */
72 (void) pthread_mutex_unlock(&mechhash_mutex);
73 free(elem);
74 return (CKR_OK);
75 }
76 }
77 elem->knext = kernel_mechhash[h];
78 kernel_mechhash[h] = elem;
79 (void) pthread_mutex_unlock(&mechhash_mutex);
80
81 return (CKR_OK);
82 }
83
84 CK_RV
kernel_mech(CK_MECHANISM_TYPE type,crypto_mech_type_t * k_number)85 kernel_mech(CK_MECHANISM_TYPE type, crypto_mech_type_t *k_number)
86 {
87 crypto_get_mechanism_number_t get_number;
88 const char *string;
89 CK_RV rv;
90 int r;
91 kmh_elem_t *elem;
92 uint_t h;
93 char buf[11]; /* Num chars for representing ulong in ASCII */
94
95 /*
96 * Search for an existing entry. No need to lock since we are
97 * just a reader and we never free the entries in the hash table.
98 */
99 h = MECH_HASH(type);
100 for (elem = kernel_mechhash[h]; elem != NULL; elem = elem->knext) {
101 if (type == elem->type) {
102 *k_number = elem->kmech;
103 return (CKR_OK);
104 }
105 }
106
107 if (type >= CKM_VENDOR_DEFINED) {
108 (void) snprintf(buf, sizeof (buf), "%#lx", type);
109 string = buf;
110 } else {
111 string = pkcs11_mech2str(type);
112 }
113
114 if (string == NULL)
115 return (CKR_MECHANISM_INVALID);
116
117 get_number.pn_mechanism_string = (char *)string;
118 get_number.pn_mechanism_len = strlen(string) + 1;
119
120 while ((r = ioctl(kernel_fd, CRYPTO_GET_MECHANISM_NUMBER,
121 &get_number)) < 0) {
122 if (errno != EINTR)
123 break;
124 }
125 if (r < 0) {
126 rv = CKR_MECHANISM_INVALID;
127 } else {
128 if (get_number.pn_return_value != CRYPTO_SUCCESS) {
129 rv = crypto2pkcs11_error_number(
130 get_number.pn_return_value);
131 } else {
132 rv = CKR_OK;
133 }
134 }
135
136 if (rv == CKR_OK) {
137 *k_number = get_number.pn_internal_number;
138 /* Add this to the hash table */
139 (void) kmech_hash_insert(type, *k_number);
140 }
141
142 return (rv);
143 }
144
145
146 /*
147 * Return the value of a secret key object.
148 * This routine allocates memory for the value.
149 * A null pointer is returned on error.
150 */
151 unsigned char *
get_symmetric_key_value(kernel_object_t * key_p)152 get_symmetric_key_value(kernel_object_t *key_p)
153 {
154 uint8_t *cipherKey;
155
156 switch (key_p->class) {
157
158 case CKO_SECRET_KEY:
159
160 cipherKey = malloc(OBJ_SEC(key_p)->sk_value_len);
161 if (cipherKey == NULL)
162 return (NULL);
163
164 (void) memcpy(cipherKey, OBJ_SEC(key_p)->sk_value,
165 OBJ_SEC(key_p)->sk_value_len);
166
167 return (cipherKey);
168
169 default:
170 return (NULL);
171 }
172 }
173
174 /*
175 * Convert a RSA private key object into a crypto_key structure.
176 * Memory is allocated for each attribute stored in the crypto_key
177 * structure. Memory for the crypto_key structure is not
178 * allocated. Attributes can be freed by free_key_attributes().
179 */
180 CK_RV
get_rsa_private_key(kernel_object_t * object_p,crypto_key_t * key)181 get_rsa_private_key(kernel_object_t *object_p, crypto_key_t *key)
182 {
183 biginteger_t *big;
184 crypto_object_attribute_t *attrs, *cur_attr;
185 char *ptr;
186 CK_RV rv;
187
188 (void) pthread_mutex_lock(&object_p->object_mutex);
189 if (object_p->key_type != CKK_RSA ||
190 object_p->class != CKO_PRIVATE_KEY) {
191 (void) pthread_mutex_unlock(&object_p->object_mutex);
192 return (CKR_ATTRIBUTE_TYPE_INVALID);
193 }
194
195 attrs = calloc(1,
196 RSA_PRI_ATTR_COUNT * sizeof (crypto_object_attribute_t));
197 if (attrs == NULL) {
198 (void) pthread_mutex_unlock(&object_p->object_mutex);
199 return (CKR_HOST_MEMORY);
200 }
201
202 key->ck_format = CRYPTO_KEY_ATTR_LIST;
203 key->ck_attrs = attrs;
204 cur_attr = attrs;
205
206 /*
207 * Allocate memory for each key attribute and set up the value
208 * value length.
209 */
210 key->ck_count = 0;
211
212 /* CKA_MODULUS is required. */
213 big = OBJ_PRI_RSA_MOD(object_p);
214 if (big->big_value == NULL) {
215 rv = CKR_ATTRIBUTE_TYPE_INVALID;
216 goto fail_cleanup;
217 } else {
218 if ((ptr = malloc(big->big_value_len)) == NULL) {
219 rv = CKR_HOST_MEMORY;
220 goto fail_cleanup;
221 }
222 ENCODE_ATTR(CKA_MODULUS, big->big_value, big->big_value_len);
223 key->ck_count++;
224 }
225
226 /* CKA_PRIVATE_EXPONENT is required. */
227 big = OBJ_PRI_RSA_PRIEXPO(object_p);
228 if (big->big_value == NULL) {
229 rv = CKR_ATTRIBUTE_TYPE_INVALID;
230 goto fail_cleanup;
231 } else {
232 if ((ptr = malloc(big->big_value_len)) == NULL) {
233 rv = CKR_HOST_MEMORY;
234 goto fail_cleanup;
235 }
236 ENCODE_ATTR(CKA_PRIVATE_EXPONENT, big->big_value,
237 big->big_value_len);
238 key->ck_count++;
239 }
240
241 /* CKA_PRIME_1 is optional. */
242 big = OBJ_PRI_RSA_PRIME1(object_p);
243 if (big->big_value != NULL) {
244 if ((ptr = malloc(big->big_value_len)) == NULL) {
245 rv = CKR_HOST_MEMORY;
246 goto fail_cleanup;
247 }
248 ENCODE_ATTR(CKA_PRIME_1, big->big_value, big->big_value_len);
249 key->ck_count++;
250 }
251
252 /* CKA_PRIME_2 is optional. */
253 big = OBJ_PRI_RSA_PRIME2(object_p);
254 if (big->big_value != NULL) {
255 if ((ptr = malloc(big->big_value_len)) == NULL) {
256 rv = CKR_HOST_MEMORY;
257 goto fail_cleanup;
258 }
259 ENCODE_ATTR(CKA_PRIME_2, big->big_value, big->big_value_len);
260 key->ck_count++;
261 }
262
263 /* CKA_EXPONENT_1 is optional. */
264 big = OBJ_PRI_RSA_EXPO1(object_p);
265 if (big->big_value != NULL) {
266 if ((ptr = malloc(big->big_value_len)) == NULL) {
267 rv = CKR_HOST_MEMORY;
268 goto fail_cleanup;
269 }
270 ENCODE_ATTR(CKA_EXPONENT_1, big->big_value,
271 big->big_value_len);
272 key->ck_count++;
273 }
274
275 /* CKA_EXPONENT_2 is optional. */
276 big = OBJ_PRI_RSA_EXPO2(object_p);
277 if (big->big_value != NULL) {
278 if ((ptr = malloc(big->big_value_len)) == NULL) {
279 rv = CKR_HOST_MEMORY;
280 goto fail_cleanup;
281 }
282 ENCODE_ATTR(CKA_EXPONENT_2, big->big_value,
283 big->big_value_len);
284 key->ck_count++;
285 }
286
287 /* CKA_COEFFICIENT is optional. */
288 big = OBJ_PRI_RSA_COEF(object_p);
289 if (big->big_value != NULL) {
290 if ((ptr = malloc(big->big_value_len)) == NULL) {
291 rv = CKR_HOST_MEMORY;
292 goto fail_cleanup;
293 }
294 ENCODE_ATTR(CKA_COEFFICIENT, big->big_value,
295 big->big_value_len);
296 key->ck_count++;
297 }
298
299 (void) pthread_mutex_unlock(&object_p->object_mutex);
300 return (CKR_OK);
301
302 fail_cleanup:
303 (void) pthread_mutex_unlock(&object_p->object_mutex);
304 free_key_attributes(key);
305 return (rv);
306 }
307
308 /*
309 * Convert a RSA public key object into a crypto_key structure.
310 * Memory is allocated for each attribute stored in the crypto_key
311 * structure. Memory for the crypto_key structure is not
312 * allocated. Attributes can be freed by free_key_attributes().
313 */
314 CK_RV
get_rsa_public_key(kernel_object_t * object_p,crypto_key_t * key)315 get_rsa_public_key(kernel_object_t *object_p, crypto_key_t *key)
316 {
317 biginteger_t *big;
318 crypto_object_attribute_t *attrs, *cur_attr;
319 char *ptr;
320
321 (void) pthread_mutex_lock(&object_p->object_mutex);
322 if (object_p->key_type != CKK_RSA ||
323 object_p->class != CKO_PUBLIC_KEY) {
324 (void) pthread_mutex_unlock(&object_p->object_mutex);
325 return (CKR_ATTRIBUTE_TYPE_INVALID);
326 }
327
328 attrs = calloc(1,
329 RSA_PUB_ATTR_COUNT * sizeof (crypto_object_attribute_t));
330 if (attrs == NULL) {
331 (void) pthread_mutex_unlock(&object_p->object_mutex);
332 return (CKR_HOST_MEMORY);
333 }
334
335 key->ck_format = CRYPTO_KEY_ATTR_LIST;
336 key->ck_count = RSA_PUB_ATTR_COUNT;
337 key->ck_attrs = attrs;
338
339 cur_attr = attrs;
340 big = OBJ_PUB_RSA_PUBEXPO(object_p);
341 if ((ptr = malloc(big->big_value_len)) == NULL)
342 goto mem_failure;
343 ENCODE_ATTR(CKA_PUBLIC_EXPONENT, big->big_value, big->big_value_len);
344
345 big = OBJ_PUB_RSA_MOD(object_p);
346 if ((ptr = malloc(big->big_value_len)) == NULL)
347 goto mem_failure;
348 ENCODE_ATTR(CKA_MODULUS, big->big_value, big->big_value_len);
349
350 if ((ptr = malloc(sizeof (CK_ULONG))) == NULL)
351 goto mem_failure;
352 ENCODE_ATTR(CKA_MODULUS_BITS, &OBJ_PUB_RSA_MOD_BITS(object_p),
353 sizeof (CK_ULONG));
354
355 (void) pthread_mutex_unlock(&object_p->object_mutex);
356 return (CKR_OK);
357
358 mem_failure:
359 (void) pthread_mutex_unlock(&object_p->object_mutex);
360 free_key_attributes(key);
361 return (CKR_HOST_MEMORY);
362 }
363
364 /*
365 * Free attribute storage in a crypto_key structure.
366 */
367 void
free_key_attributes(crypto_key_t * key)368 free_key_attributes(crypto_key_t *key)
369 {
370 int i;
371
372 if (key->ck_format == CRYPTO_KEY_ATTR_LIST &&
373 (key->ck_count > 0) && key->ck_attrs != NULL) {
374 for (i = 0; i < key->ck_count; i++) {
375 freezero(key->ck_attrs[i].oa_value,
376 key->ck_attrs[i].oa_value_len);
377 }
378 free(key->ck_attrs);
379 }
380 }
381
382
383 /*
384 * Convert a DSA private key object into a crypto_key structure.
385 * Memory is allocated for each attribute stored in the crypto_key
386 * structure. Memory for the crypto_key structure is not
387 * allocated. Attributes can be freed by free_dsa_key_attributes().
388 */
389 CK_RV
get_dsa_private_key(kernel_object_t * object_p,crypto_key_t * key)390 get_dsa_private_key(kernel_object_t *object_p, crypto_key_t *key)
391 {
392 biginteger_t *big;
393 crypto_object_attribute_t *attrs, *cur_attr;
394 char *ptr;
395
396 (void) pthread_mutex_lock(&object_p->object_mutex);
397 if (object_p->key_type != CKK_DSA ||
398 object_p->class != CKO_PRIVATE_KEY) {
399 (void) pthread_mutex_unlock(&object_p->object_mutex);
400 return (CKR_ATTRIBUTE_TYPE_INVALID);
401 }
402
403 attrs = calloc(1,
404 DSA_ATTR_COUNT * sizeof (crypto_object_attribute_t));
405 if (attrs == NULL) {
406 (void) pthread_mutex_unlock(&object_p->object_mutex);
407 return (CKR_HOST_MEMORY);
408 }
409
410 key->ck_format = CRYPTO_KEY_ATTR_LIST;
411 key->ck_count = DSA_ATTR_COUNT;
412 key->ck_attrs = attrs;
413
414 cur_attr = attrs;
415 big = OBJ_PRI_DSA_PRIME(object_p);
416 if ((ptr = malloc(big->big_value_len)) == NULL)
417 goto mem_failure;
418 ENCODE_ATTR(CKA_PRIME, big->big_value, big->big_value_len);
419
420 big = OBJ_PRI_DSA_SUBPRIME(object_p);
421 if ((ptr = malloc(big->big_value_len)) == NULL)
422 goto mem_failure;
423 ENCODE_ATTR(CKA_SUBPRIME, big->big_value, big->big_value_len);
424
425 big = OBJ_PRI_DSA_BASE(object_p);
426 if ((ptr = malloc(big->big_value_len)) == NULL)
427 goto mem_failure;
428 ENCODE_ATTR(CKA_BASE, big->big_value, big->big_value_len);
429
430 big = OBJ_PRI_DSA_VALUE(object_p);
431 if ((ptr = malloc(big->big_value_len)) == NULL)
432 goto mem_failure;
433 ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len);
434
435 (void) pthread_mutex_unlock(&object_p->object_mutex);
436 return (CKR_OK);
437
438 mem_failure:
439 (void) pthread_mutex_unlock(&object_p->object_mutex);
440 free_key_attributes(key);
441 return (CKR_HOST_MEMORY);
442 }
443
444
445 /*
446 * Convert a DSA public key object into a crypto_key structure.
447 * Memory is allocated for each attribute stored in the crypto_key
448 * structure. Memory for the crypto_key structure is not
449 * allocated. Attributes can be freed by free_dsa_key_attributes().
450 */
451 CK_RV
get_dsa_public_key(kernel_object_t * object_p,crypto_key_t * key)452 get_dsa_public_key(kernel_object_t *object_p, crypto_key_t *key)
453 {
454 biginteger_t *big;
455 crypto_object_attribute_t *attrs, *cur_attr;
456 char *ptr;
457
458 (void) pthread_mutex_lock(&object_p->object_mutex);
459 if (object_p->key_type != CKK_DSA ||
460 object_p->class != CKO_PUBLIC_KEY) {
461 (void) pthread_mutex_unlock(&object_p->object_mutex);
462 return (CKR_ATTRIBUTE_TYPE_INVALID);
463 }
464
465 attrs = calloc(1,
466 DSA_ATTR_COUNT * sizeof (crypto_object_attribute_t));
467 if (attrs == NULL) {
468 (void) pthread_mutex_unlock(&object_p->object_mutex);
469 return (CKR_HOST_MEMORY);
470 }
471
472 key->ck_format = CRYPTO_KEY_ATTR_LIST;
473 key->ck_count = DSA_ATTR_COUNT;
474 key->ck_attrs = attrs;
475
476 cur_attr = attrs;
477 big = OBJ_PUB_DSA_PRIME(object_p);
478 if ((ptr = malloc(big->big_value_len)) == NULL)
479 goto mem_failure;
480 ENCODE_ATTR(CKA_PRIME, big->big_value, big->big_value_len);
481
482 big = OBJ_PUB_DSA_SUBPRIME(object_p);
483 if ((ptr = malloc(big->big_value_len)) == NULL)
484 goto mem_failure;
485 ENCODE_ATTR(CKA_SUBPRIME, big->big_value, big->big_value_len);
486
487 big = OBJ_PUB_DSA_BASE(object_p);
488 if ((ptr = malloc(big->big_value_len)) == NULL)
489 goto mem_failure;
490 ENCODE_ATTR(CKA_BASE, big->big_value, big->big_value_len);
491
492 big = OBJ_PUB_DSA_VALUE(object_p);
493 if ((ptr = malloc(big->big_value_len)) == NULL)
494 goto mem_failure;
495 ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len);
496
497 (void) pthread_mutex_unlock(&object_p->object_mutex);
498 return (CKR_OK);
499
500 mem_failure:
501 (void) pthread_mutex_unlock(&object_p->object_mutex);
502 free_key_attributes(key);
503 return (CKR_HOST_MEMORY);
504 }
505
506
507 /*
508 * Convert a EC private key object into a crypto_key structure.
509 * Memory is allocated for each attribute stored in the crypto_key
510 * structure. Memory for the crypto_key structure is not
511 * allocated. Attributes can be freed by free_ec_key_attributes().
512 */
513 CK_RV
get_ec_private_key(kernel_object_t * object_p,crypto_key_t * key)514 get_ec_private_key(kernel_object_t *object_p, crypto_key_t *key)
515 {
516 biginteger_t *big;
517 crypto_object_attribute_t *attrs, *cur_attr;
518 CK_ATTRIBUTE tmp;
519 char *ptr;
520 int rv;
521
522 (void) pthread_mutex_lock(&object_p->object_mutex);
523 if (object_p->key_type != CKK_EC ||
524 object_p->class != CKO_PRIVATE_KEY) {
525 (void) pthread_mutex_unlock(&object_p->object_mutex);
526 return (CKR_ATTRIBUTE_TYPE_INVALID);
527 }
528
529 attrs = calloc(EC_ATTR_COUNT, sizeof (crypto_object_attribute_t));
530 if (attrs == NULL) {
531 (void) pthread_mutex_unlock(&object_p->object_mutex);
532 return (CKR_HOST_MEMORY);
533 }
534
535 key->ck_format = CRYPTO_KEY_ATTR_LIST;
536 key->ck_count = EC_ATTR_COUNT;
537 key->ck_attrs = attrs;
538
539 cur_attr = attrs;
540 big = OBJ_PRI_EC_VALUE(object_p);
541 if ((ptr = malloc(big->big_value_len)) == NULL) {
542 rv = CKR_HOST_MEMORY;
543 goto fail;
544 }
545 ENCODE_ATTR(CKA_VALUE, big->big_value, big->big_value_len);
546
547 tmp.type = CKA_EC_PARAMS;
548 tmp.pValue = NULL;
549 rv = kernel_get_attribute(object_p, &tmp);
550 if (rv != CKR_OK) {
551 goto fail;
552 }
553
554 tmp.pValue = malloc(tmp.ulValueLen);
555 if (tmp.pValue == NULL) {
556 rv = CKR_HOST_MEMORY;
557 goto fail;
558 }
559
560 rv = kernel_get_attribute(object_p, &tmp);
561 if (rv != CKR_OK) {
562 free(tmp.pValue);
563 goto fail;
564 }
565
566 cur_attr->oa_type = tmp.type;
567 cur_attr->oa_value = tmp.pValue;
568 cur_attr->oa_value_len = tmp.ulValueLen;
569
570 (void) pthread_mutex_unlock(&object_p->object_mutex);
571 return (CKR_OK);
572
573 fail:
574 (void) pthread_mutex_unlock(&object_p->object_mutex);
575 free_key_attributes(key);
576 return (rv);
577 }
578
579 /*
580 * Convert an EC public key object into a crypto_key structure.
581 * Memory is allocated for each attribute stored in the crypto_key
582 * structure. Memory for the crypto_key structure is not
583 * allocated. Attributes can be freed by free_ec_key_attributes().
584 */
585 CK_RV
get_ec_public_key(kernel_object_t * object_p,crypto_key_t * key)586 get_ec_public_key(kernel_object_t *object_p, crypto_key_t *key)
587 {
588 biginteger_t *big;
589 crypto_object_attribute_t *attrs, *cur_attr;
590 CK_ATTRIBUTE tmp;
591 char *ptr;
592 int rv;
593
594 (void) pthread_mutex_lock(&object_p->object_mutex);
595 if (object_p->key_type != CKK_EC ||
596 object_p->class != CKO_PUBLIC_KEY) {
597 (void) pthread_mutex_unlock(&object_p->object_mutex);
598 return (CKR_ATTRIBUTE_TYPE_INVALID);
599 }
600
601 attrs = calloc(EC_ATTR_COUNT, sizeof (crypto_object_attribute_t));
602 if (attrs == NULL) {
603 (void) pthread_mutex_unlock(&object_p->object_mutex);
604 return (CKR_HOST_MEMORY);
605 }
606
607 key->ck_format = CRYPTO_KEY_ATTR_LIST;
608 key->ck_count = EC_ATTR_COUNT;
609 key->ck_attrs = attrs;
610
611 cur_attr = attrs;
612 big = OBJ_PUB_EC_POINT(object_p);
613 if ((ptr = malloc(big->big_value_len)) == NULL) {
614 rv = CKR_HOST_MEMORY;
615 goto fail;
616 }
617 ENCODE_ATTR(CKA_EC_POINT, big->big_value, big->big_value_len);
618
619 tmp.type = CKA_EC_PARAMS;
620 tmp.pValue = NULL;
621 rv = kernel_get_attribute(object_p, &tmp);
622 if (rv != CKR_OK) {
623 goto fail;
624 }
625
626 tmp.pValue = malloc(tmp.ulValueLen);
627 if (tmp.pValue == NULL) {
628 rv = CKR_HOST_MEMORY;
629 goto fail;
630 }
631
632 rv = kernel_get_attribute(object_p, &tmp);
633 if (rv != CKR_OK) {
634 free(tmp.pValue);
635 goto fail;
636 }
637
638 cur_attr->oa_type = tmp.type;
639 cur_attr->oa_value = tmp.pValue;
640 cur_attr->oa_value_len = tmp.ulValueLen;
641
642 (void) pthread_mutex_unlock(&object_p->object_mutex);
643 return (CKR_OK);
644
645 fail:
646 (void) pthread_mutex_unlock(&object_p->object_mutex);
647 free_key_attributes(key);
648 return (rv);
649 }
650
651 /*
652 * Convert an attribute template into an obj_attrs array.
653 * Memory is allocated for each attribute stored in the obj_attrs.
654 * The memory can be freed by free_object_attributes().
655 *
656 * If the boolean pointer is_token_obj is not NULL, the caller wants to
657 * retrieve the value of the CKA_TOKEN attribute if it is specified in the
658 * template.
659 * - When this routine is called thru C_CreateObject(), C_CopyObject(), or
660 * any key management function, is_token_obj should NOT be NULL.
661 * - When this routine is called thru C_GetAttributeValue() or
662 * C_SetAttributeValue(), "is_token_obj" should be NULL.
663 */
664 CK_RV
process_object_attributes(CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,caddr_t * obj_attrs,CK_BBOOL * is_token_obj)665 process_object_attributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
666 caddr_t *obj_attrs, CK_BBOOL *is_token_obj)
667 {
668 crypto_object_attribute_t *attrs, *cur_attr;
669 int i, cur_i;
670 char *ptr;
671 CK_RV rv;
672 ssize_t value_len;
673
674 if (ulCount == 0) {
675 obj_attrs = NULL;
676 return (CKR_OK);
677 }
678
679 attrs = calloc(1, ulCount * sizeof (crypto_object_attribute_t));
680 if (attrs == NULL) {
681 return (CKR_HOST_MEMORY);
682 }
683
684 cur_attr = attrs;
685 for (i = 0; i < ulCount; i++) {
686 /*
687 * The length of long attributes must be set correctly
688 * so providers can determine whether they came from 32
689 * or 64-bit applications.
690 */
691 switch (pTemplate[i].type) {
692 case CKA_CLASS:
693 case CKA_CERTIFICATE_TYPE:
694 case CKA_KEY_TYPE:
695 case CKA_MODULUS_BITS:
696 case CKA_HW_FEATURE_TYPE:
697 value_len = sizeof (ulong_t);
698 if (pTemplate[i].pValue != NULL &&
699 (pTemplate[i].ulValueLen < value_len)) {
700 rv = CKR_ATTRIBUTE_VALUE_INVALID;
701 cur_i = i;
702 goto fail_cleanup;
703 }
704 break;
705 default:
706 value_len = pTemplate[i].ulValueLen;
707 }
708
709 cur_attr->oa_type = pTemplate[i].type;
710 cur_attr->oa_value_len = value_len;
711 cur_attr->oa_value = NULL;
712
713 if ((pTemplate[i].pValue != NULL) &&
714 (pTemplate[i].ulValueLen > 0)) {
715 ptr = malloc(pTemplate[i].ulValueLen);
716 if (ptr == NULL) {
717 rv = CKR_HOST_MEMORY;
718 cur_i = i;
719 goto fail_cleanup;
720 } else {
721 (void) memcpy(ptr, pTemplate[i].pValue,
722 pTemplate[i].ulValueLen);
723 cur_attr->oa_value = ptr;
724 }
725 }
726
727 if ((is_token_obj != NULL) &&
728 (pTemplate[i].type == CKA_TOKEN)) {
729 /* Get the CKA_TOKEN attribute value. */
730 if (pTemplate[i].pValue == NULL) {
731 rv = CKR_ATTRIBUTE_VALUE_INVALID;
732 cur_i = i;
733 goto fail_cleanup;
734 } else {
735 *is_token_obj =
736 *(CK_BBOOL *)pTemplate[i].pValue;
737 }
738 }
739
740 cur_attr++;
741 }
742
743 *obj_attrs = (char *)attrs;
744 return (CKR_OK);
745
746 fail_cleanup:
747 cur_attr = attrs;
748 for (i = 0; i < cur_i; i++) {
749 if (cur_attr->oa_value != NULL) {
750 (void) free(cur_attr->oa_value);
751 }
752 cur_attr++;
753 }
754
755 (void) free(attrs);
756 return (rv);
757 }
758
759
760 /*
761 * Copy the attribute values from obj_attrs to pTemplate.
762 * The obj_attrs is an image of the Template and is expected to have the
763 * same attributes in the same order and each one of the attribute pValue
764 * in obj_attr has enough space allocated for the corresponding valueLen
765 * in pTemplate.
766 */
767 CK_RV
get_object_attributes(CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,caddr_t obj_attrs)768 get_object_attributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
769 caddr_t obj_attrs)
770 {
771 crypto_object_attribute_t *cur_attr;
772 CK_RV rv = CKR_OK;
773 int i;
774
775 /* LINTED */
776 cur_attr = (crypto_object_attribute_t *)obj_attrs;
777 for (i = 0; i < ulCount; i++) {
778 if (pTemplate[i].type != cur_attr->oa_type) {
779 /* The attribute type doesn't match, this is bad. */
780 rv = CKR_FUNCTION_FAILED;
781 return (rv);
782 }
783
784 pTemplate[i].ulValueLen = cur_attr->oa_value_len;
785
786 if ((pTemplate[i].pValue != NULL) &&
787 ((CK_LONG)pTemplate[i].ulValueLen != -1)) {
788 (void) memcpy(pTemplate[i].pValue, cur_attr->oa_value,
789 pTemplate[i].ulValueLen);
790 }
791 cur_attr++;
792 }
793
794 return (rv);
795 }
796
797 /*
798 * Free the attribute storage in a crypto_object_attribute_t structure.
799 */
800 void
free_object_attributes(caddr_t obj_attrs,CK_ULONG ulCount)801 free_object_attributes(caddr_t obj_attrs, CK_ULONG ulCount)
802 {
803 crypto_object_attribute_t *cur_attr;
804 int i;
805
806 if ((ulCount == 0) || (obj_attrs == NULL)) {
807 return;
808 }
809
810 /* LINTED */
811 cur_attr = (crypto_object_attribute_t *)obj_attrs;
812 for (i = 0; i < ulCount; i++) {
813 /* XXX check that oa_value > 0 */
814 if (cur_attr->oa_value != NULL) {
815 free(cur_attr->oa_value);
816 }
817 cur_attr++;
818 }
819
820 free(obj_attrs);
821 }
822
823 /*
824 * This function is called by process_found_objects(). It will check the
825 * CKA_PRIVATE and CKA_TOKEN attributes for the kernel object "oid", then
826 * initialize all the necessary fields in the object wrapper "objp".
827 */
828 static CK_RV
create_new_tobj_in_lib(kernel_slot_t * pslot,kernel_session_t * sp,kernel_object_t * objp,crypto_object_id_t oid)829 create_new_tobj_in_lib(kernel_slot_t *pslot, kernel_session_t *sp,
830 kernel_object_t *objp, crypto_object_id_t oid)
831 {
832 CK_RV rv = CKR_OK;
833 crypto_object_get_attribute_value_t obj_ga;
834 boolean_t is_pri_obj;
835 boolean_t is_token_obj;
836 CK_BBOOL pri_value, token_value;
837 CK_ATTRIBUTE pTemplate[2];
838 int r;
839
840 /*
841 * Make a CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE ioctl call to get this
842 * kernel object's attribute values for CKA_PRIVATE and CKA_TOKEN.
843 */
844 obj_ga.og_session = sp->k_session;
845 obj_ga.og_handle = oid;
846 obj_ga.og_count = 2;
847
848 pTemplate[0].type = CKA_PRIVATE;
849 pTemplate[0].pValue = &pri_value;
850 pTemplate[0].ulValueLen = sizeof (pri_value);
851 pTemplate[1].type = CKA_TOKEN;
852 pTemplate[1].pValue = &token_value;
853 pTemplate[1].ulValueLen = sizeof (token_value);
854 rv = process_object_attributes(pTemplate, 2, &obj_ga.og_attributes,
855 NULL);
856 if (rv != CKR_OK) {
857 return (rv);
858 }
859
860 while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE,
861 &obj_ga)) < 0) {
862 if (errno != EINTR)
863 break;
864 }
865 if (r < 0) {
866 rv = CKR_FUNCTION_FAILED;
867 } else {
868 rv = crypto2pkcs11_error_number(obj_ga.og_return_value);
869 }
870
871 if (rv == CKR_OK) {
872 rv = get_object_attributes(pTemplate, 2, obj_ga.og_attributes);
873 if (rv == CKR_OK) {
874 is_pri_obj = *(CK_BBOOL *)pTemplate[0].pValue;
875 is_token_obj = *(CK_BBOOL *)pTemplate[1].pValue;
876 }
877 }
878
879 free_object_attributes(obj_ga.og_attributes, 2);
880 if (rv != CKR_OK) {
881 return (rv);
882 }
883
884 /* Make sure it is a token object. */
885 if (!is_token_obj) {
886 rv = CKR_ATTRIBUTE_VALUE_INVALID;
887 return (rv);
888 }
889
890 /* If it is a private object, make sure the user has logged in. */
891 if (is_pri_obj && (pslot->sl_state != CKU_USER)) {
892 rv = CKR_ATTRIBUTE_VALUE_INVALID;
893 return (rv);
894 }
895
896 objp->is_lib_obj = B_FALSE;
897 objp->k_handle = oid;
898 objp->bool_attr_mask |= TOKEN_BOOL_ON;
899 if (is_pri_obj) {
900 objp->bool_attr_mask |= PRIVATE_BOOL_ON;
901 } else {
902 objp->bool_attr_mask &= ~PRIVATE_BOOL_ON;
903 }
904
905 (void) pthread_mutex_init(&objp->object_mutex, NULL);
906 objp->magic_marker = KERNELTOKEN_OBJECT_MAGIC;
907 objp->session_handle = (CK_SESSION_HANDLE) sp;
908
909 return (CKR_OK);
910 }
911
912 /*
913 * This function processes the kernel object handles returned from the
914 * CRYPTO_OBJECT_FIND_UPDATE ioctl and returns an object handle list
915 * and the number of object handles to the caller - C_FindObjects().
916 * The caller acquires the slot lock and the session lock.
917 */
918 CK_RV
process_found_objects(kernel_session_t * cur_sp,CK_OBJECT_HANDLE * obj_found,CK_ULONG * found_obj_count,crypto_object_find_update_t obj_fu)919 process_found_objects(kernel_session_t *cur_sp, CK_OBJECT_HANDLE *obj_found,
920 CK_ULONG *found_obj_count, crypto_object_find_update_t obj_fu)
921 {
922 CK_RV rv = CKR_OK;
923 crypto_object_id_t *oid_p;
924 kernel_slot_t *pslot;
925 kernel_object_t *objp;
926 kernel_object_t *objp1;
927 kernel_object_t *new_tobj_list = NULL;
928 kernel_session_t *sp;
929 CK_ULONG num_obj_found = 0;
930 boolean_t is_in_lib;
931 int i;
932
933 if (obj_fu.fu_count == 0) {
934 *found_obj_count = 0;
935 return (CKR_OK);
936 }
937
938 pslot = slot_table[cur_sp->ses_slotid];
939
940 /* LINTED */
941 oid_p = (crypto_object_id_t *)obj_fu.fu_handles;
942 for (i = 0; i < obj_fu.fu_count; i++) {
943 is_in_lib = B_FALSE;
944 /*
945 * Check if this oid has an object wrapper in the library
946 * already. First, search the slot's token object list.
947 */
948 objp = pslot->sl_tobj_list;
949 while (!is_in_lib && objp) {
950 if (objp->k_handle == *oid_p) {
951 is_in_lib = B_TRUE;
952 } else {
953 objp = objp->next;
954 }
955 }
956
957 /*
958 * If it is not in the slot's token object list,
959 * search it in all the sessions.
960 */
961 if (!is_in_lib) {
962 sp = pslot->sl_sess_list;
963 while (!is_in_lib && sp) {
964 objp = sp->object_list;
965 while (!is_in_lib && objp) {
966 if (objp->k_handle == *oid_p) {
967 is_in_lib = B_TRUE;
968 } else {
969 objp = objp->next;
970 }
971 }
972 sp = sp->next;
973 }
974 }
975
976 /*
977 * If this object is in the library already, add its object
978 * wrapper to the returned find object list.
979 */
980 if (is_in_lib) {
981 obj_found[num_obj_found++] = (CK_OBJECT_HANDLE)objp;
982 }
983
984 /*
985 * If we still do not find it in the library. This object
986 * must be a token object pre-existed in the HW provider.
987 * We need to create an object wrapper for it in the library.
988 */
989 if (!is_in_lib) {
990 objp1 = calloc(1, sizeof (kernel_object_t));
991 if (objp1 == NULL) {
992 rv = CKR_HOST_MEMORY;
993 goto failed_exit;
994 }
995 rv = create_new_tobj_in_lib(pslot, cur_sp, objp1,
996 *oid_p);
997
998 if (rv == CKR_OK) {
999 /* Save the new object to the new_tobj_list. */
1000 if (new_tobj_list == NULL) {
1001 new_tobj_list = objp1;
1002 objp1->next = NULL;
1003 objp1->prev = NULL;
1004 } else {
1005 new_tobj_list->prev = objp1;
1006 objp1->next = new_tobj_list;
1007 objp1->prev = NULL;
1008 new_tobj_list = objp1;
1009 }
1010 } else {
1011 /*
1012 * If create_new_tobj_in_lib() doesn't fail
1013 * with CKR_HOST_MEMORY, the failure should be
1014 * caused by the attributes' checking. We will
1015 * just ignore this object and continue on.
1016 */
1017 free(objp1);
1018 if (rv == CKR_HOST_MEMORY) {
1019 goto failed_exit;
1020 }
1021 }
1022 }
1023
1024 /* Process next one */
1025 oid_p++;
1026 }
1027
1028 /*
1029 * Add the newly created token object wrappers to the found object
1030 * list and to the slot's token object list.
1031 */
1032 if (new_tobj_list != NULL) {
1033 /* Add to the obj_found array. */
1034 objp = new_tobj_list;
1035 while (objp) {
1036 obj_found[num_obj_found++] = (CK_OBJECT_HANDLE)objp;
1037 if (objp->next == NULL) {
1038 break;
1039 }
1040 objp = objp->next;
1041 }
1042
1043 /* Add to the beginning of the slot's token object list. */
1044 if (pslot->sl_tobj_list != NULL) {
1045 objp->next = pslot->sl_tobj_list;
1046 pslot->sl_tobj_list->prev = objp;
1047 }
1048 pslot->sl_tobj_list = new_tobj_list;
1049 }
1050
1051 *found_obj_count = num_obj_found;
1052 return (CKR_OK);
1053
1054 failed_exit:
1055
1056 /* Free the newly created token object wrappers. */
1057 objp = new_tobj_list;
1058 while (objp) {
1059 objp1 = objp->next;
1060 (void) pthread_mutex_destroy(&objp->object_mutex);
1061 free(objp);
1062 objp = objp1;
1063 }
1064
1065 return (rv);
1066 }
1067
1068
1069 /*
1070 * Get the value of the CKA_PRIVATE attribute for the object just returned
1071 * from the HW provider. This function will be called by any function
1072 * that creates a new object, because the CKA_PRIVATE value of an object is
1073 * token specific. The CKA_PRIVATE attribute value of the new object will be
1074 * stored in the object structure in the library, which will be used later at
1075 * C_Logout to clean up all private objects.
1076 */
1077 CK_RV
get_cka_private_value(kernel_session_t * sp,crypto_object_id_t oid,CK_BBOOL * is_pri_obj)1078 get_cka_private_value(kernel_session_t *sp, crypto_object_id_t oid,
1079 CK_BBOOL *is_pri_obj)
1080 {
1081 CK_RV rv = CKR_OK;
1082 crypto_object_get_attribute_value_t obj_ga;
1083 crypto_object_attribute_t obj_attr;
1084 CK_BBOOL pri_value;
1085 int r;
1086
1087 obj_ga.og_session = sp->k_session;
1088 obj_ga.og_handle = oid;
1089 obj_ga.og_count = 1;
1090
1091 obj_attr.oa_type = CKA_PRIVATE;
1092 obj_attr.oa_value = (char *)&pri_value;
1093 obj_attr.oa_value_len = sizeof (CK_BBOOL);
1094 obj_ga.og_attributes = (char *)&obj_attr;
1095
1096 while ((r = ioctl(kernel_fd, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE,
1097 &obj_ga)) < 0) {
1098 if (errno != EINTR)
1099 break;
1100 }
1101 if (r < 0) {
1102 rv = CKR_FUNCTION_FAILED;
1103 } else {
1104 rv = crypto2pkcs11_error_number(obj_ga.og_return_value);
1105 }
1106
1107 if (rv == CKR_OK) {
1108 *is_pri_obj = *(CK_BBOOL *)obj_attr.oa_value;
1109 }
1110
1111 return (rv);
1112 }
1113
1114
1115 CK_RV
get_mechanism_info(kernel_slot_t * pslot,CK_MECHANISM_TYPE type,CK_MECHANISM_INFO_PTR pInfo,uint32_t * k_mi_flags)1116 get_mechanism_info(kernel_slot_t *pslot, CK_MECHANISM_TYPE type,
1117 CK_MECHANISM_INFO_PTR pInfo, uint32_t *k_mi_flags)
1118 {
1119 crypto_get_provider_mechanism_info_t mechanism_info;
1120 const char *string;
1121 CK_FLAGS flags, mi_flags;
1122 CK_RV rv;
1123 int r;
1124 char buf[11]; /* Num chars for representing ulong in ASCII */
1125
1126 if (type >= CKM_VENDOR_DEFINED) {
1127 /* allocate/build a string containing the mechanism number */
1128 (void) snprintf(buf, sizeof (buf), "%#lx", type);
1129 string = buf;
1130 } else {
1131 string = pkcs11_mech2str(type);
1132 }
1133
1134 if (string == NULL)
1135 return (CKR_MECHANISM_INVALID);
1136
1137 (void) strcpy(mechanism_info.mi_mechanism_name, string);
1138 mechanism_info.mi_provider_id = pslot->sl_provider_id;
1139
1140 while ((r = ioctl(kernel_fd, CRYPTO_GET_PROVIDER_MECHANISM_INFO,
1141 &mechanism_info)) < 0) {
1142 if (errno != EINTR)
1143 break;
1144 }
1145 if (r < 0) {
1146 rv = CKR_FUNCTION_FAILED;
1147 } else {
1148 rv = crypto2pkcs11_error_number(
1149 mechanism_info.mi_return_value);
1150 }
1151
1152 if (rv != CKR_OK) {
1153 return (rv);
1154 }
1155
1156 /*
1157 * Atomic flags are not part of PKCS#11 so we filter
1158 * them out here.
1159 */
1160 mi_flags = mechanism_info.mi_flags;
1161 mi_flags &= ~(CRYPTO_FG_DIGEST_ATOMIC | CRYPTO_FG_ENCRYPT_ATOMIC |
1162 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_MAC_ATOMIC |
1163 CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC |
1164 CRYPTO_FG_SIGN_RECOVER_ATOMIC |
1165 CRYPTO_FG_VERIFY_RECOVER_ATOMIC |
1166 CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
1167 CRYPTO_FG_MAC_DECRYPT_ATOMIC);
1168
1169 if (mi_flags == 0) {
1170 return (CKR_MECHANISM_INVALID);
1171 }
1172
1173 if (rv == CKR_OK) {
1174 /* set the value of k_mi_flags first */
1175 *k_mi_flags = mi_flags;
1176
1177 /* convert KEF flags into pkcs11 flags */
1178 flags = CKF_HW;
1179 if (mi_flags & CRYPTO_FG_ENCRYPT)
1180 flags |= CKF_ENCRYPT;
1181 if (mi_flags & CRYPTO_FG_DECRYPT) {
1182 flags |= CKF_DECRYPT;
1183 /*
1184 * Since we'll be emulating C_UnwrapKey() for some
1185 * cases, we can go ahead and claim CKF_UNWRAP
1186 */
1187 flags |= CKF_UNWRAP;
1188 }
1189 if (mi_flags & CRYPTO_FG_DIGEST)
1190 flags |= CKF_DIGEST;
1191 if (mi_flags & CRYPTO_FG_SIGN)
1192 flags |= CKF_SIGN;
1193 if (mi_flags & CRYPTO_FG_SIGN_RECOVER)
1194 flags |= CKF_SIGN_RECOVER;
1195 if (mi_flags & CRYPTO_FG_VERIFY)
1196 flags |= CKF_VERIFY;
1197 if (mi_flags & CRYPTO_FG_VERIFY_RECOVER)
1198 flags |= CKF_VERIFY_RECOVER;
1199 if (mi_flags & CRYPTO_FG_GENERATE)
1200 flags |= CKF_GENERATE;
1201 if (mi_flags & CRYPTO_FG_GENERATE_KEY_PAIR)
1202 flags |= CKF_GENERATE_KEY_PAIR;
1203 if (mi_flags & CRYPTO_FG_WRAP)
1204 flags |= CKF_WRAP;
1205 if (mi_flags & CRYPTO_FG_UNWRAP)
1206 flags |= CKF_UNWRAP;
1207 if (mi_flags & CRYPTO_FG_DERIVE)
1208 flags |= CKF_DERIVE;
1209
1210 pInfo->ulMinKeySize = mechanism_info.mi_min_key_size;
1211 pInfo->ulMaxKeySize = mechanism_info.mi_max_key_size;
1212 pInfo->flags = flags;
1213
1214 }
1215
1216 return (rv);
1217 }
1218
1219 /*
1220 * Unfortunately the kernel and PKCS#11 use a slightly different struct to
1221 * specify CCM parameters.
1222 */
1223 void
p11_to_kernel_ccm_params(const CK_CCM_PARAMS * in,CK_AES_CCM_PARAMS * out)1224 p11_to_kernel_ccm_params(const CK_CCM_PARAMS *in, CK_AES_CCM_PARAMS *out)
1225 {
1226 out->ulMACSize = in->ulMACLen;
1227 out->ulNonceSize = in->ulNonceLen;
1228 out->ulAuthDataSize = in->ulAADLen;
1229 out->ulDataSize = in->ulDataLen;
1230 out->nonce = in->pNonce;
1231 out->authData = in->pAAD;
1232 }
1233