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 */
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <security/cryptoki.h>
29 #include <sys/crypto/common.h>
30 #include <aes_impl.h>
31 #include <blowfish_impl.h>
32 #include <arcfour.h>
33 #include <des_impl.h>
34 #include "kernelGlobal.h"
35 #include "kernelObject.h"
36 #include "kernelSession.h"
37 #include "kernelSlot.h"
38
39
40 /*
41 * This attribute table is used by the kernel_lookup_attr()
42 * to validate the attributes.
43 */
44 CK_ATTRIBUTE_TYPE attr_map[] = {
45 CKA_PRIVATE,
46 CKA_LABEL,
47 CKA_APPLICATION,
48 CKA_OBJECT_ID,
49 CKA_CERTIFICATE_TYPE,
50 CKA_ISSUER,
51 CKA_SERIAL_NUMBER,
52 CKA_AC_ISSUER,
53 CKA_OWNER,
54 CKA_ATTR_TYPES,
55 CKA_SUBJECT,
56 CKA_ID,
57 CKA_SENSITIVE,
58 CKA_START_DATE,
59 CKA_END_DATE,
60 CKA_MODULUS,
61 CKA_MODULUS_BITS,
62 CKA_PUBLIC_EXPONENT,
63 CKA_PRIVATE_EXPONENT,
64 CKA_PRIME_1,
65 CKA_PRIME_2,
66 CKA_EXPONENT_1,
67 CKA_EXPONENT_2,
68 CKA_COEFFICIENT,
69 CKA_PRIME,
70 CKA_SUBPRIME,
71 CKA_BASE,
72 CKA_EXTRACTABLE,
73 CKA_LOCAL,
74 CKA_NEVER_EXTRACTABLE,
75 CKA_ALWAYS_SENSITIVE,
76 CKA_MODIFIABLE,
77 CKA_ECDSA_PARAMS,
78 CKA_EC_POINT,
79 CKA_SECONDARY_AUTH,
80 CKA_AUTH_PIN_FLAGS,
81 CKA_HW_FEATURE_TYPE,
82 CKA_RESET_ON_INIT,
83 CKA_HAS_RESET
84 };
85
86 /*
87 * attributes that exists only in public key objects
88 * Note: some attributes may also exist in one or two
89 * other object classes, but they are also listed
90 * because not all object have them.
91 */
92 CK_ATTRIBUTE_TYPE PUB_KEY_ATTRS[] =
93 {
94 CKA_SUBJECT,
95 CKA_ENCRYPT,
96 CKA_WRAP,
97 CKA_VERIFY,
98 CKA_VERIFY_RECOVER,
99 CKA_MODULUS,
100 CKA_MODULUS_BITS,
101 CKA_PUBLIC_EXPONENT,
102 CKA_PRIME,
103 CKA_SUBPRIME,
104 CKA_BASE,
105 CKA_TRUSTED,
106 CKA_ECDSA_PARAMS,
107 CKA_EC_PARAMS,
108 CKA_EC_POINT
109 };
110
111 /*
112 * attributes that exists only in private key objects
113 * Note: some attributes may also exist in one or two
114 * other object classes, but they are also listed
115 * because not all object have them.
116 */
117 CK_ATTRIBUTE_TYPE PRIV_KEY_ATTRS[] =
118 {
119 CKA_DECRYPT,
120 CKA_UNWRAP,
121 CKA_SIGN,
122 CKA_SIGN_RECOVER,
123 CKA_MODULUS,
124 CKA_PUBLIC_EXPONENT,
125 CKA_PRIVATE_EXPONENT,
126 CKA_PRIME,
127 CKA_SUBPRIME,
128 CKA_BASE,
129 CKA_PRIME_1,
130 CKA_PRIME_2,
131 CKA_EXPONENT_1,
132 CKA_EXPONENT_2,
133 CKA_COEFFICIENT,
134 CKA_VALUE_BITS,
135 CKA_SUBJECT,
136 CKA_SENSITIVE,
137 CKA_EXTRACTABLE,
138 CKA_NEVER_EXTRACTABLE,
139 CKA_ALWAYS_SENSITIVE,
140 CKA_ECDSA_PARAMS,
141 CKA_EC_PARAMS
142 };
143
144 /*
145 * attributes that exists only in secret key objects
146 * Note: some attributes may also exist in one or two
147 * other object classes, but they are also listed
148 * because not all object have them.
149 */
150 CK_ATTRIBUTE_TYPE SECRET_KEY_ATTRS[] =
151 {
152 CKA_VALUE_LEN,
153 CKA_ENCRYPT,
154 CKA_DECRYPT,
155 CKA_WRAP,
156 CKA_UNWRAP,
157 CKA_SIGN,
158 CKA_VERIFY,
159 CKA_SENSITIVE,
160 CKA_EXTRACTABLE,
161 CKA_NEVER_EXTRACTABLE,
162 CKA_ALWAYS_SENSITIVE
163 };
164
165 /*
166 * attributes that exists only in domain parameter objects
167 * Note: some attributes may also exist in one or two
168 * other object classes, but they are also listed
169 * because not all object have them.
170 */
171 CK_ATTRIBUTE_TYPE DOMAIN_ATTRS[] =
172 {
173 CKA_PRIME,
174 CKA_SUBPRIME,
175 CKA_BASE,
176 CKA_PRIME_BITS,
177 CKA_SUBPRIME_BITS,
178 CKA_SUB_PRIME_BITS
179 };
180
181 /*
182 * attributes that exists only in hardware feature objects
183 */
184 CK_ATTRIBUTE_TYPE HARDWARE_ATTRS[] =
185 {
186 CKA_HW_FEATURE_TYPE,
187 CKA_RESET_ON_INIT,
188 CKA_HAS_RESET
189 };
190
191 /*
192 * attributes that exists only in certificate objects
193 */
194 CK_ATTRIBUTE_TYPE CERT_ATTRS[] =
195 {
196 CKA_CERTIFICATE_TYPE,
197 CKA_SUBJECT,
198 CKA_ID,
199 CKA_ISSUER,
200 CKA_AC_ISSUER,
201 CKA_SERIAL_NUMBER,
202 CKA_OWNER,
203 CKA_ATTR_TYPES
204 };
205
206
207 /*
208 * Validate the attribute by using binary search algorithm.
209 */
210 CK_RV
kernel_lookup_attr(CK_ATTRIBUTE_TYPE type)211 kernel_lookup_attr(CK_ATTRIBUTE_TYPE type)
212 {
213
214 size_t lower, middle, upper;
215
216 lower = 0;
217 upper = (sizeof (attr_map) / sizeof (CK_ATTRIBUTE_TYPE)) - 1;
218
219 while (lower <= upper) {
220 /* Always starts from middle. */
221 middle = (lower + upper) / 2;
222
223 if (type > attr_map[middle]) {
224 /* Adjust the lower bound to upper half. */
225 lower = middle + 1;
226 continue;
227 }
228
229 if (type == attr_map[middle]) {
230 /* Found it. */
231 return (CKR_OK);
232 }
233
234 if (type < attr_map[middle]) {
235 /* Adjust the upper bound to lower half. */
236 upper = middle - 1;
237 continue;
238 }
239 }
240
241 /* Failed to find the matching attribute from the attribute table. */
242 return (CKR_ATTRIBUTE_TYPE_INVALID);
243 }
244
245
246 /*
247 * Validate the attribute by using the following search algorithm:
248 *
249 * 1) Search for the most frequently used attributes first.
250 * 2) If not found, search for the usage-purpose attributes - these
251 * attributes have dense set of values, therefore compiler will
252 * optimize it with a branch table and branch to the appropriate
253 * case.
254 * 3) If still not found, use binary search for the rest of the
255 * attributes in the attr_map[] table.
256 */
257 CK_RV
kernel_validate_attr(CK_ATTRIBUTE_PTR template,CK_ULONG ulAttrNum,CK_OBJECT_CLASS * class)258 kernel_validate_attr(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
259 CK_OBJECT_CLASS *class)
260 {
261
262 CK_ULONG i;
263 CK_RV rv = CKR_OK;
264
265 for (i = 0; i < ulAttrNum; i++) {
266 /* First tier search */
267 switch (template[i].type) {
268 case CKA_CLASS:
269 *class = *((CK_OBJECT_CLASS*)template[i].pValue);
270 break;
271 case CKA_TOKEN:
272 break;
273 case CKA_KEY_TYPE:
274 break;
275 case CKA_VALUE:
276 break;
277 case CKA_VALUE_LEN:
278 break;
279 case CKA_VALUE_BITS:
280 break;
281 default:
282 /* Second tier search */
283 switch (template[i].type) {
284 case CKA_ENCRYPT:
285 break;
286 case CKA_DECRYPT:
287 break;
288 case CKA_WRAP:
289 break;
290 case CKA_UNWRAP:
291 break;
292 case CKA_SIGN:
293 break;
294 case CKA_SIGN_RECOVER:
295 break;
296 case CKA_VERIFY:
297 break;
298 case CKA_VERIFY_RECOVER:
299 break;
300 case CKA_DERIVE:
301 break;
302 default:
303 /* Third tier search */
304 rv = kernel_lookup_attr(template[i].type);
305 if (rv != CKR_OK)
306 return (rv);
307 break;
308 }
309 break;
310 }
311 }
312 return (rv);
313 }
314
315
316 /*
317 * Clean up and release all the storage in the extra attribute list
318 * of an object.
319 */
320 void
kernel_cleanup_extra_attr(kernel_object_t * object_p)321 kernel_cleanup_extra_attr(kernel_object_t *object_p)
322 {
323
324 CK_ATTRIBUTE_INFO_PTR extra_attr;
325 CK_ATTRIBUTE_INFO_PTR tmp;
326
327 extra_attr = object_p->extra_attrlistp;
328 while (extra_attr) {
329 tmp = extra_attr->next;
330 if (extra_attr->attr.pValue)
331 /*
332 * All extra attributes in the extra attribute
333 * list have pValue points to the value of the
334 * attribute (with simple byte array type).
335 * Free the storage for the value of the attribute.
336 */
337 free(extra_attr->attr.pValue);
338
339 /* Free the storage for the attribute_info struct. */
340 free(extra_attr);
341 extra_attr = tmp;
342 }
343
344 object_p->extra_attrlistp = NULL;
345 }
346
347
348 /*
349 * Create the attribute_info struct to hold the object's attribute,
350 * and add it to the extra attribute list of an object.
351 */
352 CK_RV
kernel_add_extra_attr(CK_ATTRIBUTE_PTR template,kernel_object_t * object_p)353 kernel_add_extra_attr(CK_ATTRIBUTE_PTR template, kernel_object_t *object_p)
354 {
355
356 CK_ATTRIBUTE_INFO_PTR attrp;
357
358 /* Allocate the storage for the attribute_info struct. */
359 attrp = calloc(1, sizeof (attribute_info_t));
360 if (attrp == NULL) {
361 return (CKR_HOST_MEMORY);
362 }
363
364 /* Set up attribute_info struct. */
365 attrp->attr.type = template->type;
366 attrp->attr.ulValueLen = template->ulValueLen;
367
368 if ((template->pValue != NULL) &&
369 (template->ulValueLen > 0)) {
370 /* Allocate storage for the value of the attribute. */
371 attrp->attr.pValue = malloc(template->ulValueLen);
372 if (attrp->attr.pValue == NULL) {
373 free(attrp);
374 return (CKR_HOST_MEMORY);
375 }
376
377 (void) memcpy(attrp->attr.pValue, template->pValue,
378 template->ulValueLen);
379 } else {
380 attrp->attr.pValue = NULL;
381 }
382
383 /* Insert the new attribute in front of extra attribute list. */
384 if (object_p->extra_attrlistp == NULL) {
385 object_p->extra_attrlistp = attrp;
386 attrp->next = NULL;
387 } else {
388 attrp->next = object_p->extra_attrlistp;
389 object_p->extra_attrlistp = attrp;
390 }
391
392 return (CKR_OK);
393 }
394
395
396 /*
397 * Copy the attribute_info struct from the old object to a new attribute_info
398 * struct, and add that new struct to the extra attribute list of the new
399 * object.
400 */
401 CK_RV
kernel_copy_extra_attr(CK_ATTRIBUTE_INFO_PTR old_attrp,kernel_object_t * object_p)402 kernel_copy_extra_attr(CK_ATTRIBUTE_INFO_PTR old_attrp,
403 kernel_object_t *object_p)
404 {
405 CK_ATTRIBUTE_INFO_PTR attrp;
406
407 /* Allocate attribute_info struct. */
408 attrp = calloc(1, sizeof (attribute_info_t));
409 if (attrp == NULL) {
410 return (CKR_HOST_MEMORY);
411 }
412
413 attrp->attr.type = old_attrp->attr.type;
414 attrp->attr.ulValueLen = old_attrp->attr.ulValueLen;
415
416 if ((old_attrp->attr.pValue != NULL) &&
417 (old_attrp->attr.ulValueLen > 0)) {
418 attrp->attr.pValue = malloc(old_attrp->attr.ulValueLen);
419 if (attrp->attr.pValue == NULL) {
420 free(attrp);
421 return (CKR_HOST_MEMORY);
422 }
423
424 (void) memcpy(attrp->attr.pValue, old_attrp->attr.pValue,
425 old_attrp->attr.ulValueLen);
426 } else {
427 attrp->attr.pValue = NULL;
428 }
429
430 /* Insert the new attribute in front of extra attribute list */
431 if (object_p->extra_attrlistp == NULL) {
432 object_p->extra_attrlistp = attrp;
433 attrp->next = NULL;
434 } else {
435 attrp->next = object_p->extra_attrlistp;
436 object_p->extra_attrlistp = attrp;
437 }
438
439 return (CKR_OK);
440 }
441
442
443 /*
444 * Get the attribute triple from the extra attribute list in the object
445 * (if the specified attribute type is found), and copy it to a template.
446 * Note the type of the attribute to be copied is specified by the template,
447 * and the storage is pre-allocated for the atrribute value in the template
448 * for doing the copy.
449 */
450 CK_RV
get_extra_attr_from_object(kernel_object_t * object_p,CK_ATTRIBUTE_PTR template)451 get_extra_attr_from_object(kernel_object_t *object_p, CK_ATTRIBUTE_PTR template)
452 {
453
454 CK_ATTRIBUTE_INFO_PTR extra_attr;
455 CK_ATTRIBUTE_TYPE type = template->type;
456
457 extra_attr = object_p->extra_attrlistp;
458
459 while (extra_attr) {
460 if (type == extra_attr->attr.type) {
461 /* Found it. */
462 break;
463 } else {
464 /* Does not match, try next one. */
465 extra_attr = extra_attr->next;
466 }
467 }
468
469 if (extra_attr == NULL) {
470 /* A valid but un-initialized attribute. */
471 template->ulValueLen = 0;
472 return (CKR_OK);
473 }
474
475 /*
476 * We found the attribute in the extra attribute list.
477 */
478 if (template->pValue == NULL) {
479 template->ulValueLen = extra_attr->attr.ulValueLen;
480 return (CKR_OK);
481 }
482
483 if (template->ulValueLen >= extra_attr->attr.ulValueLen) {
484 /*
485 * The buffer provided by the application is large
486 * enough to hold the value of the attribute.
487 */
488 (void) memcpy(template->pValue, extra_attr->attr.pValue,
489 extra_attr->attr.ulValueLen);
490 template->ulValueLen = extra_attr->attr.ulValueLen;
491 return (CKR_OK);
492 } else {
493 /*
494 * The buffer provided by the application does
495 * not have enough space to hold the value.
496 */
497 template->ulValueLen = (CK_ULONG)-1;
498 return (CKR_BUFFER_TOO_SMALL);
499 }
500 }
501
502
503 /*
504 * Modify the attribute triple in the extra attribute list of the object
505 * if the specified attribute type is found. Otherwise, just add it to
506 * list.
507 */
508 CK_RV
set_extra_attr_to_object(kernel_object_t * object_p,CK_ATTRIBUTE_TYPE type,CK_ATTRIBUTE_PTR template)509 set_extra_attr_to_object(kernel_object_t *object_p, CK_ATTRIBUTE_TYPE type,
510 CK_ATTRIBUTE_PTR template)
511 {
512
513 CK_ATTRIBUTE_INFO_PTR extra_attr;
514
515 extra_attr = object_p->extra_attrlistp;
516
517 while (extra_attr) {
518 if (type == extra_attr->attr.type) {
519 /* Found it. */
520 break;
521 } else {
522 /* Does not match, try next one. */
523 extra_attr = extra_attr->next;
524 }
525 }
526
527 if (extra_attr == NULL) {
528 /*
529 * This attribute is a new one, go ahead adding it to
530 * the extra attribute list.
531 */
532 return (kernel_add_extra_attr(template, object_p));
533 }
534
535 /* We found the attribute in the extra attribute list. */
536 if ((template->pValue != NULL) &&
537 (template->ulValueLen > 0)) {
538 if (template->ulValueLen > extra_attr->attr.ulValueLen) {
539 /* The old buffer is too small to hold the new value. */
540 if (extra_attr->attr.pValue != NULL)
541 /* Free storage for the old attribute value. */
542 free(extra_attr->attr.pValue);
543
544 /* Allocate storage for the new attribute value. */
545 extra_attr->attr.pValue = malloc(template->ulValueLen);
546 if (extra_attr->attr.pValue == NULL) {
547 return (CKR_HOST_MEMORY);
548 }
549 }
550
551 /* Replace the attribute with new value. */
552 extra_attr->attr.ulValueLen = template->ulValueLen;
553 (void) memcpy(extra_attr->attr.pValue, template->pValue,
554 template->ulValueLen);
555 } else {
556 extra_attr->attr.pValue = NULL;
557 }
558
559 return (CKR_OK);
560 }
561
562
563 /*
564 * Copy the big integer attribute value from template to a biginteger_t struct.
565 */
566 CK_RV
get_bigint_attr_from_template(biginteger_t * big,CK_ATTRIBUTE_PTR template)567 get_bigint_attr_from_template(biginteger_t *big, CK_ATTRIBUTE_PTR template)
568 {
569
570 if ((template->pValue != NULL) &&
571 (template->ulValueLen > 0)) {
572 /* Allocate storage for the value of the attribute. */
573 big->big_value = malloc(template->ulValueLen);
574 if (big->big_value == NULL) {
575 return (CKR_HOST_MEMORY);
576 }
577
578 (void) memcpy(big->big_value, template->pValue,
579 template->ulValueLen);
580 big->big_value_len = template->ulValueLen;
581 } else {
582 big->big_value = NULL;
583 big->big_value_len = 0;
584 }
585
586 return (CKR_OK);
587 }
588
589
590 /*
591 * Copy the big integer attribute value from a biginteger_t struct in the
592 * object to a template.
593 */
594 CK_RV
get_bigint_attr_from_object(biginteger_t * big,CK_ATTRIBUTE_PTR template)595 get_bigint_attr_from_object(biginteger_t *big, CK_ATTRIBUTE_PTR template)
596 {
597
598 if (template->pValue == NULL) {
599 template->ulValueLen = big->big_value_len;
600 return (CKR_OK);
601 }
602
603 if (big->big_value == NULL) {
604 template->ulValueLen = 0;
605 return (CKR_OK);
606 }
607
608 if (template->ulValueLen >= big->big_value_len) {
609 /*
610 * The buffer provided by the application is large
611 * enough to hold the value of the attribute.
612 */
613 (void) memcpy(template->pValue, big->big_value,
614 big->big_value_len);
615 template->ulValueLen = big->big_value_len;
616 return (CKR_OK);
617 } else {
618 /*
619 * The buffer provided by the application does
620 * not have enough space to hold the value.
621 */
622 template->ulValueLen = (CK_ULONG)-1;
623 return (CKR_BUFFER_TOO_SMALL);
624 }
625 }
626
627
628 /*
629 * Copy the boolean data type attribute value from an object for the
630 * specified attribute to the template.
631 */
632 CK_RV
get_bool_attr_from_object(kernel_object_t * object_p,CK_ULONG bool_flag,CK_ATTRIBUTE_PTR template)633 get_bool_attr_from_object(kernel_object_t *object_p, CK_ULONG bool_flag,
634 CK_ATTRIBUTE_PTR template)
635 {
636
637 if (template->pValue == NULL) {
638 template->ulValueLen = sizeof (CK_BBOOL);
639 return (CKR_OK);
640 }
641
642 if (template->ulValueLen >= sizeof (CK_BBOOL)) {
643 /*
644 * The buffer provided by the application is large
645 * enough to hold the value of the attribute.
646 */
647 if (object_p->bool_attr_mask & bool_flag) {
648 *((CK_BBOOL *)template->pValue) = B_TRUE;
649 } else {
650 *((CK_BBOOL *)template->pValue) = B_FALSE;
651 }
652
653 template->ulValueLen = sizeof (CK_BBOOL);
654 return (CKR_OK);
655 } else {
656 /*
657 * The buffer provided by the application does
658 * not have enough space to hold the value.
659 */
660 template->ulValueLen = (CK_ULONG)-1;
661 return (CKR_BUFFER_TOO_SMALL);
662 }
663 }
664
665 /*
666 * Set the boolean data type attribute value in the object.
667 */
668 CK_RV
set_bool_attr_to_object(kernel_object_t * object_p,CK_ULONG bool_flag,CK_ATTRIBUTE_PTR template)669 set_bool_attr_to_object(kernel_object_t *object_p, CK_ULONG bool_flag,
670 CK_ATTRIBUTE_PTR template)
671 {
672
673 if (*(CK_BBOOL *)template->pValue)
674 object_p->bool_attr_mask |= bool_flag;
675 else
676 object_p->bool_attr_mask &= ~bool_flag;
677
678 return (CKR_OK);
679 }
680
681
682 /*
683 * Copy the CK_ULONG data type attribute value from an object to the
684 * template.
685 */
686 CK_RV
get_ulong_attr_from_object(CK_ULONG value,CK_ATTRIBUTE_PTR template)687 get_ulong_attr_from_object(CK_ULONG value, CK_ATTRIBUTE_PTR template)
688 {
689
690 if (template->pValue == NULL) {
691 template->ulValueLen = sizeof (CK_ULONG);
692 return (CKR_OK);
693 }
694
695 if (template->ulValueLen >= sizeof (CK_ULONG)) {
696 /*
697 * The buffer provided by the application is large
698 * enough to hold the value of the attribute.
699 */
700 *(CK_ULONG_PTR)template->pValue = value;
701 template->ulValueLen = sizeof (CK_ULONG);
702 return (CKR_OK);
703 } else {
704 /*
705 * The buffer provided by the application does
706 * not have enough space to hold the value.
707 */
708 template->ulValueLen = (CK_ULONG)-1;
709 return (CKR_BUFFER_TOO_SMALL);
710 }
711 }
712
713
714 /*
715 * Copy the CK_ULONG data type attribute value from a template to the
716 * object.
717 */
718 void
get_ulong_attr_from_template(CK_ULONG * value,CK_ATTRIBUTE_PTR template)719 get_ulong_attr_from_template(CK_ULONG *value, CK_ATTRIBUTE_PTR template)
720 {
721
722 if (template->pValue != NULL) {
723 *value = *(CK_ULONG_PTR)template->pValue;
724 } else {
725 *value = 0;
726 }
727
728 }
729
730 /*
731 * Copy the big integer attribute value from source's biginteger_t to
732 * destination's biginteger_t.
733 */
734 void
copy_bigint_attr(biginteger_t * src,biginteger_t * dst)735 copy_bigint_attr(biginteger_t *src, biginteger_t *dst)
736 {
737
738 if ((src->big_value != NULL) &&
739 (src->big_value_len > 0)) {
740 /*
741 * To do the copy, just have dst's big_value points
742 * to src's.
743 */
744 dst->big_value = src->big_value;
745 dst->big_value_len = src->big_value_len;
746
747 /*
748 * After the copy, nullify the src's big_value pointer.
749 * It prevents any double freeing the value.
750 */
751 src->big_value = NULL;
752 src->big_value_len = 0;
753 } else {
754 dst->big_value = NULL;
755 dst->big_value_len = 0;
756 }
757
758 }
759
760
761 CK_RV
get_string_from_template(CK_ATTRIBUTE_PTR dest,CK_ATTRIBUTE_PTR src)762 get_string_from_template(CK_ATTRIBUTE_PTR dest, CK_ATTRIBUTE_PTR src)
763 {
764 if ((src->pValue != NULL) &&
765 (src->ulValueLen > 0)) {
766 /* Allocate storage for the value of the attribute. */
767 dest->pValue = malloc(src->ulValueLen);
768 if (dest->pValue == NULL) {
769 return (CKR_HOST_MEMORY);
770 }
771
772 (void) memcpy(dest->pValue, src->pValue,
773 src->ulValueLen);
774 dest->ulValueLen = src->ulValueLen;
775 dest->type = src->type;
776 } else {
777 dest->pValue = NULL;
778 dest->ulValueLen = 0;
779 dest->type = src->type;
780 }
781
782 return (CKR_OK);
783
784 }
785
786 void
string_attr_cleanup(CK_ATTRIBUTE_PTR template)787 string_attr_cleanup(CK_ATTRIBUTE_PTR template)
788 {
789
790 if (template->pValue) {
791 free(template->pValue);
792 template->pValue = NULL;
793 template->ulValueLen = 0;
794 }
795 }
796
797 /*
798 * Release the storage allocated for object attribute with big integer
799 * value.
800 */
801 void
bigint_attr_cleanup(biginteger_t * big)802 bigint_attr_cleanup(biginteger_t *big)
803 {
804
805 if (big == NULL)
806 return;
807
808 if (big->big_value) {
809 (void) memset(big->big_value, 0, big->big_value_len);
810 free(big->big_value);
811 big->big_value = NULL;
812 big->big_value_len = 0;
813 }
814 }
815
816
817 /*
818 * Clean up and release all the storage allocated to hold the big integer
819 * attributes associated with the type (i.e. class) of the object. Also,
820 * release the storage allocated to the type of the object.
821 */
822 void
kernel_cleanup_object_bigint_attrs(kernel_object_t * object_p)823 kernel_cleanup_object_bigint_attrs(kernel_object_t *object_p)
824 {
825
826 CK_OBJECT_CLASS class = object_p->class;
827 CK_KEY_TYPE keytype = object_p->key_type;
828
829
830 switch (class) {
831 case CKO_PUBLIC_KEY:
832 if (OBJ_PUB(object_p)) {
833 switch (keytype) {
834 case CKK_RSA:
835 bigint_attr_cleanup(OBJ_PUB_RSA_MOD(
836 object_p));
837 bigint_attr_cleanup(OBJ_PUB_RSA_PUBEXPO(
838 object_p));
839 break;
840
841 case CKK_DSA:
842 bigint_attr_cleanup(OBJ_PUB_DSA_PRIME(
843 object_p));
844 bigint_attr_cleanup(OBJ_PUB_DSA_SUBPRIME(
845 object_p));
846 bigint_attr_cleanup(OBJ_PUB_DSA_BASE(
847 object_p));
848 bigint_attr_cleanup(OBJ_PUB_DSA_VALUE(
849 object_p));
850 break;
851
852 case CKK_DH:
853 bigint_attr_cleanup(OBJ_PUB_DH_PRIME(object_p));
854 bigint_attr_cleanup(OBJ_PUB_DH_BASE(object_p));
855 bigint_attr_cleanup(OBJ_PUB_DH_VALUE(object_p));
856 break;
857
858 case CKK_EC:
859 bigint_attr_cleanup(OBJ_PUB_EC_POINT(object_p));
860 break;
861 }
862
863 /* Release Public Key Object struct */
864 free(OBJ_PUB(object_p));
865 OBJ_PUB(object_p) = NULL;
866 }
867 break;
868
869 case CKO_PRIVATE_KEY:
870 if (OBJ_PRI(object_p)) {
871 switch (keytype) {
872 case CKK_RSA:
873 bigint_attr_cleanup(OBJ_PRI_RSA_MOD(
874 object_p));
875 bigint_attr_cleanup(OBJ_PRI_RSA_PUBEXPO(
876 object_p));
877 bigint_attr_cleanup(OBJ_PRI_RSA_PRIEXPO(
878 object_p));
879 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME1(
880 object_p));
881 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME2(
882 object_p));
883 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO1(
884 object_p));
885 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO2(
886 object_p));
887 bigint_attr_cleanup(OBJ_PRI_RSA_COEF(
888 object_p));
889 break;
890
891 case CKK_DSA:
892 bigint_attr_cleanup(OBJ_PRI_DSA_PRIME(
893 object_p));
894 bigint_attr_cleanup(OBJ_PRI_DSA_SUBPRIME(
895 object_p));
896 bigint_attr_cleanup(OBJ_PRI_DSA_BASE(
897 object_p));
898 bigint_attr_cleanup(OBJ_PRI_DSA_VALUE(
899 object_p));
900 break;
901
902 case CKK_DH:
903 bigint_attr_cleanup(OBJ_PRI_DH_PRIME(object_p));
904 bigint_attr_cleanup(OBJ_PRI_DH_BASE(object_p));
905 bigint_attr_cleanup(OBJ_PRI_DH_VALUE(object_p));
906 break;
907
908 case CKK_EC:
909 bigint_attr_cleanup(OBJ_PRI_EC_VALUE(object_p));
910 break;
911 }
912
913 /* Release Private Key Object struct. */
914 free(OBJ_PRI(object_p));
915 OBJ_PRI(object_p) = NULL;
916 }
917 break;
918 }
919 }
920
921
922 /*
923 * Parse the common attributes. Return to caller with appropriate return
924 * value to indicate if the supplied template specifies a valid attribute
925 * with a valid value.
926 */
927 CK_RV
kernel_parse_common_attrs(CK_ATTRIBUTE_PTR template,kernel_session_t * sp,uint64_t * attr_mask_p)928 kernel_parse_common_attrs(CK_ATTRIBUTE_PTR template, kernel_session_t *sp,
929 uint64_t *attr_mask_p)
930 {
931
932 CK_RV rv = CKR_OK;
933 kernel_slot_t *pslot = slot_table[sp->ses_slotid];
934
935 switch (template->type) {
936 case CKA_CLASS:
937 break;
938
939 /* default boolean attributes */
940 case CKA_TOKEN:
941 if ((*(CK_BBOOL *)template->pValue) == TRUE) {
942 rv = CKR_ATTRIBUTE_VALUE_INVALID;
943 }
944 break;
945
946 case CKA_PRIVATE:
947 if ((*(CK_BBOOL *)template->pValue) == TRUE) {
948 /*
949 * Cannot create a private object if the token
950 * has a keystore and the user isn't logged in.
951 */
952 if (pslot->sl_func_list.fl_object_create &&
953 pslot->sl_state != CKU_USER) {
954 rv = CKR_ATTRIBUTE_VALUE_INVALID;
955 } else {
956 *attr_mask_p |= PRIVATE_BOOL_ON;
957 }
958 }
959 break;
960
961 case CKA_MODIFIABLE:
962 if ((*(CK_BBOOL *)template->pValue) == FALSE) {
963 *attr_mask_p &= ~MODIFIABLE_BOOL_ON;
964 }
965 break;
966
967 case CKA_LABEL:
968 break;
969
970 default:
971 rv = CKR_TEMPLATE_INCONSISTENT;
972 }
973
974 return (rv);
975 }
976
977
978
979
980 /*
981 * Build a Public Key Object.
982 *
983 * - Parse the object's template, and when an error is detected such as
984 * invalid attribute type, invalid attribute value, etc., return
985 * with appropriate return value.
986 * - Set up attribute mask field in the object for the supplied common
987 * attributes that have boolean type.
988 * - Build the attribute_info struct to hold the value of each supplied
989 * attribute that has byte array type. Link attribute_info structs
990 * together to form the extra attribute list of the object.
991 * - Allocate storage for the Public Key object.
992 * - Build the Public Key object according to the key type. Allocate
993 * storage to hold the big integer value for the supplied attributes
994 * that are required for a certain key type.
995 *
996 */
997 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)998 kernel_build_public_key_object(CK_ATTRIBUTE_PTR template,
999 CK_ULONG ulAttrNum, kernel_object_t *new_object, kernel_session_t *sp,
1000 uint_t mode)
1001 {
1002
1003 int i;
1004 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1005 uint64_t attr_mask = PUBLIC_KEY_DEFAULT;
1006 CK_RV rv = CKR_OK;
1007 int isLabel = 0;
1008 /* Must set flags */
1009 int isModulus = 0;
1010 int isPubExpo = 0;
1011 int isPrime = 0;
1012 int isSubprime = 0;
1013 int isBase = 0;
1014 int isValue = 0;
1015 int isPoint = 0;
1016 int isParams = 0;
1017 /* Must not set flags */
1018 int isModulusBits = 0;
1019 CK_ULONG modulus_bits = 0;
1020
1021 biginteger_t modulus;
1022 biginteger_t pubexpo;
1023 biginteger_t prime;
1024 biginteger_t subprime;
1025 biginteger_t base;
1026 biginteger_t value;
1027 biginteger_t point;
1028 CK_ATTRIBUTE string_tmp;
1029 CK_ATTRIBUTE param_tmp;
1030
1031 public_key_obj_t *pbk;
1032
1033 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1034 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1035 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1036 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1037 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1038 (void) memset(&base, 0x0, sizeof (biginteger_t));
1039 (void) memset(&value, 0x0, sizeof (biginteger_t));
1040 (void) memset(&point, 0x0, sizeof (biginteger_t));
1041 string_tmp.pValue = NULL;
1042 param_tmp.pValue = NULL;
1043
1044 for (i = 0; i < ulAttrNum; i++) {
1045
1046 /* Public Key Object Attributes */
1047 switch (template[i].type) {
1048
1049 /* common key attributes */
1050 case CKA_KEY_TYPE:
1051 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1052 break;
1053
1054 case CKA_ID:
1055 case CKA_START_DATE:
1056 case CKA_END_DATE:
1057
1058 /* common public key attribute */
1059 case CKA_SUBJECT:
1060 /*
1061 * Allocate storage to hold the attribute
1062 * value with byte array type, and add it to
1063 * the extra attribute list of the object.
1064 */
1065 rv = kernel_add_extra_attr(&template[i],
1066 new_object);
1067 if (rv != CKR_OK) {
1068 goto fail_cleanup;
1069 }
1070 break;
1071
1072 /*
1073 * The following key related attribute types must
1074 * not be specified by C_CreateObject.
1075 */
1076 case CKA_LOCAL:
1077 case CKA_KEY_GEN_MECHANISM:
1078 rv = CKR_TEMPLATE_INCONSISTENT;
1079 goto fail_cleanup;
1080
1081 /* Key related boolean attributes */
1082 case CKA_DERIVE:
1083 if (*(CK_BBOOL *)template[i].pValue)
1084 attr_mask |= DERIVE_BOOL_ON;
1085 break;
1086
1087 case CKA_ENCRYPT:
1088 if (*(CK_BBOOL *)template[i].pValue)
1089 attr_mask |= ENCRYPT_BOOL_ON;
1090 else
1091 attr_mask &= ~ENCRYPT_BOOL_ON;
1092 break;
1093
1094 case CKA_VERIFY:
1095 if (*(CK_BBOOL *)template[i].pValue)
1096 attr_mask |= VERIFY_BOOL_ON;
1097 else
1098 attr_mask &= ~VERIFY_BOOL_ON;
1099 break;
1100
1101 case CKA_VERIFY_RECOVER:
1102 if (*(CK_BBOOL *)template[i].pValue)
1103 attr_mask |= VERIFY_RECOVER_BOOL_ON;
1104 else
1105 attr_mask &= ~VERIFY_RECOVER_BOOL_ON;
1106 break;
1107
1108 case CKA_WRAP:
1109 if (*(CK_BBOOL *)template[i].pValue)
1110 attr_mask |= WRAP_BOOL_ON;
1111 break;
1112
1113 case CKA_TRUSTED:
1114 if (*(CK_BBOOL *)template[i].pValue)
1115 attr_mask |= TRUSTED_BOOL_ON;
1116 break;
1117
1118 /*
1119 * The following key related attribute types must
1120 * be specified according to the key type by
1121 * C_CreateObject.
1122 */
1123 case CKA_MODULUS:
1124 isModulus = 1;
1125 /*
1126 * Copyin big integer attribute from template
1127 * to a local variable.
1128 */
1129 rv = get_bigint_attr_from_template(&modulus,
1130 &template[i]);
1131 if (rv != CKR_OK)
1132 goto fail_cleanup;
1133 break;
1134
1135 case CKA_PUBLIC_EXPONENT:
1136 isPubExpo = 1;
1137 rv = get_bigint_attr_from_template(&pubexpo,
1138 &template[i]);
1139 if (rv != CKR_OK)
1140 goto fail_cleanup;
1141 break;
1142
1143 case CKA_PRIME:
1144 isPrime = 1;
1145 rv = get_bigint_attr_from_template(&prime,
1146 &template[i]);
1147 if (rv != CKR_OK)
1148 goto fail_cleanup;
1149 break;
1150
1151 case CKA_SUBPRIME:
1152 isSubprime = 1;
1153 rv = get_bigint_attr_from_template(&subprime,
1154 &template[i]);
1155 if (rv != CKR_OK)
1156 goto fail_cleanup;
1157 break;
1158
1159 case CKA_BASE:
1160 isBase = 1;
1161 rv = get_bigint_attr_from_template(&base,
1162 &template[i]);
1163 if (rv != CKR_OK)
1164 goto fail_cleanup;
1165 break;
1166
1167 case CKA_VALUE:
1168 isValue = 1;
1169 rv = get_bigint_attr_from_template(&value,
1170 &template[i]);
1171 if (rv != CKR_OK)
1172 goto fail_cleanup;
1173 break;
1174
1175 case CKA_MODULUS_BITS:
1176 isModulusBits = 1;
1177 get_ulong_attr_from_template(&modulus_bits,
1178 &template[i]);
1179 break;
1180
1181 case CKA_LABEL:
1182 isLabel = 1;
1183 rv = get_string_from_template(&string_tmp,
1184 &template[i]);
1185 if (rv != CKR_OK)
1186 goto fail_cleanup;
1187 break;
1188
1189 case CKA_EC_POINT:
1190 isPoint = 1;
1191 rv = get_bigint_attr_from_template(&point,
1192 &template[i]);
1193 if (rv != CKR_OK)
1194 goto fail_cleanup;
1195 break;
1196
1197 case CKA_EC_PARAMS:
1198 isParams = 1;
1199 rv = get_string_from_template(¶m_tmp,
1200 &template[i]);
1201 if (rv != CKR_OK)
1202 goto fail_cleanup;
1203 break;
1204
1205 default:
1206 rv = kernel_parse_common_attrs(&template[i], sp,
1207 &attr_mask);
1208 if (rv != CKR_OK)
1209 goto fail_cleanup;
1210 break;
1211 }
1212 } /* For */
1213
1214 /* Allocate storage for Public Key Object. */
1215 pbk = calloc(1, sizeof (public_key_obj_t));
1216 if (pbk == NULL) {
1217 rv = CKR_HOST_MEMORY;
1218 goto fail_cleanup;
1219 }
1220
1221 new_object->object_class_u.public_key = pbk;
1222 new_object->class = CKO_PUBLIC_KEY;
1223
1224 if (keytype == (CK_KEY_TYPE)~0UL) {
1225 rv = CKR_TEMPLATE_INCOMPLETE;
1226 goto fail_cleanup;
1227 }
1228 new_object->key_type = keytype;
1229
1230 /* Supported key types of the Public Key Object */
1231 switch (keytype) {
1232 case CKK_RSA:
1233 if (mode == KERNEL_CREATE_OBJ) {
1234 if (isModulusBits || isPrime || isSubprime ||
1235 isBase|| isValue) {
1236 rv = CKR_TEMPLATE_INCONSISTENT;
1237 goto fail_cleanup;
1238 }
1239 }
1240
1241 if (isModulus && isPubExpo) {
1242 /*
1243 * Copy big integer attribute value to the
1244 * designated place in the public key object.
1245 */
1246 copy_bigint_attr(&modulus,
1247 KEY_PUB_RSA_MOD(pbk));
1248
1249 copy_bigint_attr(&pubexpo,
1250 KEY_PUB_RSA_PUBEXPO(pbk));
1251 } else {
1252 rv = CKR_TEMPLATE_INCOMPLETE;
1253 goto fail_cleanup;
1254 }
1255
1256 /* must be generating a RSA key pair by value */
1257 if (isModulusBits) {
1258 KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits;
1259 }
1260 break;
1261
1262 case CKK_DSA:
1263 if (isModulusBits || isModulus || isPubExpo) {
1264 rv = CKR_TEMPLATE_INCONSISTENT;
1265 goto fail_cleanup;
1266 }
1267
1268 if (!(isPrime && isSubprime && isBase && isValue)) {
1269 rv = CKR_TEMPLATE_INCOMPLETE;
1270 goto fail_cleanup;
1271 }
1272
1273 copy_bigint_attr(&prime, KEY_PUB_DSA_PRIME(pbk));
1274
1275 copy_bigint_attr(&subprime, KEY_PUB_DSA_SUBPRIME(pbk));
1276
1277 copy_bigint_attr(&base, KEY_PUB_DSA_BASE(pbk));
1278
1279 copy_bigint_attr(&value, KEY_PUB_DSA_VALUE(pbk));
1280
1281 break;
1282
1283 case CKK_DH:
1284 if (!(isPrime && isBase && isValue)) {
1285 rv = CKR_TEMPLATE_INCOMPLETE;
1286 goto fail_cleanup;
1287 }
1288
1289 copy_bigint_attr(&prime, KEY_PUB_DH_PRIME(pbk));
1290
1291 copy_bigint_attr(&base, KEY_PUB_DH_BASE(pbk));
1292
1293 copy_bigint_attr(&value, KEY_PUB_DH_VALUE(pbk));
1294
1295 break;
1296
1297 case CKK_EC:
1298 if (!isPoint || !isParams) {
1299 rv = CKR_TEMPLATE_INCOMPLETE;
1300 goto fail_cleanup;
1301 }
1302
1303 copy_bigint_attr(&point, KEY_PUB_EC_POINT(pbk));
1304 rv = kernel_add_extra_attr(¶m_tmp, new_object);
1305 if (rv != CKR_OK)
1306 goto fail_cleanup;
1307 string_attr_cleanup(¶m_tmp);
1308 break;
1309 default:
1310 rv = CKR_TEMPLATE_INCONSISTENT;
1311 goto fail_cleanup;
1312 }
1313
1314 /* Set up object. */
1315 new_object->bool_attr_mask = attr_mask;
1316 if (isLabel) {
1317 rv = kernel_add_extra_attr(&string_tmp, new_object);
1318 if (rv != CKR_OK)
1319 goto fail_cleanup;
1320 string_attr_cleanup(&string_tmp);
1321 }
1322
1323 return (rv);
1324
1325 fail_cleanup:
1326 /*
1327 * cleanup the storage allocated to the local variables.
1328 */
1329 bigint_attr_cleanup(&modulus);
1330 bigint_attr_cleanup(&pubexpo);
1331 bigint_attr_cleanup(&prime);
1332 bigint_attr_cleanup(&subprime);
1333 bigint_attr_cleanup(&base);
1334 bigint_attr_cleanup(&value);
1335 bigint_attr_cleanup(&point);
1336 string_attr_cleanup(&string_tmp);
1337 string_attr_cleanup(¶m_tmp);
1338
1339 /*
1340 * cleanup the storage allocated inside the object itself.
1341 */
1342 kernel_cleanup_object(new_object);
1343
1344 return (rv);
1345 }
1346
1347
1348 /*
1349 * Build a Private Key Object.
1350 *
1351 * - Parse the object's template, and when an error is detected such as
1352 * invalid attribute type, invalid attribute value, etc., return
1353 * with appropriate return value.
1354 * - Set up attribute mask field in the object for the supplied common
1355 * attributes that have boolean type.
1356 * - Build the attribute_info struct to hold the value of each supplied
1357 * attribute that has byte array type. Link attribute_info structs
1358 * together to form the extra attribute list of the object.
1359 * - Allocate storage for the Private Key object.
1360 * - Build the Private Key object according to the key type. Allocate
1361 * storage to hold the big integer value for the supplied attributes
1362 * that are required for a certain key type.
1363 *
1364 */
1365 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)1366 kernel_build_private_key_object(CK_ATTRIBUTE_PTR template,
1367 CK_ULONG ulAttrNum, kernel_object_t *new_object, kernel_session_t *sp,
1368 uint_t mode)
1369 {
1370 ulong_t i;
1371 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1372 uint64_t attr_mask = PRIVATE_KEY_DEFAULT;
1373 CK_RV rv = CKR_OK;
1374 int isLabel = 0;
1375 /* Must set flags */
1376 int isModulus = 0;
1377 int isPriExpo = 0;
1378 int isPrime = 0;
1379 int isSubprime = 0;
1380 int isBase = 0;
1381 int isValue = 0;
1382 int isParams = 0;
1383 /* Must not set flags */
1384 int isValueBits = 0;
1385 CK_ULONG value_bits = 0;
1386
1387 /* Private Key RSA optional */
1388 int isPubExpo = 0;
1389 int isPrime1 = 0;
1390 int isPrime2 = 0;
1391 int isExpo1 = 0;
1392 int isExpo2 = 0;
1393 int isCoef = 0;
1394
1395 biginteger_t modulus;
1396 biginteger_t priexpo;
1397 biginteger_t prime;
1398 biginteger_t subprime;
1399 biginteger_t base;
1400 biginteger_t value;
1401
1402 biginteger_t pubexpo;
1403 biginteger_t prime1;
1404 biginteger_t prime2;
1405 biginteger_t expo1;
1406 biginteger_t expo2;
1407 biginteger_t coef;
1408 CK_ATTRIBUTE string_tmp;
1409 CK_ATTRIBUTE param_tmp;
1410
1411 private_key_obj_t *pvk;
1412
1413 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1414 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1415 (void) memset(&priexpo, 0x0, sizeof (biginteger_t));
1416 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1417 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1418 (void) memset(&base, 0x0, sizeof (biginteger_t));
1419 (void) memset(&value, 0x0, sizeof (biginteger_t));
1420 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1421 (void) memset(&prime1, 0x0, sizeof (biginteger_t));
1422 (void) memset(&prime2, 0x0, sizeof (biginteger_t));
1423 (void) memset(&expo1, 0x0, sizeof (biginteger_t));
1424 (void) memset(&expo2, 0x0, sizeof (biginteger_t));
1425 (void) memset(&coef, 0x0, sizeof (biginteger_t));
1426 string_tmp.pValue = NULL;
1427 param_tmp.pValue = NULL;
1428
1429 for (i = 0; i < ulAttrNum; i++) {
1430
1431 /* Private Key Object Attributes */
1432 switch (template[i].type) {
1433
1434 /* common key attributes */
1435 case CKA_KEY_TYPE:
1436 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1437 break;
1438
1439 case CKA_ID:
1440 case CKA_START_DATE:
1441 case CKA_END_DATE:
1442
1443 /* common private key attribute */
1444 case CKA_SUBJECT:
1445 /*
1446 * Allocate storage to hold the attribute
1447 * value with byte array type, and add it to
1448 * the extra attribute list of the object.
1449 */
1450 rv = kernel_add_extra_attr(&template[i],
1451 new_object);
1452 if (rv != CKR_OK) {
1453 goto fail_cleanup;
1454 }
1455 break;
1456
1457 /*
1458 * The following key related attribute types must
1459 * not be specified by C_CreateObject.
1460 */
1461 case CKA_LOCAL:
1462 case CKA_KEY_GEN_MECHANISM:
1463 case CKA_AUTH_PIN_FLAGS:
1464 case CKA_ALWAYS_SENSITIVE:
1465 case CKA_NEVER_EXTRACTABLE:
1466 rv = CKR_TEMPLATE_INCONSISTENT;
1467 goto fail_cleanup;
1468
1469 /* Key related boolean attributes */
1470 case CKA_DERIVE:
1471 if (*(CK_BBOOL *)template[i].pValue)
1472 attr_mask |= DERIVE_BOOL_ON;
1473 break;
1474
1475 case CKA_SENSITIVE:
1476 if (*(CK_BBOOL *)template[i].pValue)
1477 attr_mask |= SENSITIVE_BOOL_ON;
1478 break;
1479
1480 case CKA_SECONDARY_AUTH:
1481 if (*(CK_BBOOL *)template[i].pValue) {
1482 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1483 goto fail_cleanup;
1484 }
1485 break;
1486
1487 case CKA_DECRYPT:
1488 if (*(CK_BBOOL *)template[i].pValue)
1489 attr_mask |= DECRYPT_BOOL_ON;
1490 else
1491 attr_mask &= ~DECRYPT_BOOL_ON;
1492 break;
1493
1494 case CKA_SIGN:
1495 if (*(CK_BBOOL *)template[i].pValue)
1496 attr_mask |= SIGN_BOOL_ON;
1497 else
1498 attr_mask &= ~SIGN_BOOL_ON;
1499 break;
1500
1501 case CKA_SIGN_RECOVER:
1502 if (*(CK_BBOOL *)template[i].pValue)
1503 attr_mask |= SIGN_RECOVER_BOOL_ON;
1504 else
1505 attr_mask &= ~SIGN_RECOVER_BOOL_ON;
1506 break;
1507
1508 case CKA_UNWRAP:
1509 if (*(CK_BBOOL *)template[i].pValue)
1510 attr_mask |= UNWRAP_BOOL_ON;
1511 break;
1512
1513 case CKA_EXTRACTABLE:
1514 if (*(CK_BBOOL *)template[i].pValue)
1515 attr_mask |= EXTRACTABLE_BOOL_ON;
1516 else
1517 attr_mask &= ~EXTRACTABLE_BOOL_ON;
1518 break;
1519
1520 /*
1521 * The following key related attribute types must
1522 * be specified according to the key type by
1523 * C_CreateObject.
1524 */
1525 case CKA_MODULUS:
1526 isModulus = 1;
1527 /*
1528 * Copyin big integer attribute from template
1529 * to a local variable.
1530 */
1531 rv = get_bigint_attr_from_template(&modulus,
1532 &template[i]);
1533 if (rv != CKR_OK)
1534 goto fail_cleanup;
1535 break;
1536
1537 case CKA_PUBLIC_EXPONENT:
1538 isPubExpo = 1;
1539 rv = get_bigint_attr_from_template(&pubexpo,
1540 &template[i]);
1541 if (rv != CKR_OK)
1542 goto fail_cleanup;
1543 break;
1544
1545 case CKA_PRIVATE_EXPONENT:
1546 isPriExpo = 1;
1547 rv = get_bigint_attr_from_template(&priexpo,
1548 &template[i]);
1549 if (rv != CKR_OK)
1550 goto fail_cleanup;
1551 break;
1552
1553 case CKA_PRIME_1:
1554 isPrime1 = 1;
1555 rv = get_bigint_attr_from_template(&prime1,
1556 &template[i]);
1557 if (rv != CKR_OK)
1558 goto fail_cleanup;
1559 break;
1560
1561 case CKA_PRIME_2:
1562 isPrime2 = 1;
1563 rv = get_bigint_attr_from_template(&prime2,
1564 &template[i]);
1565 if (rv != CKR_OK)
1566 goto fail_cleanup;
1567 break;
1568
1569 case CKA_EXPONENT_1:
1570 isExpo1 = 1;
1571 rv = get_bigint_attr_from_template(&expo1,
1572 &template[i]);
1573 if (rv != CKR_OK)
1574 goto fail_cleanup;
1575 break;
1576
1577 case CKA_EXPONENT_2:
1578 isExpo2 = 1;
1579 rv = get_bigint_attr_from_template(&expo2,
1580 &template[i]);
1581 if (rv != CKR_OK)
1582 goto fail_cleanup;
1583 break;
1584
1585 case CKA_COEFFICIENT:
1586 isCoef = 1;
1587 rv = get_bigint_attr_from_template(&coef,
1588 &template[i]);
1589 if (rv != CKR_OK)
1590 goto fail_cleanup;
1591 break;
1592
1593 case CKA_PRIME:
1594 isPrime = 1;
1595 rv = get_bigint_attr_from_template(&prime,
1596 &template[i]);
1597 if (rv != CKR_OK)
1598 goto fail_cleanup;
1599 break;
1600
1601 case CKA_SUBPRIME:
1602 isSubprime = 1;
1603 rv = get_bigint_attr_from_template(&subprime,
1604 &template[i]);
1605 if (rv != CKR_OK)
1606 goto fail_cleanup;
1607 break;
1608
1609 case CKA_BASE:
1610 isBase = 1;
1611 rv = get_bigint_attr_from_template(&base,
1612 &template[i]);
1613 if (rv != CKR_OK)
1614 goto fail_cleanup;
1615 break;
1616
1617 case CKA_VALUE:
1618 isValue = 1;
1619 rv = get_bigint_attr_from_template(&value,
1620 &template[i]);
1621 if (rv != CKR_OK)
1622 goto fail_cleanup;
1623 break;
1624
1625 case CKA_VALUE_BITS:
1626 isValueBits = 1;
1627 get_ulong_attr_from_template(&value_bits,
1628 &template[i]);
1629 break;
1630
1631 case CKA_LABEL:
1632 isLabel = 1;
1633 rv = get_string_from_template(&string_tmp,
1634 &template[i]);
1635 if (rv != CKR_OK)
1636 goto fail_cleanup;
1637 break;
1638
1639 case CKA_EC_PARAMS:
1640 isParams = 1;
1641 rv = get_string_from_template(¶m_tmp,
1642 &template[i]);
1643 if (rv != CKR_OK)
1644 goto fail_cleanup;
1645 break;
1646
1647 default:
1648 rv = kernel_parse_common_attrs(&template[i], sp,
1649 &attr_mask);
1650 if (rv != CKR_OK)
1651 goto fail_cleanup;
1652 break;
1653
1654 }
1655 } /* For */
1656
1657 /* Allocate storage for Private Key Object. */
1658 pvk = calloc(1, sizeof (private_key_obj_t));
1659 if (pvk == NULL) {
1660 rv = CKR_HOST_MEMORY;
1661 goto fail_cleanup;
1662 }
1663
1664 new_object->object_class_u.private_key = pvk;
1665 new_object->class = CKO_PRIVATE_KEY;
1666
1667 if (keytype == (CK_KEY_TYPE)~0UL) {
1668 rv = CKR_TEMPLATE_INCOMPLETE;
1669 goto fail_cleanup;
1670 }
1671
1672 new_object->key_type = keytype;
1673
1674 /* Supported key types of the Private Key Object */
1675 switch (keytype) {
1676 case CKK_RSA:
1677 if (isPrime || isSubprime || isBase || isValue ||
1678 isValueBits) {
1679 rv = CKR_TEMPLATE_INCONSISTENT;
1680 goto fail_cleanup;
1681 }
1682
1683 if (isModulus && isPriExpo) {
1684 /*
1685 * Copy big integer attribute value to the
1686 * designated place in the Private Key object.
1687 */
1688 copy_bigint_attr(&modulus, KEY_PRI_RSA_MOD(pvk));
1689
1690 copy_bigint_attr(&priexpo, KEY_PRI_RSA_PRIEXPO(pvk));
1691
1692 } else {
1693 rv = CKR_TEMPLATE_INCOMPLETE;
1694 goto fail_cleanup;
1695 }
1696
1697 /* The following attributes are optional. */
1698 if (isPubExpo) {
1699 copy_bigint_attr(&pubexpo, KEY_PRI_RSA_PUBEXPO(pvk));
1700 }
1701
1702 if (isPrime1) {
1703 copy_bigint_attr(&prime1, KEY_PRI_RSA_PRIME1(pvk));
1704 }
1705
1706 if (isPrime2) {
1707 copy_bigint_attr(&prime2, KEY_PRI_RSA_PRIME2(pvk));
1708 }
1709
1710 if (isExpo1) {
1711 copy_bigint_attr(&expo1, KEY_PRI_RSA_EXPO1(pvk));
1712 }
1713
1714 if (isExpo2) {
1715 copy_bigint_attr(&expo2, KEY_PRI_RSA_EXPO2(pvk));
1716 }
1717
1718 if (isCoef) {
1719 copy_bigint_attr(&coef, KEY_PRI_RSA_COEF(pvk));
1720 }
1721 break;
1722
1723 case CKK_DSA:
1724 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
1725 isPrime2 || isExpo1 || isExpo2 || isCoef ||
1726 isValueBits) {
1727 rv = CKR_TEMPLATE_INCONSISTENT;
1728 goto fail_cleanup;
1729 }
1730
1731 if (!(isPrime && isSubprime && isBase && isValue)) {
1732 rv = CKR_TEMPLATE_INCOMPLETE;
1733 goto fail_cleanup;
1734 }
1735
1736 copy_bigint_attr(&prime, KEY_PRI_DSA_PRIME(pvk));
1737
1738 copy_bigint_attr(&subprime, KEY_PRI_DSA_SUBPRIME(pvk));
1739
1740 copy_bigint_attr(&base, KEY_PRI_DSA_BASE(pvk));
1741
1742 copy_bigint_attr(&value, KEY_PRI_DSA_VALUE(pvk));
1743
1744 break;
1745
1746 case CKK_DH:
1747 if (mode == KERNEL_CREATE_OBJ && isValueBits) {
1748 rv = CKR_TEMPLATE_INCONSISTENT;
1749 goto fail_cleanup;
1750 }
1751 if (!(isPrime && isBase && isValue)) {
1752 rv = CKR_TEMPLATE_INCOMPLETE;
1753 goto fail_cleanup;
1754 }
1755
1756 copy_bigint_attr(&prime, KEY_PRI_DH_PRIME(pvk));
1757
1758 copy_bigint_attr(&base, KEY_PRI_DH_BASE(pvk));
1759
1760 copy_bigint_attr(&value, KEY_PRI_DH_VALUE(pvk));
1761
1762 KEY_PRI_DH_VAL_BITS(pvk) = (isValueBits) ? value_bits : 0;
1763
1764 break;
1765
1766 case CKK_EC:
1767 if (!isValue || !isParams) {
1768 rv = CKR_TEMPLATE_INCOMPLETE;
1769 goto fail_cleanup;
1770 }
1771
1772 copy_bigint_attr(&value, KEY_PRI_EC_VALUE(pvk));
1773 rv = kernel_add_extra_attr(¶m_tmp, new_object);
1774 if (rv != CKR_OK)
1775 goto fail_cleanup;
1776 string_attr_cleanup(¶m_tmp);
1777 break;
1778 default:
1779 rv = CKR_TEMPLATE_INCONSISTENT;
1780 goto fail_cleanup;
1781 }
1782
1783 /* Set up object. */
1784 new_object->bool_attr_mask = attr_mask;
1785 if (isLabel) {
1786 rv = kernel_add_extra_attr(&string_tmp, new_object);
1787 if (rv != CKR_OK)
1788 goto fail_cleanup;
1789 string_attr_cleanup(&string_tmp);
1790 }
1791
1792 return (rv);
1793
1794 fail_cleanup:
1795 /*
1796 * cleanup the storage allocated to the local variables.
1797 */
1798 bigint_attr_cleanup(&modulus);
1799 bigint_attr_cleanup(&priexpo);
1800 bigint_attr_cleanup(&prime);
1801 bigint_attr_cleanup(&subprime);
1802 bigint_attr_cleanup(&base);
1803 bigint_attr_cleanup(&value);
1804 bigint_attr_cleanup(&pubexpo);
1805 bigint_attr_cleanup(&prime1);
1806 bigint_attr_cleanup(&prime2);
1807 bigint_attr_cleanup(&expo1);
1808 bigint_attr_cleanup(&expo2);
1809 bigint_attr_cleanup(&coef);
1810 string_attr_cleanup(&string_tmp);
1811 string_attr_cleanup(¶m_tmp);
1812
1813 /*
1814 * cleanup the storage allocated inside the object itself.
1815 */
1816 kernel_cleanup_object(new_object);
1817
1818 return (rv);
1819 }
1820
1821
1822 /*
1823 * Build a Secret Key Object.
1824 *
1825 * - Parse the object's template, and when an error is detected such as
1826 * invalid attribute type, invalid attribute value, etc., return
1827 * with appropriate return value.
1828 * - Set up attribute mask field in the object for the supplied common
1829 * attributes that have boolean type.
1830 * - Build the attribute_info struct to hold the value of each supplied
1831 * attribute that has byte array type. Link attribute_info structs
1832 * together to form the extra attribute list of the object.
1833 * - Allocate storage for the Secret Key object.
1834 * - Build the Secret Key object. Allocate storage to hold the big integer
1835 * value for the attribute CKA_VALUE that is required for all the key
1836 * types supported by secret key object.
1837 *
1838 */
1839 CK_RV
kernel_build_secret_key_object(CK_ATTRIBUTE_PTR template,CK_ULONG ulAttrNum,kernel_object_t * new_object,kernel_session_t * sp)1840 kernel_build_secret_key_object(CK_ATTRIBUTE_PTR template,
1841 CK_ULONG ulAttrNum, kernel_object_t *new_object, kernel_session_t *sp)
1842 {
1843
1844 int i;
1845 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1846 uint64_t attr_mask = SECRET_KEY_DEFAULT;
1847 CK_RV rv = CKR_OK;
1848 int isLabel = 0;
1849 /* Must set flags */
1850 int isValue = 0;
1851 /* Must not set flags */
1852 int isValueLen = 0;
1853
1854 CK_ATTRIBUTE string_tmp;
1855
1856 secret_key_obj_t *sck;
1857
1858 string_tmp.pValue = NULL;
1859
1860 /* Allocate storage for Secret Key Object. */
1861 sck = calloc(1, sizeof (secret_key_obj_t));
1862 if (sck == NULL) {
1863 rv = CKR_HOST_MEMORY;
1864 goto fail_cleanup;
1865 }
1866
1867 new_object->object_class_u.secret_key = sck;
1868 new_object->class = CKO_SECRET_KEY;
1869
1870 for (i = 0; i < ulAttrNum; i++) {
1871
1872 /* Secret Key Object Attributes */
1873 switch (template[i].type) {
1874
1875 /* common key attributes */
1876 case CKA_KEY_TYPE:
1877 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1878 break;
1879
1880 case CKA_ID:
1881 case CKA_START_DATE:
1882 case CKA_END_DATE:
1883 /*
1884 * Allocate storage to hold the attribute
1885 * value with byte array type, and add it to
1886 * the extra attribute list of the object.
1887 */
1888 rv = kernel_add_extra_attr(&template[i],
1889 new_object);
1890 if (rv != CKR_OK) {
1891 goto fail_cleanup;
1892 }
1893 break;
1894
1895 /*
1896 * The following key related attribute types must
1897 * not be specified by C_CreateObject.
1898 */
1899 case CKA_LOCAL:
1900 case CKA_KEY_GEN_MECHANISM:
1901 case CKA_ALWAYS_SENSITIVE:
1902 case CKA_NEVER_EXTRACTABLE:
1903 rv = CKR_TEMPLATE_INCONSISTENT;
1904 goto fail_cleanup;
1905
1906 /* Key related boolean attributes */
1907 case CKA_DERIVE:
1908 if (*(CK_BBOOL *)template[i].pValue)
1909 attr_mask |= DERIVE_BOOL_ON;
1910 break;
1911
1912 case CKA_SENSITIVE:
1913 if (*(CK_BBOOL *)template[i].pValue)
1914 attr_mask |= SENSITIVE_BOOL_ON;
1915 break;
1916
1917 case CKA_ENCRYPT:
1918 if (*(CK_BBOOL *)template[i].pValue)
1919 attr_mask |= ENCRYPT_BOOL_ON;
1920 else
1921 attr_mask &= ~ENCRYPT_BOOL_ON;
1922 break;
1923
1924 case CKA_DECRYPT:
1925 if (*(CK_BBOOL *)template[i].pValue)
1926 attr_mask |= DECRYPT_BOOL_ON;
1927 else
1928 attr_mask &= ~DECRYPT_BOOL_ON;
1929 break;
1930
1931 case CKA_SIGN:
1932 if (*(CK_BBOOL *)template[i].pValue)
1933 attr_mask |= SIGN_BOOL_ON;
1934 else
1935 attr_mask &= ~SIGN_BOOL_ON;
1936 break;
1937
1938 case CKA_VERIFY:
1939 if (*(CK_BBOOL *)template[i].pValue)
1940 attr_mask |= VERIFY_BOOL_ON;
1941 else
1942 attr_mask &= ~VERIFY_BOOL_ON;
1943 break;
1944
1945 case CKA_WRAP:
1946 if (*(CK_BBOOL *)template[i].pValue)
1947 attr_mask |= WRAP_BOOL_ON;
1948 break;
1949
1950 case CKA_UNWRAP:
1951 if (*(CK_BBOOL *)template[i].pValue)
1952 attr_mask |= UNWRAP_BOOL_ON;
1953 break;
1954
1955 case CKA_EXTRACTABLE:
1956 if (*(CK_BBOOL *)template[i].pValue)
1957 attr_mask |= EXTRACTABLE_BOOL_ON;
1958 else
1959 attr_mask &= ~EXTRACTABLE_BOOL_ON;
1960 break;
1961
1962 case CKA_VALUE:
1963 isValue = 1;
1964 if ((template[i].ulValueLen == 0) ||
1965 (template[i].pValue == NULL)) {
1966 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1967 goto fail_cleanup;
1968 }
1969
1970 /*
1971 * Copyin attribute from template
1972 * to a local variable.
1973 */
1974 sck->sk_value = malloc(template[i].ulValueLen);
1975 if (sck->sk_value == NULL) {
1976 rv = CKR_HOST_MEMORY;
1977 goto fail_cleanup;
1978 }
1979 (void) memcpy(sck->sk_value, template[i].pValue,
1980 template[i].ulValueLen);
1981 sck->sk_value_len = template[i].ulValueLen;
1982 break;
1983
1984 case CKA_VALUE_LEN:
1985 isValueLen = 1;
1986 break;
1987
1988 case CKA_LABEL:
1989 isLabel = 1;
1990 rv = get_string_from_template(&string_tmp,
1991 &template[i]);
1992 if (rv != CKR_OK)
1993 goto fail_cleanup;
1994 break;
1995
1996 default:
1997 rv = kernel_parse_common_attrs(&template[i], sp,
1998 &attr_mask);
1999 if (rv != CKR_OK)
2000 goto fail_cleanup;
2001 break;
2002
2003 }
2004 } /* For */
2005
2006 if (keytype == (CK_KEY_TYPE)~0UL) {
2007 rv = CKR_TEMPLATE_INCOMPLETE;
2008 goto fail_cleanup;
2009 }
2010
2011 new_object->key_type = keytype;
2012
2013 /* Supported key types of the Secret Key Object */
2014 switch (keytype) {
2015 case CKK_RC4:
2016 if (!isValue) {
2017 rv = CKR_TEMPLATE_INCOMPLETE;
2018 goto fail_cleanup;
2019 }
2020 if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) ||
2021 (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) {
2022 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2023 goto fail_cleanup;
2024 }
2025 break;
2026
2027 case CKK_GENERIC_SECRET:
2028 if (!isValue) {
2029 rv = CKR_TEMPLATE_INCOMPLETE;
2030 goto fail_cleanup;
2031 }
2032 break;
2033
2034 case CKK_AES:
2035 if (!isValue) {
2036 rv = CKR_TEMPLATE_INCOMPLETE;
2037 goto fail_cleanup;
2038 }
2039 if (sck->sk_value_len < AES_MIN_KEY_BYTES) {
2040 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2041 goto fail_cleanup;
2042 }
2043 break;
2044
2045 case CKK_BLOWFISH:
2046 if (!isValue) {
2047 rv = CKR_TEMPLATE_INCOMPLETE;
2048 goto fail_cleanup;
2049 }
2050 if (sck->sk_value_len < BLOWFISH_MINBYTES) {
2051 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2052 goto fail_cleanup;
2053 }
2054 break;
2055
2056 case CKK_DES:
2057 if (!isValue) {
2058 rv = CKR_TEMPLATE_INCOMPLETE;
2059 goto fail_cleanup;
2060 }
2061 if (sck->sk_value_len != DES_KEYSIZE) {
2062 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2063 goto fail_cleanup;
2064 }
2065 break;
2066
2067 case CKK_DES2:
2068 if (!isValue) {
2069 rv = CKR_TEMPLATE_INCOMPLETE;
2070 goto fail_cleanup;
2071 }
2072 if (sck->sk_value_len != DES2_KEYSIZE) {
2073 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2074 goto fail_cleanup;
2075 }
2076 break;
2077
2078 case CKK_DES3:
2079 if (!isValue) {
2080 rv = CKR_TEMPLATE_INCOMPLETE;
2081 goto fail_cleanup;
2082 }
2083 if (sck->sk_value_len != DES3_KEYSIZE) {
2084 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2085 goto fail_cleanup;
2086 }
2087 break;
2088
2089 default:
2090 rv = CKR_TEMPLATE_INCONSISTENT;
2091 goto fail_cleanup;
2092 }
2093
2094 if (isValueLen) {
2095 rv = CKR_TEMPLATE_INCONSISTENT;
2096 goto fail_cleanup;
2097 }
2098
2099 /* Set up object. */
2100 new_object->bool_attr_mask = attr_mask;
2101 if (isLabel) {
2102 rv = kernel_add_extra_attr(&string_tmp, new_object);
2103 if (rv != CKR_OK)
2104 goto fail_cleanup;
2105 string_attr_cleanup(&string_tmp);
2106 }
2107
2108 return (rv);
2109
2110 fail_cleanup:
2111 /*
2112 * cleanup the storage allocated to the local variables.
2113 */
2114 string_attr_cleanup(&string_tmp);
2115
2116 /*
2117 * cleanup the storage allocated inside the object itself.
2118 */
2119 kernel_cleanup_object(new_object);
2120
2121 return (rv);
2122 }
2123
2124
2125 /*
2126 * Validate the attribute types in the object's template. Then,
2127 * call the appropriate build function according to the class of
2128 * the object specified in the template.
2129 *
2130 * Note: The following classes of objects are supported:
2131 * - CKO_SECRET_KEY
2132 * - CKO_PUBLIC_KEY
2133 * - CKO_PRIVATE_KEY
2134 */
2135 CK_RV
kernel_build_object(CK_ATTRIBUTE_PTR template,CK_ULONG ulAttrNum,kernel_object_t * new_object,kernel_session_t * sp,uint_t mode)2136 kernel_build_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
2137 kernel_object_t *new_object, kernel_session_t *sp, uint_t mode)
2138 {
2139
2140 CK_OBJECT_CLASS class = (CK_OBJECT_CLASS)~0UL;
2141 CK_RV rv = CKR_OK;
2142
2143 if (template == NULL) {
2144 return (CKR_ARGUMENTS_BAD);
2145 }
2146
2147 /* Validate the attribute type in the template. */
2148 rv = kernel_validate_attr(template, ulAttrNum, &class);
2149 if (rv != CKR_OK)
2150 return (rv);
2151
2152 if (class == (CK_OBJECT_CLASS)~0UL)
2153 return (CKR_TEMPLATE_INCOMPLETE);
2154
2155 /*
2156 * Call the appropriate function based on the supported class
2157 * of the object.
2158 */
2159 switch (class) {
2160 case CKO_PUBLIC_KEY:
2161 rv = kernel_build_public_key_object(template, ulAttrNum,
2162 new_object, sp, mode);
2163 break;
2164
2165 case CKO_PRIVATE_KEY:
2166 rv = kernel_build_private_key_object(template, ulAttrNum,
2167 new_object, sp, mode);
2168 break;
2169
2170 case CKO_SECRET_KEY:
2171 rv = kernel_build_secret_key_object(template, ulAttrNum,
2172 new_object, sp);
2173 break;
2174
2175 case CKO_DOMAIN_PARAMETERS:
2176 case CKO_DATA:
2177 case CKO_CERTIFICATE:
2178 case CKO_HW_FEATURE:
2179 case CKO_VENDOR_DEFINED:
2180 default:
2181 return (CKR_ATTRIBUTE_VALUE_INVALID);
2182 }
2183
2184 return (rv);
2185 }
2186
2187
2188 /*
2189 * Get the value of a requested attribute that is common to all supported
2190 * classes (i.e. public key, private key, secret key classes).
2191 */
2192 CK_RV
kernel_get_common_attrs(kernel_object_t * object_p,CK_ATTRIBUTE_PTR template)2193 kernel_get_common_attrs(kernel_object_t *object_p, CK_ATTRIBUTE_PTR template)
2194 {
2195
2196 CK_RV rv = CKR_OK;
2197
2198 switch (template->type) {
2199
2200 case CKA_CLASS:
2201 return (get_ulong_attr_from_object(object_p->class,
2202 template));
2203
2204 /* default boolean attributes */
2205 case CKA_TOKEN:
2206
2207 template->ulValueLen = sizeof (CK_BBOOL);
2208 if (template->pValue == NULL) {
2209 return (CKR_OK);
2210 }
2211
2212 /*
2213 * A token object will not be created in the library, so we
2214 * return FALSE.
2215 */
2216 *((CK_BBOOL *)template->pValue) = B_FALSE;
2217 break;
2218
2219 case CKA_PRIVATE:
2220
2221 template->ulValueLen = sizeof (CK_BBOOL);
2222 if (template->pValue == NULL) {
2223 return (CKR_OK);
2224 }
2225 if (object_p->bool_attr_mask & PRIVATE_BOOL_ON) {
2226 *((CK_BBOOL *)template->pValue) = B_TRUE;
2227 } else {
2228 *((CK_BBOOL *)template->pValue) = B_FALSE;
2229 }
2230 break;
2231
2232 case CKA_MODIFIABLE:
2233 template->ulValueLen = sizeof (CK_BBOOL);
2234 if (template->pValue == NULL) {
2235 return (CKR_OK);
2236 }
2237 if ((object_p->bool_attr_mask) & MODIFIABLE_BOOL_ON)
2238 *((CK_BBOOL *)template->pValue) = B_TRUE;
2239 else
2240 *((CK_BBOOL *)template->pValue) = B_FALSE;
2241 break;
2242
2243 case CKA_LABEL:
2244 return (get_extra_attr_from_object(object_p,
2245 template));
2246 break;
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