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 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright 2012 Milan Jurik. All rights reserved.
25 */
26
27 #include <stdlib.h>
28 #include <string.h>
29 #include <security/cryptoki.h>
30 #include <sys/crypto/common.h>
31 #include <aes_impl.h>
32 #include <blowfish_impl.h>
33 #include <arcfour.h>
34 #include <des_impl.h>
35 #include "kernelGlobal.h"
36 #include "kernelObject.h"
37 #include "kernelSession.h"
38 #include "kernelSlot.h"
39
40
41 /*
42 * This attribute table is used by the kernel_lookup_attr()
43 * to validate the attributes.
44 */
45 CK_ATTRIBUTE_TYPE attr_map[] = {
46 CKA_PRIVATE,
47 CKA_LABEL,
48 CKA_APPLICATION,
49 CKA_OBJECT_ID,
50 CKA_CERTIFICATE_TYPE,
51 CKA_ISSUER,
52 CKA_SERIAL_NUMBER,
53 CKA_AC_ISSUER,
54 CKA_OWNER,
55 CKA_ATTR_TYPES,
56 CKA_SUBJECT,
57 CKA_ID,
58 CKA_SENSITIVE,
59 CKA_START_DATE,
60 CKA_END_DATE,
61 CKA_MODULUS,
62 CKA_MODULUS_BITS,
63 CKA_PUBLIC_EXPONENT,
64 CKA_PRIVATE_EXPONENT,
65 CKA_PRIME_1,
66 CKA_PRIME_2,
67 CKA_EXPONENT_1,
68 CKA_EXPONENT_2,
69 CKA_COEFFICIENT,
70 CKA_PRIME,
71 CKA_SUBPRIME,
72 CKA_BASE,
73 CKA_EXTRACTABLE,
74 CKA_LOCAL,
75 CKA_NEVER_EXTRACTABLE,
76 CKA_ALWAYS_SENSITIVE,
77 CKA_MODIFIABLE,
78 CKA_ECDSA_PARAMS,
79 CKA_EC_POINT,
80 CKA_SECONDARY_AUTH,
81 CKA_AUTH_PIN_FLAGS,
82 CKA_HW_FEATURE_TYPE,
83 CKA_RESET_ON_INIT,
84 CKA_HAS_RESET
85 };
86
87 /*
88 * attributes that exists only in public key objects
89 * Note: some attributes may also exist in one or two
90 * other object classes, but they are also listed
91 * because not all object have them.
92 */
93 CK_ATTRIBUTE_TYPE PUB_KEY_ATTRS[] =
94 {
95 CKA_SUBJECT,
96 CKA_ENCRYPT,
97 CKA_WRAP,
98 CKA_VERIFY,
99 CKA_VERIFY_RECOVER,
100 CKA_MODULUS,
101 CKA_MODULUS_BITS,
102 CKA_PUBLIC_EXPONENT,
103 CKA_PRIME,
104 CKA_SUBPRIME,
105 CKA_BASE,
106 CKA_TRUSTED,
107 CKA_ECDSA_PARAMS,
108 CKA_EC_PARAMS,
109 CKA_EC_POINT
110 };
111
112 /*
113 * attributes that exists only in private key objects
114 * Note: some attributes may also exist in one or two
115 * other object classes, but they are also listed
116 * because not all object have them.
117 */
118 CK_ATTRIBUTE_TYPE PRIV_KEY_ATTRS[] =
119 {
120 CKA_DECRYPT,
121 CKA_UNWRAP,
122 CKA_SIGN,
123 CKA_SIGN_RECOVER,
124 CKA_MODULUS,
125 CKA_PUBLIC_EXPONENT,
126 CKA_PRIVATE_EXPONENT,
127 CKA_PRIME,
128 CKA_SUBPRIME,
129 CKA_BASE,
130 CKA_PRIME_1,
131 CKA_PRIME_2,
132 CKA_EXPONENT_1,
133 CKA_EXPONENT_2,
134 CKA_COEFFICIENT,
135 CKA_VALUE_BITS,
136 CKA_SUBJECT,
137 CKA_SENSITIVE,
138 CKA_EXTRACTABLE,
139 CKA_NEVER_EXTRACTABLE,
140 CKA_ALWAYS_SENSITIVE,
141 CKA_ECDSA_PARAMS,
142 CKA_EC_PARAMS
143 };
144
145 /*
146 * attributes that exists only in secret key objects
147 * Note: some attributes may also exist in one or two
148 * other object classes, but they are also listed
149 * because not all object have them.
150 */
151 CK_ATTRIBUTE_TYPE SECRET_KEY_ATTRS[] =
152 {
153 CKA_VALUE_LEN,
154 CKA_ENCRYPT,
155 CKA_DECRYPT,
156 CKA_WRAP,
157 CKA_UNWRAP,
158 CKA_SIGN,
159 CKA_VERIFY,
160 CKA_SENSITIVE,
161 CKA_EXTRACTABLE,
162 CKA_NEVER_EXTRACTABLE,
163 CKA_ALWAYS_SENSITIVE
164 };
165
166 /*
167 * attributes that exists only in domain parameter objects
168 * Note: some attributes may also exist in one or two
169 * other object classes, but they are also listed
170 * because not all object have them.
171 */
172 CK_ATTRIBUTE_TYPE DOMAIN_ATTRS[] =
173 {
174 CKA_PRIME,
175 CKA_SUBPRIME,
176 CKA_BASE,
177 CKA_PRIME_BITS,
178 CKA_SUBPRIME_BITS,
179 CKA_SUB_PRIME_BITS
180 };
181
182 /*
183 * attributes that exists only in hardware feature objects
184 */
185 CK_ATTRIBUTE_TYPE HARDWARE_ATTRS[] =
186 {
187 CKA_HW_FEATURE_TYPE,
188 CKA_RESET_ON_INIT,
189 CKA_HAS_RESET
190 };
191
192 /*
193 * attributes that exists only in certificate objects
194 */
195 CK_ATTRIBUTE_TYPE CERT_ATTRS[] =
196 {
197 CKA_CERTIFICATE_TYPE,
198 CKA_SUBJECT,
199 CKA_ID,
200 CKA_ISSUER,
201 CKA_AC_ISSUER,
202 CKA_SERIAL_NUMBER,
203 CKA_OWNER,
204 CKA_ATTR_TYPES
205 };
206
207
208 /*
209 * Validate the attribute by using binary search algorithm.
210 */
211 CK_RV
kernel_lookup_attr(CK_ATTRIBUTE_TYPE type)212 kernel_lookup_attr(CK_ATTRIBUTE_TYPE type)
213 {
214
215 size_t lower, middle, upper;
216
217 lower = 0;
218 upper = (sizeof (attr_map) / sizeof (CK_ATTRIBUTE_TYPE)) - 1;
219
220 while (lower <= upper) {
221 /* Always starts from middle. */
222 middle = (lower + upper) / 2;
223
224 if (type > attr_map[middle]) {
225 /* Adjust the lower bound to upper half. */
226 lower = middle + 1;
227 continue;
228 }
229
230 if (type == attr_map[middle]) {
231 /* Found it. */
232 return (CKR_OK);
233 }
234
235 if (type < attr_map[middle]) {
236 /* Adjust the upper bound to lower half. */
237 upper = middle - 1;
238 continue;
239 }
240 }
241
242 /* Failed to find the matching attribute from the attribute table. */
243 return (CKR_ATTRIBUTE_TYPE_INVALID);
244 }
245
246
247 /*
248 * Validate the attribute by using the following search algorithm:
249 *
250 * 1) Search for the most frequently used attributes first.
251 * 2) If not found, search for the usage-purpose attributes - these
252 * attributes have dense set of values, therefore compiler will
253 * optimize it with a branch table and branch to the appropriate
254 * case.
255 * 3) If still not found, use binary search for the rest of the
256 * attributes in the attr_map[] table.
257 */
258 CK_RV
kernel_validate_attr(CK_ATTRIBUTE_PTR template,CK_ULONG ulAttrNum,CK_OBJECT_CLASS * class)259 kernel_validate_attr(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
260 CK_OBJECT_CLASS *class)
261 {
262
263 CK_ULONG i;
264 CK_RV rv = CKR_OK;
265
266 for (i = 0; i < ulAttrNum; i++) {
267 /* First tier search */
268 switch (template[i].type) {
269 case CKA_CLASS:
270 *class = *((CK_OBJECT_CLASS*)template[i].pValue);
271 break;
272 case CKA_TOKEN:
273 break;
274 case CKA_KEY_TYPE:
275 break;
276 case CKA_VALUE:
277 break;
278 case CKA_VALUE_LEN:
279 break;
280 case CKA_VALUE_BITS:
281 break;
282 default:
283 /* Second tier search */
284 switch (template[i].type) {
285 case CKA_ENCRYPT:
286 break;
287 case CKA_DECRYPT:
288 break;
289 case CKA_WRAP:
290 break;
291 case CKA_UNWRAP:
292 break;
293 case CKA_SIGN:
294 break;
295 case CKA_SIGN_RECOVER:
296 break;
297 case CKA_VERIFY:
298 break;
299 case CKA_VERIFY_RECOVER:
300 break;
301 case CKA_DERIVE:
302 break;
303 default:
304 /* Third tier search */
305 rv = kernel_lookup_attr(template[i].type);
306 if (rv != CKR_OK)
307 return (rv);
308 break;
309 }
310 break;
311 }
312 }
313 return (rv);
314 }
315
316
317 /*
318 * Clean up and release all the storage in the extra attribute list
319 * of an object.
320 */
321 void
kernel_cleanup_extra_attr(kernel_object_t * object_p)322 kernel_cleanup_extra_attr(kernel_object_t *object_p)
323 {
324
325 CK_ATTRIBUTE_INFO_PTR extra_attr;
326 CK_ATTRIBUTE_INFO_PTR tmp;
327
328 extra_attr = object_p->extra_attrlistp;
329 while (extra_attr) {
330 tmp = extra_attr->next;
331 if (extra_attr->attr.pValue)
332 /*
333 * All extra attributes in the extra attribute
334 * list have pValue points to the value of the
335 * attribute (with simple byte array type).
336 * Free the storage for the value of the attribute.
337 */
338 free(extra_attr->attr.pValue);
339
340 /* Free the storage for the attribute_info struct. */
341 free(extra_attr);
342 extra_attr = tmp;
343 }
344
345 object_p->extra_attrlistp = NULL;
346 }
347
348
349 /*
350 * Create the attribute_info struct to hold the object's attribute,
351 * and add it to the extra attribute list of an object.
352 */
353 CK_RV
kernel_add_extra_attr(CK_ATTRIBUTE_PTR template,kernel_object_t * object_p)354 kernel_add_extra_attr(CK_ATTRIBUTE_PTR template, kernel_object_t *object_p)
355 {
356
357 CK_ATTRIBUTE_INFO_PTR attrp;
358
359 /* Allocate the storage for the attribute_info struct. */
360 attrp = calloc(1, sizeof (attribute_info_t));
361 if (attrp == NULL) {
362 return (CKR_HOST_MEMORY);
363 }
364
365 /* Set up attribute_info struct. */
366 attrp->attr.type = template->type;
367 attrp->attr.ulValueLen = template->ulValueLen;
368
369 if ((template->pValue != NULL) &&
370 (template->ulValueLen > 0)) {
371 /* Allocate storage for the value of the attribute. */
372 attrp->attr.pValue = malloc(template->ulValueLen);
373 if (attrp->attr.pValue == NULL) {
374 free(attrp);
375 return (CKR_HOST_MEMORY);
376 }
377
378 (void) memcpy(attrp->attr.pValue, template->pValue,
379 template->ulValueLen);
380 } else {
381 attrp->attr.pValue = NULL;
382 }
383
384 /* Insert the new attribute in front of extra attribute list. */
385 if (object_p->extra_attrlistp == NULL) {
386 object_p->extra_attrlistp = attrp;
387 attrp->next = NULL;
388 } else {
389 attrp->next = object_p->extra_attrlistp;
390 object_p->extra_attrlistp = attrp;
391 }
392
393 return (CKR_OK);
394 }
395
396
397 /*
398 * Copy the attribute_info struct from the old object to a new attribute_info
399 * struct, and add that new struct to the extra attribute list of the new
400 * object.
401 */
402 CK_RV
kernel_copy_extra_attr(CK_ATTRIBUTE_INFO_PTR old_attrp,kernel_object_t * object_p)403 kernel_copy_extra_attr(CK_ATTRIBUTE_INFO_PTR old_attrp,
404 kernel_object_t *object_p)
405 {
406 CK_ATTRIBUTE_INFO_PTR attrp;
407
408 /* Allocate attribute_info struct. */
409 attrp = calloc(1, sizeof (attribute_info_t));
410 if (attrp == NULL) {
411 return (CKR_HOST_MEMORY);
412 }
413
414 attrp->attr.type = old_attrp->attr.type;
415 attrp->attr.ulValueLen = old_attrp->attr.ulValueLen;
416
417 if ((old_attrp->attr.pValue != NULL) &&
418 (old_attrp->attr.ulValueLen > 0)) {
419 attrp->attr.pValue = malloc(old_attrp->attr.ulValueLen);
420 if (attrp->attr.pValue == NULL) {
421 free(attrp);
422 return (CKR_HOST_MEMORY);
423 }
424
425 (void) memcpy(attrp->attr.pValue, old_attrp->attr.pValue,
426 old_attrp->attr.ulValueLen);
427 } else {
428 attrp->attr.pValue = NULL;
429 }
430
431 /* Insert the new attribute in front of extra attribute list */
432 if (object_p->extra_attrlistp == NULL) {
433 object_p->extra_attrlistp = attrp;
434 attrp->next = NULL;
435 } else {
436 attrp->next = object_p->extra_attrlistp;
437 object_p->extra_attrlistp = attrp;
438 }
439
440 return (CKR_OK);
441 }
442
443
444 /*
445 * Get the attribute triple from the extra attribute list in the object
446 * (if the specified attribute type is found), and copy it to a template.
447 * Note the type of the attribute to be copied is specified by the template,
448 * and the storage is pre-allocated for the atrribute value in the template
449 * for doing the copy.
450 */
451 CK_RV
get_extra_attr_from_object(kernel_object_t * object_p,CK_ATTRIBUTE_PTR template)452 get_extra_attr_from_object(kernel_object_t *object_p, CK_ATTRIBUTE_PTR template)
453 {
454
455 CK_ATTRIBUTE_INFO_PTR extra_attr;
456 CK_ATTRIBUTE_TYPE type = template->type;
457
458 extra_attr = object_p->extra_attrlistp;
459
460 while (extra_attr) {
461 if (type == extra_attr->attr.type) {
462 /* Found it. */
463 break;
464 } else {
465 /* Does not match, try next one. */
466 extra_attr = extra_attr->next;
467 }
468 }
469
470 if (extra_attr == NULL) {
471 /* A valid but un-initialized attribute. */
472 template->ulValueLen = 0;
473 return (CKR_OK);
474 }
475
476 /*
477 * We found the attribute in the extra attribute list.
478 */
479 if (template->pValue == NULL) {
480 template->ulValueLen = extra_attr->attr.ulValueLen;
481 return (CKR_OK);
482 }
483
484 if (template->ulValueLen >= extra_attr->attr.ulValueLen) {
485 /*
486 * The buffer provided by the application is large
487 * enough to hold the value of the attribute.
488 */
489 (void) memcpy(template->pValue, extra_attr->attr.pValue,
490 extra_attr->attr.ulValueLen);
491 template->ulValueLen = extra_attr->attr.ulValueLen;
492 return (CKR_OK);
493 } else {
494 /*
495 * The buffer provided by the application does
496 * not have enough space to hold the value.
497 */
498 template->ulValueLen = (CK_ULONG)-1;
499 return (CKR_BUFFER_TOO_SMALL);
500 }
501 }
502
503
504 /*
505 * Modify the attribute triple in the extra attribute list of the object
506 * if the specified attribute type is found. Otherwise, just add it to
507 * list.
508 */
509 CK_RV
set_extra_attr_to_object(kernel_object_t * object_p,CK_ATTRIBUTE_TYPE type,CK_ATTRIBUTE_PTR template)510 set_extra_attr_to_object(kernel_object_t *object_p, CK_ATTRIBUTE_TYPE type,
511 CK_ATTRIBUTE_PTR template)
512 {
513
514 CK_ATTRIBUTE_INFO_PTR extra_attr;
515
516 extra_attr = object_p->extra_attrlistp;
517
518 while (extra_attr) {
519 if (type == extra_attr->attr.type) {
520 /* Found it. */
521 break;
522 } else {
523 /* Does not match, try next one. */
524 extra_attr = extra_attr->next;
525 }
526 }
527
528 if (extra_attr == NULL) {
529 /*
530 * This attribute is a new one, go ahead adding it to
531 * the extra attribute list.
532 */
533 return (kernel_add_extra_attr(template, object_p));
534 }
535
536 /* We found the attribute in the extra attribute list. */
537 if ((template->pValue != NULL) &&
538 (template->ulValueLen > 0)) {
539 if (template->ulValueLen > extra_attr->attr.ulValueLen) {
540 /* The old buffer is too small to hold the new value. */
541 if (extra_attr->attr.pValue != NULL)
542 /* Free storage for the old attribute value. */
543 free(extra_attr->attr.pValue);
544
545 /* Allocate storage for the new attribute value. */
546 extra_attr->attr.pValue = malloc(template->ulValueLen);
547 if (extra_attr->attr.pValue == NULL) {
548 return (CKR_HOST_MEMORY);
549 }
550 }
551
552 /* Replace the attribute with new value. */
553 extra_attr->attr.ulValueLen = template->ulValueLen;
554 (void) memcpy(extra_attr->attr.pValue, template->pValue,
555 template->ulValueLen);
556 } else {
557 extra_attr->attr.pValue = NULL;
558 }
559
560 return (CKR_OK);
561 }
562
563
564 /*
565 * Copy the big integer attribute value from template to a biginteger_t struct.
566 */
567 CK_RV
get_bigint_attr_from_template(biginteger_t * big,CK_ATTRIBUTE_PTR template)568 get_bigint_attr_from_template(biginteger_t *big, CK_ATTRIBUTE_PTR template)
569 {
570
571 if ((template->pValue != NULL) &&
572 (template->ulValueLen > 0)) {
573 /* Allocate storage for the value of the attribute. */
574 big->big_value = malloc(template->ulValueLen);
575 if (big->big_value == NULL) {
576 return (CKR_HOST_MEMORY);
577 }
578
579 (void) memcpy(big->big_value, template->pValue,
580 template->ulValueLen);
581 big->big_value_len = template->ulValueLen;
582 } else {
583 big->big_value = NULL;
584 big->big_value_len = 0;
585 }
586
587 return (CKR_OK);
588 }
589
590
591 /*
592 * Copy the big integer attribute value from a biginteger_t struct in the
593 * object to a template.
594 */
595 CK_RV
get_bigint_attr_from_object(biginteger_t * big,CK_ATTRIBUTE_PTR template)596 get_bigint_attr_from_object(biginteger_t *big, CK_ATTRIBUTE_PTR template)
597 {
598
599 if (template->pValue == NULL) {
600 template->ulValueLen = big->big_value_len;
601 return (CKR_OK);
602 }
603
604 if (big->big_value == NULL) {
605 template->ulValueLen = 0;
606 return (CKR_OK);
607 }
608
609 if (template->ulValueLen >= big->big_value_len) {
610 /*
611 * The buffer provided by the application is large
612 * enough to hold the value of the attribute.
613 */
614 (void) memcpy(template->pValue, big->big_value,
615 big->big_value_len);
616 template->ulValueLen = big->big_value_len;
617 return (CKR_OK);
618 } else {
619 /*
620 * The buffer provided by the application does
621 * not have enough space to hold the value.
622 */
623 template->ulValueLen = (CK_ULONG)-1;
624 return (CKR_BUFFER_TOO_SMALL);
625 }
626 }
627
628
629 /*
630 * Copy the boolean data type attribute value from an object for the
631 * specified attribute to the template.
632 */
633 CK_RV
get_bool_attr_from_object(kernel_object_t * object_p,CK_ULONG bool_flag,CK_ATTRIBUTE_PTR template)634 get_bool_attr_from_object(kernel_object_t *object_p, CK_ULONG bool_flag,
635 CK_ATTRIBUTE_PTR template)
636 {
637
638 if (template->pValue == NULL) {
639 template->ulValueLen = sizeof (CK_BBOOL);
640 return (CKR_OK);
641 }
642
643 if (template->ulValueLen >= sizeof (CK_BBOOL)) {
644 /*
645 * The buffer provided by the application is large
646 * enough to hold the value of the attribute.
647 */
648 if (object_p->bool_attr_mask & bool_flag) {
649 *((CK_BBOOL *)template->pValue) = B_TRUE;
650 } else {
651 *((CK_BBOOL *)template->pValue) = B_FALSE;
652 }
653
654 template->ulValueLen = sizeof (CK_BBOOL);
655 return (CKR_OK);
656 } else {
657 /*
658 * The buffer provided by the application does
659 * not have enough space to hold the value.
660 */
661 template->ulValueLen = (CK_ULONG)-1;
662 return (CKR_BUFFER_TOO_SMALL);
663 }
664 }
665
666 /*
667 * Set the boolean data type attribute value in the object.
668 */
669 CK_RV
set_bool_attr_to_object(kernel_object_t * object_p,CK_ULONG bool_flag,CK_ATTRIBUTE_PTR template)670 set_bool_attr_to_object(kernel_object_t *object_p, CK_ULONG bool_flag,
671 CK_ATTRIBUTE_PTR template)
672 {
673
674 if (*(CK_BBOOL *)template->pValue)
675 object_p->bool_attr_mask |= bool_flag;
676 else
677 object_p->bool_attr_mask &= ~bool_flag;
678
679 return (CKR_OK);
680 }
681
682
683 /*
684 * Copy the CK_ULONG data type attribute value from an object to the
685 * template.
686 */
687 CK_RV
get_ulong_attr_from_object(CK_ULONG value,CK_ATTRIBUTE_PTR template)688 get_ulong_attr_from_object(CK_ULONG value, CK_ATTRIBUTE_PTR template)
689 {
690
691 if (template->pValue == NULL) {
692 template->ulValueLen = sizeof (CK_ULONG);
693 return (CKR_OK);
694 }
695
696 if (template->ulValueLen >= sizeof (CK_ULONG)) {
697 /*
698 * The buffer provided by the application is large
699 * enough to hold the value of the attribute.
700 */
701 *(CK_ULONG_PTR)template->pValue = value;
702 template->ulValueLen = sizeof (CK_ULONG);
703 return (CKR_OK);
704 } else {
705 /*
706 * The buffer provided by the application does
707 * not have enough space to hold the value.
708 */
709 template->ulValueLen = (CK_ULONG)-1;
710 return (CKR_BUFFER_TOO_SMALL);
711 }
712 }
713
714
715 /*
716 * Copy the CK_ULONG data type attribute value from a template to the
717 * object.
718 */
719 void
get_ulong_attr_from_template(CK_ULONG * value,CK_ATTRIBUTE_PTR template)720 get_ulong_attr_from_template(CK_ULONG *value, CK_ATTRIBUTE_PTR template)
721 {
722
723 if (template->pValue != NULL) {
724 *value = *(CK_ULONG_PTR)template->pValue;
725 } else {
726 *value = 0;
727 }
728
729 }
730
731 /*
732 * Copy the big integer attribute value from source's biginteger_t to
733 * destination's biginteger_t.
734 */
735 void
copy_bigint_attr(biginteger_t * src,biginteger_t * dst)736 copy_bigint_attr(biginteger_t *src, biginteger_t *dst)
737 {
738
739 if ((src->big_value != NULL) &&
740 (src->big_value_len > 0)) {
741 /*
742 * To do the copy, just have dst's big_value points
743 * to src's.
744 */
745 dst->big_value = src->big_value;
746 dst->big_value_len = src->big_value_len;
747
748 /*
749 * After the copy, nullify the src's big_value pointer.
750 * It prevents any double freeing the value.
751 */
752 src->big_value = NULL;
753 src->big_value_len = 0;
754 } else {
755 dst->big_value = NULL;
756 dst->big_value_len = 0;
757 }
758
759 }
760
761
762 CK_RV
get_string_from_template(CK_ATTRIBUTE_PTR dest,CK_ATTRIBUTE_PTR src)763 get_string_from_template(CK_ATTRIBUTE_PTR dest, CK_ATTRIBUTE_PTR src)
764 {
765 if ((src->pValue != NULL) &&
766 (src->ulValueLen > 0)) {
767 /* Allocate storage for the value of the attribute. */
768 dest->pValue = malloc(src->ulValueLen);
769 if (dest->pValue == NULL) {
770 return (CKR_HOST_MEMORY);
771 }
772
773 (void) memcpy(dest->pValue, src->pValue,
774 src->ulValueLen);
775 dest->ulValueLen = src->ulValueLen;
776 dest->type = src->type;
777 } else {
778 dest->pValue = NULL;
779 dest->ulValueLen = 0;
780 dest->type = src->type;
781 }
782
783 return (CKR_OK);
784
785 }
786
787 void
string_attr_cleanup(CK_ATTRIBUTE_PTR template)788 string_attr_cleanup(CK_ATTRIBUTE_PTR template)
789 {
790
791 if (template->pValue) {
792 free(template->pValue);
793 template->pValue = NULL;
794 template->ulValueLen = 0;
795 }
796 }
797
798 /*
799 * Release the storage allocated for object attribute with big integer
800 * value.
801 */
802 void
bigint_attr_cleanup(biginteger_t * big)803 bigint_attr_cleanup(biginteger_t *big)
804 {
805
806 if (big == NULL)
807 return;
808
809 if (big->big_value) {
810 (void) memset(big->big_value, 0, big->big_value_len);
811 free(big->big_value);
812 big->big_value = NULL;
813 big->big_value_len = 0;
814 }
815 }
816
817
818 /*
819 * Clean up and release all the storage allocated to hold the big integer
820 * attributes associated with the type (i.e. class) of the object. Also,
821 * release the storage allocated to the type of the object.
822 */
823 void
kernel_cleanup_object_bigint_attrs(kernel_object_t * object_p)824 kernel_cleanup_object_bigint_attrs(kernel_object_t *object_p)
825 {
826
827 CK_OBJECT_CLASS class = object_p->class;
828 CK_KEY_TYPE keytype = object_p->key_type;
829
830
831 switch (class) {
832 case CKO_PUBLIC_KEY:
833 if (OBJ_PUB(object_p)) {
834 switch (keytype) {
835 case CKK_RSA:
836 bigint_attr_cleanup(OBJ_PUB_RSA_MOD(
837 object_p));
838 bigint_attr_cleanup(OBJ_PUB_RSA_PUBEXPO(
839 object_p));
840 break;
841
842 case CKK_DSA:
843 bigint_attr_cleanup(OBJ_PUB_DSA_PRIME(
844 object_p));
845 bigint_attr_cleanup(OBJ_PUB_DSA_SUBPRIME(
846 object_p));
847 bigint_attr_cleanup(OBJ_PUB_DSA_BASE(
848 object_p));
849 bigint_attr_cleanup(OBJ_PUB_DSA_VALUE(
850 object_p));
851 break;
852
853 case CKK_DH:
854 bigint_attr_cleanup(OBJ_PUB_DH_PRIME(object_p));
855 bigint_attr_cleanup(OBJ_PUB_DH_BASE(object_p));
856 bigint_attr_cleanup(OBJ_PUB_DH_VALUE(object_p));
857 break;
858
859 case CKK_EC:
860 bigint_attr_cleanup(OBJ_PUB_EC_POINT(object_p));
861 break;
862 }
863
864 /* Release Public Key Object struct */
865 free(OBJ_PUB(object_p));
866 OBJ_PUB(object_p) = NULL;
867 }
868 break;
869
870 case CKO_PRIVATE_KEY:
871 if (OBJ_PRI(object_p)) {
872 switch (keytype) {
873 case CKK_RSA:
874 bigint_attr_cleanup(OBJ_PRI_RSA_MOD(
875 object_p));
876 bigint_attr_cleanup(OBJ_PRI_RSA_PUBEXPO(
877 object_p));
878 bigint_attr_cleanup(OBJ_PRI_RSA_PRIEXPO(
879 object_p));
880 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME1(
881 object_p));
882 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME2(
883 object_p));
884 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO1(
885 object_p));
886 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO2(
887 object_p));
888 bigint_attr_cleanup(OBJ_PRI_RSA_COEF(
889 object_p));
890 break;
891
892 case CKK_DSA:
893 bigint_attr_cleanup(OBJ_PRI_DSA_PRIME(
894 object_p));
895 bigint_attr_cleanup(OBJ_PRI_DSA_SUBPRIME(
896 object_p));
897 bigint_attr_cleanup(OBJ_PRI_DSA_BASE(
898 object_p));
899 bigint_attr_cleanup(OBJ_PRI_DSA_VALUE(
900 object_p));
901 break;
902
903 case CKK_DH:
904 bigint_attr_cleanup(OBJ_PRI_DH_PRIME(object_p));
905 bigint_attr_cleanup(OBJ_PRI_DH_BASE(object_p));
906 bigint_attr_cleanup(OBJ_PRI_DH_VALUE(object_p));
907 break;
908
909 case CKK_EC:
910 bigint_attr_cleanup(OBJ_PRI_EC_VALUE(object_p));
911 break;
912 }
913
914 /* Release Private Key Object struct. */
915 free(OBJ_PRI(object_p));
916 OBJ_PRI(object_p) = NULL;
917 }
918 break;
919 }
920 }
921
922
923 /*
924 * Parse the common attributes. Return to caller with appropriate return
925 * value to indicate if the supplied template specifies a valid attribute
926 * with a valid value.
927 */
928 CK_RV
kernel_parse_common_attrs(CK_ATTRIBUTE_PTR template,kernel_session_t * sp,uint64_t * attr_mask_p)929 kernel_parse_common_attrs(CK_ATTRIBUTE_PTR template, kernel_session_t *sp,
930 uint64_t *attr_mask_p)
931 {
932
933 CK_RV rv = CKR_OK;
934 kernel_slot_t *pslot = slot_table[sp->ses_slotid];
935
936 switch (template->type) {
937 case CKA_CLASS:
938 break;
939
940 /* default boolean attributes */
941 case CKA_TOKEN:
942 if ((*(CK_BBOOL *)template->pValue) == TRUE) {
943 rv = CKR_ATTRIBUTE_VALUE_INVALID;
944 }
945 break;
946
947 case CKA_PRIVATE:
948 if ((*(CK_BBOOL *)template->pValue) == TRUE) {
949 /*
950 * Cannot create a private object if the token
951 * has a keystore and the user isn't logged in.
952 */
953 if (pslot->sl_func_list.fl_object_create &&
954 pslot->sl_state != CKU_USER) {
955 rv = CKR_ATTRIBUTE_VALUE_INVALID;
956 } else {
957 *attr_mask_p |= PRIVATE_BOOL_ON;
958 }
959 }
960 break;
961
962 case CKA_MODIFIABLE:
963 if ((*(CK_BBOOL *)template->pValue) == FALSE) {
964 *attr_mask_p &= ~MODIFIABLE_BOOL_ON;
965 }
966 break;
967
968 case CKA_LABEL:
969 break;
970
971 default:
972 rv = CKR_TEMPLATE_INCONSISTENT;
973 }
974
975 return (rv);
976 }
977
978
979
980
981 /*
982 * Build a Public Key Object.
983 *
984 * - Parse the object's template, and when an error is detected such as
985 * invalid attribute type, invalid attribute value, etc., return
986 * with appropriate return value.
987 * - Set up attribute mask field in the object for the supplied common
988 * attributes that have boolean type.
989 * - Build the attribute_info struct to hold the value of each supplied
990 * attribute that has byte array type. Link attribute_info structs
991 * together to form the extra attribute list of the object.
992 * - Allocate storage for the Public Key object.
993 * - Build the Public Key object according to the key type. Allocate
994 * storage to hold the big integer value for the supplied attributes
995 * that are required for a certain key type.
996 *
997 */
998 CK_RV
kernel_build_public_key_object(CK_ATTRIBUTE_PTR template,CK_ULONG ulAttrNum,kernel_object_t * new_object,kernel_session_t * sp,uint_t mode)999 kernel_build_public_key_object(CK_ATTRIBUTE_PTR template,
1000 CK_ULONG ulAttrNum, kernel_object_t *new_object, kernel_session_t *sp,
1001 uint_t mode)
1002 {
1003
1004 int i;
1005 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1006 uint64_t attr_mask = PUBLIC_KEY_DEFAULT;
1007 CK_RV rv = CKR_OK;
1008 int isLabel = 0;
1009 /* Must set flags */
1010 int isModulus = 0;
1011 int isPubExpo = 0;
1012 int isPrime = 0;
1013 int isSubprime = 0;
1014 int isBase = 0;
1015 int isValue = 0;
1016 int isPoint = 0;
1017 int isParams = 0;
1018 /* Must not set flags */
1019 int isModulusBits = 0;
1020 CK_ULONG modulus_bits = 0;
1021
1022 biginteger_t modulus;
1023 biginteger_t pubexpo;
1024 biginteger_t prime;
1025 biginteger_t subprime;
1026 biginteger_t base;
1027 biginteger_t value;
1028 biginteger_t point;
1029 CK_ATTRIBUTE string_tmp;
1030 CK_ATTRIBUTE param_tmp;
1031
1032 public_key_obj_t *pbk;
1033
1034 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1035 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1036 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1037 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1038 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1039 (void) memset(&base, 0x0, sizeof (biginteger_t));
1040 (void) memset(&value, 0x0, sizeof (biginteger_t));
1041 (void) memset(&point, 0x0, sizeof (biginteger_t));
1042 string_tmp.pValue = NULL;
1043 param_tmp.pValue = NULL;
1044
1045 for (i = 0; i < ulAttrNum; i++) {
1046
1047 /* Public Key Object Attributes */
1048 switch (template[i].type) {
1049
1050 /* common key attributes */
1051 case CKA_KEY_TYPE:
1052 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1053 break;
1054
1055 case CKA_ID:
1056 case CKA_START_DATE:
1057 case CKA_END_DATE:
1058
1059 /* common public key attribute */
1060 case CKA_SUBJECT:
1061 /*
1062 * Allocate storage to hold the attribute
1063 * value with byte array type, and add it to
1064 * the extra attribute list of the object.
1065 */
1066 rv = kernel_add_extra_attr(&template[i],
1067 new_object);
1068 if (rv != CKR_OK) {
1069 goto fail_cleanup;
1070 }
1071 break;
1072
1073 /*
1074 * The following key related attribute types must
1075 * not be specified by C_CreateObject.
1076 */
1077 case CKA_LOCAL:
1078 case CKA_KEY_GEN_MECHANISM:
1079 rv = CKR_TEMPLATE_INCONSISTENT;
1080 goto fail_cleanup;
1081
1082 /* Key related boolean attributes */
1083 case CKA_DERIVE:
1084 if (*(CK_BBOOL *)template[i].pValue)
1085 attr_mask |= DERIVE_BOOL_ON;
1086 break;
1087
1088 case CKA_ENCRYPT:
1089 if (*(CK_BBOOL *)template[i].pValue)
1090 attr_mask |= ENCRYPT_BOOL_ON;
1091 else
1092 attr_mask &= ~ENCRYPT_BOOL_ON;
1093 break;
1094
1095 case CKA_VERIFY:
1096 if (*(CK_BBOOL *)template[i].pValue)
1097 attr_mask |= VERIFY_BOOL_ON;
1098 else
1099 attr_mask &= ~VERIFY_BOOL_ON;
1100 break;
1101
1102 case CKA_VERIFY_RECOVER:
1103 if (*(CK_BBOOL *)template[i].pValue)
1104 attr_mask |= VERIFY_RECOVER_BOOL_ON;
1105 else
1106 attr_mask &= ~VERIFY_RECOVER_BOOL_ON;
1107 break;
1108
1109 case CKA_WRAP:
1110 if (*(CK_BBOOL *)template[i].pValue)
1111 attr_mask |= WRAP_BOOL_ON;
1112 break;
1113
1114 case CKA_TRUSTED:
1115 if (*(CK_BBOOL *)template[i].pValue)
1116 attr_mask |= TRUSTED_BOOL_ON;
1117 break;
1118
1119 /*
1120 * The following key related attribute types must
1121 * be specified according to the key type by
1122 * C_CreateObject.
1123 */
1124 case CKA_MODULUS:
1125 isModulus = 1;
1126 /*
1127 * Copyin big integer attribute from template
1128 * to a local variable.
1129 */
1130 rv = get_bigint_attr_from_template(&modulus,
1131 &template[i]);
1132 if (rv != CKR_OK)
1133 goto fail_cleanup;
1134 break;
1135
1136 case CKA_PUBLIC_EXPONENT:
1137 isPubExpo = 1;
1138 rv = get_bigint_attr_from_template(&pubexpo,
1139 &template[i]);
1140 if (rv != CKR_OK)
1141 goto fail_cleanup;
1142 break;
1143
1144 case CKA_PRIME:
1145 isPrime = 1;
1146 rv = get_bigint_attr_from_template(&prime,
1147 &template[i]);
1148 if (rv != CKR_OK)
1149 goto fail_cleanup;
1150 break;
1151
1152 case CKA_SUBPRIME:
1153 isSubprime = 1;
1154 rv = get_bigint_attr_from_template(&subprime,
1155 &template[i]);
1156 if (rv != CKR_OK)
1157 goto fail_cleanup;
1158 break;
1159
1160 case CKA_BASE:
1161 isBase = 1;
1162 rv = get_bigint_attr_from_template(&base,
1163 &template[i]);
1164 if (rv != CKR_OK)
1165 goto fail_cleanup;
1166 break;
1167
1168 case CKA_VALUE:
1169 isValue = 1;
1170 rv = get_bigint_attr_from_template(&value,
1171 &template[i]);
1172 if (rv != CKR_OK)
1173 goto fail_cleanup;
1174 break;
1175
1176 case CKA_MODULUS_BITS:
1177 isModulusBits = 1;
1178 get_ulong_attr_from_template(&modulus_bits,
1179 &template[i]);
1180 break;
1181
1182 case CKA_LABEL:
1183 isLabel = 1;
1184 rv = get_string_from_template(&string_tmp,
1185 &template[i]);
1186 if (rv != CKR_OK)
1187 goto fail_cleanup;
1188 break;
1189
1190 case CKA_EC_POINT:
1191 isPoint = 1;
1192 rv = get_bigint_attr_from_template(&point,
1193 &template[i]);
1194 if (rv != CKR_OK)
1195 goto fail_cleanup;
1196 break;
1197
1198 case CKA_EC_PARAMS:
1199 isParams = 1;
1200 rv = get_string_from_template(¶m_tmp,
1201 &template[i]);
1202 if (rv != CKR_OK)
1203 goto fail_cleanup;
1204 break;
1205
1206 default:
1207 rv = kernel_parse_common_attrs(&template[i], sp,
1208 &attr_mask);
1209 if (rv != CKR_OK)
1210 goto fail_cleanup;
1211 break;
1212 }
1213 } /* For */
1214
1215 /* Allocate storage for Public Key Object. */
1216 pbk = calloc(1, sizeof (public_key_obj_t));
1217 if (pbk == NULL) {
1218 rv = CKR_HOST_MEMORY;
1219 goto fail_cleanup;
1220 }
1221
1222 new_object->object_class_u.public_key = pbk;
1223 new_object->class = CKO_PUBLIC_KEY;
1224
1225 if (keytype == (CK_KEY_TYPE)~0UL) {
1226 rv = CKR_TEMPLATE_INCOMPLETE;
1227 goto fail_cleanup;
1228 }
1229 new_object->key_type = keytype;
1230
1231 /* Supported key types of the Public Key Object */
1232 switch (keytype) {
1233 case CKK_RSA:
1234 if (mode == KERNEL_CREATE_OBJ) {
1235 if (isModulusBits || isPrime || isSubprime ||
1236 isBase|| isValue) {
1237 rv = CKR_TEMPLATE_INCONSISTENT;
1238 goto fail_cleanup;
1239 }
1240 }
1241
1242 if (isModulus && isPubExpo) {
1243 /*
1244 * Copy big integer attribute value to the
1245 * designated place in the public key object.
1246 */
1247 copy_bigint_attr(&modulus,
1248 KEY_PUB_RSA_MOD(pbk));
1249
1250 copy_bigint_attr(&pubexpo,
1251 KEY_PUB_RSA_PUBEXPO(pbk));
1252 } else {
1253 rv = CKR_TEMPLATE_INCOMPLETE;
1254 goto fail_cleanup;
1255 }
1256
1257 /* must be generating a RSA key pair by value */
1258 if (isModulusBits) {
1259 KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits;
1260 }
1261 break;
1262
1263 case CKK_DSA:
1264 if (isModulusBits || isModulus || isPubExpo) {
1265 rv = CKR_TEMPLATE_INCONSISTENT;
1266 goto fail_cleanup;
1267 }
1268
1269 if (!(isPrime && isSubprime && isBase && isValue)) {
1270 rv = CKR_TEMPLATE_INCOMPLETE;
1271 goto fail_cleanup;
1272 }
1273
1274 copy_bigint_attr(&prime, KEY_PUB_DSA_PRIME(pbk));
1275
1276 copy_bigint_attr(&subprime, KEY_PUB_DSA_SUBPRIME(pbk));
1277
1278 copy_bigint_attr(&base, KEY_PUB_DSA_BASE(pbk));
1279
1280 copy_bigint_attr(&value, KEY_PUB_DSA_VALUE(pbk));
1281
1282 break;
1283
1284 case CKK_DH:
1285 if (!(isPrime && isBase && isValue)) {
1286 rv = CKR_TEMPLATE_INCOMPLETE;
1287 goto fail_cleanup;
1288 }
1289
1290 copy_bigint_attr(&prime, KEY_PUB_DH_PRIME(pbk));
1291
1292 copy_bigint_attr(&base, KEY_PUB_DH_BASE(pbk));
1293
1294 copy_bigint_attr(&value, KEY_PUB_DH_VALUE(pbk));
1295
1296 break;
1297
1298 case CKK_EC:
1299 if (!isPoint || !isParams) {
1300 rv = CKR_TEMPLATE_INCOMPLETE;
1301 goto fail_cleanup;
1302 }
1303
1304 copy_bigint_attr(&point, KEY_PUB_EC_POINT(pbk));
1305 rv = kernel_add_extra_attr(¶m_tmp, new_object);
1306 if (rv != CKR_OK)
1307 goto fail_cleanup;
1308 string_attr_cleanup(¶m_tmp);
1309 break;
1310 default:
1311 rv = CKR_TEMPLATE_INCONSISTENT;
1312 goto fail_cleanup;
1313 }
1314
1315 /* Set up object. */
1316 new_object->bool_attr_mask = attr_mask;
1317 if (isLabel) {
1318 rv = kernel_add_extra_attr(&string_tmp, new_object);
1319 if (rv != CKR_OK)
1320 goto fail_cleanup;
1321 string_attr_cleanup(&string_tmp);
1322 }
1323
1324 return (rv);
1325
1326 fail_cleanup:
1327 /*
1328 * cleanup the storage allocated to the local variables.
1329 */
1330 bigint_attr_cleanup(&modulus);
1331 bigint_attr_cleanup(&pubexpo);
1332 bigint_attr_cleanup(&prime);
1333 bigint_attr_cleanup(&subprime);
1334 bigint_attr_cleanup(&base);
1335 bigint_attr_cleanup(&value);
1336 bigint_attr_cleanup(&point);
1337 string_attr_cleanup(&string_tmp);
1338 string_attr_cleanup(¶m_tmp);
1339
1340 /*
1341 * cleanup the storage allocated inside the object itself.
1342 */
1343 kernel_cleanup_object(new_object);
1344
1345 return (rv);
1346 }
1347
1348
1349 /*
1350 * Build a Private Key Object.
1351 *
1352 * - Parse the object's template, and when an error is detected such as
1353 * invalid attribute type, invalid attribute value, etc., return
1354 * with appropriate return value.
1355 * - Set up attribute mask field in the object for the supplied common
1356 * attributes that have boolean type.
1357 * - Build the attribute_info struct to hold the value of each supplied
1358 * attribute that has byte array type. Link attribute_info structs
1359 * together to form the extra attribute list of the object.
1360 * - Allocate storage for the Private Key object.
1361 * - Build the Private Key object according to the key type. Allocate
1362 * storage to hold the big integer value for the supplied attributes
1363 * that are required for a certain key type.
1364 *
1365 */
1366 CK_RV
kernel_build_private_key_object(CK_ATTRIBUTE_PTR template,CK_ULONG ulAttrNum,kernel_object_t * new_object,kernel_session_t * sp,uint_t mode)1367 kernel_build_private_key_object(CK_ATTRIBUTE_PTR template,
1368 CK_ULONG ulAttrNum, kernel_object_t *new_object, kernel_session_t *sp,
1369 uint_t mode)
1370 {
1371 ulong_t i;
1372 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1373 uint64_t attr_mask = PRIVATE_KEY_DEFAULT;
1374 CK_RV rv = CKR_OK;
1375 int isLabel = 0;
1376 /* Must set flags */
1377 int isModulus = 0;
1378 int isPriExpo = 0;
1379 int isPrime = 0;
1380 int isSubprime = 0;
1381 int isBase = 0;
1382 int isValue = 0;
1383 int isParams = 0;
1384 /* Must not set flags */
1385 int isValueBits = 0;
1386 CK_ULONG value_bits = 0;
1387
1388 /* Private Key RSA optional */
1389 int isPubExpo = 0;
1390 int isPrime1 = 0;
1391 int isPrime2 = 0;
1392 int isExpo1 = 0;
1393 int isExpo2 = 0;
1394 int isCoef = 0;
1395
1396 biginteger_t modulus;
1397 biginteger_t priexpo;
1398 biginteger_t prime;
1399 biginteger_t subprime;
1400 biginteger_t base;
1401 biginteger_t value;
1402
1403 biginteger_t pubexpo;
1404 biginteger_t prime1;
1405 biginteger_t prime2;
1406 biginteger_t expo1;
1407 biginteger_t expo2;
1408 biginteger_t coef;
1409 CK_ATTRIBUTE string_tmp;
1410 CK_ATTRIBUTE param_tmp;
1411
1412 private_key_obj_t *pvk;
1413
1414 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1415 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1416 (void) memset(&priexpo, 0x0, sizeof (biginteger_t));
1417 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1418 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1419 (void) memset(&base, 0x0, sizeof (biginteger_t));
1420 (void) memset(&value, 0x0, sizeof (biginteger_t));
1421 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1422 (void) memset(&prime1, 0x0, sizeof (biginteger_t));
1423 (void) memset(&prime2, 0x0, sizeof (biginteger_t));
1424 (void) memset(&expo1, 0x0, sizeof (biginteger_t));
1425 (void) memset(&expo2, 0x0, sizeof (biginteger_t));
1426 (void) memset(&coef, 0x0, sizeof (biginteger_t));
1427 string_tmp.pValue = NULL;
1428 param_tmp.pValue = NULL;
1429
1430 for (i = 0; i < ulAttrNum; i++) {
1431
1432 /* Private Key Object Attributes */
1433 switch (template[i].type) {
1434
1435 /* common key attributes */
1436 case CKA_KEY_TYPE:
1437 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1438 break;
1439
1440 case CKA_ID:
1441 case CKA_START_DATE:
1442 case CKA_END_DATE:
1443
1444 /* common private key attribute */
1445 case CKA_SUBJECT:
1446 /*
1447 * Allocate storage to hold the attribute
1448 * value with byte array type, and add it to
1449 * the extra attribute list of the object.
1450 */
1451 rv = kernel_add_extra_attr(&template[i],
1452 new_object);
1453 if (rv != CKR_OK) {
1454 goto fail_cleanup;
1455 }
1456 break;
1457
1458 /*
1459 * The following key related attribute types must
1460 * not be specified by C_CreateObject.
1461 */
1462 case CKA_LOCAL:
1463 case CKA_KEY_GEN_MECHANISM:
1464 case CKA_AUTH_PIN_FLAGS:
1465 case CKA_ALWAYS_SENSITIVE:
1466 case CKA_NEVER_EXTRACTABLE:
1467 rv = CKR_TEMPLATE_INCONSISTENT;
1468 goto fail_cleanup;
1469
1470 /* Key related boolean attributes */
1471 case CKA_DERIVE:
1472 if (*(CK_BBOOL *)template[i].pValue)
1473 attr_mask |= DERIVE_BOOL_ON;
1474 break;
1475
1476 case CKA_SENSITIVE:
1477 if (*(CK_BBOOL *)template[i].pValue)
1478 attr_mask |= SENSITIVE_BOOL_ON;
1479 break;
1480
1481 case CKA_SECONDARY_AUTH:
1482 if (*(CK_BBOOL *)template[i].pValue) {
1483 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1484 goto fail_cleanup;
1485 }
1486 break;
1487
1488 case CKA_DECRYPT:
1489 if (*(CK_BBOOL *)template[i].pValue)
1490 attr_mask |= DECRYPT_BOOL_ON;
1491 else
1492 attr_mask &= ~DECRYPT_BOOL_ON;
1493 break;
1494
1495 case CKA_SIGN:
1496 if (*(CK_BBOOL *)template[i].pValue)
1497 attr_mask |= SIGN_BOOL_ON;
1498 else
1499 attr_mask &= ~SIGN_BOOL_ON;
1500 break;
1501
1502 case CKA_SIGN_RECOVER:
1503 if (*(CK_BBOOL *)template[i].pValue)
1504 attr_mask |= SIGN_RECOVER_BOOL_ON;
1505 else
1506 attr_mask &= ~SIGN_RECOVER_BOOL_ON;
1507 break;
1508
1509 case CKA_UNWRAP:
1510 if (*(CK_BBOOL *)template[i].pValue)
1511 attr_mask |= UNWRAP_BOOL_ON;
1512 break;
1513
1514 case CKA_EXTRACTABLE:
1515 if (*(CK_BBOOL *)template[i].pValue)
1516 attr_mask |= EXTRACTABLE_BOOL_ON;
1517 else
1518 attr_mask &= ~EXTRACTABLE_BOOL_ON;
1519 break;
1520
1521 /*
1522 * The following key related attribute types must
1523 * be specified according to the key type by
1524 * C_CreateObject.
1525 */
1526 case CKA_MODULUS:
1527 isModulus = 1;
1528 /*
1529 * Copyin big integer attribute from template
1530 * to a local variable.
1531 */
1532 rv = get_bigint_attr_from_template(&modulus,
1533 &template[i]);
1534 if (rv != CKR_OK)
1535 goto fail_cleanup;
1536 break;
1537
1538 case CKA_PUBLIC_EXPONENT:
1539 isPubExpo = 1;
1540 rv = get_bigint_attr_from_template(&pubexpo,
1541 &template[i]);
1542 if (rv != CKR_OK)
1543 goto fail_cleanup;
1544 break;
1545
1546 case CKA_PRIVATE_EXPONENT:
1547 isPriExpo = 1;
1548 rv = get_bigint_attr_from_template(&priexpo,
1549 &template[i]);
1550 if (rv != CKR_OK)
1551 goto fail_cleanup;
1552 break;
1553
1554 case CKA_PRIME_1:
1555 isPrime1 = 1;
1556 rv = get_bigint_attr_from_template(&prime1,
1557 &template[i]);
1558 if (rv != CKR_OK)
1559 goto fail_cleanup;
1560 break;
1561
1562 case CKA_PRIME_2:
1563 isPrime2 = 1;
1564 rv = get_bigint_attr_from_template(&prime2,
1565 &template[i]);
1566 if (rv != CKR_OK)
1567 goto fail_cleanup;
1568 break;
1569
1570 case CKA_EXPONENT_1:
1571 isExpo1 = 1;
1572 rv = get_bigint_attr_from_template(&expo1,
1573 &template[i]);
1574 if (rv != CKR_OK)
1575 goto fail_cleanup;
1576 break;
1577
1578 case CKA_EXPONENT_2:
1579 isExpo2 = 1;
1580 rv = get_bigint_attr_from_template(&expo2,
1581 &template[i]);
1582 if (rv != CKR_OK)
1583 goto fail_cleanup;
1584 break;
1585
1586 case CKA_COEFFICIENT:
1587 isCoef = 1;
1588 rv = get_bigint_attr_from_template(&coef,
1589 &template[i]);
1590 if (rv != CKR_OK)
1591 goto fail_cleanup;
1592 break;
1593
1594 case CKA_PRIME:
1595 isPrime = 1;
1596 rv = get_bigint_attr_from_template(&prime,
1597 &template[i]);
1598 if (rv != CKR_OK)
1599 goto fail_cleanup;
1600 break;
1601
1602 case CKA_SUBPRIME:
1603 isSubprime = 1;
1604 rv = get_bigint_attr_from_template(&subprime,
1605 &template[i]);
1606 if (rv != CKR_OK)
1607 goto fail_cleanup;
1608 break;
1609
1610 case CKA_BASE:
1611 isBase = 1;
1612 rv = get_bigint_attr_from_template(&base,
1613 &template[i]);
1614 if (rv != CKR_OK)
1615 goto fail_cleanup;
1616 break;
1617
1618 case CKA_VALUE:
1619 isValue = 1;
1620 rv = get_bigint_attr_from_template(&value,
1621 &template[i]);
1622 if (rv != CKR_OK)
1623 goto fail_cleanup;
1624 break;
1625
1626 case CKA_VALUE_BITS:
1627 isValueBits = 1;
1628 get_ulong_attr_from_template(&value_bits,
1629 &template[i]);
1630 break;
1631
1632 case CKA_LABEL:
1633 isLabel = 1;
1634 rv = get_string_from_template(&string_tmp,
1635 &template[i]);
1636 if (rv != CKR_OK)
1637 goto fail_cleanup;
1638 break;
1639
1640 case CKA_EC_PARAMS:
1641 isParams = 1;
1642 rv = get_string_from_template(¶m_tmp,
1643 &template[i]);
1644 if (rv != CKR_OK)
1645 goto fail_cleanup;
1646 break;
1647
1648 default:
1649 rv = kernel_parse_common_attrs(&template[i], sp,
1650 &attr_mask);
1651 if (rv != CKR_OK)
1652 goto fail_cleanup;
1653 break;
1654
1655 }
1656 } /* For */
1657
1658 /* Allocate storage for Private Key Object. */
1659 pvk = calloc(1, sizeof (private_key_obj_t));
1660 if (pvk == NULL) {
1661 rv = CKR_HOST_MEMORY;
1662 goto fail_cleanup;
1663 }
1664
1665 new_object->object_class_u.private_key = pvk;
1666 new_object->class = CKO_PRIVATE_KEY;
1667
1668 if (keytype == (CK_KEY_TYPE)~0UL) {
1669 rv = CKR_TEMPLATE_INCOMPLETE;
1670 goto fail_cleanup;
1671 }
1672
1673 new_object->key_type = keytype;
1674
1675 /* Supported key types of the Private Key Object */
1676 switch (keytype) {
1677 case CKK_RSA:
1678 if (isPrime || isSubprime || isBase || isValue ||
1679 isValueBits) {
1680 rv = CKR_TEMPLATE_INCONSISTENT;
1681 goto fail_cleanup;
1682 }
1683
1684 if (isModulus && isPriExpo) {
1685 /*
1686 * Copy big integer attribute value to the
1687 * designated place in the Private Key object.
1688 */
1689 copy_bigint_attr(&modulus, KEY_PRI_RSA_MOD(pvk));
1690
1691 copy_bigint_attr(&priexpo, KEY_PRI_RSA_PRIEXPO(pvk));
1692
1693 } else {
1694 rv = CKR_TEMPLATE_INCOMPLETE;
1695 goto fail_cleanup;
1696 }
1697
1698 /* The following attributes are optional. */
1699 if (isPubExpo) {
1700 copy_bigint_attr(&pubexpo, KEY_PRI_RSA_PUBEXPO(pvk));
1701 }
1702
1703 if (isPrime1) {
1704 copy_bigint_attr(&prime1, KEY_PRI_RSA_PRIME1(pvk));
1705 }
1706
1707 if (isPrime2) {
1708 copy_bigint_attr(&prime2, KEY_PRI_RSA_PRIME2(pvk));
1709 }
1710
1711 if (isExpo1) {
1712 copy_bigint_attr(&expo1, KEY_PRI_RSA_EXPO1(pvk));
1713 }
1714
1715 if (isExpo2) {
1716 copy_bigint_attr(&expo2, KEY_PRI_RSA_EXPO2(pvk));
1717 }
1718
1719 if (isCoef) {
1720 copy_bigint_attr(&coef, KEY_PRI_RSA_COEF(pvk));
1721 }
1722 break;
1723
1724 case CKK_DSA:
1725 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
1726 isPrime2 || isExpo1 || isExpo2 || isCoef ||
1727 isValueBits) {
1728 rv = CKR_TEMPLATE_INCONSISTENT;
1729 goto fail_cleanup;
1730 }
1731
1732 if (!(isPrime && isSubprime && isBase && isValue)) {
1733 rv = CKR_TEMPLATE_INCOMPLETE;
1734 goto fail_cleanup;
1735 }
1736
1737 copy_bigint_attr(&prime, KEY_PRI_DSA_PRIME(pvk));
1738
1739 copy_bigint_attr(&subprime, KEY_PRI_DSA_SUBPRIME(pvk));
1740
1741 copy_bigint_attr(&base, KEY_PRI_DSA_BASE(pvk));
1742
1743 copy_bigint_attr(&value, KEY_PRI_DSA_VALUE(pvk));
1744
1745 break;
1746
1747 case CKK_DH:
1748 if (mode == KERNEL_CREATE_OBJ && isValueBits) {
1749 rv = CKR_TEMPLATE_INCONSISTENT;
1750 goto fail_cleanup;
1751 }
1752 if (!(isPrime && isBase && isValue)) {
1753 rv = CKR_TEMPLATE_INCOMPLETE;
1754 goto fail_cleanup;
1755 }
1756
1757 copy_bigint_attr(&prime, KEY_PRI_DH_PRIME(pvk));
1758
1759 copy_bigint_attr(&base, KEY_PRI_DH_BASE(pvk));
1760
1761 copy_bigint_attr(&value, KEY_PRI_DH_VALUE(pvk));
1762
1763 KEY_PRI_DH_VAL_BITS(pvk) = (isValueBits) ? value_bits : 0;
1764
1765 break;
1766
1767 case CKK_EC:
1768 if (!isValue || !isParams) {
1769 rv = CKR_TEMPLATE_INCOMPLETE;
1770 goto fail_cleanup;
1771 }
1772
1773 copy_bigint_attr(&value, KEY_PRI_EC_VALUE(pvk));
1774 rv = kernel_add_extra_attr(¶m_tmp, new_object);
1775 if (rv != CKR_OK)
1776 goto fail_cleanup;
1777 string_attr_cleanup(¶m_tmp);
1778 break;
1779 default:
1780 rv = CKR_TEMPLATE_INCONSISTENT;
1781 goto fail_cleanup;
1782 }
1783
1784 /* Set up object. */
1785 new_object->bool_attr_mask = attr_mask;
1786 if (isLabel) {
1787 rv = kernel_add_extra_attr(&string_tmp, new_object);
1788 if (rv != CKR_OK)
1789 goto fail_cleanup;
1790 string_attr_cleanup(&string_tmp);
1791 }
1792
1793 return (rv);
1794
1795 fail_cleanup:
1796 /*
1797 * cleanup the storage allocated to the local variables.
1798 */
1799 bigint_attr_cleanup(&modulus);
1800 bigint_attr_cleanup(&priexpo);
1801 bigint_attr_cleanup(&prime);
1802 bigint_attr_cleanup(&subprime);
1803 bigint_attr_cleanup(&base);
1804 bigint_attr_cleanup(&value);
1805 bigint_attr_cleanup(&pubexpo);
1806 bigint_attr_cleanup(&prime1);
1807 bigint_attr_cleanup(&prime2);
1808 bigint_attr_cleanup(&expo1);
1809 bigint_attr_cleanup(&expo2);
1810 bigint_attr_cleanup(&coef);
1811 string_attr_cleanup(&string_tmp);
1812 string_attr_cleanup(¶m_tmp);
1813
1814 /*
1815 * cleanup the storage allocated inside the object itself.
1816 */
1817 kernel_cleanup_object(new_object);
1818
1819 return (rv);
1820 }
1821
1822
1823 /*
1824 * Build a Secret Key Object.
1825 *
1826 * - Parse the object's template, and when an error is detected such as
1827 * invalid attribute type, invalid attribute value, etc., return
1828 * with appropriate return value.
1829 * - Set up attribute mask field in the object for the supplied common
1830 * attributes that have boolean type.
1831 * - Build the attribute_info struct to hold the value of each supplied
1832 * attribute that has byte array type. Link attribute_info structs
1833 * together to form the extra attribute list of the object.
1834 * - Allocate storage for the Secret Key object.
1835 * - Build the Secret Key object. Allocate storage to hold the big integer
1836 * value for the attribute CKA_VALUE that is required for all the key
1837 * types supported by secret key object.
1838 *
1839 */
1840 CK_RV
kernel_build_secret_key_object(CK_ATTRIBUTE_PTR template,CK_ULONG ulAttrNum,kernel_object_t * new_object,kernel_session_t * sp)1841 kernel_build_secret_key_object(CK_ATTRIBUTE_PTR template,
1842 CK_ULONG ulAttrNum, kernel_object_t *new_object, kernel_session_t *sp)
1843 {
1844
1845 int i;
1846 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1847 uint64_t attr_mask = SECRET_KEY_DEFAULT;
1848 CK_RV rv = CKR_OK;
1849 int isLabel = 0;
1850 /* Must set flags */
1851 int isValue = 0;
1852 /* Must not set flags */
1853 int isValueLen = 0;
1854
1855 CK_ATTRIBUTE string_tmp;
1856
1857 secret_key_obj_t *sck;
1858
1859 string_tmp.pValue = NULL;
1860
1861 /* Allocate storage for Secret Key Object. */
1862 sck = calloc(1, sizeof (secret_key_obj_t));
1863 if (sck == NULL) {
1864 rv = CKR_HOST_MEMORY;
1865 goto fail_cleanup;
1866 }
1867
1868 new_object->object_class_u.secret_key = sck;
1869 new_object->class = CKO_SECRET_KEY;
1870
1871 for (i = 0; i < ulAttrNum; i++) {
1872
1873 /* Secret Key Object Attributes */
1874 switch (template[i].type) {
1875
1876 /* common key attributes */
1877 case CKA_KEY_TYPE:
1878 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1879 break;
1880
1881 case CKA_ID:
1882 case CKA_START_DATE:
1883 case CKA_END_DATE:
1884 /*
1885 * Allocate storage to hold the attribute
1886 * value with byte array type, and add it to
1887 * the extra attribute list of the object.
1888 */
1889 rv = kernel_add_extra_attr(&template[i],
1890 new_object);
1891 if (rv != CKR_OK) {
1892 goto fail_cleanup;
1893 }
1894 break;
1895
1896 /*
1897 * The following key related attribute types must
1898 * not be specified by C_CreateObject.
1899 */
1900 case CKA_LOCAL:
1901 case CKA_KEY_GEN_MECHANISM:
1902 case CKA_ALWAYS_SENSITIVE:
1903 case CKA_NEVER_EXTRACTABLE:
1904 rv = CKR_TEMPLATE_INCONSISTENT;
1905 goto fail_cleanup;
1906
1907 /* Key related boolean attributes */
1908 case CKA_DERIVE:
1909 if (*(CK_BBOOL *)template[i].pValue)
1910 attr_mask |= DERIVE_BOOL_ON;
1911 break;
1912
1913 case CKA_SENSITIVE:
1914 if (*(CK_BBOOL *)template[i].pValue)
1915 attr_mask |= SENSITIVE_BOOL_ON;
1916 break;
1917
1918 case CKA_ENCRYPT:
1919 if (*(CK_BBOOL *)template[i].pValue)
1920 attr_mask |= ENCRYPT_BOOL_ON;
1921 else
1922 attr_mask &= ~ENCRYPT_BOOL_ON;
1923 break;
1924
1925 case CKA_DECRYPT:
1926 if (*(CK_BBOOL *)template[i].pValue)
1927 attr_mask |= DECRYPT_BOOL_ON;
1928 else
1929 attr_mask &= ~DECRYPT_BOOL_ON;
1930 break;
1931
1932 case CKA_SIGN:
1933 if (*(CK_BBOOL *)template[i].pValue)
1934 attr_mask |= SIGN_BOOL_ON;
1935 else
1936 attr_mask &= ~SIGN_BOOL_ON;
1937 break;
1938
1939 case CKA_VERIFY:
1940 if (*(CK_BBOOL *)template[i].pValue)
1941 attr_mask |= VERIFY_BOOL_ON;
1942 else
1943 attr_mask &= ~VERIFY_BOOL_ON;
1944 break;
1945
1946 case CKA_WRAP:
1947 if (*(CK_BBOOL *)template[i].pValue)
1948 attr_mask |= WRAP_BOOL_ON;
1949 break;
1950
1951 case CKA_UNWRAP:
1952 if (*(CK_BBOOL *)template[i].pValue)
1953 attr_mask |= UNWRAP_BOOL_ON;
1954 break;
1955
1956 case CKA_EXTRACTABLE:
1957 if (*(CK_BBOOL *)template[i].pValue)
1958 attr_mask |= EXTRACTABLE_BOOL_ON;
1959 else
1960 attr_mask &= ~EXTRACTABLE_BOOL_ON;
1961 break;
1962
1963 case CKA_VALUE:
1964 isValue = 1;
1965 if ((template[i].ulValueLen == 0) ||
1966 (template[i].pValue == NULL)) {
1967 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1968 goto fail_cleanup;
1969 }
1970
1971 /*
1972 * Copyin attribute from template
1973 * to a local variable.
1974 */
1975 sck->sk_value = malloc(template[i].ulValueLen);
1976 if (sck->sk_value == NULL) {
1977 rv = CKR_HOST_MEMORY;
1978 goto fail_cleanup;
1979 }
1980 (void) memcpy(sck->sk_value, template[i].pValue,
1981 template[i].ulValueLen);
1982 sck->sk_value_len = template[i].ulValueLen;
1983 break;
1984
1985 case CKA_VALUE_LEN:
1986 isValueLen = 1;
1987 break;
1988
1989 case CKA_LABEL:
1990 isLabel = 1;
1991 rv = get_string_from_template(&string_tmp,
1992 &template[i]);
1993 if (rv != CKR_OK)
1994 goto fail_cleanup;
1995 break;
1996
1997 default:
1998 rv = kernel_parse_common_attrs(&template[i], sp,
1999 &attr_mask);
2000 if (rv != CKR_OK)
2001 goto fail_cleanup;
2002 break;
2003
2004 }
2005 } /* For */
2006
2007 if (keytype == (CK_KEY_TYPE)~0UL) {
2008 rv = CKR_TEMPLATE_INCOMPLETE;
2009 goto fail_cleanup;
2010 }
2011
2012 new_object->key_type = keytype;
2013
2014 /* Supported key types of the Secret Key Object */
2015 switch (keytype) {
2016 case CKK_RC4:
2017 if (!isValue) {
2018 rv = CKR_TEMPLATE_INCOMPLETE;
2019 goto fail_cleanup;
2020 }
2021 if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) ||
2022 (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) {
2023 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2024 goto fail_cleanup;
2025 }
2026 break;
2027
2028 case CKK_GENERIC_SECRET:
2029 if (!isValue) {
2030 rv = CKR_TEMPLATE_INCOMPLETE;
2031 goto fail_cleanup;
2032 }
2033 break;
2034
2035 case CKK_AES:
2036 if (!isValue) {
2037 rv = CKR_TEMPLATE_INCOMPLETE;
2038 goto fail_cleanup;
2039 }
2040 if (sck->sk_value_len < AES_MIN_KEY_BYTES) {
2041 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2042 goto fail_cleanup;
2043 }
2044 break;
2045
2046 case CKK_BLOWFISH:
2047 if (!isValue) {
2048 rv = CKR_TEMPLATE_INCOMPLETE;
2049 goto fail_cleanup;
2050 }
2051 if (sck->sk_value_len < BLOWFISH_MINBYTES) {
2052 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2053 goto fail_cleanup;
2054 }
2055 break;
2056
2057 case CKK_DES:
2058 if (!isValue) {
2059 rv = CKR_TEMPLATE_INCOMPLETE;
2060 goto fail_cleanup;
2061 }
2062 if (sck->sk_value_len != DES_KEYSIZE) {
2063 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2064 goto fail_cleanup;
2065 }
2066 break;
2067
2068 case CKK_DES2:
2069 if (!isValue) {
2070 rv = CKR_TEMPLATE_INCOMPLETE;
2071 goto fail_cleanup;
2072 }
2073 if (sck->sk_value_len != DES2_KEYSIZE) {
2074 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2075 goto fail_cleanup;
2076 }
2077 break;
2078
2079 case CKK_DES3:
2080 if (!isValue) {
2081 rv = CKR_TEMPLATE_INCOMPLETE;
2082 goto fail_cleanup;
2083 }
2084 if (sck->sk_value_len != DES3_KEYSIZE) {
2085 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2086 goto fail_cleanup;
2087 }
2088 break;
2089
2090 default:
2091 rv = CKR_TEMPLATE_INCONSISTENT;
2092 goto fail_cleanup;
2093 }
2094
2095 if (isValueLen) {
2096 rv = CKR_TEMPLATE_INCONSISTENT;
2097 goto fail_cleanup;
2098 }
2099
2100 /* Set up object. */
2101 new_object->bool_attr_mask = attr_mask;
2102 if (isLabel) {
2103 rv = kernel_add_extra_attr(&string_tmp, new_object);
2104 if (rv != CKR_OK)
2105 goto fail_cleanup;
2106 string_attr_cleanup(&string_tmp);
2107 }
2108
2109 return (rv);
2110
2111 fail_cleanup:
2112 /*
2113 * cleanup the storage allocated to the local variables.
2114 */
2115 string_attr_cleanup(&string_tmp);
2116
2117 /*
2118 * cleanup the storage allocated inside the object itself.
2119 */
2120 kernel_cleanup_object(new_object);
2121
2122 return (rv);
2123 }
2124
2125
2126 /*
2127 * Validate the attribute types in the object's template. Then,
2128 * call the appropriate build function according to the class of
2129 * the object specified in the template.
2130 *
2131 * Note: The following classes of objects are supported:
2132 * - CKO_SECRET_KEY
2133 * - CKO_PUBLIC_KEY
2134 * - CKO_PRIVATE_KEY
2135 */
2136 CK_RV
kernel_build_object(CK_ATTRIBUTE_PTR template,CK_ULONG ulAttrNum,kernel_object_t * new_object,kernel_session_t * sp,uint_t mode)2137 kernel_build_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
2138 kernel_object_t *new_object, kernel_session_t *sp, uint_t mode)
2139 {
2140
2141 CK_OBJECT_CLASS class = (CK_OBJECT_CLASS)~0UL;
2142 CK_RV rv = CKR_OK;
2143
2144 if (template == NULL) {
2145 return (CKR_ARGUMENTS_BAD);
2146 }
2147
2148 /* Validate the attribute type in the template. */
2149 rv = kernel_validate_attr(template, ulAttrNum, &class);
2150 if (rv != CKR_OK)
2151 return (rv);
2152
2153 if (class == (CK_OBJECT_CLASS)~0UL)
2154 return (CKR_TEMPLATE_INCOMPLETE);
2155
2156 /*
2157 * Call the appropriate function based on the supported class
2158 * of the object.
2159 */
2160 switch (class) {
2161 case CKO_PUBLIC_KEY:
2162 rv = kernel_build_public_key_object(template, ulAttrNum,
2163 new_object, sp, mode);
2164 break;
2165
2166 case CKO_PRIVATE_KEY:
2167 rv = kernel_build_private_key_object(template, ulAttrNum,
2168 new_object, sp, mode);
2169 break;
2170
2171 case CKO_SECRET_KEY:
2172 rv = kernel_build_secret_key_object(template, ulAttrNum,
2173 new_object, sp);
2174 break;
2175
2176 case CKO_DOMAIN_PARAMETERS:
2177 case CKO_DATA:
2178 case CKO_CERTIFICATE:
2179 case CKO_HW_FEATURE:
2180 case CKO_VENDOR_DEFINED:
2181 default:
2182 return (CKR_ATTRIBUTE_VALUE_INVALID);
2183 }
2184
2185 return (rv);
2186 }
2187
2188
2189 /*
2190 * Get the value of a requested attribute that is common to all supported
2191 * classes (i.e. public key, private key, secret key classes).
2192 */
2193 CK_RV
kernel_get_common_attrs(kernel_object_t * object_p,CK_ATTRIBUTE_PTR template)2194 kernel_get_common_attrs(kernel_object_t *object_p, CK_ATTRIBUTE_PTR template)
2195 {
2196
2197 CK_RV rv = CKR_OK;
2198
2199 switch (template->type) {
2200
2201 case CKA_CLASS:
2202 return (get_ulong_attr_from_object(object_p->class,
2203 template));
2204
2205 /* default boolean attributes */
2206 case CKA_TOKEN:
2207
2208 template->ulValueLen = sizeof (CK_BBOOL);
2209 if (template->pValue == NULL) {
2210 return (CKR_OK);
2211 }
2212
2213 /*
2214 * A token object will not be created in the library, so we
2215 * return FALSE.
2216 */
2217 *((CK_BBOOL *)template->pValue) = B_FALSE;
2218 break;
2219
2220 case CKA_PRIVATE:
2221
2222 template->ulValueLen = sizeof (CK_BBOOL);
2223 if (template->pValue == NULL) {
2224 return (CKR_OK);
2225 }
2226 if (object_p->bool_attr_mask & PRIVATE_BOOL_ON) {
2227 *((CK_BBOOL *)template->pValue) = B_TRUE;
2228 } else {
2229 *((CK_BBOOL *)template->pValue) = B_FALSE;
2230 }
2231 break;
2232
2233 case CKA_MODIFIABLE:
2234 template->ulValueLen = sizeof (CK_BBOOL);
2235 if (template->pValue == NULL) {
2236 return (CKR_OK);
2237 }
2238 if ((object_p->bool_attr_mask) & MODIFIABLE_BOOL_ON)
2239 *((CK_BBOOL *)template->pValue) = B_TRUE;
2240 else
2241 *((CK_BBOOL *)template->pValue) = B_FALSE;
2242 break;
2243
2244 case CKA_LABEL:
2245 return (get_extra_attr_from_object(object_p,
2246 template));
2247
2248 default:
2249 /*
2250 * The specified attribute for the object is invalid.
2251 * (the object does not possess such an attribute.)
2252 */
2253 template->ulValueLen = (CK_ULONG)-1;
2254 return (CKR_ATTRIBUTE_TYPE_INVALID);
2255 }
2256
2257 return (rv);
2258 }
2259
2260 /*
2261 * Get the value of a requested attribute that is common to all key objects
2262 * (i.e. public key, private key and secret key).
2263 */
2264 CK_RV
kernel_get_common_key_attrs(kernel_object_t * object_p,CK_ATTRIBUTE_PTR template)2265 kernel_get_common_key_attrs(kernel_object_t *object_p,
2266 CK_ATTRIBUTE_PTR template)
2267 {
2268
2269 switch (template->type) {
2270
2271 case CKA_KEY_TYPE:
2272 return (get_ulong_attr_from_object(object_p->key_type,
2273 template));
2274
2275 case CKA_ID:
2276 case CKA_START_DATE:
2277 case CKA_END_DATE:
2278 /*
2279 * The above extra attributes have byte array type.
2280 */
2281 return (get_extra_attr_from_object(object_p,
2282 template));
2283
2284 /* Key related boolean attributes */
2285 case CKA_LOCAL:
2286 return (get_bool_attr_from_object(object_p,
2287 LOCAL_BOOL_ON, template));
2288
2289 case CKA_DERIVE:
2290 return (get_bool_attr_from_object(object_p,
2291 DERIVE_BOOL_ON, template));
2292
2293 case CKA_KEY_GEN_MECHANISM:
2294 return (get_ulong_attr_from_object(object_p->mechanism,
2295 template));
2296
2297 default:
2298 return (CKR_ATTRIBUTE_TYPE_INVALID);
2299 }
2300 }
2301
2302
2303 /*
2304 * Get the value of a requested attribute of a Public Key Object.
2305 *
2306 * Rule: All the attributes in the public key object can be revealed.
2307 */
2308 CK_RV
kernel_get_public_key_attribute(kernel_object_t * object_p,CK_ATTRIBUTE_PTR template)2309 kernel_get_public_key_attribute(kernel_object_t *object_p,
2310 CK_ATTRIBUTE_PTR template)
2311 {
2312
2313 CK_RV rv = CKR_OK;
2314 CK_KEY_TYPE keytype = object_p->key_type;
2315
2316 switch (template->type) {
2317
2318 case CKA_SUBJECT:
2319 case CKA_EC_PARAMS:
2320 /*
2321 * The above extra attributes have byte array type.
2322 */
2323 return (get_extra_attr_from_object(object_p,
2324 template));
2325
2326 /* Key related boolean attributes */
2327 case CKA_ENCRYPT:
2328 return (get_bool_attr_from_object(object_p,
2329 ENCRYPT_BOOL_ON, template));
2330
2331 case CKA_VERIFY:
2332 return (get_bool_attr_from_object(object_p,
2333 VERIFY_BOOL_ON, template));
2334
2335 case CKA_VERIFY_RECOVER:
2336 return (get_bool_attr_from_object(object_p,
2337 VERIFY_RECOVER_BOOL_ON, template));
2338
2339 case CKA_WRAP:
2340 return (get_bool_attr_from_object(object_p,
2341 WRAP_BOOL_ON, template));
2342
2343 case CKA_TRUSTED:
2344 return (get_bool_attr_from_object(object_p,
2345 TRUSTED_BOOL_ON, template));
2346
2347 case CKA_MODULUS:
2348 /*
2349 * This attribute is valid only for RSA public key
2350 * object.
2351 */
2352 if (keytype == CKK_RSA) {
2353 return (get_bigint_attr_from_object(
2354 OBJ_PUB_RSA_MOD(object_p), template));
2355 } else {
2356 template->ulValueLen = (CK_ULONG)-1;
2357 return (CKR_ATTRIBUTE_TYPE_INVALID);
2358 }
2359
2360 case CKA_PUBLIC_EXPONENT:
2361 if (keytype == CKK_RSA) {
2362 return (get_bigint_attr_from_object(
2363 OBJ_PUB_RSA_PUBEXPO(object_p), template));
2364 } else {
2365 template->ulValueLen = (CK_ULONG)-1;
2366 return (CKR_ATTRIBUTE_TYPE_INVALID);
2367 }
2368
2369 case CKA_MODULUS_BITS:
2370 if (keytype == CKK_RSA) {
2371 return (get_ulong_attr_from_object(
2372 OBJ_PUB_RSA_MOD_BITS(object_p), template));
2373 } else {
2374 template->ulValueLen = (CK_ULONG)-1;
2375 return (CKR_ATTRIBUTE_TYPE_INVALID);
2376 }
2377
2378 case CKA_PRIME:
2379 switch (keytype) {
2380 case CKK_DSA:
2381 return (get_bigint_attr_from_object(
2382 OBJ_PUB_DSA_PRIME(object_p), template));
2383 case CKK_DH:
2384 return (get_bigint_attr_from_object(
2385 OBJ_PUB_DH_PRIME(object_p), template));
2386 default:
2387 template->ulValueLen = (CK_ULONG)-1;
2388 return (CKR_ATTRIBUTE_TYPE_INVALID);
2389 }
2390
2391 case CKA_SUBPRIME:
2392 switch (keytype) {
2393 case CKK_DSA:
2394 return (get_bigint_attr_from_object(
2395 OBJ_PUB_DSA_SUBPRIME(object_p), template));
2396 default:
2397 template->ulValueLen = (CK_ULONG)-1;
2398 return (CKR_ATTRIBUTE_TYPE_INVALID);
2399 }
2400
2401 case CKA_BASE:
2402 switch (keytype) {
2403 case CKK_DSA:
2404 return (get_bigint_attr_from_object(
2405 OBJ_PUB_DSA_BASE(object_p), template));
2406 case CKK_DH:
2407 return (get_bigint_attr_from_object(
2408 OBJ_PUB_DH_BASE(object_p), template));
2409 default:
2410 template->ulValueLen = (CK_ULONG)-1;
2411 return (CKR_ATTRIBUTE_TYPE_INVALID);
2412 }
2413
2414 case CKA_VALUE:
2415 switch (keytype) {
2416 case CKK_DSA:
2417 return (get_bigint_attr_from_object(
2418 OBJ_PUB_DSA_VALUE(object_p), template));
2419 case CKK_DH:
2420 return (get_bigint_attr_from_object(
2421 OBJ_PUB_DH_VALUE(object_p), template));
2422 default:
2423 template->ulValueLen = (CK_ULONG)-1;
2424 return (CKR_ATTRIBUTE_TYPE_INVALID);
2425 }
2426
2427 case CKA_EC_POINT:
2428 switch (keytype) {
2429 case CKK_EC:
2430 return (get_bigint_attr_from_object(
2431 OBJ_PUB_EC_POINT(object_p), template));
2432 default:
2433 template->ulValueLen = (CK_ULONG)-1;
2434 return (CKR_ATTRIBUTE_TYPE_INVALID);
2435 }
2436 default:
2437 /*
2438 * First, get the value of the request attribute defined
2439 * in the list of common key attributes. If the request
2440 * attribute is not found in that list, then get the
2441 * attribute from the list of common attributes.
2442 */
2443 rv = kernel_get_common_key_attrs(object_p, template);
2444 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
2445 rv = kernel_get_common_attrs(object_p, template);
2446 }
2447 break;
2448 }
2449
2450 return (rv);
2451 }
2452
2453
2454 /*
2455 * Get the value of a requested attribute of a Private Key Object.
2456 *
2457 * Rule: All the attributes in the private key object can be revealed
2458 * except those marked with footnote number "7" when the object
2459 * has its CKA_SENSITIVE attribute set to TRUE or its
2460 * CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.).
2461 */
2462 CK_RV
kernel_get_private_key_attribute(kernel_object_t * object_p,CK_ATTRIBUTE_PTR template)2463 kernel_get_private_key_attribute(kernel_object_t *object_p,
2464 CK_ATTRIBUTE_PTR template)
2465 {
2466
2467 CK_RV rv = CKR_OK;
2468 CK_KEY_TYPE keytype = object_p->key_type;
2469
2470
2471 /*
2472 * If the following specified attributes for the private key
2473 * object cannot be revealed because the object is sensitive
2474 * or unextractable, then the ulValueLen is set to -1.
2475 */
2476 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
2477 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
2478
2479 switch (template->type) {
2480 case CKA_PRIVATE_EXPONENT:
2481 case CKA_PRIME_1:
2482 case CKA_PRIME_2:
2483 case CKA_EXPONENT_1:
2484 case CKA_EXPONENT_2:
2485 case CKA_COEFFICIENT:
2486 case CKA_VALUE:
2487 template->ulValueLen = (CK_ULONG)-1;
2488 return (CKR_ATTRIBUTE_SENSITIVE);
2489 }
2490 }
2491
2492 switch (template->type) {
2493
2494 case CKA_SUBJECT:
2495 case CKA_EC_PARAMS:
2496 /*
2497 * The above extra attributes have byte array type.
2498 */
2499 return (get_extra_attr_from_object(object_p,
2500 template));
2501
2502 /* Key related boolean attributes */
2503 case CKA_SENSITIVE:
2504 return (get_bool_attr_from_object(object_p,
2505 SENSITIVE_BOOL_ON, template));
2506
2507 case CKA_SECONDARY_AUTH:
2508 return (get_bool_attr_from_object(object_p,
2509 SECONDARY_AUTH_BOOL_ON, template));
2510
2511 case CKA_DECRYPT:
2512 return (get_bool_attr_from_object(object_p,
2513 DECRYPT_BOOL_ON, template));
2514
2515 case CKA_SIGN:
2516 return (get_bool_attr_from_object(object_p,
2517 SIGN_BOOL_ON, template));
2518
2519 case CKA_SIGN_RECOVER:
2520 return (get_bool_attr_from_object(object_p,
2521 SIGN_RECOVER_BOOL_ON, template));
2522
2523 case CKA_UNWRAP:
2524 return (get_bool_attr_from_object(object_p,
2525 UNWRAP_BOOL_ON, template));
2526
2527 case CKA_EXTRACTABLE:
2528 return (get_bool_attr_from_object(object_p,
2529 EXTRACTABLE_BOOL_ON, template));
2530
2531 case CKA_ALWAYS_SENSITIVE:
2532 return (get_bool_attr_from_object(object_p,
2533 ALWAYS_SENSITIVE_BOOL_ON, template));
2534
2535 case CKA_NEVER_EXTRACTABLE:
2536 return (get_bool_attr_from_object(object_p,
2537 NEVER_EXTRACTABLE_BOOL_ON, template));
2538
2539 case CKA_MODULUS:
2540 if (keytype == CKK_RSA) {
2541 return (get_bigint_attr_from_object(
2542 OBJ_PRI_RSA_MOD(object_p), template));
2543 } else {
2544 template->ulValueLen = (CK_ULONG)-1;
2545 rv = CKR_ATTRIBUTE_TYPE_INVALID;
2546 break;
2547 }
2548
2549 case CKA_PUBLIC_EXPONENT:
2550 if (keytype == CKK_RSA) {
2551 return (get_bigint_attr_from_object(
2552 OBJ_PRI_RSA_PUBEXPO(object_p), template));
2553 } else {
2554 template->ulValueLen = (CK_ULONG)-1;
2555 rv = CKR_ATTRIBUTE_TYPE_INVALID;
2556 break;
2557 }
2558
2559 case CKA_PRIVATE_EXPONENT:
2560 if (keytype == CKK_RSA) {
2561 return (get_bigint_attr_from_object(
2562 OBJ_PRI_RSA_PRIEXPO(object_p), template));
2563 } else {
2564 template->ulValueLen = (CK_ULONG)-1;
2565 rv = CKR_ATTRIBUTE_TYPE_INVALID;
2566 break;
2567 }
2568
2569 case CKA_PRIME_1:
2570 if (keytype == CKK_RSA) {
2571 return (get_bigint_attr_from_object(
2572 OBJ_PRI_RSA_PRIME1(object_p), template));
2573 } else {
2574 template->ulValueLen = (CK_ULONG)-1;
2575 rv = CKR_ATTRIBUTE_TYPE_INVALID;
2576 break;
2577 }
2578
2579 case CKA_PRIME_2:
2580 if (keytype == CKK_RSA) {
2581 return (get_bigint_attr_from_object(
2582 OBJ_PRI_RSA_PRIME2(object_p), template));
2583 } else {
2584 template->ulValueLen = (CK_ULONG)-1;
2585 rv = CKR_ATTRIBUTE_TYPE_INVALID;
2586 break;
2587 }
2588
2589 case CKA_EXPONENT_1:
2590 if (keytype == CKK_RSA) {
2591 return (get_bigint_attr_from_object(
2592 OBJ_PRI_RSA_EXPO1(object_p), template));
2593 } else {
2594 template->ulValueLen = (CK_ULONG)-1;
2595 rv = CKR_ATTRIBUTE_TYPE_INVALID;
2596 break;
2597 }
2598
2599 case CKA_EXPONENT_2:
2600 if (keytype == CKK_RSA) {
2601 return (get_bigint_attr_from_object(
2602 OBJ_PRI_RSA_EXPO2(object_p), template));
2603 } else {
2604 template->ulValueLen = (CK_ULONG)-1;
2605 rv = CKR_ATTRIBUTE_TYPE_INVALID;
2606 break;
2607 }
2608
2609 case CKA_COEFFICIENT:
2610 if (keytype == CKK_RSA) {
2611 return (get_bigint_attr_from_object(
2612 OBJ_PRI_RSA_COEF(object_p), template));
2613 } else {
2614 template->ulValueLen = (CK_ULONG)-1;
2615 rv = CKR_ATTRIBUTE_TYPE_INVALID;
2616 break;
2617 }
2618
2619 case CKA_VALUE_BITS:
2620 if (keytype == CKK_DH) {
2621 return (get_ulong_attr_from_object(
2622 OBJ_PRI_DH_VAL_BITS(object_p), template));
2623 } else {
2624 template->ulValueLen = (CK_ULONG)-1;
2625 rv = CKR_ATTRIBUTE_TYPE_INVALID;
2626 break;
2627 }
2628
2629 case CKA_PRIME:
2630 switch (keytype) {
2631 case CKK_DSA:
2632 return (get_bigint_attr_from_object(
2633 OBJ_PRI_DSA_PRIME(object_p), template));
2634 case CKK_DH:
2635 return (get_bigint_attr_from_object(
2636 OBJ_PRI_DH_PRIME(object_p), template));
2637 default:
2638 template->ulValueLen = (CK_ULONG)-1;
2639 return (CKR_ATTRIBUTE_TYPE_INVALID);
2640 }
2641
2642 case CKA_SUBPRIME:
2643 switch (keytype) {
2644 case CKK_DSA:
2645 return (get_bigint_attr_from_object(
2646 OBJ_PRI_DSA_SUBPRIME(object_p), template));
2647 default:
2648 template->ulValueLen = (CK_ULONG)-1;
2649 return (CKR_ATTRIBUTE_TYPE_INVALID);
2650 }
2651
2652 case CKA_BASE:
2653 switch (keytype) {
2654 case CKK_DSA:
2655 return (get_bigint_attr_from_object(
2656 OBJ_PRI_DSA_BASE(object_p), template));
2657 case CKK_DH:
2658 return (get_bigint_attr_from_object(
2659 OBJ_PRI_DH_BASE(object_p), template));
2660 default:
2661 template->ulValueLen = (CK_ULONG)-1;
2662 return (CKR_ATTRIBUTE_TYPE_INVALID);
2663 }
2664
2665 case CKA_VALUE:
2666 switch (keytype) {
2667 case CKK_DSA:
2668 return (get_bigint_attr_from_object(
2669 OBJ_PRI_DSA_VALUE(object_p), template));
2670 case CKK_DH:
2671 return (get_bigint_attr_from_object(
2672 OBJ_PRI_DH_VALUE(object_p), template));
2673 case CKK_EC:
2674 return (get_bigint_attr_from_object(
2675 OBJ_PRI_EC_VALUE(object_p), template));
2676 default:
2677 template->ulValueLen = (CK_ULONG)-1;
2678 return (CKR_ATTRIBUTE_TYPE_INVALID);
2679 }
2680
2681 default:
2682 /*
2683 * First, get the value of the request attribute defined
2684 * in the list of common key attributes. If the request
2685 * attribute is not found in that list, then get the
2686 * attribute from the list of common attributes.
2687 */
2688 rv = kernel_get_common_key_attrs(object_p, template);
2689 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
2690 rv = kernel_get_common_attrs(object_p, template);
2691 }
2692 break;
2693 }
2694
2695 return (rv);
2696 }
2697
2698
2699 /*
2700 * Get the value of a requested attribute of a Secret Key Object.
2701 *
2702 * Rule: All the attributes in the secret key object can be revealed
2703 * except those marked with footnote number "7" when the object
2704 * has its CKA_SENSITIVE attribute set to TRUE or its
2705 * CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.).
2706 */
2707 CK_RV
kernel_get_secret_key_attribute(kernel_object_t * object_p,CK_ATTRIBUTE_PTR template)2708 kernel_get_secret_key_attribute(kernel_object_t *object_p,
2709 CK_ATTRIBUTE_PTR template)
2710 {
2711
2712 CK_RV rv = CKR_OK;
2713 CK_KEY_TYPE keytype = object_p->key_type;
2714
2715 switch (template->type) {
2716
2717 /* Key related boolean attributes */
2718 case CKA_SENSITIVE:
2719 return (get_bool_attr_from_object(object_p,
2720 SENSITIVE_BOOL_ON, template));
2721
2722 case CKA_ENCRYPT:
2723 return (get_bool_attr_from_object(object_p,
2724 ENCRYPT_BOOL_ON, template));
2725
2726 case CKA_DECRYPT:
2727 return (get_bool_attr_from_object(object_p,
2728 DECRYPT_BOOL_ON, template));
2729
2730 case CKA_SIGN:
2731 return (get_bool_attr_from_object(object_p,
2732 SIGN_BOOL_ON, template));
2733
2734 case CKA_VERIFY:
2735 return (get_bool_attr_from_object(object_p,
2736 VERIFY_BOOL_ON, template));
2737
2738 case CKA_WRAP:
2739 return (get_bool_attr_from_object(object_p,
2740 WRAP_BOOL_ON, template));
2741
2742 case CKA_UNWRAP:
2743 return (get_bool_attr_from_object(object_p,
2744 UNWRAP_BOOL_ON, template));
2745
2746 case CKA_EXTRACTABLE:
2747 return (get_bool_attr_from_object(object_p,
2748 EXTRACTABLE_BOOL_ON, template));
2749
2750 case CKA_ALWAYS_SENSITIVE:
2751 return (get_bool_attr_from_object(object_p,
2752 ALWAYS_SENSITIVE_BOOL_ON, template));
2753
2754 case CKA_NEVER_EXTRACTABLE:
2755 return (get_bool_attr_from_object(object_p,
2756 NEVER_EXTRACTABLE_BOOL_ON, template));
2757
2758 case CKA_VALUE:
2759 /*
2760 * If the specified attribute for the secret key object
2761 * cannot be revealed because the object is sensitive
2762 * or unextractable, then the ulValueLen is set to -1.
2763 */
2764 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
2765 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
2766 template->ulValueLen = (CK_ULONG)-1;
2767 return (CKR_ATTRIBUTE_SENSITIVE);
2768 }
2769
2770 switch (keytype) {
2771 case CKK_RC4:
2772 case CKK_GENERIC_SECRET:
2773 case CKK_RC5:
2774 case CKK_DES:
2775 case CKK_DES2:
2776 case CKK_DES3:
2777 case CKK_CDMF:
2778 case CKK_AES:
2779 case CKK_BLOWFISH:
2780 /*
2781 * Copy secret key object attributes to template.
2782 */
2783 if (template->pValue == NULL) {
2784 template->ulValueLen =
2785 OBJ_SEC_VALUE_LEN(object_p);
2786 return (CKR_OK);
2787 }
2788
2789 if (OBJ_SEC_VALUE(object_p) == NULL) {
2790 template->ulValueLen = 0;
2791 return (CKR_OK);
2792 }
2793
2794 if (template->ulValueLen >=
2795 OBJ_SEC_VALUE_LEN(object_p)) {
2796 (void) memcpy(template->pValue,
2797 OBJ_SEC_VALUE(object_p),
2798 OBJ_SEC_VALUE_LEN(object_p));
2799 template->ulValueLen =
2800 OBJ_SEC_VALUE_LEN(object_p);
2801 return (CKR_OK);
2802 } else {
2803 template->ulValueLen = (CK_ULONG)-1;
2804 return (CKR_BUFFER_TOO_SMALL);
2805 }
2806
2807 default:
2808 template->ulValueLen = (CK_ULONG)-1;
2809 rv = CKR_ATTRIBUTE_TYPE_INVALID;
2810 break;
2811 }
2812 break;
2813
2814 case CKA_VALUE_LEN:
2815 return (get_ulong_attr_from_object(OBJ_SEC_VALUE_LEN(object_p),
2816 template));
2817
2818 default:
2819 /*
2820 * First, get the value of the request attribute defined
2821 * in the list of common key attributes. If the request
2822 * attribute is not found in that list, then get the
2823 * attribute from the list of common attributes.
2824 */
2825 rv = kernel_get_common_key_attrs(object_p, template);
2826 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
2827 rv = kernel_get_common_attrs(object_p, template);
2828 }
2829 break;
2830 }
2831
2832 return (rv);
2833
2834 }
2835
2836
2837
2838
2839 /*
2840 * Call the appropriate get attribute function according to the class
2841 * of object.
2842 *
2843 * The caller of this function holds the lock on the object.
2844 */
2845 CK_RV
kernel_get_attribute(kernel_object_t * object_p,CK_ATTRIBUTE_PTR template)2846 kernel_get_attribute(kernel_object_t *object_p, CK_ATTRIBUTE_PTR template)
2847 {
2848
2849 CK_RV rv = CKR_OK;
2850 CK_OBJECT_CLASS class = object_p->class;
2851
2852 switch (class) {
2853
2854 case CKO_PUBLIC_KEY:
2855 rv = kernel_get_public_key_attribute(object_p, template);
2856 break;
2857
2858 case CKO_PRIVATE_KEY:
2859 rv = kernel_get_private_key_attribute(object_p, template);
2860 break;
2861
2862 case CKO_SECRET_KEY:
2863 rv = kernel_get_secret_key_attribute(object_p, template);
2864 break;
2865
2866 default:
2867 /*
2868 * If the specified attribute for the object is invalid
2869 * (the object does not possess such as attribute), then
2870 * the ulValueLen is modified to hold the value -1.
2871 */
2872 template->ulValueLen = (CK_ULONG)-1;
2873 return (CKR_ATTRIBUTE_TYPE_INVALID);
2874 }
2875
2876 return (rv);
2877
2878 }
2879
2880 /*
2881 * Set the value of an attribute that is common to all key objects
2882 * (i.e. public key, private key and secret key).
2883 */
2884 CK_RV
kernel_set_common_key_attribute(kernel_object_t * object_p,CK_ATTRIBUTE_PTR template,boolean_t copy,kernel_session_t * sp)2885 kernel_set_common_key_attribute(kernel_object_t *object_p,
2886 CK_ATTRIBUTE_PTR template, boolean_t copy, kernel_session_t *sp)
2887 {
2888
2889 kernel_slot_t *pslot = slot_table[sp->ses_slotid];
2890 CK_RV rv = CKR_OK;
2891
2892 switch (template->type) {
2893
2894 case CKA_LABEL:
2895 /*
2896 * Only the LABEL can be modified in the common storage
2897 * object attributes after the object is created.
2898 */
2899 return (set_extra_attr_to_object(object_p,
2900 CKA_LABEL, template));
2901
2902 case CKA_ID:
2903 return (set_extra_attr_to_object(object_p,
2904 CKA_ID, template));
2905
2906 case CKA_START_DATE:
2907 return (set_extra_attr_to_object(object_p,
2908 CKA_START_DATE, template));
2909
2910 case CKA_END_DATE:
2911 return (set_extra_attr_to_object(object_p,
2912 CKA_END_DATE, template));
2913
2914 case CKA_DERIVE:
2915 return (set_bool_attr_to_object(object_p,
2916 DERIVE_BOOL_ON, template));
2917
2918 case CKA_CLASS:
2919 case CKA_KEY_TYPE:
2920 case CKA_LOCAL:
2921 return (CKR_ATTRIBUTE_READ_ONLY);
2922
2923 case CKA_PRIVATE:
2924 if (!copy) {
2925 /* called from C_SetAttributeValue() */
2926 return (CKR_ATTRIBUTE_READ_ONLY);
2927 }
2928
2929 /* called from C_CopyObject() */
2930 if ((*(CK_BBOOL *)template->pValue) != B_TRUE) {
2931 return (CKR_OK);
2932 }
2933
2934 (void) pthread_mutex_lock(&pslot->sl_mutex);
2935 /*
2936 * Cannot create a private object if the token
2937 * has a keystore and the user isn't logged in.
2938 */
2939 if (pslot->sl_func_list.fl_object_create &&
2940 pslot->sl_state != CKU_USER) {
2941 rv = CKR_USER_NOT_LOGGED_IN;
2942 } else {
2943 rv = set_bool_attr_to_object(object_p,
2944 PRIVATE_BOOL_ON, template);
2945 }
2946 (void) pthread_mutex_unlock(&pslot->sl_mutex);
2947 return (rv);
2948
2949 case CKA_MODIFIABLE:
2950 if (copy) {
2951 rv = set_bool_attr_to_object(object_p,
2952 MODIFIABLE_BOOL_ON, template);
2953 } else {
2954 rv = CKR_ATTRIBUTE_READ_ONLY;
2955 }
2956 return (rv);
2957
2958 default:
2959 return (CKR_TEMPLATE_INCONSISTENT);
2960 }
2961
2962 }
2963
2964
2965 /*
2966 * Set the value of an attribute of a Public Key Object.
2967 *
2968 * Rule: The attributes marked with footnote number "8" in the PKCS11
2969 * spec may be modified (p.88 in PKCS11 spec.).
2970 */
2971 CK_RV
kernel_set_public_key_attribute(kernel_object_t * object_p,CK_ATTRIBUTE_PTR template,boolean_t copy,kernel_session_t * sp)2972 kernel_set_public_key_attribute(kernel_object_t *object_p,
2973 CK_ATTRIBUTE_PTR template, boolean_t copy, kernel_session_t *sp)
2974 {
2975 CK_KEY_TYPE keytype = object_p->key_type;
2976
2977 switch (template->type) {
2978
2979 case CKA_SUBJECT:
2980 return (set_extra_attr_to_object(object_p,
2981 CKA_SUBJECT, template));
2982
2983 case CKA_ENCRYPT:
2984 return (set_bool_attr_to_object(object_p,
2985 ENCRYPT_BOOL_ON, template));
2986
2987 case CKA_VERIFY:
2988 return (set_bool_attr_to_object(object_p,
2989 VERIFY_BOOL_ON, template));
2990
2991 case CKA_VERIFY_RECOVER:
2992 return (set_bool_attr_to_object(object_p,
2993 VERIFY_RECOVER_BOOL_ON, template));
2994
2995 case CKA_WRAP:
2996 return (set_bool_attr_to_object(object_p,
2997 WRAP_BOOL_ON, template));
2998
2999 case CKA_MODULUS:
3000 case CKA_MODULUS_BITS:
3001 case CKA_PUBLIC_EXPONENT:
3002 if (keytype == CKK_RSA)
3003 return (CKR_ATTRIBUTE_READ_ONLY);
3004 break;
3005
3006 case CKA_SUBPRIME:
3007 case CKA_PRIME:
3008 case CKA_BASE:
3009 case CKA_VALUE:
3010 if (keytype == CKK_DSA)
3011 return (CKR_ATTRIBUTE_READ_ONLY);
3012 break;
3013
3014 default:
3015 /*
3016 * Set the value of a common key attribute.
3017 */
3018 return (kernel_set_common_key_attribute(object_p,
3019 template, copy, sp));
3020
3021 }
3022
3023 /*
3024 * If we got this far, then the combination of key type
3025 * and requested attribute is invalid.
3026 */
3027 return (CKR_ATTRIBUTE_TYPE_INVALID);
3028 }
3029
3030
3031 /*
3032 * Set the value of an attribute of a Private Key Object.
3033 *
3034 * Rule: The attributes marked with footnote number "8" in the PKCS11
3035 * spec may be modified (p.88 in PKCS11 spec.).
3036 */
3037 CK_RV
kernel_set_private_key_attribute(kernel_object_t * object_p,CK_ATTRIBUTE_PTR template,boolean_t copy,kernel_session_t * sp)3038 kernel_set_private_key_attribute(kernel_object_t *object_p,
3039 CK_ATTRIBUTE_PTR template, boolean_t copy, kernel_session_t *sp)
3040 {
3041 CK_KEY_TYPE keytype = object_p->key_type;
3042
3043 switch (template->type) {
3044
3045 case CKA_SUBJECT:
3046 return (set_extra_attr_to_object(object_p,
3047 CKA_SUBJECT, template));
3048
3049 case CKA_SENSITIVE:
3050 /*
3051 * Cannot set SENSITIVE to FALSE if it is already ON.
3052 */
3053 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
3054 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
3055 return (CKR_ATTRIBUTE_READ_ONLY);
3056 }
3057
3058 if (*(CK_BBOOL *)template->pValue)
3059 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
3060 return (CKR_OK);
3061
3062 case CKA_DECRYPT:
3063 return (set_bool_attr_to_object(object_p,
3064 DECRYPT_BOOL_ON, template));
3065
3066 case CKA_SIGN:
3067 return (set_bool_attr_to_object(object_p,
3068 SIGN_BOOL_ON, template));
3069
3070 case CKA_SIGN_RECOVER:
3071 return (set_bool_attr_to_object(object_p,
3072 SIGN_RECOVER_BOOL_ON, template));
3073
3074 case CKA_UNWRAP:
3075 return (set_bool_attr_to_object(object_p,
3076 UNWRAP_BOOL_ON, template));
3077
3078 case CKA_EXTRACTABLE:
3079 /*
3080 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
3081 */
3082 if ((*(CK_BBOOL *)template->pValue) &&
3083 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
3084 return (CKR_ATTRIBUTE_READ_ONLY);
3085 }
3086
3087 if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
3088 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
3089 return (CKR_OK);
3090
3091 case CKA_MODULUS:
3092 case CKA_PUBLIC_EXPONENT:
3093 case CKA_PRIVATE_EXPONENT:
3094 case CKA_PRIME_1:
3095 case CKA_PRIME_2:
3096 case CKA_EXPONENT_1:
3097 case CKA_EXPONENT_2:
3098 case CKA_COEFFICIENT:
3099 if (keytype == CKK_RSA) {
3100 return (CKR_ATTRIBUTE_READ_ONLY);
3101 }
3102 break;
3103
3104 case CKA_SUBPRIME:
3105 case CKA_PRIME:
3106 case CKA_BASE:
3107 case CKA_VALUE:
3108 if (keytype == CKK_DSA)
3109 return (CKR_ATTRIBUTE_READ_ONLY);
3110 break;
3111
3112 default:
3113 /*
3114 * Set the value of a common key attribute.
3115 */
3116 return (kernel_set_common_key_attribute(object_p,
3117 template, copy, sp));
3118 }
3119
3120 /*
3121 * If we got this far, then the combination of key type
3122 * and requested attribute is invalid.
3123 */
3124 return (CKR_ATTRIBUTE_TYPE_INVALID);
3125 }
3126
3127
3128
3129 /*
3130 * Set the value of an attribute of a Secret Key Object.
3131 *
3132 * Rule: The attributes marked with footnote number "8" in the PKCS11
3133 * spec may be modified (p.88 in PKCS11 spec.).
3134 */
3135 CK_RV
kernel_set_secret_key_attribute(kernel_object_t * object_p,CK_ATTRIBUTE_PTR template,boolean_t copy,kernel_session_t * sp)3136 kernel_set_secret_key_attribute(kernel_object_t *object_p,
3137 CK_ATTRIBUTE_PTR template, boolean_t copy, kernel_session_t *sp)
3138 {
3139 CK_KEY_TYPE keytype = object_p->key_type;
3140
3141 switch (template->type) {
3142
3143 case CKA_SENSITIVE:
3144 /*
3145 * Cannot set SENSITIVE to FALSE if it is already ON.
3146 */
3147 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
3148 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
3149 return (CKR_ATTRIBUTE_READ_ONLY);
3150 }
3151
3152 if (*(CK_BBOOL *)template->pValue)
3153 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
3154 return (CKR_OK);
3155
3156 case CKA_ENCRYPT:
3157 return (set_bool_attr_to_object(object_p,
3158 ENCRYPT_BOOL_ON, template));
3159
3160 case CKA_DECRYPT:
3161 return (set_bool_attr_to_object(object_p,
3162 DECRYPT_BOOL_ON, template));
3163
3164 case CKA_SIGN:
3165 return (set_bool_attr_to_object(object_p,
3166 SIGN_BOOL_ON, template));
3167
3168 case CKA_VERIFY:
3169 return (set_bool_attr_to_object(object_p,
3170 VERIFY_BOOL_ON, template));
3171
3172 case CKA_WRAP:
3173 return (set_bool_attr_to_object(object_p,
3174 WRAP_BOOL_ON, template));
3175
3176 case CKA_UNWRAP:
3177 return (set_bool_attr_to_object(object_p,
3178 UNWRAP_BOOL_ON, template));
3179
3180 case CKA_EXTRACTABLE:
3181 /*
3182 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
3183 */
3184 if ((*(CK_BBOOL *)template->pValue) &&
3185 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
3186 return (CKR_ATTRIBUTE_READ_ONLY);
3187 }
3188
3189 if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
3190 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
3191 return (CKR_OK);
3192
3193 case CKA_VALUE:
3194 return (CKR_ATTRIBUTE_READ_ONLY);
3195
3196 case CKA_VALUE_LEN:
3197 if ((keytype == CKK_RC4) ||
3198 (keytype == CKK_GENERIC_SECRET) ||
3199 (keytype == CKK_AES) ||
3200 (keytype == CKK_BLOWFISH))
3201 return (CKR_ATTRIBUTE_READ_ONLY);
3202 break;
3203
3204 default:
3205 /*
3206 * Set the value of a common key attribute.
3207 */
3208 return (kernel_set_common_key_attribute(object_p,
3209 template, copy, sp));
3210 }
3211
3212 /*
3213 * If we got this far, then the combination of key type
3214 * and requested attribute is invalid.
3215 */
3216 return (CKR_ATTRIBUTE_TYPE_INVALID);
3217 }
3218
3219
3220 /*
3221 * Call the appropriate set attribute function according to the class
3222 * of object.
3223 *
3224 * The caller of this function does not hold the lock on the original
3225 * object, since this function is setting the attribute on the new object
3226 * that is being modified.
3227 *
3228 */
3229 CK_RV
kernel_set_attribute(kernel_object_t * object_p,CK_ATTRIBUTE_PTR template,boolean_t copy,kernel_session_t * sp)3230 kernel_set_attribute(kernel_object_t *object_p, CK_ATTRIBUTE_PTR template,
3231 boolean_t copy, kernel_session_t *sp)
3232 {
3233
3234 CK_RV rv = CKR_OK;
3235 CK_OBJECT_CLASS class = object_p->class;
3236
3237 switch (class) {
3238
3239 case CKO_PUBLIC_KEY:
3240 rv = kernel_set_public_key_attribute(object_p, template,
3241 copy, sp);
3242 break;
3243
3244 case CKO_PRIVATE_KEY:
3245 rv = kernel_set_private_key_attribute(object_p, template,
3246 copy, sp);
3247 break;
3248
3249 case CKO_SECRET_KEY:
3250 rv = kernel_set_secret_key_attribute(object_p, template,
3251 copy, sp);
3252 break;
3253
3254 default:
3255 /*
3256 * If the template specifies a value of an attribute
3257 * which is incompatible with other existing attributes
3258 * of the object, then fails with return code
3259 * CKR_TEMPLATE_INCONSISTENT.
3260 */
3261 rv = CKR_TEMPLATE_INCONSISTENT;
3262 break;
3263 }
3264
3265 return (rv);
3266 }
3267
3268
3269 static CK_RV
copy_bigint(biginteger_t * new_bigint,biginteger_t * old_bigint)3270 copy_bigint(biginteger_t *new_bigint, biginteger_t *old_bigint)
3271 {
3272 new_bigint->big_value =
3273 malloc((sizeof (CK_BYTE) * new_bigint->big_value_len));
3274
3275 if (new_bigint->big_value == NULL) {
3276 return (CKR_HOST_MEMORY);
3277 }
3278
3279 (void) memcpy(new_bigint->big_value, old_bigint->big_value,
3280 (sizeof (CK_BYTE) * new_bigint->big_value_len));
3281
3282 return (CKR_OK);
3283 }
3284
3285 static void
free_public_key_attr(public_key_obj_t * pbk,CK_KEY_TYPE key_type)3286 free_public_key_attr(public_key_obj_t *pbk, CK_KEY_TYPE key_type)
3287 {
3288 if (pbk == NULL) {
3289 return;
3290 }
3291
3292 switch (key_type) {
3293 case CKK_RSA:
3294 bigint_attr_cleanup(KEY_PUB_RSA_MOD(pbk));
3295 bigint_attr_cleanup(KEY_PUB_RSA_PUBEXPO(pbk));
3296 break;
3297 case CKK_DSA:
3298 bigint_attr_cleanup(KEY_PUB_DSA_PRIME(pbk));
3299 bigint_attr_cleanup(KEY_PUB_DSA_SUBPRIME(pbk));
3300 bigint_attr_cleanup(KEY_PUB_DSA_BASE(pbk));
3301 bigint_attr_cleanup(KEY_PUB_DSA_VALUE(pbk));
3302 break;
3303 default:
3304 break;
3305 }
3306 free(pbk);
3307 }
3308
3309
3310 CK_RV
kernel_copy_public_key_attr(public_key_obj_t * old_pub_key_obj_p,public_key_obj_t ** new_pub_key_obj_p,CK_KEY_TYPE key_type)3311 kernel_copy_public_key_attr(public_key_obj_t *old_pub_key_obj_p,
3312 public_key_obj_t **new_pub_key_obj_p, CK_KEY_TYPE key_type)
3313 {
3314
3315 public_key_obj_t *pbk;
3316 CK_RV rv = CKR_OK;
3317
3318 pbk = calloc(1, sizeof (public_key_obj_t));
3319 if (pbk == NULL) {
3320 return (CKR_HOST_MEMORY);
3321 }
3322
3323 switch (key_type) {
3324 case CKK_RSA:
3325 (void) memcpy(KEY_PUB_RSA(pbk),
3326 KEY_PUB_RSA(old_pub_key_obj_p),
3327 sizeof (rsa_pub_key_t));
3328 /* copy modulus */
3329 rv = copy_bigint(KEY_PUB_RSA_MOD(pbk),
3330 KEY_PUB_RSA_MOD(old_pub_key_obj_p));
3331 if (rv != CKR_OK) {
3332 free_public_key_attr(pbk, key_type);
3333 return (rv);
3334 }
3335 /* copy public exponent */
3336 rv = copy_bigint(KEY_PUB_RSA_PUBEXPO(pbk),
3337 KEY_PUB_RSA_PUBEXPO(old_pub_key_obj_p));
3338 if (rv != CKR_OK) {
3339 free_public_key_attr(pbk, key_type);
3340 return (rv);
3341 }
3342 break;
3343 case CKK_DSA:
3344 (void) memcpy(KEY_PUB_DSA(pbk),
3345 KEY_PUB_DSA(old_pub_key_obj_p),
3346 sizeof (dsa_pub_key_t));
3347
3348 /* copy prime */
3349 rv = copy_bigint(KEY_PUB_DSA_PRIME(pbk),
3350 KEY_PUB_DSA_PRIME(old_pub_key_obj_p));
3351 if (rv != CKR_OK) {
3352 free_public_key_attr(pbk, key_type);
3353 return (rv);
3354 }
3355
3356 /* copy subprime */
3357 rv = copy_bigint(KEY_PUB_DSA_SUBPRIME(pbk),
3358 KEY_PUB_DSA_SUBPRIME(old_pub_key_obj_p));
3359 if (rv != CKR_OK) {
3360 free_public_key_attr(pbk, key_type);
3361 return (rv);
3362 }
3363
3364 /* copy base */
3365 rv = copy_bigint(KEY_PUB_DSA_BASE(pbk),
3366 KEY_PUB_DSA_BASE(old_pub_key_obj_p));
3367 if (rv != CKR_OK) {
3368 free_public_key_attr(pbk, key_type);
3369 return (rv);
3370 }
3371
3372 /* copy value */
3373 rv = copy_bigint(KEY_PUB_DSA_VALUE(pbk),
3374 KEY_PUB_DSA_VALUE(old_pub_key_obj_p));
3375 if (rv != CKR_OK) {
3376 free_public_key_attr(pbk, key_type);
3377 return (rv);
3378 }
3379 break;
3380 default:
3381 break;
3382 }
3383 *new_pub_key_obj_p = pbk;
3384 return (rv);
3385 }
3386
3387
3388 static void
free_private_key_attr(private_key_obj_t * pbk,CK_KEY_TYPE key_type)3389 free_private_key_attr(private_key_obj_t *pbk, CK_KEY_TYPE key_type)
3390 {
3391 if (pbk == NULL) {
3392 return;
3393 }
3394
3395 switch (key_type) {
3396 case CKK_RSA:
3397 bigint_attr_cleanup(KEY_PRI_RSA_MOD(pbk));
3398 bigint_attr_cleanup(KEY_PRI_RSA_PUBEXPO(pbk));
3399 bigint_attr_cleanup(KEY_PRI_RSA_PRIEXPO(pbk));
3400 bigint_attr_cleanup(KEY_PRI_RSA_PRIME1(pbk));
3401 bigint_attr_cleanup(KEY_PRI_RSA_PRIME2(pbk));
3402 bigint_attr_cleanup(KEY_PRI_RSA_EXPO1(pbk));
3403 bigint_attr_cleanup(KEY_PRI_RSA_EXPO2(pbk));
3404 bigint_attr_cleanup(KEY_PRI_RSA_COEF(pbk));
3405 break;
3406 case CKK_DSA:
3407 bigint_attr_cleanup(KEY_PRI_DSA_PRIME(pbk));
3408 bigint_attr_cleanup(KEY_PRI_DSA_SUBPRIME(pbk));
3409 bigint_attr_cleanup(KEY_PRI_DSA_BASE(pbk));
3410 bigint_attr_cleanup(KEY_PRI_DSA_VALUE(pbk));
3411 break;
3412 default:
3413 break;
3414 }
3415 free(pbk);
3416 }
3417
3418 CK_RV
kernel_copy_private_key_attr(private_key_obj_t * old_pri_key_obj_p,private_key_obj_t ** new_pri_key_obj_p,CK_KEY_TYPE key_type)3419 kernel_copy_private_key_attr(private_key_obj_t *old_pri_key_obj_p,
3420 private_key_obj_t **new_pri_key_obj_p, CK_KEY_TYPE key_type)
3421 {
3422 CK_RV rv = CKR_OK;
3423 private_key_obj_t *pbk;
3424
3425 pbk = calloc(1, sizeof (private_key_obj_t));
3426 if (pbk == NULL) {
3427 return (CKR_HOST_MEMORY);
3428 }
3429
3430 switch (key_type) {
3431 case CKK_RSA:
3432 (void) memcpy(KEY_PRI_RSA(pbk),
3433 KEY_PRI_RSA(old_pri_key_obj_p),
3434 sizeof (rsa_pri_key_t));
3435 /* copy modulus */
3436 rv = copy_bigint(KEY_PRI_RSA_MOD(pbk),
3437 KEY_PRI_RSA_MOD(old_pri_key_obj_p));
3438 if (rv != CKR_OK) {
3439 free_private_key_attr(pbk, key_type);
3440 return (rv);
3441 }
3442 /* copy public exponent */
3443 rv = copy_bigint(KEY_PRI_RSA_PUBEXPO(pbk),
3444 KEY_PRI_RSA_PUBEXPO(old_pri_key_obj_p));
3445 if (rv != CKR_OK) {
3446 free_private_key_attr(pbk, key_type);
3447 return (rv);
3448 }
3449 /* copy private exponent */
3450 rv = copy_bigint(KEY_PRI_RSA_PRIEXPO(pbk),
3451 KEY_PRI_RSA_PRIEXPO(old_pri_key_obj_p));
3452 if (rv != CKR_OK) {
3453 free_private_key_attr(pbk, key_type);
3454 return (rv);
3455 }
3456 /* copy prime_1 */
3457 rv = copy_bigint(KEY_PRI_RSA_PRIME1(pbk),
3458 KEY_PRI_RSA_PRIME1(old_pri_key_obj_p));
3459 if (rv != CKR_OK) {
3460 free_private_key_attr(pbk, key_type);
3461 return (rv);
3462 }
3463 /* copy prime_2 */
3464 rv = copy_bigint(KEY_PRI_RSA_PRIME2(pbk),
3465 KEY_PRI_RSA_PRIME2(old_pri_key_obj_p));
3466 if (rv != CKR_OK) {
3467 free_private_key_attr(pbk, key_type);
3468 return (rv);
3469 }
3470 /* copy exponent_1 */
3471 rv = copy_bigint(KEY_PRI_RSA_EXPO1(pbk),
3472 KEY_PRI_RSA_EXPO1(old_pri_key_obj_p));
3473 if (rv != CKR_OK) {
3474 free_private_key_attr(pbk, key_type);
3475 return (rv);
3476 }
3477 /* copy exponent_2 */
3478 rv = copy_bigint(KEY_PRI_RSA_EXPO2(pbk),
3479 KEY_PRI_RSA_EXPO2(old_pri_key_obj_p));
3480 if (rv != CKR_OK) {
3481 free_private_key_attr(pbk, key_type);
3482 return (rv);
3483 }
3484 /* copy coefficient */
3485 rv = copy_bigint(KEY_PRI_RSA_COEF(pbk),
3486 KEY_PRI_RSA_COEF(old_pri_key_obj_p));
3487 if (rv != CKR_OK) {
3488 free_private_key_attr(pbk, key_type);
3489 return (rv);
3490 }
3491 break;
3492 case CKK_DSA:
3493 (void) memcpy(KEY_PRI_DSA(pbk),
3494 KEY_PRI_DSA(old_pri_key_obj_p),
3495 sizeof (dsa_pri_key_t));
3496
3497 /* copy prime */
3498 rv = copy_bigint(KEY_PRI_DSA_PRIME(pbk),
3499 KEY_PRI_DSA_PRIME(old_pri_key_obj_p));
3500 if (rv != CKR_OK) {
3501 free_private_key_attr(pbk, key_type);
3502 return (rv);
3503 }
3504
3505 /* copy subprime */
3506 rv = copy_bigint(KEY_PRI_DSA_SUBPRIME(pbk),
3507 KEY_PRI_DSA_SUBPRIME(old_pri_key_obj_p));
3508 if (rv != CKR_OK) {
3509 free_private_key_attr(pbk, key_type);
3510 return (rv);
3511 }
3512
3513 /* copy base */
3514 rv = copy_bigint(KEY_PRI_DSA_BASE(pbk),
3515 KEY_PRI_DSA_BASE(old_pri_key_obj_p));
3516 if (rv != CKR_OK) {
3517 free_private_key_attr(pbk, key_type);
3518 return (rv);
3519 }
3520
3521 /* copy value */
3522 rv = copy_bigint(KEY_PRI_DSA_VALUE(pbk),
3523 KEY_PRI_DSA_VALUE(old_pri_key_obj_p));
3524 if (rv != CKR_OK) {
3525 free_private_key_attr(pbk, key_type);
3526 return (rv);
3527 }
3528 break;
3529 default:
3530 break;
3531 }
3532 *new_pri_key_obj_p = pbk;
3533 return (rv);
3534 }
3535
3536
3537 CK_RV
kernel_copy_secret_key_attr(secret_key_obj_t * old_secret_key_obj_p,secret_key_obj_t ** new_secret_key_obj_p)3538 kernel_copy_secret_key_attr(secret_key_obj_t *old_secret_key_obj_p,
3539 secret_key_obj_t **new_secret_key_obj_p)
3540 {
3541 secret_key_obj_t *sk;
3542
3543 sk = malloc(sizeof (secret_key_obj_t));
3544 if (sk == NULL) {
3545 return (CKR_HOST_MEMORY);
3546 }
3547 (void) memcpy(sk, old_secret_key_obj_p, sizeof (secret_key_obj_t));
3548
3549 /* copy the secret key value */
3550 sk->sk_value = malloc((sizeof (CK_BYTE) * sk->sk_value_len));
3551 if (sk->sk_value == NULL) {
3552 free(sk);
3553 return (CKR_HOST_MEMORY);
3554 }
3555 (void) memcpy(sk->sk_value, old_secret_key_obj_p->sk_value,
3556 (sizeof (CK_BYTE) * sk->sk_value_len));
3557
3558 *new_secret_key_obj_p = sk;
3559
3560 return (CKR_OK);
3561 }
3562
3563
3564
3565 /*
3566 * If CKA_CLASS not given, guess CKA_CLASS using
3567 * attributes on template .
3568 *
3569 * Some attributes are specific to an object class. If one or more
3570 * of these attributes are in the template, make a list of classes
3571 * that can have these attributes. This would speed up the search later,
3572 * because we can immediately skip an object if the class of that
3573 * object can not possibly contain one of the attributes.
3574 *
3575 */
3576 void
kernel_process_find_attr(CK_OBJECT_CLASS * pclasses,CK_ULONG * num_result_pclasses,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)3577 kernel_process_find_attr(CK_OBJECT_CLASS *pclasses,
3578 CK_ULONG *num_result_pclasses, CK_ATTRIBUTE_PTR pTemplate,
3579 CK_ULONG ulCount)
3580 {
3581 ulong_t i;
3582 int j;
3583 boolean_t pub_found = B_FALSE,
3584 priv_found = B_FALSE,
3585 secret_found = B_FALSE,
3586 domain_found = B_FALSE,
3587 hardware_found = B_FALSE,
3588 cert_found = B_FALSE;
3589 int num_pub_key_attrs, num_priv_key_attrs,
3590 num_secret_key_attrs, num_domain_attrs,
3591 num_hardware_attrs, num_cert_attrs;
3592 int num_pclasses = 0;
3593
3594 for (i = 0; i < ulCount; i++) {
3595 if (pTemplate[i].type == CKA_CLASS) {
3596 /*
3597 * don't need to guess the class, it is specified.
3598 * Just record the class, and return.
3599 */
3600 pclasses[0] =
3601 (*((CK_OBJECT_CLASS *)pTemplate[i].pValue));
3602 *num_result_pclasses = 1;
3603 return;
3604 }
3605 }
3606
3607 num_pub_key_attrs =
3608 sizeof (PUB_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
3609 num_priv_key_attrs =
3610 sizeof (PRIV_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
3611 num_secret_key_attrs =
3612 sizeof (SECRET_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
3613 num_domain_attrs =
3614 sizeof (DOMAIN_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
3615 num_hardware_attrs =
3616 sizeof (HARDWARE_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
3617 num_cert_attrs =
3618 sizeof (CERT_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
3619
3620 /*
3621 * Get the list of objects class that might contain
3622 * some attributes.
3623 */
3624 for (i = 0; i < ulCount; i++) {
3625 /*
3626 * only check if this attribute can belong to public key object
3627 * class if public key object isn't already in the list
3628 */
3629 if (!pub_found) {
3630 for (j = 0; j < num_pub_key_attrs; j++) {
3631 if (pTemplate[i].type == PUB_KEY_ATTRS[j]) {
3632 pub_found = B_TRUE;
3633 pclasses[num_pclasses++] =
3634 CKO_PUBLIC_KEY;
3635 break;
3636 }
3637 }
3638 }
3639
3640 if (!priv_found) {
3641 for (j = 0; j < num_priv_key_attrs; j++) {
3642 if (pTemplate[i].type == PRIV_KEY_ATTRS[j]) {
3643 priv_found = B_TRUE;
3644 pclasses[num_pclasses++] =
3645 CKO_PRIVATE_KEY;
3646 break;
3647 }
3648 }
3649 }
3650
3651 if (!secret_found) {
3652 for (j = 0; j < num_secret_key_attrs; j++) {
3653 if (pTemplate[i].type == SECRET_KEY_ATTRS[j]) {
3654 secret_found = B_TRUE;
3655 pclasses[num_pclasses++] =
3656 CKO_SECRET_KEY;
3657 break;
3658 }
3659 }
3660 }
3661
3662 if (!domain_found) {
3663 for (j = 0; j < num_domain_attrs; j++) {
3664 if (pTemplate[i].type == DOMAIN_ATTRS[j]) {
3665 domain_found = B_TRUE;
3666 pclasses[num_pclasses++] =
3667 CKO_DOMAIN_PARAMETERS;
3668 break;
3669 }
3670 }
3671 }
3672
3673 if (!hardware_found) {
3674 for (j = 0; j < num_hardware_attrs; j++) {
3675 if (pTemplate[i].type == HARDWARE_ATTRS[j]) {
3676 hardware_found = B_TRUE;
3677 pclasses[num_pclasses++] =
3678 CKO_HW_FEATURE;
3679 break;
3680 }
3681 }
3682 }
3683
3684 if (!cert_found) {
3685 for (j = 0; j < num_cert_attrs; j++) {
3686 if (pTemplate[i].type == CERT_ATTRS[j]) {
3687 cert_found = B_TRUE;
3688 pclasses[num_pclasses++] =
3689 CKO_CERTIFICATE;
3690 break;
3691 }
3692 }
3693 }
3694 }
3695 *num_result_pclasses = num_pclasses;
3696 }
3697
3698
3699 boolean_t
kernel_find_match_attrs(kernel_object_t * obj,CK_OBJECT_CLASS * pclasses,CK_ULONG num_pclasses,CK_ATTRIBUTE * template,CK_ULONG num_attr)3700 kernel_find_match_attrs(kernel_object_t *obj, CK_OBJECT_CLASS *pclasses,
3701 CK_ULONG num_pclasses, CK_ATTRIBUTE *template, CK_ULONG num_attr)
3702 {
3703 ulong_t i;
3704 CK_ATTRIBUTE *tmpl_attr, *obj_attr;
3705 uint64_t attr_mask;
3706 biginteger_t *bigint;
3707 boolean_t compare_attr, compare_bigint, compare_boolean;
3708
3709 /*
3710 * Check if the class of this object match with any
3711 * of object classes that can possibly contain the
3712 * requested attributes.
3713 */
3714 if (num_pclasses > 0) {
3715 for (i = 0; i < num_pclasses; i++) {
3716 if (obj->class == pclasses[i]) {
3717 break;
3718 }
3719 }
3720 if (i == num_pclasses) {
3721 /*
3722 * this object can't possibly contain one or
3723 * more attributes, don't need to check this object
3724 */
3725 return (B_FALSE);
3726 }
3727 }
3728
3729 /* need to examine everything */
3730 for (i = 0; i < num_attr; i++) {
3731 tmpl_attr = &(template[i]);
3732 compare_attr = B_FALSE;
3733 compare_bigint = B_FALSE;
3734 compare_boolean = B_FALSE;
3735 switch (tmpl_attr->type) {
3736 /* First, check the most common attributes */
3737 case CKA_CLASS:
3738 if (*((CK_OBJECT_CLASS *)tmpl_attr->pValue) !=
3739 obj->class) {
3740 return (B_FALSE);
3741 }
3742 break;
3743 case CKA_KEY_TYPE:
3744 if (*((CK_KEY_TYPE *)tmpl_attr->pValue) !=
3745 obj->key_type) {
3746 return (B_FALSE);
3747 }
3748 break;
3749 case CKA_ENCRYPT:
3750 attr_mask = (obj->bool_attr_mask) & ENCRYPT_BOOL_ON;
3751 compare_boolean = B_TRUE;
3752 break;
3753 case CKA_DECRYPT:
3754 attr_mask = (obj->bool_attr_mask) & DECRYPT_BOOL_ON;
3755 compare_boolean = B_TRUE;
3756 break;
3757 case CKA_WRAP:
3758 attr_mask = (obj->bool_attr_mask) & WRAP_BOOL_ON;
3759 compare_boolean = B_TRUE;
3760 break;
3761 case CKA_UNWRAP:
3762 attr_mask = (obj->bool_attr_mask) & UNWRAP_BOOL_ON;
3763 compare_boolean = B_TRUE;
3764 break;
3765 case CKA_SIGN:
3766 attr_mask = (obj->bool_attr_mask) & SIGN_BOOL_ON;
3767 compare_boolean = B_TRUE;
3768 break;
3769 case CKA_SIGN_RECOVER:
3770 attr_mask = (obj->bool_attr_mask) &
3771 SIGN_RECOVER_BOOL_ON;
3772 compare_boolean = B_TRUE;
3773 break;
3774 case CKA_VERIFY:
3775 attr_mask = (obj->bool_attr_mask) & VERIFY_BOOL_ON;
3776 compare_boolean = B_TRUE;
3777 break;
3778 case CKA_VERIFY_RECOVER:
3779 attr_mask = (obj->bool_attr_mask) &
3780 VERIFY_RECOVER_BOOL_ON;
3781 compare_boolean = B_TRUE;
3782 break;
3783 case CKA_DERIVE:
3784 attr_mask = (obj->bool_attr_mask) & DERIVE_BOOL_ON;
3785 compare_boolean = B_TRUE;
3786 break;
3787 case CKA_LOCAL:
3788 attr_mask = (obj->bool_attr_mask) & LOCAL_BOOL_ON;
3789 compare_boolean = B_TRUE;
3790 break;
3791 case CKA_SENSITIVE:
3792 attr_mask = (obj->bool_attr_mask) & SENSITIVE_BOOL_ON;
3793 compare_boolean = B_TRUE;
3794 break;
3795 case CKA_SECONDARY_AUTH:
3796 attr_mask = (obj->bool_attr_mask) &
3797 SECONDARY_AUTH_BOOL_ON;
3798 compare_boolean = B_TRUE;
3799 break;
3800 case CKA_TRUSTED:
3801 attr_mask = (obj->bool_attr_mask) & TRUSTED_BOOL_ON;
3802 compare_boolean = B_TRUE;
3803 break;
3804 case CKA_EXTRACTABLE:
3805 attr_mask = (obj->bool_attr_mask) &
3806 EXTRACTABLE_BOOL_ON;
3807 compare_boolean = B_TRUE;
3808 break;
3809 case CKA_ALWAYS_SENSITIVE:
3810 attr_mask = (obj->bool_attr_mask) &
3811 ALWAYS_SENSITIVE_BOOL_ON;
3812 compare_boolean = B_TRUE;
3813 break;
3814 case CKA_NEVER_EXTRACTABLE:
3815 attr_mask = (obj->bool_attr_mask) &
3816 NEVER_EXTRACTABLE_BOOL_ON;
3817 compare_boolean = B_TRUE;
3818 break;
3819 case CKA_TOKEN:
3820 /*
3821 * CKA_TOKEN value is not applicable to an object
3822 * created in the library, it should only contain
3823 * the default value FALSE
3824 */
3825 attr_mask = 0;
3826 compare_boolean = B_TRUE;
3827 break;
3828 case CKA_PRIVATE:
3829 attr_mask = (obj->bool_attr_mask) & PRIVATE_BOOL_ON;
3830 compare_boolean = B_TRUE;
3831 break;
3832 case CKA_MODIFIABLE:
3833 attr_mask = (obj->bool_attr_mask) & MODIFIABLE_BOOL_ON;
3834 compare_boolean = B_TRUE;
3835 break;
3836 case CKA_SUBJECT:
3837 case CKA_ID:
3838 case CKA_START_DATE:
3839 case CKA_END_DATE:
3840 case CKA_KEY_GEN_MECHANISM:
3841 case CKA_LABEL:
3842 /* find these attributes from extra_attrlistp */
3843 obj_attr = get_extra_attr(tmpl_attr->type, obj);
3844 compare_attr = B_TRUE;
3845 break;
3846 case CKA_VALUE_LEN:
3847 /* only secret key has this attribute */
3848 if (obj->class == CKO_SECRET_KEY) {
3849 if (*((CK_ULONG *)tmpl_attr->pValue) !=
3850 OBJ_SEC_VALUE_LEN(obj)) {
3851 return (B_FALSE);
3852 }
3853 } else {
3854 return (B_FALSE);
3855 }
3856 break;
3857 case CKA_VALUE:
3858 switch (obj->class) {
3859 case CKO_SECRET_KEY:
3860 /*
3861 * secret_key_obj_t is the same as
3862 * biginteger_t
3863 */
3864 bigint = (biginteger_t *)OBJ_SEC(obj);
3865 break;
3866 case CKO_PRIVATE_KEY:
3867 if (obj->key_type == CKK_DSA) {
3868 bigint = OBJ_PRI_DSA_VALUE(obj);
3869 } else {
3870 return (B_FALSE);
3871 }
3872 break;
3873 case CKO_PUBLIC_KEY:
3874 if (obj->key_type == CKK_DSA) {
3875 bigint = OBJ_PUB_DSA_VALUE(obj);
3876 } else {
3877 return (B_FALSE);
3878 }
3879 break;
3880 default:
3881 return (B_FALSE);
3882 }
3883 compare_bigint = B_TRUE;
3884 break;
3885 case CKA_MODULUS:
3886 /* only RSA public and private key have this attr */
3887 if (obj->key_type == CKK_RSA) {
3888 if (obj->class == CKO_PUBLIC_KEY) {
3889 bigint = OBJ_PUB_RSA_MOD(obj);
3890 } else if (obj->class == CKO_PRIVATE_KEY) {
3891 bigint = OBJ_PRI_RSA_MOD(obj);
3892 } else {
3893 return (B_FALSE);
3894 }
3895 compare_bigint = B_TRUE;
3896 } else {
3897 return (B_FALSE);
3898 }
3899 break;
3900 case CKA_MODULUS_BITS:
3901 /* only RSA public key has this attribute */
3902 if ((obj->key_type == CKK_RSA) &&
3903 (obj->class == CKO_PUBLIC_KEY)) {
3904 CK_ULONG mod_bits = OBJ_PUB_RSA_MOD_BITS(obj);
3905 if (mod_bits !=
3906 *((CK_ULONG *)tmpl_attr->pValue)) {
3907 return (B_FALSE);
3908 }
3909 } else {
3910 return (B_FALSE);
3911 }
3912 break;
3913 case CKA_PUBLIC_EXPONENT:
3914 /* only RSA public and private key have this attr */
3915 if (obj->key_type == CKK_RSA) {
3916 if (obj->class == CKO_PUBLIC_KEY) {
3917 bigint = OBJ_PUB_RSA_PUBEXPO(obj);
3918 } else if (obj->class == CKO_PRIVATE_KEY) {
3919 bigint = OBJ_PRI_RSA_PUBEXPO(obj);
3920 } else {
3921 return (B_FALSE);
3922 }
3923 compare_bigint = B_TRUE;
3924 } else {
3925 return (B_FALSE);
3926 }
3927 break;
3928 case CKA_PRIVATE_EXPONENT:
3929 /* only RSA private key has this attribute */
3930 if ((obj->key_type == CKK_RSA) &&
3931 (obj->class == CKO_PRIVATE_KEY)) {
3932 bigint = OBJ_PRI_RSA_PRIEXPO(obj);
3933 compare_bigint = B_TRUE;
3934 } else {
3935 return (B_FALSE);
3936 }
3937 break;
3938 case CKA_PRIME_1:
3939 /* only RSA private key has this attribute */
3940 if ((obj->key_type == CKK_RSA) &&
3941 (obj->class == CKO_PRIVATE_KEY)) {
3942 bigint = OBJ_PRI_RSA_PRIME1(obj);
3943 compare_bigint = B_TRUE;
3944 } else {
3945 return (B_FALSE);
3946 }
3947 break;
3948 case CKA_PRIME_2:
3949 /* only RSA private key has this attribute */
3950 if ((obj->key_type == CKK_RSA) &&
3951 (obj->class == CKO_PRIVATE_KEY)) {
3952 bigint = OBJ_PRI_RSA_PRIME2(obj);
3953 compare_bigint = B_TRUE;
3954 } else {
3955 return (B_FALSE);
3956 }
3957 break;
3958 case CKA_EXPONENT_1:
3959 /* only RSA private key has this attribute */
3960 if ((obj->key_type == CKK_RSA) &&
3961 (obj->class == CKO_PRIVATE_KEY)) {
3962 bigint = OBJ_PRI_RSA_EXPO1(obj);
3963 compare_bigint = B_TRUE;
3964 } else {
3965 return (B_FALSE);
3966 }
3967 break;
3968 case CKA_EXPONENT_2:
3969 /* only RSA private key has this attribute */
3970 if ((obj->key_type == CKK_RSA) &&
3971 (obj->class == CKO_PRIVATE_KEY)) {
3972 bigint = OBJ_PRI_RSA_EXPO2(obj);
3973 compare_bigint = B_TRUE;
3974 } else {
3975 return (B_FALSE);
3976 }
3977 break;
3978 case CKA_COEFFICIENT:
3979 /* only RSA private key has this attribute */
3980 if ((obj->key_type == CKK_RSA) &&
3981 (obj->class == CKO_PRIVATE_KEY)) {
3982 bigint = OBJ_PRI_RSA_COEF(obj);
3983 compare_bigint = B_TRUE;
3984 } else {
3985 return (B_FALSE);
3986 }
3987 break;
3988 case CKA_VALUE_BITS:
3989 return (B_FALSE);
3990 case CKA_PRIME:
3991 if (obj->class == CKO_PUBLIC_KEY) {
3992 switch (obj->key_type) {
3993 case CKK_DSA:
3994 bigint = OBJ_PUB_DSA_PRIME(obj);
3995 break;
3996 default:
3997 return (B_FALSE);
3998 }
3999 } else if (obj->class == CKO_PRIVATE_KEY) {
4000 switch (obj->key_type) {
4001 case CKK_DSA:
4002 bigint = OBJ_PRI_DSA_PRIME(obj);
4003 break;
4004 default:
4005 return (B_FALSE);
4006 }
4007 } else {
4008 return (B_FALSE);
4009 }
4010 compare_bigint = B_TRUE;
4011 break;
4012 case CKA_SUBPRIME:
4013 if (obj->class == CKO_PUBLIC_KEY) {
4014 switch (obj->key_type) {
4015 case CKK_DSA:
4016 bigint = OBJ_PUB_DSA_SUBPRIME(obj);
4017 break;
4018 default:
4019 return (B_FALSE);
4020 }
4021 } else if (obj->class == CKO_PRIVATE_KEY) {
4022 switch (obj->key_type) {
4023 case CKK_DSA:
4024 bigint = OBJ_PRI_DSA_SUBPRIME(obj);
4025 break;
4026 default:
4027 return (B_FALSE);
4028 }
4029 } else {
4030 return (B_FALSE);
4031 }
4032 compare_bigint = B_TRUE;
4033 break;
4034 case CKA_BASE:
4035 if (obj->class == CKO_PUBLIC_KEY) {
4036 switch (obj->key_type) {
4037 case CKK_DSA:
4038 bigint = OBJ_PUB_DSA_BASE(obj);
4039 break;
4040 default:
4041 return (B_FALSE);
4042 }
4043 } else if (obj->class == CKO_PRIVATE_KEY) {
4044 switch (obj->key_type) {
4045 case CKK_DSA:
4046 bigint = OBJ_PRI_DSA_BASE(obj);
4047 break;
4048 default:
4049 return (B_FALSE);
4050 }
4051 } else {
4052 return (B_FALSE);
4053 }
4054 compare_bigint = B_TRUE;
4055 break;
4056 case CKA_PRIME_BITS:
4057 return (B_FALSE);
4058 case CKA_SUBPRIME_BITS:
4059 return (B_FALSE);
4060 default:
4061 /*
4062 * any other attributes are currently not supported.
4063 * so, it's not possible for them to be in the
4064 * object
4065 */
4066 return (B_FALSE);
4067 }
4068 if (compare_boolean) {
4069 CK_BBOOL bval;
4070
4071 if (attr_mask) {
4072 bval = TRUE;
4073 } else {
4074 bval = FALSE;
4075 }
4076 if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) {
4077 return (B_FALSE);
4078 }
4079 } else if (compare_bigint) {
4080 if (bigint == NULL) {
4081 return (B_FALSE);
4082 }
4083 if (tmpl_attr->ulValueLen != bigint->big_value_len) {
4084 return (B_FALSE);
4085 }
4086 if (memcmp(tmpl_attr->pValue, bigint->big_value,
4087 tmpl_attr->ulValueLen) != 0) {
4088 return (B_FALSE);
4089 }
4090 } else if (compare_attr) {
4091 if (obj_attr == NULL) {
4092 /*
4093 * The attribute type is valid, and its value
4094 * has not been initialized in the object. In
4095 * this case, it only matches the template's
4096 * attribute if the template's value length
4097 * is 0.
4098 */
4099 if (tmpl_attr->ulValueLen != 0)
4100 return (B_FALSE);
4101 } else {
4102 if (tmpl_attr->ulValueLen !=
4103 obj_attr->ulValueLen) {
4104 return (B_FALSE);
4105 }
4106 if (memcmp(tmpl_attr->pValue, obj_attr->pValue,
4107 tmpl_attr->ulValueLen) != 0) {
4108 return (B_FALSE);
4109 }
4110 }
4111 }
4112 }
4113 return (B_TRUE);
4114 }
4115
4116 CK_ATTRIBUTE_PTR
get_extra_attr(CK_ATTRIBUTE_TYPE type,kernel_object_t * obj)4117 get_extra_attr(CK_ATTRIBUTE_TYPE type, kernel_object_t *obj)
4118 {
4119 CK_ATTRIBUTE_INFO_PTR tmp;
4120
4121 tmp = obj->extra_attrlistp;
4122 while (tmp != NULL) {
4123 if (tmp->attr.type == type) {
4124 return (&(tmp->attr));
4125 }
4126 tmp = tmp->next;
4127 }
4128 /* if get there, the specified attribute is not found */
4129 return (NULL);
4130 }
4131