8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / pkcs11 / pkcs11_kernel / common / kernelAttributeUtil.c
blob73dd9e0949a20a0c55022e9fbbaaa0d8031d8ca9
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright 2012 Milan Jurik. All rights reserved.
27 #include <stdlib.h>
28 #include <string.h>
29 #include <security/cryptoki.h>
30 #include <sys/crypto/common.h>
31 #include <aes_impl.h>
32 #include <blowfish_impl.h>
33 #include <arcfour.h>
34 #include <des_impl.h>
35 #include "kernelGlobal.h"
36 #include "kernelObject.h"
37 #include "kernelSession.h"
38 #include "kernelSlot.h"
42 * This attribute table is used by the kernel_lookup_attr()
43 * to validate the attributes.
45 CK_ATTRIBUTE_TYPE attr_map[] = {
46 CKA_PRIVATE,
47 CKA_LABEL,
48 CKA_APPLICATION,
49 CKA_OBJECT_ID,
50 CKA_CERTIFICATE_TYPE,
51 CKA_ISSUER,
52 CKA_SERIAL_NUMBER,
53 CKA_AC_ISSUER,
54 CKA_OWNER,
55 CKA_ATTR_TYPES,
56 CKA_SUBJECT,
57 CKA_ID,
58 CKA_SENSITIVE,
59 CKA_START_DATE,
60 CKA_END_DATE,
61 CKA_MODULUS,
62 CKA_MODULUS_BITS,
63 CKA_PUBLIC_EXPONENT,
64 CKA_PRIVATE_EXPONENT,
65 CKA_PRIME_1,
66 CKA_PRIME_2,
67 CKA_EXPONENT_1,
68 CKA_EXPONENT_2,
69 CKA_COEFFICIENT,
70 CKA_PRIME,
71 CKA_SUBPRIME,
72 CKA_BASE,
73 CKA_EXTRACTABLE,
74 CKA_LOCAL,
75 CKA_NEVER_EXTRACTABLE,
76 CKA_ALWAYS_SENSITIVE,
77 CKA_MODIFIABLE,
78 CKA_ECDSA_PARAMS,
79 CKA_EC_POINT,
80 CKA_SECONDARY_AUTH,
81 CKA_AUTH_PIN_FLAGS,
82 CKA_HW_FEATURE_TYPE,
83 CKA_RESET_ON_INIT,
84 CKA_HAS_RESET
88 * attributes that exists only in public key objects
89 * Note: some attributes may also exist in one or two
90 * other object classes, but they are also listed
91 * because not all object have them.
93 CK_ATTRIBUTE_TYPE PUB_KEY_ATTRS[] =
95 CKA_SUBJECT,
96 CKA_ENCRYPT,
97 CKA_WRAP,
98 CKA_VERIFY,
99 CKA_VERIFY_RECOVER,
100 CKA_MODULUS,
101 CKA_MODULUS_BITS,
102 CKA_PUBLIC_EXPONENT,
103 CKA_PRIME,
104 CKA_SUBPRIME,
105 CKA_BASE,
106 CKA_TRUSTED,
107 CKA_ECDSA_PARAMS,
108 CKA_EC_PARAMS,
109 CKA_EC_POINT
113 * attributes that exists only in private key objects
114 * Note: some attributes may also exist in one or two
115 * other object classes, but they are also listed
116 * because not all object have them.
118 CK_ATTRIBUTE_TYPE PRIV_KEY_ATTRS[] =
120 CKA_DECRYPT,
121 CKA_UNWRAP,
122 CKA_SIGN,
123 CKA_SIGN_RECOVER,
124 CKA_MODULUS,
125 CKA_PUBLIC_EXPONENT,
126 CKA_PRIVATE_EXPONENT,
127 CKA_PRIME,
128 CKA_SUBPRIME,
129 CKA_BASE,
130 CKA_PRIME_1,
131 CKA_PRIME_2,
132 CKA_EXPONENT_1,
133 CKA_EXPONENT_2,
134 CKA_COEFFICIENT,
135 CKA_VALUE_BITS,
136 CKA_SUBJECT,
137 CKA_SENSITIVE,
138 CKA_EXTRACTABLE,
139 CKA_NEVER_EXTRACTABLE,
140 CKA_ALWAYS_SENSITIVE,
141 CKA_ECDSA_PARAMS,
142 CKA_EC_PARAMS
146 * attributes that exists only in secret key objects
147 * Note: some attributes may also exist in one or two
148 * other object classes, but they are also listed
149 * because not all object have them.
151 CK_ATTRIBUTE_TYPE SECRET_KEY_ATTRS[] =
153 CKA_VALUE_LEN,
154 CKA_ENCRYPT,
155 CKA_DECRYPT,
156 CKA_WRAP,
157 CKA_UNWRAP,
158 CKA_SIGN,
159 CKA_VERIFY,
160 CKA_SENSITIVE,
161 CKA_EXTRACTABLE,
162 CKA_NEVER_EXTRACTABLE,
163 CKA_ALWAYS_SENSITIVE
167 * attributes that exists only in domain parameter objects
168 * Note: some attributes may also exist in one or two
169 * other object classes, but they are also listed
170 * because not all object have them.
172 CK_ATTRIBUTE_TYPE DOMAIN_ATTRS[] =
174 CKA_PRIME,
175 CKA_SUBPRIME,
176 CKA_BASE,
177 CKA_PRIME_BITS,
178 CKA_SUBPRIME_BITS,
179 CKA_SUB_PRIME_BITS
183 * attributes that exists only in hardware feature objects
185 CK_ATTRIBUTE_TYPE HARDWARE_ATTRS[] =
187 CKA_HW_FEATURE_TYPE,
188 CKA_RESET_ON_INIT,
189 CKA_HAS_RESET
193 * attributes that exists only in certificate objects
195 CK_ATTRIBUTE_TYPE CERT_ATTRS[] =
197 CKA_CERTIFICATE_TYPE,
198 CKA_SUBJECT,
199 CKA_ID,
200 CKA_ISSUER,
201 CKA_AC_ISSUER,
202 CKA_SERIAL_NUMBER,
203 CKA_OWNER,
204 CKA_ATTR_TYPES
209 * Validate the attribute by using binary search algorithm.
211 CK_RV
212 kernel_lookup_attr(CK_ATTRIBUTE_TYPE type)
215 size_t lower, middle, upper;
217 lower = 0;
218 upper = (sizeof (attr_map) / sizeof (CK_ATTRIBUTE_TYPE)) - 1;
220 while (lower <= upper) {
221 /* Always starts from middle. */
222 middle = (lower + upper) / 2;
224 if (type > attr_map[middle]) {
225 /* Adjust the lower bound to upper half. */
226 lower = middle + 1;
227 continue;
230 if (type == attr_map[middle]) {
231 /* Found it. */
232 return (CKR_OK);
235 if (type < attr_map[middle]) {
236 /* Adjust the upper bound to lower half. */
237 upper = middle - 1;
238 continue;
242 /* Failed to find the matching attribute from the attribute table. */
243 return (CKR_ATTRIBUTE_TYPE_INVALID);
248 * Validate the attribute by using the following search algorithm:
250 * 1) Search for the most frequently used attributes first.
251 * 2) If not found, search for the usage-purpose attributes - these
252 * attributes have dense set of values, therefore compiler will
253 * optimize it with a branch table and branch to the appropriate
254 * case.
255 * 3) If still not found, use binary search for the rest of the
256 * attributes in the attr_map[] table.
258 CK_RV
259 kernel_validate_attr(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
260 CK_OBJECT_CLASS *class)
263 CK_ULONG i;
264 CK_RV rv = CKR_OK;
266 for (i = 0; i < ulAttrNum; i++) {
267 /* First tier search */
268 switch (template[i].type) {
269 case CKA_CLASS:
270 *class = *((CK_OBJECT_CLASS*)template[i].pValue);
271 break;
272 case CKA_TOKEN:
273 break;
274 case CKA_KEY_TYPE:
275 break;
276 case CKA_VALUE:
277 break;
278 case CKA_VALUE_LEN:
279 break;
280 case CKA_VALUE_BITS:
281 break;
282 default:
283 /* Second tier search */
284 switch (template[i].type) {
285 case CKA_ENCRYPT:
286 break;
287 case CKA_DECRYPT:
288 break;
289 case CKA_WRAP:
290 break;
291 case CKA_UNWRAP:
292 break;
293 case CKA_SIGN:
294 break;
295 case CKA_SIGN_RECOVER:
296 break;
297 case CKA_VERIFY:
298 break;
299 case CKA_VERIFY_RECOVER:
300 break;
301 case CKA_DERIVE:
302 break;
303 default:
304 /* Third tier search */
305 rv = kernel_lookup_attr(template[i].type);
306 if (rv != CKR_OK)
307 return (rv);
308 break;
310 break;
313 return (rv);
318 * Clean up and release all the storage in the extra attribute list
319 * of an object.
321 void
322 kernel_cleanup_extra_attr(kernel_object_t *object_p)
325 CK_ATTRIBUTE_INFO_PTR extra_attr;
326 CK_ATTRIBUTE_INFO_PTR tmp;
328 extra_attr = object_p->extra_attrlistp;
329 while (extra_attr) {
330 tmp = extra_attr->next;
331 if (extra_attr->attr.pValue)
333 * All extra attributes in the extra attribute
334 * list have pValue points to the value of the
335 * attribute (with simple byte array type).
336 * Free the storage for the value of the attribute.
338 free(extra_attr->attr.pValue);
340 /* Free the storage for the attribute_info struct. */
341 free(extra_attr);
342 extra_attr = tmp;
345 object_p->extra_attrlistp = NULL;
350 * Create the attribute_info struct to hold the object's attribute,
351 * and add it to the extra attribute list of an object.
353 CK_RV
354 kernel_add_extra_attr(CK_ATTRIBUTE_PTR template, kernel_object_t *object_p)
357 CK_ATTRIBUTE_INFO_PTR attrp;
359 /* Allocate the storage for the attribute_info struct. */
360 attrp = calloc(1, sizeof (attribute_info_t));
361 if (attrp == NULL) {
362 return (CKR_HOST_MEMORY);
365 /* Set up attribute_info struct. */
366 attrp->attr.type = template->type;
367 attrp->attr.ulValueLen = template->ulValueLen;
369 if ((template->pValue != NULL) &&
370 (template->ulValueLen > 0)) {
371 /* Allocate storage for the value of the attribute. */
372 attrp->attr.pValue = malloc(template->ulValueLen);
373 if (attrp->attr.pValue == NULL) {
374 free(attrp);
375 return (CKR_HOST_MEMORY);
378 (void) memcpy(attrp->attr.pValue, template->pValue,
379 template->ulValueLen);
380 } else {
381 attrp->attr.pValue = NULL;
384 /* Insert the new attribute in front of extra attribute list. */
385 if (object_p->extra_attrlistp == NULL) {
386 object_p->extra_attrlistp = attrp;
387 attrp->next = NULL;
388 } else {
389 attrp->next = object_p->extra_attrlistp;
390 object_p->extra_attrlistp = attrp;
393 return (CKR_OK);
398 * Copy the attribute_info struct from the old object to a new attribute_info
399 * struct, and add that new struct to the extra attribute list of the new
400 * object.
402 CK_RV
403 kernel_copy_extra_attr(CK_ATTRIBUTE_INFO_PTR old_attrp,
404 kernel_object_t *object_p)
406 CK_ATTRIBUTE_INFO_PTR attrp;
408 /* Allocate attribute_info struct. */
409 attrp = calloc(1, sizeof (attribute_info_t));
410 if (attrp == NULL) {
411 return (CKR_HOST_MEMORY);
414 attrp->attr.type = old_attrp->attr.type;
415 attrp->attr.ulValueLen = old_attrp->attr.ulValueLen;
417 if ((old_attrp->attr.pValue != NULL) &&
418 (old_attrp->attr.ulValueLen > 0)) {
419 attrp->attr.pValue = malloc(old_attrp->attr.ulValueLen);
420 if (attrp->attr.pValue == NULL) {
421 free(attrp);
422 return (CKR_HOST_MEMORY);
425 (void) memcpy(attrp->attr.pValue, old_attrp->attr.pValue,
426 old_attrp->attr.ulValueLen);
427 } else {
428 attrp->attr.pValue = NULL;
431 /* Insert the new attribute in front of extra attribute list */
432 if (object_p->extra_attrlistp == NULL) {
433 object_p->extra_attrlistp = attrp;
434 attrp->next = NULL;
435 } else {
436 attrp->next = object_p->extra_attrlistp;
437 object_p->extra_attrlistp = attrp;
440 return (CKR_OK);
445 * Get the attribute triple from the extra attribute list in the object
446 * (if the specified attribute type is found), and copy it to a template.
447 * Note the type of the attribute to be copied is specified by the template,
448 * and the storage is pre-allocated for the atrribute value in the template
449 * for doing the copy.
451 CK_RV
452 get_extra_attr_from_object(kernel_object_t *object_p, CK_ATTRIBUTE_PTR template)
455 CK_ATTRIBUTE_INFO_PTR extra_attr;
456 CK_ATTRIBUTE_TYPE type = template->type;
458 extra_attr = object_p->extra_attrlistp;
460 while (extra_attr) {
461 if (type == extra_attr->attr.type) {
462 /* Found it. */
463 break;
464 } else {
465 /* Does not match, try next one. */
466 extra_attr = extra_attr->next;
470 if (extra_attr == NULL) {
471 /* A valid but un-initialized attribute. */
472 template->ulValueLen = 0;
473 return (CKR_OK);
477 * We found the attribute in the extra attribute list.
479 if (template->pValue == NULL) {
480 template->ulValueLen = extra_attr->attr.ulValueLen;
481 return (CKR_OK);
484 if (template->ulValueLen >= extra_attr->attr.ulValueLen) {
486 * The buffer provided by the application is large
487 * enough to hold the value of the attribute.
489 (void) memcpy(template->pValue, extra_attr->attr.pValue,
490 extra_attr->attr.ulValueLen);
491 template->ulValueLen = extra_attr->attr.ulValueLen;
492 return (CKR_OK);
493 } else {
495 * The buffer provided by the application does
496 * not have enough space to hold the value.
498 template->ulValueLen = (CK_ULONG)-1;
499 return (CKR_BUFFER_TOO_SMALL);
505 * Modify the attribute triple in the extra attribute list of the object
506 * if the specified attribute type is found. Otherwise, just add it to
507 * list.
509 CK_RV
510 set_extra_attr_to_object(kernel_object_t *object_p, CK_ATTRIBUTE_TYPE type,
511 CK_ATTRIBUTE_PTR template)
514 CK_ATTRIBUTE_INFO_PTR extra_attr;
516 extra_attr = object_p->extra_attrlistp;
518 while (extra_attr) {
519 if (type == extra_attr->attr.type) {
520 /* Found it. */
521 break;
522 } else {
523 /* Does not match, try next one. */
524 extra_attr = extra_attr->next;
528 if (extra_attr == NULL) {
530 * This attribute is a new one, go ahead adding it to
531 * the extra attribute list.
533 return (kernel_add_extra_attr(template, object_p));
536 /* We found the attribute in the extra attribute list. */
537 if ((template->pValue != NULL) &&
538 (template->ulValueLen > 0)) {
539 if (template->ulValueLen > extra_attr->attr.ulValueLen) {
540 /* The old buffer is too small to hold the new value. */
541 if (extra_attr->attr.pValue != NULL)
542 /* Free storage for the old attribute value. */
543 free(extra_attr->attr.pValue);
545 /* Allocate storage for the new attribute value. */
546 extra_attr->attr.pValue = malloc(template->ulValueLen);
547 if (extra_attr->attr.pValue == NULL) {
548 return (CKR_HOST_MEMORY);
552 /* Replace the attribute with new value. */
553 extra_attr->attr.ulValueLen = template->ulValueLen;
554 (void) memcpy(extra_attr->attr.pValue, template->pValue,
555 template->ulValueLen);
556 } else {
557 extra_attr->attr.pValue = NULL;
560 return (CKR_OK);
565 * Copy the big integer attribute value from template to a biginteger_t struct.
567 CK_RV
568 get_bigint_attr_from_template(biginteger_t *big, CK_ATTRIBUTE_PTR template)
571 if ((template->pValue != NULL) &&
572 (template->ulValueLen > 0)) {
573 /* Allocate storage for the value of the attribute. */
574 big->big_value = malloc(template->ulValueLen);
575 if (big->big_value == NULL) {
576 return (CKR_HOST_MEMORY);
579 (void) memcpy(big->big_value, template->pValue,
580 template->ulValueLen);
581 big->big_value_len = template->ulValueLen;
582 } else {
583 big->big_value = NULL;
584 big->big_value_len = 0;
587 return (CKR_OK);
592 * Copy the big integer attribute value from a biginteger_t struct in the
593 * object to a template.
595 CK_RV
596 get_bigint_attr_from_object(biginteger_t *big, CK_ATTRIBUTE_PTR template)
599 if (template->pValue == NULL) {
600 template->ulValueLen = big->big_value_len;
601 return (CKR_OK);
604 if (big->big_value == NULL) {
605 template->ulValueLen = 0;
606 return (CKR_OK);
609 if (template->ulValueLen >= big->big_value_len) {
611 * The buffer provided by the application is large
612 * enough to hold the value of the attribute.
614 (void) memcpy(template->pValue, big->big_value,
615 big->big_value_len);
616 template->ulValueLen = big->big_value_len;
617 return (CKR_OK);
618 } else {
620 * The buffer provided by the application does
621 * not have enough space to hold the value.
623 template->ulValueLen = (CK_ULONG)-1;
624 return (CKR_BUFFER_TOO_SMALL);
630 * Copy the boolean data type attribute value from an object for the
631 * specified attribute to the template.
633 CK_RV
634 get_bool_attr_from_object(kernel_object_t *object_p, CK_ULONG bool_flag,
635 CK_ATTRIBUTE_PTR template)
638 if (template->pValue == NULL) {
639 template->ulValueLen = sizeof (CK_BBOOL);
640 return (CKR_OK);
643 if (template->ulValueLen >= sizeof (CK_BBOOL)) {
645 * The buffer provided by the application is large
646 * enough to hold the value of the attribute.
648 if (object_p->bool_attr_mask & bool_flag) {
649 *((CK_BBOOL *)template->pValue) = B_TRUE;
650 } else {
651 *((CK_BBOOL *)template->pValue) = B_FALSE;
654 template->ulValueLen = sizeof (CK_BBOOL);
655 return (CKR_OK);
656 } else {
658 * The buffer provided by the application does
659 * not have enough space to hold the value.
661 template->ulValueLen = (CK_ULONG)-1;
662 return (CKR_BUFFER_TOO_SMALL);
667 * Set the boolean data type attribute value in the object.
669 CK_RV
670 set_bool_attr_to_object(kernel_object_t *object_p, CK_ULONG bool_flag,
671 CK_ATTRIBUTE_PTR template)
674 if (*(CK_BBOOL *)template->pValue)
675 object_p->bool_attr_mask |= bool_flag;
676 else
677 object_p->bool_attr_mask &= ~bool_flag;
679 return (CKR_OK);
684 * Copy the CK_ULONG data type attribute value from an object to the
685 * template.
687 CK_RV
688 get_ulong_attr_from_object(CK_ULONG value, CK_ATTRIBUTE_PTR template)
691 if (template->pValue == NULL) {
692 template->ulValueLen = sizeof (CK_ULONG);
693 return (CKR_OK);
696 if (template->ulValueLen >= sizeof (CK_ULONG)) {
698 * The buffer provided by the application is large
699 * enough to hold the value of the attribute.
701 *(CK_ULONG_PTR)template->pValue = value;
702 template->ulValueLen = sizeof (CK_ULONG);
703 return (CKR_OK);
704 } else {
706 * The buffer provided by the application does
707 * not have enough space to hold the value.
709 template->ulValueLen = (CK_ULONG)-1;
710 return (CKR_BUFFER_TOO_SMALL);
716 * Copy the CK_ULONG data type attribute value from a template to the
717 * object.
719 void
720 get_ulong_attr_from_template(CK_ULONG *value, CK_ATTRIBUTE_PTR template)
723 if (template->pValue != NULL) {
724 *value = *(CK_ULONG_PTR)template->pValue;
725 } else {
726 *value = 0;
732 * Copy the big integer attribute value from source's biginteger_t to
733 * destination's biginteger_t.
735 void
736 copy_bigint_attr(biginteger_t *src, biginteger_t *dst)
739 if ((src->big_value != NULL) &&
740 (src->big_value_len > 0)) {
742 * To do the copy, just have dst's big_value points
743 * to src's.
745 dst->big_value = src->big_value;
746 dst->big_value_len = src->big_value_len;
749 * After the copy, nullify the src's big_value pointer.
750 * It prevents any double freeing the value.
752 src->big_value = NULL;
753 src->big_value_len = 0;
754 } else {
755 dst->big_value = NULL;
756 dst->big_value_len = 0;
762 CK_RV
763 get_string_from_template(CK_ATTRIBUTE_PTR dest, CK_ATTRIBUTE_PTR src)
765 if ((src->pValue != NULL) &&
766 (src->ulValueLen > 0)) {
767 /* Allocate storage for the value of the attribute. */
768 dest->pValue = malloc(src->ulValueLen);
769 if (dest->pValue == NULL) {
770 return (CKR_HOST_MEMORY);
773 (void) memcpy(dest->pValue, src->pValue,
774 src->ulValueLen);
775 dest->ulValueLen = src->ulValueLen;
776 dest->type = src->type;
777 } else {
778 dest->pValue = NULL;
779 dest->ulValueLen = 0;
780 dest->type = src->type;
783 return (CKR_OK);
787 void
788 string_attr_cleanup(CK_ATTRIBUTE_PTR template)
791 if (template->pValue) {
792 free(template->pValue);
793 template->pValue = NULL;
794 template->ulValueLen = 0;
799 * Release the storage allocated for object attribute with big integer
800 * value.
802 void
803 bigint_attr_cleanup(biginteger_t *big)
806 if (big == NULL)
807 return;
809 if (big->big_value) {
810 (void) memset(big->big_value, 0, big->big_value_len);
811 free(big->big_value);
812 big->big_value = NULL;
813 big->big_value_len = 0;
819 * Clean up and release all the storage allocated to hold the big integer
820 * attributes associated with the type (i.e. class) of the object. Also,
821 * release the storage allocated to the type of the object.
823 void
824 kernel_cleanup_object_bigint_attrs(kernel_object_t *object_p)
827 CK_OBJECT_CLASS class = object_p->class;
828 CK_KEY_TYPE keytype = object_p->key_type;
831 switch (class) {
832 case CKO_PUBLIC_KEY:
833 if (OBJ_PUB(object_p)) {
834 switch (keytype) {
835 case CKK_RSA:
836 bigint_attr_cleanup(OBJ_PUB_RSA_MOD(
837 object_p));
838 bigint_attr_cleanup(OBJ_PUB_RSA_PUBEXPO(
839 object_p));
840 break;
842 case CKK_DSA:
843 bigint_attr_cleanup(OBJ_PUB_DSA_PRIME(
844 object_p));
845 bigint_attr_cleanup(OBJ_PUB_DSA_SUBPRIME(
846 object_p));
847 bigint_attr_cleanup(OBJ_PUB_DSA_BASE(
848 object_p));
849 bigint_attr_cleanup(OBJ_PUB_DSA_VALUE(
850 object_p));
851 break;
853 case CKK_DH:
854 bigint_attr_cleanup(OBJ_PUB_DH_PRIME(object_p));
855 bigint_attr_cleanup(OBJ_PUB_DH_BASE(object_p));
856 bigint_attr_cleanup(OBJ_PUB_DH_VALUE(object_p));
857 break;
859 case CKK_EC:
860 bigint_attr_cleanup(OBJ_PUB_EC_POINT(object_p));
861 break;
864 /* Release Public Key Object struct */
865 free(OBJ_PUB(object_p));
866 OBJ_PUB(object_p) = NULL;
868 break;
870 case CKO_PRIVATE_KEY:
871 if (OBJ_PRI(object_p)) {
872 switch (keytype) {
873 case CKK_RSA:
874 bigint_attr_cleanup(OBJ_PRI_RSA_MOD(
875 object_p));
876 bigint_attr_cleanup(OBJ_PRI_RSA_PUBEXPO(
877 object_p));
878 bigint_attr_cleanup(OBJ_PRI_RSA_PRIEXPO(
879 object_p));
880 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME1(
881 object_p));
882 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME2(
883 object_p));
884 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO1(
885 object_p));
886 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO2(
887 object_p));
888 bigint_attr_cleanup(OBJ_PRI_RSA_COEF(
889 object_p));
890 break;
892 case CKK_DSA:
893 bigint_attr_cleanup(OBJ_PRI_DSA_PRIME(
894 object_p));
895 bigint_attr_cleanup(OBJ_PRI_DSA_SUBPRIME(
896 object_p));
897 bigint_attr_cleanup(OBJ_PRI_DSA_BASE(
898 object_p));
899 bigint_attr_cleanup(OBJ_PRI_DSA_VALUE(
900 object_p));
901 break;
903 case CKK_DH:
904 bigint_attr_cleanup(OBJ_PRI_DH_PRIME(object_p));
905 bigint_attr_cleanup(OBJ_PRI_DH_BASE(object_p));
906 bigint_attr_cleanup(OBJ_PRI_DH_VALUE(object_p));
907 break;
909 case CKK_EC:
910 bigint_attr_cleanup(OBJ_PRI_EC_VALUE(object_p));
911 break;
914 /* Release Private Key Object struct. */
915 free(OBJ_PRI(object_p));
916 OBJ_PRI(object_p) = NULL;
918 break;
924 * Parse the common attributes. Return to caller with appropriate return
925 * value to indicate if the supplied template specifies a valid attribute
926 * with a valid value.
928 CK_RV
929 kernel_parse_common_attrs(CK_ATTRIBUTE_PTR template, kernel_session_t *sp,
930 uint64_t *attr_mask_p)
933 CK_RV rv = CKR_OK;
934 kernel_slot_t *pslot = slot_table[sp->ses_slotid];
936 switch (template->type) {
937 case CKA_CLASS:
938 break;
940 /* default boolean attributes */
941 case CKA_TOKEN:
942 if ((*(CK_BBOOL *)template->pValue) == TRUE) {
943 rv = CKR_ATTRIBUTE_VALUE_INVALID;
945 break;
947 case CKA_PRIVATE:
948 if ((*(CK_BBOOL *)template->pValue) == TRUE) {
950 * Cannot create a private object if the token
951 * has a keystore and the user isn't logged in.
953 if (pslot->sl_func_list.fl_object_create &&
954 pslot->sl_state != CKU_USER) {
955 rv = CKR_ATTRIBUTE_VALUE_INVALID;
956 } else {
957 *attr_mask_p |= PRIVATE_BOOL_ON;
960 break;
962 case CKA_MODIFIABLE:
963 if ((*(CK_BBOOL *)template->pValue) == FALSE) {
964 *attr_mask_p &= ~MODIFIABLE_BOOL_ON;
966 break;
968 case CKA_LABEL:
969 break;
971 default:
972 rv = CKR_TEMPLATE_INCONSISTENT;
975 return (rv);
982 * Build a Public Key Object.
984 * - Parse the object's template, and when an error is detected such as
985 * invalid attribute type, invalid attribute value, etc., return
986 * with appropriate return value.
987 * - Set up attribute mask field in the object for the supplied common
988 * attributes that have boolean type.
989 * - Build the attribute_info struct to hold the value of each supplied
990 * attribute that has byte array type. Link attribute_info structs
991 * together to form the extra attribute list of the object.
992 * - Allocate storage for the Public Key object.
993 * - Build the Public Key object according to the key type. Allocate
994 * storage to hold the big integer value for the supplied attributes
995 * that are required for a certain key type.
998 CK_RV
999 kernel_build_public_key_object(CK_ATTRIBUTE_PTR template,
1000 CK_ULONG ulAttrNum, kernel_object_t *new_object, kernel_session_t *sp,
1001 uint_t mode)
1004 int i;
1005 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1006 uint64_t attr_mask = PUBLIC_KEY_DEFAULT;
1007 CK_RV rv = CKR_OK;
1008 int isLabel = 0;
1009 /* Must set flags */
1010 int isModulus = 0;
1011 int isPubExpo = 0;
1012 int isPrime = 0;
1013 int isSubprime = 0;
1014 int isBase = 0;
1015 int isValue = 0;
1016 int isPoint = 0;
1017 int isParams = 0;
1018 /* Must not set flags */
1019 int isModulusBits = 0;
1020 CK_ULONG modulus_bits = 0;
1022 biginteger_t modulus;
1023 biginteger_t pubexpo;
1024 biginteger_t prime;
1025 biginteger_t subprime;
1026 biginteger_t base;
1027 biginteger_t value;
1028 biginteger_t point;
1029 CK_ATTRIBUTE string_tmp;
1030 CK_ATTRIBUTE param_tmp;
1032 public_key_obj_t *pbk;
1034 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1035 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1036 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1037 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1038 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1039 (void) memset(&base, 0x0, sizeof (biginteger_t));
1040 (void) memset(&value, 0x0, sizeof (biginteger_t));
1041 (void) memset(&point, 0x0, sizeof (biginteger_t));
1042 string_tmp.pValue = NULL;
1043 param_tmp.pValue = NULL;
1045 for (i = 0; i < ulAttrNum; i++) {
1047 /* Public Key Object Attributes */
1048 switch (template[i].type) {
1050 /* common key attributes */
1051 case CKA_KEY_TYPE:
1052 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1053 break;
1055 case CKA_ID:
1056 case CKA_START_DATE:
1057 case CKA_END_DATE:
1059 /* common public key attribute */
1060 case CKA_SUBJECT:
1062 * Allocate storage to hold the attribute
1063 * value with byte array type, and add it to
1064 * the extra attribute list of the object.
1066 rv = kernel_add_extra_attr(&template[i],
1067 new_object);
1068 if (rv != CKR_OK) {
1069 goto fail_cleanup;
1071 break;
1074 * The following key related attribute types must
1075 * not be specified by C_CreateObject.
1077 case CKA_LOCAL:
1078 case CKA_KEY_GEN_MECHANISM:
1079 rv = CKR_TEMPLATE_INCONSISTENT;
1080 goto fail_cleanup;
1082 /* Key related boolean attributes */
1083 case CKA_DERIVE:
1084 if (*(CK_BBOOL *)template[i].pValue)
1085 attr_mask |= DERIVE_BOOL_ON;
1086 break;
1088 case CKA_ENCRYPT:
1089 if (*(CK_BBOOL *)template[i].pValue)
1090 attr_mask |= ENCRYPT_BOOL_ON;
1091 else
1092 attr_mask &= ~ENCRYPT_BOOL_ON;
1093 break;
1095 case CKA_VERIFY:
1096 if (*(CK_BBOOL *)template[i].pValue)
1097 attr_mask |= VERIFY_BOOL_ON;
1098 else
1099 attr_mask &= ~VERIFY_BOOL_ON;
1100 break;
1102 case CKA_VERIFY_RECOVER:
1103 if (*(CK_BBOOL *)template[i].pValue)
1104 attr_mask |= VERIFY_RECOVER_BOOL_ON;
1105 else
1106 attr_mask &= ~VERIFY_RECOVER_BOOL_ON;
1107 break;
1109 case CKA_WRAP:
1110 if (*(CK_BBOOL *)template[i].pValue)
1111 attr_mask |= WRAP_BOOL_ON;
1112 break;
1114 case CKA_TRUSTED:
1115 if (*(CK_BBOOL *)template[i].pValue)
1116 attr_mask |= TRUSTED_BOOL_ON;
1117 break;
1120 * The following key related attribute types must
1121 * be specified according to the key type by
1122 * C_CreateObject.
1124 case CKA_MODULUS:
1125 isModulus = 1;
1127 * Copyin big integer attribute from template
1128 * to a local variable.
1130 rv = get_bigint_attr_from_template(&modulus,
1131 &template[i]);
1132 if (rv != CKR_OK)
1133 goto fail_cleanup;
1134 break;
1136 case CKA_PUBLIC_EXPONENT:
1137 isPubExpo = 1;
1138 rv = get_bigint_attr_from_template(&pubexpo,
1139 &template[i]);
1140 if (rv != CKR_OK)
1141 goto fail_cleanup;
1142 break;
1144 case CKA_PRIME:
1145 isPrime = 1;
1146 rv = get_bigint_attr_from_template(&prime,
1147 &template[i]);
1148 if (rv != CKR_OK)
1149 goto fail_cleanup;
1150 break;
1152 case CKA_SUBPRIME:
1153 isSubprime = 1;
1154 rv = get_bigint_attr_from_template(&subprime,
1155 &template[i]);
1156 if (rv != CKR_OK)
1157 goto fail_cleanup;
1158 break;
1160 case CKA_BASE:
1161 isBase = 1;
1162 rv = get_bigint_attr_from_template(&base,
1163 &template[i]);
1164 if (rv != CKR_OK)
1165 goto fail_cleanup;
1166 break;
1168 case CKA_VALUE:
1169 isValue = 1;
1170 rv = get_bigint_attr_from_template(&value,
1171 &template[i]);
1172 if (rv != CKR_OK)
1173 goto fail_cleanup;
1174 break;
1176 case CKA_MODULUS_BITS:
1177 isModulusBits = 1;
1178 get_ulong_attr_from_template(&modulus_bits,
1179 &template[i]);
1180 break;
1182 case CKA_LABEL:
1183 isLabel = 1;
1184 rv = get_string_from_template(&string_tmp,
1185 &template[i]);
1186 if (rv != CKR_OK)
1187 goto fail_cleanup;
1188 break;
1190 case CKA_EC_POINT:
1191 isPoint = 1;
1192 rv = get_bigint_attr_from_template(&point,
1193 &template[i]);
1194 if (rv != CKR_OK)
1195 goto fail_cleanup;
1196 break;
1198 case CKA_EC_PARAMS:
1199 isParams = 1;
1200 rv = get_string_from_template(&param_tmp,
1201 &template[i]);
1202 if (rv != CKR_OK)
1203 goto fail_cleanup;
1204 break;
1206 default:
1207 rv = kernel_parse_common_attrs(&template[i], sp,
1208 &attr_mask);
1209 if (rv != CKR_OK)
1210 goto fail_cleanup;
1211 break;
1213 } /* For */
1215 /* Allocate storage for Public Key Object. */
1216 pbk = calloc(1, sizeof (public_key_obj_t));
1217 if (pbk == NULL) {
1218 rv = CKR_HOST_MEMORY;
1219 goto fail_cleanup;
1222 new_object->object_class_u.public_key = pbk;
1223 new_object->class = CKO_PUBLIC_KEY;
1225 if (keytype == (CK_KEY_TYPE)~0UL) {
1226 rv = CKR_TEMPLATE_INCOMPLETE;
1227 goto fail_cleanup;
1229 new_object->key_type = keytype;
1231 /* Supported key types of the Public Key Object */
1232 switch (keytype) {
1233 case CKK_RSA:
1234 if (mode == KERNEL_CREATE_OBJ) {
1235 if (isModulusBits || isPrime || isSubprime ||
1236 isBase|| isValue) {
1237 rv = CKR_TEMPLATE_INCONSISTENT;
1238 goto fail_cleanup;
1242 if (isModulus && isPubExpo) {
1244 * Copy big integer attribute value to the
1245 * designated place in the public key object.
1247 copy_bigint_attr(&modulus,
1248 KEY_PUB_RSA_MOD(pbk));
1250 copy_bigint_attr(&pubexpo,
1251 KEY_PUB_RSA_PUBEXPO(pbk));
1252 } else {
1253 rv = CKR_TEMPLATE_INCOMPLETE;
1254 goto fail_cleanup;
1257 /* must be generating a RSA key pair by value */
1258 if (isModulusBits) {
1259 KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits;
1261 break;
1263 case CKK_DSA:
1264 if (isModulusBits || isModulus || isPubExpo) {
1265 rv = CKR_TEMPLATE_INCONSISTENT;
1266 goto fail_cleanup;
1269 if (!(isPrime && isSubprime && isBase && isValue)) {
1270 rv = CKR_TEMPLATE_INCOMPLETE;
1271 goto fail_cleanup;
1274 copy_bigint_attr(&prime, KEY_PUB_DSA_PRIME(pbk));
1276 copy_bigint_attr(&subprime, KEY_PUB_DSA_SUBPRIME(pbk));
1278 copy_bigint_attr(&base, KEY_PUB_DSA_BASE(pbk));
1280 copy_bigint_attr(&value, KEY_PUB_DSA_VALUE(pbk));
1282 break;
1284 case CKK_DH:
1285 if (!(isPrime && isBase && isValue)) {
1286 rv = CKR_TEMPLATE_INCOMPLETE;
1287 goto fail_cleanup;
1290 copy_bigint_attr(&prime, KEY_PUB_DH_PRIME(pbk));
1292 copy_bigint_attr(&base, KEY_PUB_DH_BASE(pbk));
1294 copy_bigint_attr(&value, KEY_PUB_DH_VALUE(pbk));
1296 break;
1298 case CKK_EC:
1299 if (!isPoint || !isParams) {
1300 rv = CKR_TEMPLATE_INCOMPLETE;
1301 goto fail_cleanup;
1304 copy_bigint_attr(&point, KEY_PUB_EC_POINT(pbk));
1305 rv = kernel_add_extra_attr(&param_tmp, new_object);
1306 if (rv != CKR_OK)
1307 goto fail_cleanup;
1308 string_attr_cleanup(&param_tmp);
1309 break;
1310 default:
1311 rv = CKR_TEMPLATE_INCONSISTENT;
1312 goto fail_cleanup;
1315 /* Set up object. */
1316 new_object->bool_attr_mask = attr_mask;
1317 if (isLabel) {
1318 rv = kernel_add_extra_attr(&string_tmp, new_object);
1319 if (rv != CKR_OK)
1320 goto fail_cleanup;
1321 string_attr_cleanup(&string_tmp);
1324 return (rv);
1326 fail_cleanup:
1328 * cleanup the storage allocated to the local variables.
1330 bigint_attr_cleanup(&modulus);
1331 bigint_attr_cleanup(&pubexpo);
1332 bigint_attr_cleanup(&prime);
1333 bigint_attr_cleanup(&subprime);
1334 bigint_attr_cleanup(&base);
1335 bigint_attr_cleanup(&value);
1336 bigint_attr_cleanup(&point);
1337 string_attr_cleanup(&string_tmp);
1338 string_attr_cleanup(&param_tmp);
1341 * cleanup the storage allocated inside the object itself.
1343 kernel_cleanup_object(new_object);
1345 return (rv);
1350 * Build a Private Key Object.
1352 * - Parse the object's template, and when an error is detected such as
1353 * invalid attribute type, invalid attribute value, etc., return
1354 * with appropriate return value.
1355 * - Set up attribute mask field in the object for the supplied common
1356 * attributes that have boolean type.
1357 * - Build the attribute_info struct to hold the value of each supplied
1358 * attribute that has byte array type. Link attribute_info structs
1359 * together to form the extra attribute list of the object.
1360 * - Allocate storage for the Private Key object.
1361 * - Build the Private Key object according to the key type. Allocate
1362 * storage to hold the big integer value for the supplied attributes
1363 * that are required for a certain key type.
1366 CK_RV
1367 kernel_build_private_key_object(CK_ATTRIBUTE_PTR template,
1368 CK_ULONG ulAttrNum, kernel_object_t *new_object, kernel_session_t *sp,
1369 uint_t mode)
1371 ulong_t i;
1372 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1373 uint64_t attr_mask = PRIVATE_KEY_DEFAULT;
1374 CK_RV rv = CKR_OK;
1375 int isLabel = 0;
1376 /* Must set flags */
1377 int isModulus = 0;
1378 int isPriExpo = 0;
1379 int isPrime = 0;
1380 int isSubprime = 0;
1381 int isBase = 0;
1382 int isValue = 0;
1383 int isParams = 0;
1384 /* Must not set flags */
1385 int isValueBits = 0;
1386 CK_ULONG value_bits = 0;
1388 /* Private Key RSA optional */
1389 int isPubExpo = 0;
1390 int isPrime1 = 0;
1391 int isPrime2 = 0;
1392 int isExpo1 = 0;
1393 int isExpo2 = 0;
1394 int isCoef = 0;
1396 biginteger_t modulus;
1397 biginteger_t priexpo;
1398 biginteger_t prime;
1399 biginteger_t subprime;
1400 biginteger_t base;
1401 biginteger_t value;
1403 biginteger_t pubexpo;
1404 biginteger_t prime1;
1405 biginteger_t prime2;
1406 biginteger_t expo1;
1407 biginteger_t expo2;
1408 biginteger_t coef;
1409 CK_ATTRIBUTE string_tmp;
1410 CK_ATTRIBUTE param_tmp;
1412 private_key_obj_t *pvk;
1414 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1415 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1416 (void) memset(&priexpo, 0x0, sizeof (biginteger_t));
1417 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1418 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1419 (void) memset(&base, 0x0, sizeof (biginteger_t));
1420 (void) memset(&value, 0x0, sizeof (biginteger_t));
1421 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1422 (void) memset(&prime1, 0x0, sizeof (biginteger_t));
1423 (void) memset(&prime2, 0x0, sizeof (biginteger_t));
1424 (void) memset(&expo1, 0x0, sizeof (biginteger_t));
1425 (void) memset(&expo2, 0x0, sizeof (biginteger_t));
1426 (void) memset(&coef, 0x0, sizeof (biginteger_t));
1427 string_tmp.pValue = NULL;
1428 param_tmp.pValue = NULL;
1430 for (i = 0; i < ulAttrNum; i++) {
1432 /* Private Key Object Attributes */
1433 switch (template[i].type) {
1435 /* common key attributes */
1436 case CKA_KEY_TYPE:
1437 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1438 break;
1440 case CKA_ID:
1441 case CKA_START_DATE:
1442 case CKA_END_DATE:
1444 /* common private key attribute */
1445 case CKA_SUBJECT:
1447 * Allocate storage to hold the attribute
1448 * value with byte array type, and add it to
1449 * the extra attribute list of the object.
1451 rv = kernel_add_extra_attr(&template[i],
1452 new_object);
1453 if (rv != CKR_OK) {
1454 goto fail_cleanup;
1456 break;
1459 * The following key related attribute types must
1460 * not be specified by C_CreateObject.
1462 case CKA_LOCAL:
1463 case CKA_KEY_GEN_MECHANISM:
1464 case CKA_AUTH_PIN_FLAGS:
1465 case CKA_ALWAYS_SENSITIVE:
1466 case CKA_NEVER_EXTRACTABLE:
1467 rv = CKR_TEMPLATE_INCONSISTENT;
1468 goto fail_cleanup;
1470 /* Key related boolean attributes */
1471 case CKA_DERIVE:
1472 if (*(CK_BBOOL *)template[i].pValue)
1473 attr_mask |= DERIVE_BOOL_ON;
1474 break;
1476 case CKA_SENSITIVE:
1477 if (*(CK_BBOOL *)template[i].pValue)
1478 attr_mask |= SENSITIVE_BOOL_ON;
1479 break;
1481 case CKA_SECONDARY_AUTH:
1482 if (*(CK_BBOOL *)template[i].pValue) {
1483 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1484 goto fail_cleanup;
1486 break;
1488 case CKA_DECRYPT:
1489 if (*(CK_BBOOL *)template[i].pValue)
1490 attr_mask |= DECRYPT_BOOL_ON;
1491 else
1492 attr_mask &= ~DECRYPT_BOOL_ON;
1493 break;
1495 case CKA_SIGN:
1496 if (*(CK_BBOOL *)template[i].pValue)
1497 attr_mask |= SIGN_BOOL_ON;
1498 else
1499 attr_mask &= ~SIGN_BOOL_ON;
1500 break;
1502 case CKA_SIGN_RECOVER:
1503 if (*(CK_BBOOL *)template[i].pValue)
1504 attr_mask |= SIGN_RECOVER_BOOL_ON;
1505 else
1506 attr_mask &= ~SIGN_RECOVER_BOOL_ON;
1507 break;
1509 case CKA_UNWRAP:
1510 if (*(CK_BBOOL *)template[i].pValue)
1511 attr_mask |= UNWRAP_BOOL_ON;
1512 break;
1514 case CKA_EXTRACTABLE:
1515 if (*(CK_BBOOL *)template[i].pValue)
1516 attr_mask |= EXTRACTABLE_BOOL_ON;
1517 else
1518 attr_mask &= ~EXTRACTABLE_BOOL_ON;
1519 break;
1522 * The following key related attribute types must
1523 * be specified according to the key type by
1524 * C_CreateObject.
1526 case CKA_MODULUS:
1527 isModulus = 1;
1529 * Copyin big integer attribute from template
1530 * to a local variable.
1532 rv = get_bigint_attr_from_template(&modulus,
1533 &template[i]);
1534 if (rv != CKR_OK)
1535 goto fail_cleanup;
1536 break;
1538 case CKA_PUBLIC_EXPONENT:
1539 isPubExpo = 1;
1540 rv = get_bigint_attr_from_template(&pubexpo,
1541 &template[i]);
1542 if (rv != CKR_OK)
1543 goto fail_cleanup;
1544 break;
1546 case CKA_PRIVATE_EXPONENT:
1547 isPriExpo = 1;
1548 rv = get_bigint_attr_from_template(&priexpo,
1549 &template[i]);
1550 if (rv != CKR_OK)
1551 goto fail_cleanup;
1552 break;
1554 case CKA_PRIME_1:
1555 isPrime1 = 1;
1556 rv = get_bigint_attr_from_template(&prime1,
1557 &template[i]);
1558 if (rv != CKR_OK)
1559 goto fail_cleanup;
1560 break;
1562 case CKA_PRIME_2:
1563 isPrime2 = 1;
1564 rv = get_bigint_attr_from_template(&prime2,
1565 &template[i]);
1566 if (rv != CKR_OK)
1567 goto fail_cleanup;
1568 break;
1570 case CKA_EXPONENT_1:
1571 isExpo1 = 1;
1572 rv = get_bigint_attr_from_template(&expo1,
1573 &template[i]);
1574 if (rv != CKR_OK)
1575 goto fail_cleanup;
1576 break;
1578 case CKA_EXPONENT_2:
1579 isExpo2 = 1;
1580 rv = get_bigint_attr_from_template(&expo2,
1581 &template[i]);
1582 if (rv != CKR_OK)
1583 goto fail_cleanup;
1584 break;
1586 case CKA_COEFFICIENT:
1587 isCoef = 1;
1588 rv = get_bigint_attr_from_template(&coef,
1589 &template[i]);
1590 if (rv != CKR_OK)
1591 goto fail_cleanup;
1592 break;
1594 case CKA_PRIME:
1595 isPrime = 1;
1596 rv = get_bigint_attr_from_template(&prime,
1597 &template[i]);
1598 if (rv != CKR_OK)
1599 goto fail_cleanup;
1600 break;
1602 case CKA_SUBPRIME:
1603 isSubprime = 1;
1604 rv = get_bigint_attr_from_template(&subprime,
1605 &template[i]);
1606 if (rv != CKR_OK)
1607 goto fail_cleanup;
1608 break;
1610 case CKA_BASE:
1611 isBase = 1;
1612 rv = get_bigint_attr_from_template(&base,
1613 &template[i]);
1614 if (rv != CKR_OK)
1615 goto fail_cleanup;
1616 break;
1618 case CKA_VALUE:
1619 isValue = 1;
1620 rv = get_bigint_attr_from_template(&value,
1621 &template[i]);
1622 if (rv != CKR_OK)
1623 goto fail_cleanup;
1624 break;
1626 case CKA_VALUE_BITS:
1627 isValueBits = 1;
1628 get_ulong_attr_from_template(&value_bits,
1629 &template[i]);
1630 break;
1632 case CKA_LABEL:
1633 isLabel = 1;
1634 rv = get_string_from_template(&string_tmp,
1635 &template[i]);
1636 if (rv != CKR_OK)
1637 goto fail_cleanup;
1638 break;
1640 case CKA_EC_PARAMS:
1641 isParams = 1;
1642 rv = get_string_from_template(&param_tmp,
1643 &template[i]);
1644 if (rv != CKR_OK)
1645 goto fail_cleanup;
1646 break;
1648 default:
1649 rv = kernel_parse_common_attrs(&template[i], sp,
1650 &attr_mask);
1651 if (rv != CKR_OK)
1652 goto fail_cleanup;
1653 break;
1656 } /* For */
1658 /* Allocate storage for Private Key Object. */
1659 pvk = calloc(1, sizeof (private_key_obj_t));
1660 if (pvk == NULL) {
1661 rv = CKR_HOST_MEMORY;
1662 goto fail_cleanup;
1665 new_object->object_class_u.private_key = pvk;
1666 new_object->class = CKO_PRIVATE_KEY;
1668 if (keytype == (CK_KEY_TYPE)~0UL) {
1669 rv = CKR_TEMPLATE_INCOMPLETE;
1670 goto fail_cleanup;
1673 new_object->key_type = keytype;
1675 /* Supported key types of the Private Key Object */
1676 switch (keytype) {
1677 case CKK_RSA:
1678 if (isPrime || isSubprime || isBase || isValue ||
1679 isValueBits) {
1680 rv = CKR_TEMPLATE_INCONSISTENT;
1681 goto fail_cleanup;
1684 if (isModulus && isPriExpo) {
1686 * Copy big integer attribute value to the
1687 * designated place in the Private Key object.
1689 copy_bigint_attr(&modulus, KEY_PRI_RSA_MOD(pvk));
1691 copy_bigint_attr(&priexpo, KEY_PRI_RSA_PRIEXPO(pvk));
1693 } else {
1694 rv = CKR_TEMPLATE_INCOMPLETE;
1695 goto fail_cleanup;
1698 /* The following attributes are optional. */
1699 if (isPubExpo) {
1700 copy_bigint_attr(&pubexpo, KEY_PRI_RSA_PUBEXPO(pvk));
1703 if (isPrime1) {
1704 copy_bigint_attr(&prime1, KEY_PRI_RSA_PRIME1(pvk));
1707 if (isPrime2) {
1708 copy_bigint_attr(&prime2, KEY_PRI_RSA_PRIME2(pvk));
1711 if (isExpo1) {
1712 copy_bigint_attr(&expo1, KEY_PRI_RSA_EXPO1(pvk));
1715 if (isExpo2) {
1716 copy_bigint_attr(&expo2, KEY_PRI_RSA_EXPO2(pvk));
1719 if (isCoef) {
1720 copy_bigint_attr(&coef, KEY_PRI_RSA_COEF(pvk));
1722 break;
1724 case CKK_DSA:
1725 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
1726 isPrime2 || isExpo1 || isExpo2 || isCoef ||
1727 isValueBits) {
1728 rv = CKR_TEMPLATE_INCONSISTENT;
1729 goto fail_cleanup;
1732 if (!(isPrime && isSubprime && isBase && isValue)) {
1733 rv = CKR_TEMPLATE_INCOMPLETE;
1734 goto fail_cleanup;
1737 copy_bigint_attr(&prime, KEY_PRI_DSA_PRIME(pvk));
1739 copy_bigint_attr(&subprime, KEY_PRI_DSA_SUBPRIME(pvk));
1741 copy_bigint_attr(&base, KEY_PRI_DSA_BASE(pvk));
1743 copy_bigint_attr(&value, KEY_PRI_DSA_VALUE(pvk));
1745 break;
1747 case CKK_DH:
1748 if (mode == KERNEL_CREATE_OBJ && isValueBits) {
1749 rv = CKR_TEMPLATE_INCONSISTENT;
1750 goto fail_cleanup;
1752 if (!(isPrime && isBase && isValue)) {
1753 rv = CKR_TEMPLATE_INCOMPLETE;
1754 goto fail_cleanup;
1757 copy_bigint_attr(&prime, KEY_PRI_DH_PRIME(pvk));
1759 copy_bigint_attr(&base, KEY_PRI_DH_BASE(pvk));
1761 copy_bigint_attr(&value, KEY_PRI_DH_VALUE(pvk));
1763 KEY_PRI_DH_VAL_BITS(pvk) = (isValueBits) ? value_bits : 0;
1765 break;
1767 case CKK_EC:
1768 if (!isValue || !isParams) {
1769 rv = CKR_TEMPLATE_INCOMPLETE;
1770 goto fail_cleanup;
1773 copy_bigint_attr(&value, KEY_PRI_EC_VALUE(pvk));
1774 rv = kernel_add_extra_attr(&param_tmp, new_object);
1775 if (rv != CKR_OK)
1776 goto fail_cleanup;
1777 string_attr_cleanup(&param_tmp);
1778 break;
1779 default:
1780 rv = CKR_TEMPLATE_INCONSISTENT;
1781 goto fail_cleanup;
1784 /* Set up object. */
1785 new_object->bool_attr_mask = attr_mask;
1786 if (isLabel) {
1787 rv = kernel_add_extra_attr(&string_tmp, new_object);
1788 if (rv != CKR_OK)
1789 goto fail_cleanup;
1790 string_attr_cleanup(&string_tmp);
1793 return (rv);
1795 fail_cleanup:
1797 * cleanup the storage allocated to the local variables.
1799 bigint_attr_cleanup(&modulus);
1800 bigint_attr_cleanup(&priexpo);
1801 bigint_attr_cleanup(&prime);
1802 bigint_attr_cleanup(&subprime);
1803 bigint_attr_cleanup(&base);
1804 bigint_attr_cleanup(&value);
1805 bigint_attr_cleanup(&pubexpo);
1806 bigint_attr_cleanup(&prime1);
1807 bigint_attr_cleanup(&prime2);
1808 bigint_attr_cleanup(&expo1);
1809 bigint_attr_cleanup(&expo2);
1810 bigint_attr_cleanup(&coef);
1811 string_attr_cleanup(&string_tmp);
1812 string_attr_cleanup(&param_tmp);
1815 * cleanup the storage allocated inside the object itself.
1817 kernel_cleanup_object(new_object);
1819 return (rv);
1824 * Build a Secret Key Object.
1826 * - Parse the object's template, and when an error is detected such as
1827 * invalid attribute type, invalid attribute value, etc., return
1828 * with appropriate return value.
1829 * - Set up attribute mask field in the object for the supplied common
1830 * attributes that have boolean type.
1831 * - Build the attribute_info struct to hold the value of each supplied
1832 * attribute that has byte array type. Link attribute_info structs
1833 * together to form the extra attribute list of the object.
1834 * - Allocate storage for the Secret Key object.
1835 * - Build the Secret Key object. Allocate storage to hold the big integer
1836 * value for the attribute CKA_VALUE that is required for all the key
1837 * types supported by secret key object.
1840 CK_RV
1841 kernel_build_secret_key_object(CK_ATTRIBUTE_PTR template,
1842 CK_ULONG ulAttrNum, kernel_object_t *new_object, kernel_session_t *sp)
1845 int i;
1846 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1847 uint64_t attr_mask = SECRET_KEY_DEFAULT;
1848 CK_RV rv = CKR_OK;
1849 int isLabel = 0;
1850 /* Must set flags */
1851 int isValue = 0;
1852 /* Must not set flags */
1853 int isValueLen = 0;
1855 CK_ATTRIBUTE string_tmp;
1857 secret_key_obj_t *sck;
1859 string_tmp.pValue = NULL;
1861 /* Allocate storage for Secret Key Object. */
1862 sck = calloc(1, sizeof (secret_key_obj_t));
1863 if (sck == NULL) {
1864 rv = CKR_HOST_MEMORY;
1865 goto fail_cleanup;
1868 new_object->object_class_u.secret_key = sck;
1869 new_object->class = CKO_SECRET_KEY;
1871 for (i = 0; i < ulAttrNum; i++) {
1873 /* Secret Key Object Attributes */
1874 switch (template[i].type) {
1876 /* common key attributes */
1877 case CKA_KEY_TYPE:
1878 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1879 break;
1881 case CKA_ID:
1882 case CKA_START_DATE:
1883 case CKA_END_DATE:
1885 * Allocate storage to hold the attribute
1886 * value with byte array type, and add it to
1887 * the extra attribute list of the object.
1889 rv = kernel_add_extra_attr(&template[i],
1890 new_object);
1891 if (rv != CKR_OK) {
1892 goto fail_cleanup;
1894 break;
1897 * The following key related attribute types must
1898 * not be specified by C_CreateObject.
1900 case CKA_LOCAL:
1901 case CKA_KEY_GEN_MECHANISM:
1902 case CKA_ALWAYS_SENSITIVE:
1903 case CKA_NEVER_EXTRACTABLE:
1904 rv = CKR_TEMPLATE_INCONSISTENT;
1905 goto fail_cleanup;
1907 /* Key related boolean attributes */
1908 case CKA_DERIVE:
1909 if (*(CK_BBOOL *)template[i].pValue)
1910 attr_mask |= DERIVE_BOOL_ON;
1911 break;
1913 case CKA_SENSITIVE:
1914 if (*(CK_BBOOL *)template[i].pValue)
1915 attr_mask |= SENSITIVE_BOOL_ON;
1916 break;
1918 case CKA_ENCRYPT:
1919 if (*(CK_BBOOL *)template[i].pValue)
1920 attr_mask |= ENCRYPT_BOOL_ON;
1921 else
1922 attr_mask &= ~ENCRYPT_BOOL_ON;
1923 break;
1925 case CKA_DECRYPT:
1926 if (*(CK_BBOOL *)template[i].pValue)
1927 attr_mask |= DECRYPT_BOOL_ON;
1928 else
1929 attr_mask &= ~DECRYPT_BOOL_ON;
1930 break;
1932 case CKA_SIGN:
1933 if (*(CK_BBOOL *)template[i].pValue)
1934 attr_mask |= SIGN_BOOL_ON;
1935 else
1936 attr_mask &= ~SIGN_BOOL_ON;
1937 break;
1939 case CKA_VERIFY:
1940 if (*(CK_BBOOL *)template[i].pValue)
1941 attr_mask |= VERIFY_BOOL_ON;
1942 else
1943 attr_mask &= ~VERIFY_BOOL_ON;
1944 break;
1946 case CKA_WRAP:
1947 if (*(CK_BBOOL *)template[i].pValue)
1948 attr_mask |= WRAP_BOOL_ON;
1949 break;
1951 case CKA_UNWRAP:
1952 if (*(CK_BBOOL *)template[i].pValue)
1953 attr_mask |= UNWRAP_BOOL_ON;
1954 break;
1956 case CKA_EXTRACTABLE:
1957 if (*(CK_BBOOL *)template[i].pValue)
1958 attr_mask |= EXTRACTABLE_BOOL_ON;
1959 else
1960 attr_mask &= ~EXTRACTABLE_BOOL_ON;
1961 break;
1963 case CKA_VALUE:
1964 isValue = 1;
1965 if ((template[i].ulValueLen == 0) ||
1966 (template[i].pValue == NULL)) {
1967 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1968 goto fail_cleanup;
1972 * Copyin attribute from template
1973 * to a local variable.
1975 sck->sk_value = malloc(template[i].ulValueLen);
1976 if (sck->sk_value == NULL) {
1977 rv = CKR_HOST_MEMORY;
1978 goto fail_cleanup;
1980 (void) memcpy(sck->sk_value, template[i].pValue,
1981 template[i].ulValueLen);
1982 sck->sk_value_len = template[i].ulValueLen;
1983 break;
1985 case CKA_VALUE_LEN:
1986 isValueLen = 1;
1987 break;
1989 case CKA_LABEL:
1990 isLabel = 1;
1991 rv = get_string_from_template(&string_tmp,
1992 &template[i]);
1993 if (rv != CKR_OK)
1994 goto fail_cleanup;
1995 break;
1997 default:
1998 rv = kernel_parse_common_attrs(&template[i], sp,
1999 &attr_mask);
2000 if (rv != CKR_OK)
2001 goto fail_cleanup;
2002 break;
2005 } /* For */
2007 if (keytype == (CK_KEY_TYPE)~0UL) {
2008 rv = CKR_TEMPLATE_INCOMPLETE;
2009 goto fail_cleanup;
2012 new_object->key_type = keytype;
2014 /* Supported key types of the Secret Key Object */
2015 switch (keytype) {
2016 case CKK_RC4:
2017 if (!isValue) {
2018 rv = CKR_TEMPLATE_INCOMPLETE;
2019 goto fail_cleanup;
2021 if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) ||
2022 (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) {
2023 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2024 goto fail_cleanup;
2026 break;
2028 case CKK_GENERIC_SECRET:
2029 if (!isValue) {
2030 rv = CKR_TEMPLATE_INCOMPLETE;
2031 goto fail_cleanup;
2033 break;
2035 case CKK_AES:
2036 if (!isValue) {
2037 rv = CKR_TEMPLATE_INCOMPLETE;
2038 goto fail_cleanup;
2040 if (sck->sk_value_len < AES_MIN_KEY_BYTES) {
2041 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2042 goto fail_cleanup;
2044 break;
2046 case CKK_BLOWFISH:
2047 if (!isValue) {
2048 rv = CKR_TEMPLATE_INCOMPLETE;
2049 goto fail_cleanup;
2051 if (sck->sk_value_len < BLOWFISH_MINBYTES) {
2052 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2053 goto fail_cleanup;
2055 break;
2057 case CKK_DES:
2058 if (!isValue) {
2059 rv = CKR_TEMPLATE_INCOMPLETE;
2060 goto fail_cleanup;
2062 if (sck->sk_value_len != DES_KEYSIZE) {
2063 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2064 goto fail_cleanup;
2066 break;
2068 case CKK_DES2:
2069 if (!isValue) {
2070 rv = CKR_TEMPLATE_INCOMPLETE;
2071 goto fail_cleanup;
2073 if (sck->sk_value_len != DES2_KEYSIZE) {
2074 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2075 goto fail_cleanup;
2077 break;
2079 case CKK_DES3:
2080 if (!isValue) {
2081 rv = CKR_TEMPLATE_INCOMPLETE;
2082 goto fail_cleanup;
2084 if (sck->sk_value_len != DES3_KEYSIZE) {
2085 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2086 goto fail_cleanup;
2088 break;
2090 default:
2091 rv = CKR_TEMPLATE_INCONSISTENT;
2092 goto fail_cleanup;
2095 if (isValueLen) {
2096 rv = CKR_TEMPLATE_INCONSISTENT;
2097 goto fail_cleanup;
2100 /* Set up object. */
2101 new_object->bool_attr_mask = attr_mask;
2102 if (isLabel) {
2103 rv = kernel_add_extra_attr(&string_tmp, new_object);
2104 if (rv != CKR_OK)
2105 goto fail_cleanup;
2106 string_attr_cleanup(&string_tmp);
2109 return (rv);
2111 fail_cleanup:
2113 * cleanup the storage allocated to the local variables.
2115 string_attr_cleanup(&string_tmp);
2118 * cleanup the storage allocated inside the object itself.
2120 kernel_cleanup_object(new_object);
2122 return (rv);
2127 * Validate the attribute types in the object's template. Then,
2128 * call the appropriate build function according to the class of
2129 * the object specified in the template.
2131 * Note: The following classes of objects are supported:
2132 * - CKO_SECRET_KEY
2133 * - CKO_PUBLIC_KEY
2134 * - CKO_PRIVATE_KEY
2136 CK_RV
2137 kernel_build_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
2138 kernel_object_t *new_object, kernel_session_t *sp, uint_t mode)
2141 CK_OBJECT_CLASS class = (CK_OBJECT_CLASS)~0UL;
2142 CK_RV rv = CKR_OK;
2144 if (template == NULL) {
2145 return (CKR_ARGUMENTS_BAD);
2148 /* Validate the attribute type in the template. */
2149 rv = kernel_validate_attr(template, ulAttrNum, &class);
2150 if (rv != CKR_OK)
2151 return (rv);
2153 if (class == (CK_OBJECT_CLASS)~0UL)
2154 return (CKR_TEMPLATE_INCOMPLETE);
2157 * Call the appropriate function based on the supported class
2158 * of the object.
2160 switch (class) {
2161 case CKO_PUBLIC_KEY:
2162 rv = kernel_build_public_key_object(template, ulAttrNum,
2163 new_object, sp, mode);
2164 break;
2166 case CKO_PRIVATE_KEY:
2167 rv = kernel_build_private_key_object(template, ulAttrNum,
2168 new_object, sp, mode);
2169 break;
2171 case CKO_SECRET_KEY:
2172 rv = kernel_build_secret_key_object(template, ulAttrNum,
2173 new_object, sp);
2174 break;
2176 case CKO_DOMAIN_PARAMETERS:
2177 case CKO_DATA:
2178 case CKO_CERTIFICATE:
2179 case CKO_HW_FEATURE:
2180 case CKO_VENDOR_DEFINED:
2181 default:
2182 return (CKR_ATTRIBUTE_VALUE_INVALID);
2185 return (rv);
2190 * Get the value of a requested attribute that is common to all supported
2191 * classes (i.e. public key, private key, secret key classes).
2193 CK_RV
2194 kernel_get_common_attrs(kernel_object_t *object_p, CK_ATTRIBUTE_PTR template)
2197 CK_RV rv = CKR_OK;
2199 switch (template->type) {
2201 case CKA_CLASS:
2202 return (get_ulong_attr_from_object(object_p->class,
2203 template));
2205 /* default boolean attributes */
2206 case CKA_TOKEN:
2208 template->ulValueLen = sizeof (CK_BBOOL);
2209 if (template->pValue == NULL) {
2210 return (CKR_OK);
2214 * A token object will not be created in the library, so we
2215 * return FALSE.
2217 *((CK_BBOOL *)template->pValue) = B_FALSE;
2218 break;
2220 case CKA_PRIVATE:
2222 template->ulValueLen = sizeof (CK_BBOOL);
2223 if (template->pValue == NULL) {
2224 return (CKR_OK);
2226 if (object_p->bool_attr_mask & PRIVATE_BOOL_ON) {
2227 *((CK_BBOOL *)template->pValue) = B_TRUE;
2228 } else {
2229 *((CK_BBOOL *)template->pValue) = B_FALSE;
2231 break;
2233 case CKA_MODIFIABLE:
2234 template->ulValueLen = sizeof (CK_BBOOL);
2235 if (template->pValue == NULL) {
2236 return (CKR_OK);
2238 if ((object_p->bool_attr_mask) & MODIFIABLE_BOOL_ON)
2239 *((CK_BBOOL *)template->pValue) = B_TRUE;
2240 else
2241 *((CK_BBOOL *)template->pValue) = B_FALSE;
2242 break;
2244 case CKA_LABEL:
2245 return (get_extra_attr_from_object(object_p,
2246 template));
2248 default:
2250 * The specified attribute for the object is invalid.
2251 * (the object does not possess such an attribute.)
2253 template->ulValueLen = (CK_ULONG)-1;
2254 return (CKR_ATTRIBUTE_TYPE_INVALID);
2257 return (rv);
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).
2264 CK_RV
2265 kernel_get_common_key_attrs(kernel_object_t *object_p,
2266 CK_ATTRIBUTE_PTR template)
2269 switch (template->type) {
2271 case CKA_KEY_TYPE:
2272 return (get_ulong_attr_from_object(object_p->key_type,
2273 template));
2275 case CKA_ID:
2276 case CKA_START_DATE:
2277 case CKA_END_DATE:
2279 * The above extra attributes have byte array type.
2281 return (get_extra_attr_from_object(object_p,
2282 template));
2284 /* Key related boolean attributes */
2285 case CKA_LOCAL:
2286 return (get_bool_attr_from_object(object_p,
2287 LOCAL_BOOL_ON, template));
2289 case CKA_DERIVE:
2290 return (get_bool_attr_from_object(object_p,
2291 DERIVE_BOOL_ON, template));
2293 case CKA_KEY_GEN_MECHANISM:
2294 return (get_ulong_attr_from_object(object_p->mechanism,
2295 template));
2297 default:
2298 return (CKR_ATTRIBUTE_TYPE_INVALID);
2304 * Get the value of a requested attribute of a Public Key Object.
2306 * Rule: All the attributes in the public key object can be revealed.
2308 CK_RV
2309 kernel_get_public_key_attribute(kernel_object_t *object_p,
2310 CK_ATTRIBUTE_PTR template)
2313 CK_RV rv = CKR_OK;
2314 CK_KEY_TYPE keytype = object_p->key_type;
2316 switch (template->type) {
2318 case CKA_SUBJECT:
2319 case CKA_EC_PARAMS:
2321 * The above extra attributes have byte array type.
2323 return (get_extra_attr_from_object(object_p,
2324 template));
2326 /* Key related boolean attributes */
2327 case CKA_ENCRYPT:
2328 return (get_bool_attr_from_object(object_p,
2329 ENCRYPT_BOOL_ON, template));
2331 case CKA_VERIFY:
2332 return (get_bool_attr_from_object(object_p,
2333 VERIFY_BOOL_ON, template));
2335 case CKA_VERIFY_RECOVER:
2336 return (get_bool_attr_from_object(object_p,
2337 VERIFY_RECOVER_BOOL_ON, template));
2339 case CKA_WRAP:
2340 return (get_bool_attr_from_object(object_p,
2341 WRAP_BOOL_ON, template));
2343 case CKA_TRUSTED:
2344 return (get_bool_attr_from_object(object_p,
2345 TRUSTED_BOOL_ON, template));
2347 case CKA_MODULUS:
2349 * This attribute is valid only for RSA public key
2350 * object.
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);
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);
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);
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);
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);
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);
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);
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);
2436 default:
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.
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);
2447 break;
2450 return (rv);
2455 * Get the value of a requested attribute of a Private Key Object.
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.).
2462 CK_RV
2463 kernel_get_private_key_attribute(kernel_object_t *object_p,
2464 CK_ATTRIBUTE_PTR template)
2467 CK_RV rv = CKR_OK;
2468 CK_KEY_TYPE keytype = object_p->key_type;
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.
2476 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
2477 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
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);
2492 switch (template->type) {
2494 case CKA_SUBJECT:
2495 case CKA_EC_PARAMS:
2497 * The above extra attributes have byte array type.
2499 return (get_extra_attr_from_object(object_p,
2500 template));
2502 /* Key related boolean attributes */
2503 case CKA_SENSITIVE:
2504 return (get_bool_attr_from_object(object_p,
2505 SENSITIVE_BOOL_ON, template));
2507 case CKA_SECONDARY_AUTH:
2508 return (get_bool_attr_from_object(object_p,
2509 SECONDARY_AUTH_BOOL_ON, template));
2511 case CKA_DECRYPT:
2512 return (get_bool_attr_from_object(object_p,
2513 DECRYPT_BOOL_ON, template));
2515 case CKA_SIGN:
2516 return (get_bool_attr_from_object(object_p,
2517 SIGN_BOOL_ON, template));
2519 case CKA_SIGN_RECOVER:
2520 return (get_bool_attr_from_object(object_p,
2521 SIGN_RECOVER_BOOL_ON, template));
2523 case CKA_UNWRAP:
2524 return (get_bool_attr_from_object(object_p,
2525 UNWRAP_BOOL_ON, template));
2527 case CKA_EXTRACTABLE:
2528 return (get_bool_attr_from_object(object_p,
2529 EXTRACTABLE_BOOL_ON, template));
2531 case CKA_ALWAYS_SENSITIVE:
2532 return (get_bool_attr_from_object(object_p,
2533 ALWAYS_SENSITIVE_BOOL_ON, template));
2535 case CKA_NEVER_EXTRACTABLE:
2536 return (get_bool_attr_from_object(object_p,
2537 NEVER_EXTRACTABLE_BOOL_ON, template));
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;
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;
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;
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;
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;
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;
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;
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;
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;
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);
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);
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);
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);
2681 default:
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.
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);
2692 break;
2695 return (rv);
2700 * Get the value of a requested attribute of a Secret Key Object.
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.).
2707 CK_RV
2708 kernel_get_secret_key_attribute(kernel_object_t *object_p,
2709 CK_ATTRIBUTE_PTR template)
2712 CK_RV rv = CKR_OK;
2713 CK_KEY_TYPE keytype = object_p->key_type;
2715 switch (template->type) {
2717 /* Key related boolean attributes */
2718 case CKA_SENSITIVE:
2719 return (get_bool_attr_from_object(object_p,
2720 SENSITIVE_BOOL_ON, template));
2722 case CKA_ENCRYPT:
2723 return (get_bool_attr_from_object(object_p,
2724 ENCRYPT_BOOL_ON, template));
2726 case CKA_DECRYPT:
2727 return (get_bool_attr_from_object(object_p,
2728 DECRYPT_BOOL_ON, template));
2730 case CKA_SIGN:
2731 return (get_bool_attr_from_object(object_p,
2732 SIGN_BOOL_ON, template));
2734 case CKA_VERIFY:
2735 return (get_bool_attr_from_object(object_p,
2736 VERIFY_BOOL_ON, template));
2738 case CKA_WRAP:
2739 return (get_bool_attr_from_object(object_p,
2740 WRAP_BOOL_ON, template));
2742 case CKA_UNWRAP:
2743 return (get_bool_attr_from_object(object_p,
2744 UNWRAP_BOOL_ON, template));
2746 case CKA_EXTRACTABLE:
2747 return (get_bool_attr_from_object(object_p,
2748 EXTRACTABLE_BOOL_ON, template));
2750 case CKA_ALWAYS_SENSITIVE:
2751 return (get_bool_attr_from_object(object_p,
2752 ALWAYS_SENSITIVE_BOOL_ON, template));
2754 case CKA_NEVER_EXTRACTABLE:
2755 return (get_bool_attr_from_object(object_p,
2756 NEVER_EXTRACTABLE_BOOL_ON, template));
2758 case CKA_VALUE:
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.
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);
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:
2781 * Copy secret key object attributes to template.
2783 if (template->pValue == NULL) {
2784 template->ulValueLen =
2785 OBJ_SEC_VALUE_LEN(object_p);
2786 return (CKR_OK);
2789 if (OBJ_SEC_VALUE(object_p) == NULL) {
2790 template->ulValueLen = 0;
2791 return (CKR_OK);
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);
2807 default:
2808 template->ulValueLen = (CK_ULONG)-1;
2809 rv = CKR_ATTRIBUTE_TYPE_INVALID;
2810 break;
2812 break;
2814 case CKA_VALUE_LEN:
2815 return (get_ulong_attr_from_object(OBJ_SEC_VALUE_LEN(object_p),
2816 template));
2818 default:
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.
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);
2829 break;
2832 return (rv);
2840 * Call the appropriate get attribute function according to the class
2841 * of object.
2843 * The caller of this function holds the lock on the object.
2845 CK_RV
2846 kernel_get_attribute(kernel_object_t *object_p, CK_ATTRIBUTE_PTR template)
2849 CK_RV rv = CKR_OK;
2850 CK_OBJECT_CLASS class = object_p->class;
2852 switch (class) {
2854 case CKO_PUBLIC_KEY:
2855 rv = kernel_get_public_key_attribute(object_p, template);
2856 break;
2858 case CKO_PRIVATE_KEY:
2859 rv = kernel_get_private_key_attribute(object_p, template);
2860 break;
2862 case CKO_SECRET_KEY:
2863 rv = kernel_get_secret_key_attribute(object_p, template);
2864 break;
2866 default:
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.
2872 template->ulValueLen = (CK_ULONG)-1;
2873 return (CKR_ATTRIBUTE_TYPE_INVALID);
2876 return (rv);
2881 * Set the value of an attribute that is common to all key objects
2882 * (i.e. public key, private key and secret key).
2884 CK_RV
2885 kernel_set_common_key_attribute(kernel_object_t *object_p,
2886 CK_ATTRIBUTE_PTR template, boolean_t copy, kernel_session_t *sp)
2889 kernel_slot_t *pslot = slot_table[sp->ses_slotid];
2890 CK_RV rv = CKR_OK;
2892 switch (template->type) {
2894 case CKA_LABEL:
2896 * Only the LABEL can be modified in the common storage
2897 * object attributes after the object is created.
2899 return (set_extra_attr_to_object(object_p,
2900 CKA_LABEL, template));
2902 case CKA_ID:
2903 return (set_extra_attr_to_object(object_p,
2904 CKA_ID, template));
2906 case CKA_START_DATE:
2907 return (set_extra_attr_to_object(object_p,
2908 CKA_START_DATE, template));
2910 case CKA_END_DATE:
2911 return (set_extra_attr_to_object(object_p,
2912 CKA_END_DATE, template));
2914 case CKA_DERIVE:
2915 return (set_bool_attr_to_object(object_p,
2916 DERIVE_BOOL_ON, template));
2918 case CKA_CLASS:
2919 case CKA_KEY_TYPE:
2920 case CKA_LOCAL:
2921 return (CKR_ATTRIBUTE_READ_ONLY);
2923 case CKA_PRIVATE:
2924 if (!copy) {
2925 /* called from C_SetAttributeValue() */
2926 return (CKR_ATTRIBUTE_READ_ONLY);
2929 /* called from C_CopyObject() */
2930 if ((*(CK_BBOOL *)template->pValue) != B_TRUE) {
2931 return (CKR_OK);
2934 (void) pthread_mutex_lock(&pslot->sl_mutex);
2936 * Cannot create a private object if the token
2937 * has a keystore and the user isn't logged in.
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);
2946 (void) pthread_mutex_unlock(&pslot->sl_mutex);
2947 return (rv);
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;
2956 return (rv);
2958 default:
2959 return (CKR_TEMPLATE_INCONSISTENT);
2966 * Set the value of an attribute of a Public Key Object.
2968 * Rule: The attributes marked with footnote number "8" in the PKCS11
2969 * spec may be modified (p.88 in PKCS11 spec.).
2971 CK_RV
2972 kernel_set_public_key_attribute(kernel_object_t *object_p,
2973 CK_ATTRIBUTE_PTR template, boolean_t copy, kernel_session_t *sp)
2975 CK_KEY_TYPE keytype = object_p->key_type;
2977 switch (template->type) {
2979 case CKA_SUBJECT:
2980 return (set_extra_attr_to_object(object_p,
2981 CKA_SUBJECT, template));
2983 case CKA_ENCRYPT:
2984 return (set_bool_attr_to_object(object_p,
2985 ENCRYPT_BOOL_ON, template));
2987 case CKA_VERIFY:
2988 return (set_bool_attr_to_object(object_p,
2989 VERIFY_BOOL_ON, template));
2991 case CKA_VERIFY_RECOVER:
2992 return (set_bool_attr_to_object(object_p,
2993 VERIFY_RECOVER_BOOL_ON, template));
2995 case CKA_WRAP:
2996 return (set_bool_attr_to_object(object_p,
2997 WRAP_BOOL_ON, template));
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;
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;
3014 default:
3016 * Set the value of a common key attribute.
3018 return (kernel_set_common_key_attribute(object_p,
3019 template, copy, sp));
3024 * If we got this far, then the combination of key type
3025 * and requested attribute is invalid.
3027 return (CKR_ATTRIBUTE_TYPE_INVALID);
3032 * Set the value of an attribute of a Private Key Object.
3034 * Rule: The attributes marked with footnote number "8" in the PKCS11
3035 * spec may be modified (p.88 in PKCS11 spec.).
3037 CK_RV
3038 kernel_set_private_key_attribute(kernel_object_t *object_p,
3039 CK_ATTRIBUTE_PTR template, boolean_t copy, kernel_session_t *sp)
3041 CK_KEY_TYPE keytype = object_p->key_type;
3043 switch (template->type) {
3045 case CKA_SUBJECT:
3046 return (set_extra_attr_to_object(object_p,
3047 CKA_SUBJECT, template));
3049 case CKA_SENSITIVE:
3051 * Cannot set SENSITIVE to FALSE if it is already ON.
3053 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
3054 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
3055 return (CKR_ATTRIBUTE_READ_ONLY);
3058 if (*(CK_BBOOL *)template->pValue)
3059 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
3060 return (CKR_OK);
3062 case CKA_DECRYPT:
3063 return (set_bool_attr_to_object(object_p,
3064 DECRYPT_BOOL_ON, template));
3066 case CKA_SIGN:
3067 return (set_bool_attr_to_object(object_p,
3068 SIGN_BOOL_ON, template));
3070 case CKA_SIGN_RECOVER:
3071 return (set_bool_attr_to_object(object_p,
3072 SIGN_RECOVER_BOOL_ON, template));
3074 case CKA_UNWRAP:
3075 return (set_bool_attr_to_object(object_p,
3076 UNWRAP_BOOL_ON, template));
3078 case CKA_EXTRACTABLE:
3080 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
3082 if ((*(CK_BBOOL *)template->pValue) &&
3083 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
3084 return (CKR_ATTRIBUTE_READ_ONLY);
3087 if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
3088 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
3089 return (CKR_OK);
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);
3102 break;
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;
3112 default:
3114 * Set the value of a common key attribute.
3116 return (kernel_set_common_key_attribute(object_p,
3117 template, copy, sp));
3121 * If we got this far, then the combination of key type
3122 * and requested attribute is invalid.
3124 return (CKR_ATTRIBUTE_TYPE_INVALID);
3130 * Set the value of an attribute of a Secret Key Object.
3132 * Rule: The attributes marked with footnote number "8" in the PKCS11
3133 * spec may be modified (p.88 in PKCS11 spec.).
3135 CK_RV
3136 kernel_set_secret_key_attribute(kernel_object_t *object_p,
3137 CK_ATTRIBUTE_PTR template, boolean_t copy, kernel_session_t *sp)
3139 CK_KEY_TYPE keytype = object_p->key_type;
3141 switch (template->type) {
3143 case CKA_SENSITIVE:
3145 * Cannot set SENSITIVE to FALSE if it is already ON.
3147 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
3148 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
3149 return (CKR_ATTRIBUTE_READ_ONLY);
3152 if (*(CK_BBOOL *)template->pValue)
3153 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
3154 return (CKR_OK);
3156 case CKA_ENCRYPT:
3157 return (set_bool_attr_to_object(object_p,
3158 ENCRYPT_BOOL_ON, template));
3160 case CKA_DECRYPT:
3161 return (set_bool_attr_to_object(object_p,
3162 DECRYPT_BOOL_ON, template));
3164 case CKA_SIGN:
3165 return (set_bool_attr_to_object(object_p,
3166 SIGN_BOOL_ON, template));
3168 case CKA_VERIFY:
3169 return (set_bool_attr_to_object(object_p,
3170 VERIFY_BOOL_ON, template));
3172 case CKA_WRAP:
3173 return (set_bool_attr_to_object(object_p,
3174 WRAP_BOOL_ON, template));
3176 case CKA_UNWRAP:
3177 return (set_bool_attr_to_object(object_p,
3178 UNWRAP_BOOL_ON, template));
3180 case CKA_EXTRACTABLE:
3182 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
3184 if ((*(CK_BBOOL *)template->pValue) &&
3185 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
3186 return (CKR_ATTRIBUTE_READ_ONLY);
3189 if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
3190 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
3191 return (CKR_OK);
3193 case CKA_VALUE:
3194 return (CKR_ATTRIBUTE_READ_ONLY);
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;
3204 default:
3206 * Set the value of a common key attribute.
3208 return (kernel_set_common_key_attribute(object_p,
3209 template, copy, sp));
3213 * If we got this far, then the combination of key type
3214 * and requested attribute is invalid.
3216 return (CKR_ATTRIBUTE_TYPE_INVALID);
3221 * Call the appropriate set attribute function according to the class
3222 * of object.
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.
3229 CK_RV
3230 kernel_set_attribute(kernel_object_t *object_p, CK_ATTRIBUTE_PTR template,
3231 boolean_t copy, kernel_session_t *sp)
3234 CK_RV rv = CKR_OK;
3235 CK_OBJECT_CLASS class = object_p->class;
3237 switch (class) {
3239 case CKO_PUBLIC_KEY:
3240 rv = kernel_set_public_key_attribute(object_p, template,
3241 copy, sp);
3242 break;
3244 case CKO_PRIVATE_KEY:
3245 rv = kernel_set_private_key_attribute(object_p, template,
3246 copy, sp);
3247 break;
3249 case CKO_SECRET_KEY:
3250 rv = kernel_set_secret_key_attribute(object_p, template,
3251 copy, sp);
3252 break;
3254 default:
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.
3261 rv = CKR_TEMPLATE_INCONSISTENT;
3262 break;
3265 return (rv);
3269 static CK_RV
3270 copy_bigint(biginteger_t *new_bigint, biginteger_t *old_bigint)
3272 new_bigint->big_value =
3273 malloc((sizeof (CK_BYTE) * new_bigint->big_value_len));
3275 if (new_bigint->big_value == NULL) {
3276 return (CKR_HOST_MEMORY);
3279 (void) memcpy(new_bigint->big_value, old_bigint->big_value,
3280 (sizeof (CK_BYTE) * new_bigint->big_value_len));
3282 return (CKR_OK);
3285 static void
3286 free_public_key_attr(public_key_obj_t *pbk, CK_KEY_TYPE key_type)
3288 if (pbk == NULL) {
3289 return;
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;
3306 free(pbk);
3310 CK_RV
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)
3315 public_key_obj_t *pbk;
3316 CK_RV rv = CKR_OK;
3318 pbk = calloc(1, sizeof (public_key_obj_t));
3319 if (pbk == NULL) {
3320 return (CKR_HOST_MEMORY);
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);
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);
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));
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);
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);
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);
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);
3379 break;
3380 default:
3381 break;
3383 *new_pub_key_obj_p = pbk;
3384 return (rv);
3388 static void
3389 free_private_key_attr(private_key_obj_t *pbk, CK_KEY_TYPE key_type)
3391 if (pbk == NULL) {
3392 return;
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;
3415 free(pbk);
3418 CK_RV
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)
3422 CK_RV rv = CKR_OK;
3423 private_key_obj_t *pbk;
3425 pbk = calloc(1, sizeof (private_key_obj_t));
3426 if (pbk == NULL) {
3427 return (CKR_HOST_MEMORY);
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);
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);
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);
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);
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);
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);
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);
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);
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));
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);
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);
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);
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);
3528 break;
3529 default:
3530 break;
3532 *new_pri_key_obj_p = pbk;
3533 return (rv);
3537 CK_RV
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)
3541 secret_key_obj_t *sk;
3543 sk = malloc(sizeof (secret_key_obj_t));
3544 if (sk == NULL) {
3545 return (CKR_HOST_MEMORY);
3547 (void) memcpy(sk, old_secret_key_obj_p, sizeof (secret_key_obj_t));
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);
3555 (void) memcpy(sk->sk_value, old_secret_key_obj_p->sk_value,
3556 (sizeof (CK_BYTE) * sk->sk_value_len));
3558 *new_secret_key_obj_p = sk;
3560 return (CKR_OK);
3566 * If CKA_CLASS not given, guess CKA_CLASS using
3567 * attributes on template .
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.
3576 void
3577 kernel_process_find_attr(CK_OBJECT_CLASS *pclasses,
3578 CK_ULONG *num_result_pclasses, CK_ATTRIBUTE_PTR pTemplate,
3579 CK_ULONG ulCount)
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;
3594 for (i = 0; i < ulCount; i++) {
3595 if (pTemplate[i].type == CKA_CLASS) {
3597 * don't need to guess the class, it is specified.
3598 * Just record the class, and return.
3600 pclasses[0] =
3601 (*((CK_OBJECT_CLASS *)pTemplate[i].pValue));
3602 *num_result_pclasses = 1;
3603 return;
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);
3621 * Get the list of objects class that might contain
3622 * some attributes.
3624 for (i = 0; i < ulCount; i++) {
3626 * only check if this attribute can belong to public key object
3627 * class if public key object isn't already in the list
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;
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;
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;
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;
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;
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;
3695 *num_result_pclasses = num_pclasses;
3699 boolean_t
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)
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;
3710 * Check if the class of this object match with any
3711 * of object classes that can possibly contain the
3712 * requested attributes.
3714 if (num_pclasses > 0) {
3715 for (i = 0; i < num_pclasses; i++) {
3716 if (obj->class == pclasses[i]) {
3717 break;
3720 if (i == num_pclasses) {
3722 * this object can't possibly contain one or
3723 * more attributes, don't need to check this object
3725 return (B_FALSE);
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);
3742 break;
3743 case CKA_KEY_TYPE:
3744 if (*((CK_KEY_TYPE *)tmpl_attr->pValue) !=
3745 obj->key_type) {
3746 return (B_FALSE);
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:
3821 * CKA_TOKEN value is not applicable to an object
3822 * created in the library, it should only contain
3823 * the default value FALSE
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);
3853 } else {
3854 return (B_FALSE);
3856 break;
3857 case CKA_VALUE:
3858 switch (obj->class) {
3859 case CKO_SECRET_KEY:
3861 * secret_key_obj_t is the same as
3862 * biginteger_t
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);
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);
3879 break;
3880 default:
3881 return (B_FALSE);
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);
3895 compare_bigint = B_TRUE;
3896 } else {
3897 return (B_FALSE);
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);
3909 } else {
3910 return (B_FALSE);
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);
3923 compare_bigint = B_TRUE;
3924 } else {
3925 return (B_FALSE);
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);
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);
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);
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);
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);
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);
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);
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);
4007 } else {
4008 return (B_FALSE);
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);
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);
4029 } else {
4030 return (B_FALSE);
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);
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);
4051 } else {
4052 return (B_FALSE);
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:
4062 * any other attributes are currently not supported.
4063 * so, it's not possible for them to be in the
4064 * object
4066 return (B_FALSE);
4068 if (compare_boolean) {
4069 CK_BBOOL bval;
4071 if (attr_mask) {
4072 bval = TRUE;
4073 } else {
4074 bval = FALSE;
4076 if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) {
4077 return (B_FALSE);
4079 } else if (compare_bigint) {
4080 if (bigint == NULL) {
4081 return (B_FALSE);
4083 if (tmpl_attr->ulValueLen != bigint->big_value_len) {
4084 return (B_FALSE);
4086 if (memcmp(tmpl_attr->pValue, bigint->big_value,
4087 tmpl_attr->ulValueLen) != 0) {
4088 return (B_FALSE);
4090 } else if (compare_attr) {
4091 if (obj_attr == NULL) {
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.
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);
4106 if (memcmp(tmpl_attr->pValue, obj_attr->pValue,
4107 tmpl_attr->ulValueLen) != 0) {
4108 return (B_FALSE);
4113 return (B_TRUE);
4116 CK_ATTRIBUTE_PTR
4117 get_extra_attr(CK_ATTRIBUTE_TYPE type, kernel_object_t *obj)
4119 CK_ATTRIBUTE_INFO_PTR tmp;
4121 tmp = obj->extra_attrlistp;
4122 while (tmp != NULL) {
4123 if (tmp->attr.type == type) {
4124 return (&(tmp->attr));
4126 tmp = tmp->next;
4128 /* if get there, the specified attribute is not found */
4129 return (NULL);