dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / pkcs11 / pkcs11_kernel / common / kernelAttributeUtil.c
bloba5af5c64e01b8e67b3470d8d2424bb6542d16aa7
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 free(extra_attr->attr.pValue);
333 /* Free the storage for the attribute_info struct. */
334 free(extra_attr);
335 extra_attr = tmp;
338 object_p->extra_attrlistp = NULL;
343 * Create the attribute_info struct to hold the object's attribute,
344 * and add it to the extra attribute list of an object.
346 CK_RV
347 kernel_add_extra_attr(CK_ATTRIBUTE_PTR template, kernel_object_t *object_p)
350 CK_ATTRIBUTE_INFO_PTR attrp;
352 /* Allocate the storage for the attribute_info struct. */
353 attrp = calloc(1, sizeof (attribute_info_t));
354 if (attrp == NULL) {
355 return (CKR_HOST_MEMORY);
358 /* Set up attribute_info struct. */
359 attrp->attr.type = template->type;
360 attrp->attr.ulValueLen = template->ulValueLen;
362 if ((template->pValue != NULL) &&
363 (template->ulValueLen > 0)) {
364 /* Allocate storage for the value of the attribute. */
365 attrp->attr.pValue = malloc(template->ulValueLen);
366 if (attrp->attr.pValue == NULL) {
367 free(attrp);
368 return (CKR_HOST_MEMORY);
371 (void) memcpy(attrp->attr.pValue, template->pValue,
372 template->ulValueLen);
373 } else {
374 attrp->attr.pValue = NULL;
377 /* Insert the new attribute in front of extra attribute list. */
378 if (object_p->extra_attrlistp == NULL) {
379 object_p->extra_attrlistp = attrp;
380 attrp->next = NULL;
381 } else {
382 attrp->next = object_p->extra_attrlistp;
383 object_p->extra_attrlistp = attrp;
386 return (CKR_OK);
391 * Copy the attribute_info struct from the old object to a new attribute_info
392 * struct, and add that new struct to the extra attribute list of the new
393 * object.
395 CK_RV
396 kernel_copy_extra_attr(CK_ATTRIBUTE_INFO_PTR old_attrp,
397 kernel_object_t *object_p)
399 CK_ATTRIBUTE_INFO_PTR attrp;
401 /* Allocate attribute_info struct. */
402 attrp = calloc(1, sizeof (attribute_info_t));
403 if (attrp == NULL) {
404 return (CKR_HOST_MEMORY);
407 attrp->attr.type = old_attrp->attr.type;
408 attrp->attr.ulValueLen = old_attrp->attr.ulValueLen;
410 if ((old_attrp->attr.pValue != NULL) &&
411 (old_attrp->attr.ulValueLen > 0)) {
412 attrp->attr.pValue = malloc(old_attrp->attr.ulValueLen);
413 if (attrp->attr.pValue == NULL) {
414 free(attrp);
415 return (CKR_HOST_MEMORY);
418 (void) memcpy(attrp->attr.pValue, old_attrp->attr.pValue,
419 old_attrp->attr.ulValueLen);
420 } else {
421 attrp->attr.pValue = NULL;
424 /* Insert the new attribute in front of extra attribute list */
425 if (object_p->extra_attrlistp == NULL) {
426 object_p->extra_attrlistp = attrp;
427 attrp->next = NULL;
428 } else {
429 attrp->next = object_p->extra_attrlistp;
430 object_p->extra_attrlistp = attrp;
433 return (CKR_OK);
438 * Get the attribute triple from the extra attribute list in the object
439 * (if the specified attribute type is found), and copy it to a template.
440 * Note the type of the attribute to be copied is specified by the template,
441 * and the storage is pre-allocated for the atrribute value in the template
442 * for doing the copy.
444 CK_RV
445 get_extra_attr_from_object(kernel_object_t *object_p, CK_ATTRIBUTE_PTR template)
448 CK_ATTRIBUTE_INFO_PTR extra_attr;
449 CK_ATTRIBUTE_TYPE type = template->type;
451 extra_attr = object_p->extra_attrlistp;
453 while (extra_attr) {
454 if (type == extra_attr->attr.type) {
455 /* Found it. */
456 break;
457 } else {
458 /* Does not match, try next one. */
459 extra_attr = extra_attr->next;
463 if (extra_attr == NULL) {
464 /* A valid but un-initialized attribute. */
465 template->ulValueLen = 0;
466 return (CKR_OK);
470 * We found the attribute in the extra attribute list.
472 if (template->pValue == NULL) {
473 template->ulValueLen = extra_attr->attr.ulValueLen;
474 return (CKR_OK);
477 if (template->ulValueLen >= extra_attr->attr.ulValueLen) {
479 * The buffer provided by the application is large
480 * enough to hold the value of the attribute.
482 (void) memcpy(template->pValue, extra_attr->attr.pValue,
483 extra_attr->attr.ulValueLen);
484 template->ulValueLen = extra_attr->attr.ulValueLen;
485 return (CKR_OK);
486 } else {
488 * The buffer provided by the application does
489 * not have enough space to hold the value.
491 template->ulValueLen = (CK_ULONG)-1;
492 return (CKR_BUFFER_TOO_SMALL);
498 * Modify the attribute triple in the extra attribute list of the object
499 * if the specified attribute type is found. Otherwise, just add it to
500 * list.
502 CK_RV
503 set_extra_attr_to_object(kernel_object_t *object_p, CK_ATTRIBUTE_TYPE type,
504 CK_ATTRIBUTE_PTR template)
507 CK_ATTRIBUTE_INFO_PTR extra_attr;
509 extra_attr = object_p->extra_attrlistp;
511 while (extra_attr) {
512 if (type == extra_attr->attr.type) {
513 /* Found it. */
514 break;
515 } else {
516 /* Does not match, try next one. */
517 extra_attr = extra_attr->next;
521 if (extra_attr == NULL) {
523 * This attribute is a new one, go ahead adding it to
524 * the extra attribute list.
526 return (kernel_add_extra_attr(template, object_p));
529 /* We found the attribute in the extra attribute list. */
530 if ((template->pValue != NULL) &&
531 (template->ulValueLen > 0)) {
532 if (template->ulValueLen > extra_attr->attr.ulValueLen) {
533 /* The old buffer is too small to hold the new value. */
534 free(extra_attr->attr.pValue);
536 /* Allocate storage for the new attribute value. */
537 extra_attr->attr.pValue = malloc(template->ulValueLen);
538 if (extra_attr->attr.pValue == NULL) {
539 return (CKR_HOST_MEMORY);
543 /* Replace the attribute with new value. */
544 extra_attr->attr.ulValueLen = template->ulValueLen;
545 (void) memcpy(extra_attr->attr.pValue, template->pValue,
546 template->ulValueLen);
547 } else {
548 extra_attr->attr.pValue = NULL;
551 return (CKR_OK);
556 * Copy the big integer attribute value from template to a biginteger_t struct.
558 CK_RV
559 get_bigint_attr_from_template(biginteger_t *big, CK_ATTRIBUTE_PTR template)
562 if ((template->pValue != NULL) &&
563 (template->ulValueLen > 0)) {
564 /* Allocate storage for the value of the attribute. */
565 big->big_value = malloc(template->ulValueLen);
566 if (big->big_value == NULL) {
567 return (CKR_HOST_MEMORY);
570 (void) memcpy(big->big_value, template->pValue,
571 template->ulValueLen);
572 big->big_value_len = template->ulValueLen;
573 } else {
574 big->big_value = NULL;
575 big->big_value_len = 0;
578 return (CKR_OK);
583 * Copy the big integer attribute value from a biginteger_t struct in the
584 * object to a template.
586 CK_RV
587 get_bigint_attr_from_object(biginteger_t *big, CK_ATTRIBUTE_PTR template)
590 if (template->pValue == NULL) {
591 template->ulValueLen = big->big_value_len;
592 return (CKR_OK);
595 if (big->big_value == NULL) {
596 template->ulValueLen = 0;
597 return (CKR_OK);
600 if (template->ulValueLen >= big->big_value_len) {
602 * The buffer provided by the application is large
603 * enough to hold the value of the attribute.
605 (void) memcpy(template->pValue, big->big_value,
606 big->big_value_len);
607 template->ulValueLen = big->big_value_len;
608 return (CKR_OK);
609 } else {
611 * The buffer provided by the application does
612 * not have enough space to hold the value.
614 template->ulValueLen = (CK_ULONG)-1;
615 return (CKR_BUFFER_TOO_SMALL);
621 * Copy the boolean data type attribute value from an object for the
622 * specified attribute to the template.
624 CK_RV
625 get_bool_attr_from_object(kernel_object_t *object_p, CK_ULONG bool_flag,
626 CK_ATTRIBUTE_PTR template)
629 if (template->pValue == NULL) {
630 template->ulValueLen = sizeof (CK_BBOOL);
631 return (CKR_OK);
634 if (template->ulValueLen >= sizeof (CK_BBOOL)) {
636 * The buffer provided by the application is large
637 * enough to hold the value of the attribute.
639 if (object_p->bool_attr_mask & bool_flag) {
640 *((CK_BBOOL *)template->pValue) = B_TRUE;
641 } else {
642 *((CK_BBOOL *)template->pValue) = B_FALSE;
645 template->ulValueLen = sizeof (CK_BBOOL);
646 return (CKR_OK);
647 } else {
649 * The buffer provided by the application does
650 * not have enough space to hold the value.
652 template->ulValueLen = (CK_ULONG)-1;
653 return (CKR_BUFFER_TOO_SMALL);
658 * Set the boolean data type attribute value in the object.
660 CK_RV
661 set_bool_attr_to_object(kernel_object_t *object_p, CK_ULONG bool_flag,
662 CK_ATTRIBUTE_PTR template)
665 if (*(CK_BBOOL *)template->pValue)
666 object_p->bool_attr_mask |= bool_flag;
667 else
668 object_p->bool_attr_mask &= ~bool_flag;
670 return (CKR_OK);
675 * Copy the CK_ULONG data type attribute value from an object to the
676 * template.
678 CK_RV
679 get_ulong_attr_from_object(CK_ULONG value, CK_ATTRIBUTE_PTR template)
682 if (template->pValue == NULL) {
683 template->ulValueLen = sizeof (CK_ULONG);
684 return (CKR_OK);
687 if (template->ulValueLen >= sizeof (CK_ULONG)) {
689 * The buffer provided by the application is large
690 * enough to hold the value of the attribute.
692 *(CK_ULONG_PTR)template->pValue = value;
693 template->ulValueLen = sizeof (CK_ULONG);
694 return (CKR_OK);
695 } else {
697 * The buffer provided by the application does
698 * not have enough space to hold the value.
700 template->ulValueLen = (CK_ULONG)-1;
701 return (CKR_BUFFER_TOO_SMALL);
707 * Copy the CK_ULONG data type attribute value from a template to the
708 * object.
710 void
711 get_ulong_attr_from_template(CK_ULONG *value, CK_ATTRIBUTE_PTR template)
714 if (template->pValue != NULL) {
715 *value = *(CK_ULONG_PTR)template->pValue;
716 } else {
717 *value = 0;
723 * Copy the big integer attribute value from source's biginteger_t to
724 * destination's biginteger_t.
726 void
727 copy_bigint_attr(biginteger_t *src, biginteger_t *dst)
730 if ((src->big_value != NULL) &&
731 (src->big_value_len > 0)) {
733 * To do the copy, just have dst's big_value points
734 * to src's.
736 dst->big_value = src->big_value;
737 dst->big_value_len = src->big_value_len;
740 * After the copy, nullify the src's big_value pointer.
741 * It prevents any double freeing the value.
743 src->big_value = NULL;
744 src->big_value_len = 0;
745 } else {
746 dst->big_value = NULL;
747 dst->big_value_len = 0;
753 CK_RV
754 get_string_from_template(CK_ATTRIBUTE_PTR dest, CK_ATTRIBUTE_PTR src)
756 if ((src->pValue != NULL) &&
757 (src->ulValueLen > 0)) {
758 /* Allocate storage for the value of the attribute. */
759 dest->pValue = malloc(src->ulValueLen);
760 if (dest->pValue == NULL) {
761 return (CKR_HOST_MEMORY);
764 (void) memcpy(dest->pValue, src->pValue,
765 src->ulValueLen);
766 dest->ulValueLen = src->ulValueLen;
767 dest->type = src->type;
768 } else {
769 dest->pValue = NULL;
770 dest->ulValueLen = 0;
771 dest->type = src->type;
774 return (CKR_OK);
778 void
779 string_attr_cleanup(CK_ATTRIBUTE_PTR template)
782 if (template->pValue) {
783 free(template->pValue);
784 template->pValue = NULL;
785 template->ulValueLen = 0;
790 * Release the storage allocated for object attribute with big integer
791 * value.
793 void
794 bigint_attr_cleanup(biginteger_t *big)
797 if (big == NULL)
798 return;
800 if (big->big_value) {
801 (void) memset(big->big_value, 0, big->big_value_len);
802 free(big->big_value);
803 big->big_value = NULL;
804 big->big_value_len = 0;
810 * Clean up and release all the storage allocated to hold the big integer
811 * attributes associated with the type (i.e. class) of the object. Also,
812 * release the storage allocated to the type of the object.
814 void
815 kernel_cleanup_object_bigint_attrs(kernel_object_t *object_p)
818 CK_OBJECT_CLASS class = object_p->class;
819 CK_KEY_TYPE keytype = object_p->key_type;
822 switch (class) {
823 case CKO_PUBLIC_KEY:
824 if (OBJ_PUB(object_p)) {
825 switch (keytype) {
826 case CKK_RSA:
827 bigint_attr_cleanup(OBJ_PUB_RSA_MOD(
828 object_p));
829 bigint_attr_cleanup(OBJ_PUB_RSA_PUBEXPO(
830 object_p));
831 break;
833 case CKK_DSA:
834 bigint_attr_cleanup(OBJ_PUB_DSA_PRIME(
835 object_p));
836 bigint_attr_cleanup(OBJ_PUB_DSA_SUBPRIME(
837 object_p));
838 bigint_attr_cleanup(OBJ_PUB_DSA_BASE(
839 object_p));
840 bigint_attr_cleanup(OBJ_PUB_DSA_VALUE(
841 object_p));
842 break;
844 case CKK_DH:
845 bigint_attr_cleanup(OBJ_PUB_DH_PRIME(object_p));
846 bigint_attr_cleanup(OBJ_PUB_DH_BASE(object_p));
847 bigint_attr_cleanup(OBJ_PUB_DH_VALUE(object_p));
848 break;
850 case CKK_EC:
851 bigint_attr_cleanup(OBJ_PUB_EC_POINT(object_p));
852 break;
855 /* Release Public Key Object struct */
856 free(OBJ_PUB(object_p));
857 OBJ_PUB(object_p) = NULL;
859 break;
861 case CKO_PRIVATE_KEY:
862 if (OBJ_PRI(object_p)) {
863 switch (keytype) {
864 case CKK_RSA:
865 bigint_attr_cleanup(OBJ_PRI_RSA_MOD(
866 object_p));
867 bigint_attr_cleanup(OBJ_PRI_RSA_PUBEXPO(
868 object_p));
869 bigint_attr_cleanup(OBJ_PRI_RSA_PRIEXPO(
870 object_p));
871 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME1(
872 object_p));
873 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME2(
874 object_p));
875 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO1(
876 object_p));
877 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO2(
878 object_p));
879 bigint_attr_cleanup(OBJ_PRI_RSA_COEF(
880 object_p));
881 break;
883 case CKK_DSA:
884 bigint_attr_cleanup(OBJ_PRI_DSA_PRIME(
885 object_p));
886 bigint_attr_cleanup(OBJ_PRI_DSA_SUBPRIME(
887 object_p));
888 bigint_attr_cleanup(OBJ_PRI_DSA_BASE(
889 object_p));
890 bigint_attr_cleanup(OBJ_PRI_DSA_VALUE(
891 object_p));
892 break;
894 case CKK_DH:
895 bigint_attr_cleanup(OBJ_PRI_DH_PRIME(object_p));
896 bigint_attr_cleanup(OBJ_PRI_DH_BASE(object_p));
897 bigint_attr_cleanup(OBJ_PRI_DH_VALUE(object_p));
898 break;
900 case CKK_EC:
901 bigint_attr_cleanup(OBJ_PRI_EC_VALUE(object_p));
902 break;
905 /* Release Private Key Object struct. */
906 free(OBJ_PRI(object_p));
907 OBJ_PRI(object_p) = NULL;
909 break;
915 * Parse the common attributes. Return to caller with appropriate return
916 * value to indicate if the supplied template specifies a valid attribute
917 * with a valid value.
919 CK_RV
920 kernel_parse_common_attrs(CK_ATTRIBUTE_PTR template, kernel_session_t *sp,
921 uint64_t *attr_mask_p)
924 CK_RV rv = CKR_OK;
925 kernel_slot_t *pslot = slot_table[sp->ses_slotid];
927 switch (template->type) {
928 case CKA_CLASS:
929 break;
931 /* default boolean attributes */
932 case CKA_TOKEN:
933 if ((*(CK_BBOOL *)template->pValue) == TRUE) {
934 rv = CKR_ATTRIBUTE_VALUE_INVALID;
936 break;
938 case CKA_PRIVATE:
939 if ((*(CK_BBOOL *)template->pValue) == TRUE) {
941 * Cannot create a private object if the token
942 * has a keystore and the user isn't logged in.
944 if (pslot->sl_func_list.fl_object_create &&
945 pslot->sl_state != CKU_USER) {
946 rv = CKR_ATTRIBUTE_VALUE_INVALID;
947 } else {
948 *attr_mask_p |= PRIVATE_BOOL_ON;
951 break;
953 case CKA_MODIFIABLE:
954 if ((*(CK_BBOOL *)template->pValue) == FALSE) {
955 *attr_mask_p &= ~MODIFIABLE_BOOL_ON;
957 break;
959 case CKA_LABEL:
960 break;
962 default:
963 rv = CKR_TEMPLATE_INCONSISTENT;
966 return (rv);
973 * Build a Public Key Object.
975 * - Parse the object's template, and when an error is detected such as
976 * invalid attribute type, invalid attribute value, etc., return
977 * with appropriate return value.
978 * - Set up attribute mask field in the object for the supplied common
979 * attributes that have boolean type.
980 * - Build the attribute_info struct to hold the value of each supplied
981 * attribute that has byte array type. Link attribute_info structs
982 * together to form the extra attribute list of the object.
983 * - Allocate storage for the Public Key object.
984 * - Build the Public Key object according to the key type. Allocate
985 * storage to hold the big integer value for the supplied attributes
986 * that are required for a certain key type.
989 CK_RV
990 kernel_build_public_key_object(CK_ATTRIBUTE_PTR template,
991 CK_ULONG ulAttrNum, kernel_object_t *new_object, kernel_session_t *sp,
992 uint_t mode)
995 int i;
996 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
997 uint64_t attr_mask = PUBLIC_KEY_DEFAULT;
998 CK_RV rv = CKR_OK;
999 int isLabel = 0;
1000 /* Must set flags */
1001 int isModulus = 0;
1002 int isPubExpo = 0;
1003 int isPrime = 0;
1004 int isSubprime = 0;
1005 int isBase = 0;
1006 int isValue = 0;
1007 int isPoint = 0;
1008 int isParams = 0;
1009 /* Must not set flags */
1010 int isModulusBits = 0;
1011 CK_ULONG modulus_bits = 0;
1013 biginteger_t modulus;
1014 biginteger_t pubexpo;
1015 biginteger_t prime;
1016 biginteger_t subprime;
1017 biginteger_t base;
1018 biginteger_t value;
1019 biginteger_t point;
1020 CK_ATTRIBUTE string_tmp;
1021 CK_ATTRIBUTE param_tmp;
1023 public_key_obj_t *pbk;
1025 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1026 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1027 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1028 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1029 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1030 (void) memset(&base, 0x0, sizeof (biginteger_t));
1031 (void) memset(&value, 0x0, sizeof (biginteger_t));
1032 (void) memset(&point, 0x0, sizeof (biginteger_t));
1033 string_tmp.pValue = NULL;
1034 param_tmp.pValue = NULL;
1036 for (i = 0; i < ulAttrNum; i++) {
1038 /* Public Key Object Attributes */
1039 switch (template[i].type) {
1041 /* common key attributes */
1042 case CKA_KEY_TYPE:
1043 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1044 break;
1046 case CKA_ID:
1047 case CKA_START_DATE:
1048 case CKA_END_DATE:
1050 /* common public key attribute */
1051 case CKA_SUBJECT:
1053 * Allocate storage to hold the attribute
1054 * value with byte array type, and add it to
1055 * the extra attribute list of the object.
1057 rv = kernel_add_extra_attr(&template[i],
1058 new_object);
1059 if (rv != CKR_OK) {
1060 goto fail_cleanup;
1062 break;
1065 * The following key related attribute types must
1066 * not be specified by C_CreateObject.
1068 case CKA_LOCAL:
1069 case CKA_KEY_GEN_MECHANISM:
1070 rv = CKR_TEMPLATE_INCONSISTENT;
1071 goto fail_cleanup;
1073 /* Key related boolean attributes */
1074 case CKA_DERIVE:
1075 if (*(CK_BBOOL *)template[i].pValue)
1076 attr_mask |= DERIVE_BOOL_ON;
1077 break;
1079 case CKA_ENCRYPT:
1080 if (*(CK_BBOOL *)template[i].pValue)
1081 attr_mask |= ENCRYPT_BOOL_ON;
1082 else
1083 attr_mask &= ~ENCRYPT_BOOL_ON;
1084 break;
1086 case CKA_VERIFY:
1087 if (*(CK_BBOOL *)template[i].pValue)
1088 attr_mask |= VERIFY_BOOL_ON;
1089 else
1090 attr_mask &= ~VERIFY_BOOL_ON;
1091 break;
1093 case CKA_VERIFY_RECOVER:
1094 if (*(CK_BBOOL *)template[i].pValue)
1095 attr_mask |= VERIFY_RECOVER_BOOL_ON;
1096 else
1097 attr_mask &= ~VERIFY_RECOVER_BOOL_ON;
1098 break;
1100 case CKA_WRAP:
1101 if (*(CK_BBOOL *)template[i].pValue)
1102 attr_mask |= WRAP_BOOL_ON;
1103 break;
1105 case CKA_TRUSTED:
1106 if (*(CK_BBOOL *)template[i].pValue)
1107 attr_mask |= TRUSTED_BOOL_ON;
1108 break;
1111 * The following key related attribute types must
1112 * be specified according to the key type by
1113 * C_CreateObject.
1115 case CKA_MODULUS:
1116 isModulus = 1;
1118 * Copyin big integer attribute from template
1119 * to a local variable.
1121 rv = get_bigint_attr_from_template(&modulus,
1122 &template[i]);
1123 if (rv != CKR_OK)
1124 goto fail_cleanup;
1125 break;
1127 case CKA_PUBLIC_EXPONENT:
1128 isPubExpo = 1;
1129 rv = get_bigint_attr_from_template(&pubexpo,
1130 &template[i]);
1131 if (rv != CKR_OK)
1132 goto fail_cleanup;
1133 break;
1135 case CKA_PRIME:
1136 isPrime = 1;
1137 rv = get_bigint_attr_from_template(&prime,
1138 &template[i]);
1139 if (rv != CKR_OK)
1140 goto fail_cleanup;
1141 break;
1143 case CKA_SUBPRIME:
1144 isSubprime = 1;
1145 rv = get_bigint_attr_from_template(&subprime,
1146 &template[i]);
1147 if (rv != CKR_OK)
1148 goto fail_cleanup;
1149 break;
1151 case CKA_BASE:
1152 isBase = 1;
1153 rv = get_bigint_attr_from_template(&base,
1154 &template[i]);
1155 if (rv != CKR_OK)
1156 goto fail_cleanup;
1157 break;
1159 case CKA_VALUE:
1160 isValue = 1;
1161 rv = get_bigint_attr_from_template(&value,
1162 &template[i]);
1163 if (rv != CKR_OK)
1164 goto fail_cleanup;
1165 break;
1167 case CKA_MODULUS_BITS:
1168 isModulusBits = 1;
1169 get_ulong_attr_from_template(&modulus_bits,
1170 &template[i]);
1171 break;
1173 case CKA_LABEL:
1174 isLabel = 1;
1175 rv = get_string_from_template(&string_tmp,
1176 &template[i]);
1177 if (rv != CKR_OK)
1178 goto fail_cleanup;
1179 break;
1181 case CKA_EC_POINT:
1182 isPoint = 1;
1183 rv = get_bigint_attr_from_template(&point,
1184 &template[i]);
1185 if (rv != CKR_OK)
1186 goto fail_cleanup;
1187 break;
1189 case CKA_EC_PARAMS:
1190 isParams = 1;
1191 rv = get_string_from_template(&param_tmp,
1192 &template[i]);
1193 if (rv != CKR_OK)
1194 goto fail_cleanup;
1195 break;
1197 default:
1198 rv = kernel_parse_common_attrs(&template[i], sp,
1199 &attr_mask);
1200 if (rv != CKR_OK)
1201 goto fail_cleanup;
1202 break;
1204 } /* For */
1206 /* Allocate storage for Public Key Object. */
1207 pbk = calloc(1, sizeof (public_key_obj_t));
1208 if (pbk == NULL) {
1209 rv = CKR_HOST_MEMORY;
1210 goto fail_cleanup;
1213 new_object->object_class_u.public_key = pbk;
1214 new_object->class = CKO_PUBLIC_KEY;
1216 if (keytype == (CK_KEY_TYPE)~0UL) {
1217 rv = CKR_TEMPLATE_INCOMPLETE;
1218 goto fail_cleanup;
1220 new_object->key_type = keytype;
1222 /* Supported key types of the Public Key Object */
1223 switch (keytype) {
1224 case CKK_RSA:
1225 if (mode == KERNEL_CREATE_OBJ) {
1226 if (isModulusBits || isPrime || isSubprime ||
1227 isBase|| isValue) {
1228 rv = CKR_TEMPLATE_INCONSISTENT;
1229 goto fail_cleanup;
1233 if (isModulus && isPubExpo) {
1235 * Copy big integer attribute value to the
1236 * designated place in the public key object.
1238 copy_bigint_attr(&modulus,
1239 KEY_PUB_RSA_MOD(pbk));
1241 copy_bigint_attr(&pubexpo,
1242 KEY_PUB_RSA_PUBEXPO(pbk));
1243 } else {
1244 rv = CKR_TEMPLATE_INCOMPLETE;
1245 goto fail_cleanup;
1248 /* must be generating a RSA key pair by value */
1249 if (isModulusBits) {
1250 KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits;
1252 break;
1254 case CKK_DSA:
1255 if (isModulusBits || isModulus || isPubExpo) {
1256 rv = CKR_TEMPLATE_INCONSISTENT;
1257 goto fail_cleanup;
1260 if (!(isPrime && isSubprime && isBase && isValue)) {
1261 rv = CKR_TEMPLATE_INCOMPLETE;
1262 goto fail_cleanup;
1265 copy_bigint_attr(&prime, KEY_PUB_DSA_PRIME(pbk));
1267 copy_bigint_attr(&subprime, KEY_PUB_DSA_SUBPRIME(pbk));
1269 copy_bigint_attr(&base, KEY_PUB_DSA_BASE(pbk));
1271 copy_bigint_attr(&value, KEY_PUB_DSA_VALUE(pbk));
1273 break;
1275 case CKK_DH:
1276 if (!(isPrime && isBase && isValue)) {
1277 rv = CKR_TEMPLATE_INCOMPLETE;
1278 goto fail_cleanup;
1281 copy_bigint_attr(&prime, KEY_PUB_DH_PRIME(pbk));
1283 copy_bigint_attr(&base, KEY_PUB_DH_BASE(pbk));
1285 copy_bigint_attr(&value, KEY_PUB_DH_VALUE(pbk));
1287 break;
1289 case CKK_EC:
1290 if (!isPoint || !isParams) {
1291 rv = CKR_TEMPLATE_INCOMPLETE;
1292 goto fail_cleanup;
1295 copy_bigint_attr(&point, KEY_PUB_EC_POINT(pbk));
1296 rv = kernel_add_extra_attr(&param_tmp, new_object);
1297 if (rv != CKR_OK)
1298 goto fail_cleanup;
1299 string_attr_cleanup(&param_tmp);
1300 break;
1301 default:
1302 rv = CKR_TEMPLATE_INCONSISTENT;
1303 goto fail_cleanup;
1306 /* Set up object. */
1307 new_object->bool_attr_mask = attr_mask;
1308 if (isLabel) {
1309 rv = kernel_add_extra_attr(&string_tmp, new_object);
1310 if (rv != CKR_OK)
1311 goto fail_cleanup;
1312 string_attr_cleanup(&string_tmp);
1315 return (rv);
1317 fail_cleanup:
1319 * cleanup the storage allocated to the local variables.
1321 bigint_attr_cleanup(&modulus);
1322 bigint_attr_cleanup(&pubexpo);
1323 bigint_attr_cleanup(&prime);
1324 bigint_attr_cleanup(&subprime);
1325 bigint_attr_cleanup(&base);
1326 bigint_attr_cleanup(&value);
1327 bigint_attr_cleanup(&point);
1328 string_attr_cleanup(&string_tmp);
1329 string_attr_cleanup(&param_tmp);
1332 * cleanup the storage allocated inside the object itself.
1334 kernel_cleanup_object(new_object);
1336 return (rv);
1341 * Build a Private Key Object.
1343 * - Parse the object's template, and when an error is detected such as
1344 * invalid attribute type, invalid attribute value, etc., return
1345 * with appropriate return value.
1346 * - Set up attribute mask field in the object for the supplied common
1347 * attributes that have boolean type.
1348 * - Build the attribute_info struct to hold the value of each supplied
1349 * attribute that has byte array type. Link attribute_info structs
1350 * together to form the extra attribute list of the object.
1351 * - Allocate storage for the Private Key object.
1352 * - Build the Private Key object according to the key type. Allocate
1353 * storage to hold the big integer value for the supplied attributes
1354 * that are required for a certain key type.
1357 CK_RV
1358 kernel_build_private_key_object(CK_ATTRIBUTE_PTR template,
1359 CK_ULONG ulAttrNum, kernel_object_t *new_object, kernel_session_t *sp,
1360 uint_t mode)
1362 ulong_t i;
1363 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1364 uint64_t attr_mask = PRIVATE_KEY_DEFAULT;
1365 CK_RV rv = CKR_OK;
1366 int isLabel = 0;
1367 /* Must set flags */
1368 int isModulus = 0;
1369 int isPriExpo = 0;
1370 int isPrime = 0;
1371 int isSubprime = 0;
1372 int isBase = 0;
1373 int isValue = 0;
1374 int isParams = 0;
1375 /* Must not set flags */
1376 int isValueBits = 0;
1377 CK_ULONG value_bits = 0;
1379 /* Private Key RSA optional */
1380 int isPubExpo = 0;
1381 int isPrime1 = 0;
1382 int isPrime2 = 0;
1383 int isExpo1 = 0;
1384 int isExpo2 = 0;
1385 int isCoef = 0;
1387 biginteger_t modulus;
1388 biginteger_t priexpo;
1389 biginteger_t prime;
1390 biginteger_t subprime;
1391 biginteger_t base;
1392 biginteger_t value;
1394 biginteger_t pubexpo;
1395 biginteger_t prime1;
1396 biginteger_t prime2;
1397 biginteger_t expo1;
1398 biginteger_t expo2;
1399 biginteger_t coef;
1400 CK_ATTRIBUTE string_tmp;
1401 CK_ATTRIBUTE param_tmp;
1403 private_key_obj_t *pvk;
1405 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1406 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1407 (void) memset(&priexpo, 0x0, sizeof (biginteger_t));
1408 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1409 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1410 (void) memset(&base, 0x0, sizeof (biginteger_t));
1411 (void) memset(&value, 0x0, sizeof (biginteger_t));
1412 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1413 (void) memset(&prime1, 0x0, sizeof (biginteger_t));
1414 (void) memset(&prime2, 0x0, sizeof (biginteger_t));
1415 (void) memset(&expo1, 0x0, sizeof (biginteger_t));
1416 (void) memset(&expo2, 0x0, sizeof (biginteger_t));
1417 (void) memset(&coef, 0x0, sizeof (biginteger_t));
1418 string_tmp.pValue = NULL;
1419 param_tmp.pValue = NULL;
1421 for (i = 0; i < ulAttrNum; i++) {
1423 /* Private Key Object Attributes */
1424 switch (template[i].type) {
1426 /* common key attributes */
1427 case CKA_KEY_TYPE:
1428 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1429 break;
1431 case CKA_ID:
1432 case CKA_START_DATE:
1433 case CKA_END_DATE:
1435 /* common private key attribute */
1436 case CKA_SUBJECT:
1438 * Allocate storage to hold the attribute
1439 * value with byte array type, and add it to
1440 * the extra attribute list of the object.
1442 rv = kernel_add_extra_attr(&template[i],
1443 new_object);
1444 if (rv != CKR_OK) {
1445 goto fail_cleanup;
1447 break;
1450 * The following key related attribute types must
1451 * not be specified by C_CreateObject.
1453 case CKA_LOCAL:
1454 case CKA_KEY_GEN_MECHANISM:
1455 case CKA_AUTH_PIN_FLAGS:
1456 case CKA_ALWAYS_SENSITIVE:
1457 case CKA_NEVER_EXTRACTABLE:
1458 rv = CKR_TEMPLATE_INCONSISTENT;
1459 goto fail_cleanup;
1461 /* Key related boolean attributes */
1462 case CKA_DERIVE:
1463 if (*(CK_BBOOL *)template[i].pValue)
1464 attr_mask |= DERIVE_BOOL_ON;
1465 break;
1467 case CKA_SENSITIVE:
1468 if (*(CK_BBOOL *)template[i].pValue)
1469 attr_mask |= SENSITIVE_BOOL_ON;
1470 break;
1472 case CKA_SECONDARY_AUTH:
1473 if (*(CK_BBOOL *)template[i].pValue) {
1474 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1475 goto fail_cleanup;
1477 break;
1479 case CKA_DECRYPT:
1480 if (*(CK_BBOOL *)template[i].pValue)
1481 attr_mask |= DECRYPT_BOOL_ON;
1482 else
1483 attr_mask &= ~DECRYPT_BOOL_ON;
1484 break;
1486 case CKA_SIGN:
1487 if (*(CK_BBOOL *)template[i].pValue)
1488 attr_mask |= SIGN_BOOL_ON;
1489 else
1490 attr_mask &= ~SIGN_BOOL_ON;
1491 break;
1493 case CKA_SIGN_RECOVER:
1494 if (*(CK_BBOOL *)template[i].pValue)
1495 attr_mask |= SIGN_RECOVER_BOOL_ON;
1496 else
1497 attr_mask &= ~SIGN_RECOVER_BOOL_ON;
1498 break;
1500 case CKA_UNWRAP:
1501 if (*(CK_BBOOL *)template[i].pValue)
1502 attr_mask |= UNWRAP_BOOL_ON;
1503 break;
1505 case CKA_EXTRACTABLE:
1506 if (*(CK_BBOOL *)template[i].pValue)
1507 attr_mask |= EXTRACTABLE_BOOL_ON;
1508 else
1509 attr_mask &= ~EXTRACTABLE_BOOL_ON;
1510 break;
1513 * The following key related attribute types must
1514 * be specified according to the key type by
1515 * C_CreateObject.
1517 case CKA_MODULUS:
1518 isModulus = 1;
1520 * Copyin big integer attribute from template
1521 * to a local variable.
1523 rv = get_bigint_attr_from_template(&modulus,
1524 &template[i]);
1525 if (rv != CKR_OK)
1526 goto fail_cleanup;
1527 break;
1529 case CKA_PUBLIC_EXPONENT:
1530 isPubExpo = 1;
1531 rv = get_bigint_attr_from_template(&pubexpo,
1532 &template[i]);
1533 if (rv != CKR_OK)
1534 goto fail_cleanup;
1535 break;
1537 case CKA_PRIVATE_EXPONENT:
1538 isPriExpo = 1;
1539 rv = get_bigint_attr_from_template(&priexpo,
1540 &template[i]);
1541 if (rv != CKR_OK)
1542 goto fail_cleanup;
1543 break;
1545 case CKA_PRIME_1:
1546 isPrime1 = 1;
1547 rv = get_bigint_attr_from_template(&prime1,
1548 &template[i]);
1549 if (rv != CKR_OK)
1550 goto fail_cleanup;
1551 break;
1553 case CKA_PRIME_2:
1554 isPrime2 = 1;
1555 rv = get_bigint_attr_from_template(&prime2,
1556 &template[i]);
1557 if (rv != CKR_OK)
1558 goto fail_cleanup;
1559 break;
1561 case CKA_EXPONENT_1:
1562 isExpo1 = 1;
1563 rv = get_bigint_attr_from_template(&expo1,
1564 &template[i]);
1565 if (rv != CKR_OK)
1566 goto fail_cleanup;
1567 break;
1569 case CKA_EXPONENT_2:
1570 isExpo2 = 1;
1571 rv = get_bigint_attr_from_template(&expo2,
1572 &template[i]);
1573 if (rv != CKR_OK)
1574 goto fail_cleanup;
1575 break;
1577 case CKA_COEFFICIENT:
1578 isCoef = 1;
1579 rv = get_bigint_attr_from_template(&coef,
1580 &template[i]);
1581 if (rv != CKR_OK)
1582 goto fail_cleanup;
1583 break;
1585 case CKA_PRIME:
1586 isPrime = 1;
1587 rv = get_bigint_attr_from_template(&prime,
1588 &template[i]);
1589 if (rv != CKR_OK)
1590 goto fail_cleanup;
1591 break;
1593 case CKA_SUBPRIME:
1594 isSubprime = 1;
1595 rv = get_bigint_attr_from_template(&subprime,
1596 &template[i]);
1597 if (rv != CKR_OK)
1598 goto fail_cleanup;
1599 break;
1601 case CKA_BASE:
1602 isBase = 1;
1603 rv = get_bigint_attr_from_template(&base,
1604 &template[i]);
1605 if (rv != CKR_OK)
1606 goto fail_cleanup;
1607 break;
1609 case CKA_VALUE:
1610 isValue = 1;
1611 rv = get_bigint_attr_from_template(&value,
1612 &template[i]);
1613 if (rv != CKR_OK)
1614 goto fail_cleanup;
1615 break;
1617 case CKA_VALUE_BITS:
1618 isValueBits = 1;
1619 get_ulong_attr_from_template(&value_bits,
1620 &template[i]);
1621 break;
1623 case CKA_LABEL:
1624 isLabel = 1;
1625 rv = get_string_from_template(&string_tmp,
1626 &template[i]);
1627 if (rv != CKR_OK)
1628 goto fail_cleanup;
1629 break;
1631 case CKA_EC_PARAMS:
1632 isParams = 1;
1633 rv = get_string_from_template(&param_tmp,
1634 &template[i]);
1635 if (rv != CKR_OK)
1636 goto fail_cleanup;
1637 break;
1639 default:
1640 rv = kernel_parse_common_attrs(&template[i], sp,
1641 &attr_mask);
1642 if (rv != CKR_OK)
1643 goto fail_cleanup;
1644 break;
1647 } /* For */
1649 /* Allocate storage for Private Key Object. */
1650 pvk = calloc(1, sizeof (private_key_obj_t));
1651 if (pvk == NULL) {
1652 rv = CKR_HOST_MEMORY;
1653 goto fail_cleanup;
1656 new_object->object_class_u.private_key = pvk;
1657 new_object->class = CKO_PRIVATE_KEY;
1659 if (keytype == (CK_KEY_TYPE)~0UL) {
1660 rv = CKR_TEMPLATE_INCOMPLETE;
1661 goto fail_cleanup;
1664 new_object->key_type = keytype;
1666 /* Supported key types of the Private Key Object */
1667 switch (keytype) {
1668 case CKK_RSA:
1669 if (isPrime || isSubprime || isBase || isValue ||
1670 isValueBits) {
1671 rv = CKR_TEMPLATE_INCONSISTENT;
1672 goto fail_cleanup;
1675 if (isModulus && isPriExpo) {
1677 * Copy big integer attribute value to the
1678 * designated place in the Private Key object.
1680 copy_bigint_attr(&modulus, KEY_PRI_RSA_MOD(pvk));
1682 copy_bigint_attr(&priexpo, KEY_PRI_RSA_PRIEXPO(pvk));
1684 } else {
1685 rv = CKR_TEMPLATE_INCOMPLETE;
1686 goto fail_cleanup;
1689 /* The following attributes are optional. */
1690 if (isPubExpo) {
1691 copy_bigint_attr(&pubexpo, KEY_PRI_RSA_PUBEXPO(pvk));
1694 if (isPrime1) {
1695 copy_bigint_attr(&prime1, KEY_PRI_RSA_PRIME1(pvk));
1698 if (isPrime2) {
1699 copy_bigint_attr(&prime2, KEY_PRI_RSA_PRIME2(pvk));
1702 if (isExpo1) {
1703 copy_bigint_attr(&expo1, KEY_PRI_RSA_EXPO1(pvk));
1706 if (isExpo2) {
1707 copy_bigint_attr(&expo2, KEY_PRI_RSA_EXPO2(pvk));
1710 if (isCoef) {
1711 copy_bigint_attr(&coef, KEY_PRI_RSA_COEF(pvk));
1713 break;
1715 case CKK_DSA:
1716 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
1717 isPrime2 || isExpo1 || isExpo2 || isCoef ||
1718 isValueBits) {
1719 rv = CKR_TEMPLATE_INCONSISTENT;
1720 goto fail_cleanup;
1723 if (!(isPrime && isSubprime && isBase && isValue)) {
1724 rv = CKR_TEMPLATE_INCOMPLETE;
1725 goto fail_cleanup;
1728 copy_bigint_attr(&prime, KEY_PRI_DSA_PRIME(pvk));
1730 copy_bigint_attr(&subprime, KEY_PRI_DSA_SUBPRIME(pvk));
1732 copy_bigint_attr(&base, KEY_PRI_DSA_BASE(pvk));
1734 copy_bigint_attr(&value, KEY_PRI_DSA_VALUE(pvk));
1736 break;
1738 case CKK_DH:
1739 if (mode == KERNEL_CREATE_OBJ && isValueBits) {
1740 rv = CKR_TEMPLATE_INCONSISTENT;
1741 goto fail_cleanup;
1743 if (!(isPrime && isBase && isValue)) {
1744 rv = CKR_TEMPLATE_INCOMPLETE;
1745 goto fail_cleanup;
1748 copy_bigint_attr(&prime, KEY_PRI_DH_PRIME(pvk));
1750 copy_bigint_attr(&base, KEY_PRI_DH_BASE(pvk));
1752 copy_bigint_attr(&value, KEY_PRI_DH_VALUE(pvk));
1754 KEY_PRI_DH_VAL_BITS(pvk) = (isValueBits) ? value_bits : 0;
1756 break;
1758 case CKK_EC:
1759 if (!isValue || !isParams) {
1760 rv = CKR_TEMPLATE_INCOMPLETE;
1761 goto fail_cleanup;
1764 copy_bigint_attr(&value, KEY_PRI_EC_VALUE(pvk));
1765 rv = kernel_add_extra_attr(&param_tmp, new_object);
1766 if (rv != CKR_OK)
1767 goto fail_cleanup;
1768 string_attr_cleanup(&param_tmp);
1769 break;
1770 default:
1771 rv = CKR_TEMPLATE_INCONSISTENT;
1772 goto fail_cleanup;
1775 /* Set up object. */
1776 new_object->bool_attr_mask = attr_mask;
1777 if (isLabel) {
1778 rv = kernel_add_extra_attr(&string_tmp, new_object);
1779 if (rv != CKR_OK)
1780 goto fail_cleanup;
1781 string_attr_cleanup(&string_tmp);
1784 return (rv);
1786 fail_cleanup:
1788 * cleanup the storage allocated to the local variables.
1790 bigint_attr_cleanup(&modulus);
1791 bigint_attr_cleanup(&priexpo);
1792 bigint_attr_cleanup(&prime);
1793 bigint_attr_cleanup(&subprime);
1794 bigint_attr_cleanup(&base);
1795 bigint_attr_cleanup(&value);
1796 bigint_attr_cleanup(&pubexpo);
1797 bigint_attr_cleanup(&prime1);
1798 bigint_attr_cleanup(&prime2);
1799 bigint_attr_cleanup(&expo1);
1800 bigint_attr_cleanup(&expo2);
1801 bigint_attr_cleanup(&coef);
1802 string_attr_cleanup(&string_tmp);
1803 string_attr_cleanup(&param_tmp);
1806 * cleanup the storage allocated inside the object itself.
1808 kernel_cleanup_object(new_object);
1810 return (rv);
1815 * Build a Secret Key Object.
1817 * - Parse the object's template, and when an error is detected such as
1818 * invalid attribute type, invalid attribute value, etc., return
1819 * with appropriate return value.
1820 * - Set up attribute mask field in the object for the supplied common
1821 * attributes that have boolean type.
1822 * - Build the attribute_info struct to hold the value of each supplied
1823 * attribute that has byte array type. Link attribute_info structs
1824 * together to form the extra attribute list of the object.
1825 * - Allocate storage for the Secret Key object.
1826 * - Build the Secret Key object. Allocate storage to hold the big integer
1827 * value for the attribute CKA_VALUE that is required for all the key
1828 * types supported by secret key object.
1831 CK_RV
1832 kernel_build_secret_key_object(CK_ATTRIBUTE_PTR template,
1833 CK_ULONG ulAttrNum, kernel_object_t *new_object, kernel_session_t *sp)
1836 int i;
1837 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1838 uint64_t attr_mask = SECRET_KEY_DEFAULT;
1839 CK_RV rv = CKR_OK;
1840 int isLabel = 0;
1841 /* Must set flags */
1842 int isValue = 0;
1843 /* Must not set flags */
1844 int isValueLen = 0;
1846 CK_ATTRIBUTE string_tmp;
1848 secret_key_obj_t *sck;
1850 string_tmp.pValue = NULL;
1852 /* Allocate storage for Secret Key Object. */
1853 sck = calloc(1, sizeof (secret_key_obj_t));
1854 if (sck == NULL) {
1855 rv = CKR_HOST_MEMORY;
1856 goto fail_cleanup;
1859 new_object->object_class_u.secret_key = sck;
1860 new_object->class = CKO_SECRET_KEY;
1862 for (i = 0; i < ulAttrNum; i++) {
1864 /* Secret Key Object Attributes */
1865 switch (template[i].type) {
1867 /* common key attributes */
1868 case CKA_KEY_TYPE:
1869 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1870 break;
1872 case CKA_ID:
1873 case CKA_START_DATE:
1874 case CKA_END_DATE:
1876 * Allocate storage to hold the attribute
1877 * value with byte array type, and add it to
1878 * the extra attribute list of the object.
1880 rv = kernel_add_extra_attr(&template[i],
1881 new_object);
1882 if (rv != CKR_OK) {
1883 goto fail_cleanup;
1885 break;
1888 * The following key related attribute types must
1889 * not be specified by C_CreateObject.
1891 case CKA_LOCAL:
1892 case CKA_KEY_GEN_MECHANISM:
1893 case CKA_ALWAYS_SENSITIVE:
1894 case CKA_NEVER_EXTRACTABLE:
1895 rv = CKR_TEMPLATE_INCONSISTENT;
1896 goto fail_cleanup;
1898 /* Key related boolean attributes */
1899 case CKA_DERIVE:
1900 if (*(CK_BBOOL *)template[i].pValue)
1901 attr_mask |= DERIVE_BOOL_ON;
1902 break;
1904 case CKA_SENSITIVE:
1905 if (*(CK_BBOOL *)template[i].pValue)
1906 attr_mask |= SENSITIVE_BOOL_ON;
1907 break;
1909 case CKA_ENCRYPT:
1910 if (*(CK_BBOOL *)template[i].pValue)
1911 attr_mask |= ENCRYPT_BOOL_ON;
1912 else
1913 attr_mask &= ~ENCRYPT_BOOL_ON;
1914 break;
1916 case CKA_DECRYPT:
1917 if (*(CK_BBOOL *)template[i].pValue)
1918 attr_mask |= DECRYPT_BOOL_ON;
1919 else
1920 attr_mask &= ~DECRYPT_BOOL_ON;
1921 break;
1923 case CKA_SIGN:
1924 if (*(CK_BBOOL *)template[i].pValue)
1925 attr_mask |= SIGN_BOOL_ON;
1926 else
1927 attr_mask &= ~SIGN_BOOL_ON;
1928 break;
1930 case CKA_VERIFY:
1931 if (*(CK_BBOOL *)template[i].pValue)
1932 attr_mask |= VERIFY_BOOL_ON;
1933 else
1934 attr_mask &= ~VERIFY_BOOL_ON;
1935 break;
1937 case CKA_WRAP:
1938 if (*(CK_BBOOL *)template[i].pValue)
1939 attr_mask |= WRAP_BOOL_ON;
1940 break;
1942 case CKA_UNWRAP:
1943 if (*(CK_BBOOL *)template[i].pValue)
1944 attr_mask |= UNWRAP_BOOL_ON;
1945 break;
1947 case CKA_EXTRACTABLE:
1948 if (*(CK_BBOOL *)template[i].pValue)
1949 attr_mask |= EXTRACTABLE_BOOL_ON;
1950 else
1951 attr_mask &= ~EXTRACTABLE_BOOL_ON;
1952 break;
1954 case CKA_VALUE:
1955 isValue = 1;
1956 if ((template[i].ulValueLen == 0) ||
1957 (template[i].pValue == NULL)) {
1958 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1959 goto fail_cleanup;
1963 * Copyin attribute from template
1964 * to a local variable.
1966 sck->sk_value = malloc(template[i].ulValueLen);
1967 if (sck->sk_value == NULL) {
1968 rv = CKR_HOST_MEMORY;
1969 goto fail_cleanup;
1971 (void) memcpy(sck->sk_value, template[i].pValue,
1972 template[i].ulValueLen);
1973 sck->sk_value_len = template[i].ulValueLen;
1974 break;
1976 case CKA_VALUE_LEN:
1977 isValueLen = 1;
1978 break;
1980 case CKA_LABEL:
1981 isLabel = 1;
1982 rv = get_string_from_template(&string_tmp,
1983 &template[i]);
1984 if (rv != CKR_OK)
1985 goto fail_cleanup;
1986 break;
1988 default:
1989 rv = kernel_parse_common_attrs(&template[i], sp,
1990 &attr_mask);
1991 if (rv != CKR_OK)
1992 goto fail_cleanup;
1993 break;
1996 } /* For */
1998 if (keytype == (CK_KEY_TYPE)~0UL) {
1999 rv = CKR_TEMPLATE_INCOMPLETE;
2000 goto fail_cleanup;
2003 new_object->key_type = keytype;
2005 /* Supported key types of the Secret Key Object */
2006 switch (keytype) {
2007 case CKK_RC4:
2008 if (!isValue) {
2009 rv = CKR_TEMPLATE_INCOMPLETE;
2010 goto fail_cleanup;
2012 if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) ||
2013 (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) {
2014 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2015 goto fail_cleanup;
2017 break;
2019 case CKK_GENERIC_SECRET:
2020 if (!isValue) {
2021 rv = CKR_TEMPLATE_INCOMPLETE;
2022 goto fail_cleanup;
2024 break;
2026 case CKK_AES:
2027 if (!isValue) {
2028 rv = CKR_TEMPLATE_INCOMPLETE;
2029 goto fail_cleanup;
2031 if (sck->sk_value_len < AES_MIN_KEY_BYTES) {
2032 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2033 goto fail_cleanup;
2035 break;
2037 case CKK_BLOWFISH:
2038 if (!isValue) {
2039 rv = CKR_TEMPLATE_INCOMPLETE;
2040 goto fail_cleanup;
2042 if (sck->sk_value_len < BLOWFISH_MINBYTES) {
2043 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2044 goto fail_cleanup;
2046 break;
2048 case CKK_DES:
2049 if (!isValue) {
2050 rv = CKR_TEMPLATE_INCOMPLETE;
2051 goto fail_cleanup;
2053 if (sck->sk_value_len != DES_KEYSIZE) {
2054 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2055 goto fail_cleanup;
2057 break;
2059 case CKK_DES2:
2060 if (!isValue) {
2061 rv = CKR_TEMPLATE_INCOMPLETE;
2062 goto fail_cleanup;
2064 if (sck->sk_value_len != DES2_KEYSIZE) {
2065 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2066 goto fail_cleanup;
2068 break;
2070 case CKK_DES3:
2071 if (!isValue) {
2072 rv = CKR_TEMPLATE_INCOMPLETE;
2073 goto fail_cleanup;
2075 if (sck->sk_value_len != DES3_KEYSIZE) {
2076 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2077 goto fail_cleanup;
2079 break;
2081 default:
2082 rv = CKR_TEMPLATE_INCONSISTENT;
2083 goto fail_cleanup;
2086 if (isValueLen) {
2087 rv = CKR_TEMPLATE_INCONSISTENT;
2088 goto fail_cleanup;
2091 /* Set up object. */
2092 new_object->bool_attr_mask = attr_mask;
2093 if (isLabel) {
2094 rv = kernel_add_extra_attr(&string_tmp, new_object);
2095 if (rv != CKR_OK)
2096 goto fail_cleanup;
2097 string_attr_cleanup(&string_tmp);
2100 return (rv);
2102 fail_cleanup:
2104 * cleanup the storage allocated to the local variables.
2106 string_attr_cleanup(&string_tmp);
2109 * cleanup the storage allocated inside the object itself.
2111 kernel_cleanup_object(new_object);
2113 return (rv);
2118 * Validate the attribute types in the object's template. Then,
2119 * call the appropriate build function according to the class of
2120 * the object specified in the template.
2122 * Note: The following classes of objects are supported:
2123 * - CKO_SECRET_KEY
2124 * - CKO_PUBLIC_KEY
2125 * - CKO_PRIVATE_KEY
2127 CK_RV
2128 kernel_build_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
2129 kernel_object_t *new_object, kernel_session_t *sp, uint_t mode)
2132 CK_OBJECT_CLASS class = (CK_OBJECT_CLASS)~0UL;
2133 CK_RV rv = CKR_OK;
2135 if (template == NULL) {
2136 return (CKR_ARGUMENTS_BAD);
2139 /* Validate the attribute type in the template. */
2140 rv = kernel_validate_attr(template, ulAttrNum, &class);
2141 if (rv != CKR_OK)
2142 return (rv);
2144 if (class == (CK_OBJECT_CLASS)~0UL)
2145 return (CKR_TEMPLATE_INCOMPLETE);
2148 * Call the appropriate function based on the supported class
2149 * of the object.
2151 switch (class) {
2152 case CKO_PUBLIC_KEY:
2153 rv = kernel_build_public_key_object(template, ulAttrNum,
2154 new_object, sp, mode);
2155 break;
2157 case CKO_PRIVATE_KEY:
2158 rv = kernel_build_private_key_object(template, ulAttrNum,
2159 new_object, sp, mode);
2160 break;
2162 case CKO_SECRET_KEY:
2163 rv = kernel_build_secret_key_object(template, ulAttrNum,
2164 new_object, sp);
2165 break;
2167 case CKO_DOMAIN_PARAMETERS:
2168 case CKO_DATA:
2169 case CKO_CERTIFICATE:
2170 case CKO_HW_FEATURE:
2171 case CKO_VENDOR_DEFINED:
2172 default:
2173 return (CKR_ATTRIBUTE_VALUE_INVALID);
2176 return (rv);
2181 * Get the value of a requested attribute that is common to all supported
2182 * classes (i.e. public key, private key, secret key classes).
2184 CK_RV
2185 kernel_get_common_attrs(kernel_object_t *object_p, CK_ATTRIBUTE_PTR template)
2188 CK_RV rv = CKR_OK;
2190 switch (template->type) {
2192 case CKA_CLASS:
2193 return (get_ulong_attr_from_object(object_p->class,
2194 template));
2196 /* default boolean attributes */
2197 case CKA_TOKEN:
2199 template->ulValueLen = sizeof (CK_BBOOL);
2200 if (template->pValue == NULL) {
2201 return (CKR_OK);
2205 * A token object will not be created in the library, so we
2206 * return FALSE.
2208 *((CK_BBOOL *)template->pValue) = B_FALSE;
2209 break;
2211 case CKA_PRIVATE:
2213 template->ulValueLen = sizeof (CK_BBOOL);
2214 if (template->pValue == NULL) {
2215 return (CKR_OK);
2217 if (object_p->bool_attr_mask & PRIVATE_BOOL_ON) {
2218 *((CK_BBOOL *)template->pValue) = B_TRUE;
2219 } else {
2220 *((CK_BBOOL *)template->pValue) = B_FALSE;
2222 break;
2224 case CKA_MODIFIABLE:
2225 template->ulValueLen = sizeof (CK_BBOOL);
2226 if (template->pValue == NULL) {
2227 return (CKR_OK);
2229 if ((object_p->bool_attr_mask) & MODIFIABLE_BOOL_ON)
2230 *((CK_BBOOL *)template->pValue) = B_TRUE;
2231 else
2232 *((CK_BBOOL *)template->pValue) = B_FALSE;
2233 break;
2235 case CKA_LABEL:
2236 return (get_extra_attr_from_object(object_p,
2237 template));
2239 default:
2241 * The specified attribute for the object is invalid.
2242 * (the object does not possess such an attribute.)
2244 template->ulValueLen = (CK_ULONG)-1;
2245 return (CKR_ATTRIBUTE_TYPE_INVALID);
2248 return (rv);
2252 * Get the value of a requested attribute that is common to all key objects
2253 * (i.e. public key, private key and secret key).
2255 CK_RV
2256 kernel_get_common_key_attrs(kernel_object_t *object_p,
2257 CK_ATTRIBUTE_PTR template)
2260 switch (template->type) {
2262 case CKA_KEY_TYPE:
2263 return (get_ulong_attr_from_object(object_p->key_type,
2264 template));
2266 case CKA_ID:
2267 case CKA_START_DATE:
2268 case CKA_END_DATE:
2270 * The above extra attributes have byte array type.
2272 return (get_extra_attr_from_object(object_p,
2273 template));
2275 /* Key related boolean attributes */
2276 case CKA_LOCAL:
2277 return (get_bool_attr_from_object(object_p,
2278 LOCAL_BOOL_ON, template));
2280 case CKA_DERIVE:
2281 return (get_bool_attr_from_object(object_p,
2282 DERIVE_BOOL_ON, template));
2284 case CKA_KEY_GEN_MECHANISM:
2285 return (get_ulong_attr_from_object(object_p->mechanism,
2286 template));
2288 default:
2289 return (CKR_ATTRIBUTE_TYPE_INVALID);
2295 * Get the value of a requested attribute of a Public Key Object.
2297 * Rule: All the attributes in the public key object can be revealed.
2299 CK_RV
2300 kernel_get_public_key_attribute(kernel_object_t *object_p,
2301 CK_ATTRIBUTE_PTR template)
2304 CK_RV rv = CKR_OK;
2305 CK_KEY_TYPE keytype = object_p->key_type;
2307 switch (template->type) {
2309 case CKA_SUBJECT:
2310 case CKA_EC_PARAMS:
2312 * The above extra attributes have byte array type.
2314 return (get_extra_attr_from_object(object_p,
2315 template));
2317 /* Key related boolean attributes */
2318 case CKA_ENCRYPT:
2319 return (get_bool_attr_from_object(object_p,
2320 ENCRYPT_BOOL_ON, template));
2322 case CKA_VERIFY:
2323 return (get_bool_attr_from_object(object_p,
2324 VERIFY_BOOL_ON, template));
2326 case CKA_VERIFY_RECOVER:
2327 return (get_bool_attr_from_object(object_p,
2328 VERIFY_RECOVER_BOOL_ON, template));
2330 case CKA_WRAP:
2331 return (get_bool_attr_from_object(object_p,
2332 WRAP_BOOL_ON, template));
2334 case CKA_TRUSTED:
2335 return (get_bool_attr_from_object(object_p,
2336 TRUSTED_BOOL_ON, template));
2338 case CKA_MODULUS:
2340 * This attribute is valid only for RSA public key
2341 * object.
2343 if (keytype == CKK_RSA) {
2344 return (get_bigint_attr_from_object(
2345 OBJ_PUB_RSA_MOD(object_p), template));
2346 } else {
2347 template->ulValueLen = (CK_ULONG)-1;
2348 return (CKR_ATTRIBUTE_TYPE_INVALID);
2351 case CKA_PUBLIC_EXPONENT:
2352 if (keytype == CKK_RSA) {
2353 return (get_bigint_attr_from_object(
2354 OBJ_PUB_RSA_PUBEXPO(object_p), template));
2355 } else {
2356 template->ulValueLen = (CK_ULONG)-1;
2357 return (CKR_ATTRIBUTE_TYPE_INVALID);
2360 case CKA_MODULUS_BITS:
2361 if (keytype == CKK_RSA) {
2362 return (get_ulong_attr_from_object(
2363 OBJ_PUB_RSA_MOD_BITS(object_p), template));
2364 } else {
2365 template->ulValueLen = (CK_ULONG)-1;
2366 return (CKR_ATTRIBUTE_TYPE_INVALID);
2369 case CKA_PRIME:
2370 switch (keytype) {
2371 case CKK_DSA:
2372 return (get_bigint_attr_from_object(
2373 OBJ_PUB_DSA_PRIME(object_p), template));
2374 case CKK_DH:
2375 return (get_bigint_attr_from_object(
2376 OBJ_PUB_DH_PRIME(object_p), template));
2377 default:
2378 template->ulValueLen = (CK_ULONG)-1;
2379 return (CKR_ATTRIBUTE_TYPE_INVALID);
2382 case CKA_SUBPRIME:
2383 switch (keytype) {
2384 case CKK_DSA:
2385 return (get_bigint_attr_from_object(
2386 OBJ_PUB_DSA_SUBPRIME(object_p), template));
2387 default:
2388 template->ulValueLen = (CK_ULONG)-1;
2389 return (CKR_ATTRIBUTE_TYPE_INVALID);
2392 case CKA_BASE:
2393 switch (keytype) {
2394 case CKK_DSA:
2395 return (get_bigint_attr_from_object(
2396 OBJ_PUB_DSA_BASE(object_p), template));
2397 case CKK_DH:
2398 return (get_bigint_attr_from_object(
2399 OBJ_PUB_DH_BASE(object_p), template));
2400 default:
2401 template->ulValueLen = (CK_ULONG)-1;
2402 return (CKR_ATTRIBUTE_TYPE_INVALID);
2405 case CKA_VALUE:
2406 switch (keytype) {
2407 case CKK_DSA:
2408 return (get_bigint_attr_from_object(
2409 OBJ_PUB_DSA_VALUE(object_p), template));
2410 case CKK_DH:
2411 return (get_bigint_attr_from_object(
2412 OBJ_PUB_DH_VALUE(object_p), template));
2413 default:
2414 template->ulValueLen = (CK_ULONG)-1;
2415 return (CKR_ATTRIBUTE_TYPE_INVALID);
2418 case CKA_EC_POINT:
2419 switch (keytype) {
2420 case CKK_EC:
2421 return (get_bigint_attr_from_object(
2422 OBJ_PUB_EC_POINT(object_p), template));
2423 default:
2424 template->ulValueLen = (CK_ULONG)-1;
2425 return (CKR_ATTRIBUTE_TYPE_INVALID);
2427 default:
2429 * First, get the value of the request attribute defined
2430 * in the list of common key attributes. If the request
2431 * attribute is not found in that list, then get the
2432 * attribute from the list of common attributes.
2434 rv = kernel_get_common_key_attrs(object_p, template);
2435 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
2436 rv = kernel_get_common_attrs(object_p, template);
2438 break;
2441 return (rv);
2446 * Get the value of a requested attribute of a Private Key Object.
2448 * Rule: All the attributes in the private key object can be revealed
2449 * except those marked with footnote number "7" when the object
2450 * has its CKA_SENSITIVE attribute set to TRUE or its
2451 * CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.).
2453 CK_RV
2454 kernel_get_private_key_attribute(kernel_object_t *object_p,
2455 CK_ATTRIBUTE_PTR template)
2458 CK_RV rv = CKR_OK;
2459 CK_KEY_TYPE keytype = object_p->key_type;
2463 * If the following specified attributes for the private key
2464 * object cannot be revealed because the object is sensitive
2465 * or unextractable, then the ulValueLen is set to -1.
2467 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
2468 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
2470 switch (template->type) {
2471 case CKA_PRIVATE_EXPONENT:
2472 case CKA_PRIME_1:
2473 case CKA_PRIME_2:
2474 case CKA_EXPONENT_1:
2475 case CKA_EXPONENT_2:
2476 case CKA_COEFFICIENT:
2477 case CKA_VALUE:
2478 template->ulValueLen = (CK_ULONG)-1;
2479 return (CKR_ATTRIBUTE_SENSITIVE);
2483 switch (template->type) {
2485 case CKA_SUBJECT:
2486 case CKA_EC_PARAMS:
2488 * The above extra attributes have byte array type.
2490 return (get_extra_attr_from_object(object_p,
2491 template));
2493 /* Key related boolean attributes */
2494 case CKA_SENSITIVE:
2495 return (get_bool_attr_from_object(object_p,
2496 SENSITIVE_BOOL_ON, template));
2498 case CKA_SECONDARY_AUTH:
2499 return (get_bool_attr_from_object(object_p,
2500 SECONDARY_AUTH_BOOL_ON, template));
2502 case CKA_DECRYPT:
2503 return (get_bool_attr_from_object(object_p,
2504 DECRYPT_BOOL_ON, template));
2506 case CKA_SIGN:
2507 return (get_bool_attr_from_object(object_p,
2508 SIGN_BOOL_ON, template));
2510 case CKA_SIGN_RECOVER:
2511 return (get_bool_attr_from_object(object_p,
2512 SIGN_RECOVER_BOOL_ON, template));
2514 case CKA_UNWRAP:
2515 return (get_bool_attr_from_object(object_p,
2516 UNWRAP_BOOL_ON, template));
2518 case CKA_EXTRACTABLE:
2519 return (get_bool_attr_from_object(object_p,
2520 EXTRACTABLE_BOOL_ON, template));
2522 case CKA_ALWAYS_SENSITIVE:
2523 return (get_bool_attr_from_object(object_p,
2524 ALWAYS_SENSITIVE_BOOL_ON, template));
2526 case CKA_NEVER_EXTRACTABLE:
2527 return (get_bool_attr_from_object(object_p,
2528 NEVER_EXTRACTABLE_BOOL_ON, template));
2530 case CKA_MODULUS:
2531 if (keytype == CKK_RSA) {
2532 return (get_bigint_attr_from_object(
2533 OBJ_PRI_RSA_MOD(object_p), template));
2534 } else {
2535 template->ulValueLen = (CK_ULONG)-1;
2536 rv = CKR_ATTRIBUTE_TYPE_INVALID;
2537 break;
2540 case CKA_PUBLIC_EXPONENT:
2541 if (keytype == CKK_RSA) {
2542 return (get_bigint_attr_from_object(
2543 OBJ_PRI_RSA_PUBEXPO(object_p), template));
2544 } else {
2545 template->ulValueLen = (CK_ULONG)-1;
2546 rv = CKR_ATTRIBUTE_TYPE_INVALID;
2547 break;
2550 case CKA_PRIVATE_EXPONENT:
2551 if (keytype == CKK_RSA) {
2552 return (get_bigint_attr_from_object(
2553 OBJ_PRI_RSA_PRIEXPO(object_p), template));
2554 } else {
2555 template->ulValueLen = (CK_ULONG)-1;
2556 rv = CKR_ATTRIBUTE_TYPE_INVALID;
2557 break;
2560 case CKA_PRIME_1:
2561 if (keytype == CKK_RSA) {
2562 return (get_bigint_attr_from_object(
2563 OBJ_PRI_RSA_PRIME1(object_p), template));
2564 } else {
2565 template->ulValueLen = (CK_ULONG)-1;
2566 rv = CKR_ATTRIBUTE_TYPE_INVALID;
2567 break;
2570 case CKA_PRIME_2:
2571 if (keytype == CKK_RSA) {
2572 return (get_bigint_attr_from_object(
2573 OBJ_PRI_RSA_PRIME2(object_p), template));
2574 } else {
2575 template->ulValueLen = (CK_ULONG)-1;
2576 rv = CKR_ATTRIBUTE_TYPE_INVALID;
2577 break;
2580 case CKA_EXPONENT_1:
2581 if (keytype == CKK_RSA) {
2582 return (get_bigint_attr_from_object(
2583 OBJ_PRI_RSA_EXPO1(object_p), template));
2584 } else {
2585 template->ulValueLen = (CK_ULONG)-1;
2586 rv = CKR_ATTRIBUTE_TYPE_INVALID;
2587 break;
2590 case CKA_EXPONENT_2:
2591 if (keytype == CKK_RSA) {
2592 return (get_bigint_attr_from_object(
2593 OBJ_PRI_RSA_EXPO2(object_p), template));
2594 } else {
2595 template->ulValueLen = (CK_ULONG)-1;
2596 rv = CKR_ATTRIBUTE_TYPE_INVALID;
2597 break;
2600 case CKA_COEFFICIENT:
2601 if (keytype == CKK_RSA) {
2602 return (get_bigint_attr_from_object(
2603 OBJ_PRI_RSA_COEF(object_p), template));
2604 } else {
2605 template->ulValueLen = (CK_ULONG)-1;
2606 rv = CKR_ATTRIBUTE_TYPE_INVALID;
2607 break;
2610 case CKA_VALUE_BITS:
2611 if (keytype == CKK_DH) {
2612 return (get_ulong_attr_from_object(
2613 OBJ_PRI_DH_VAL_BITS(object_p), template));
2614 } else {
2615 template->ulValueLen = (CK_ULONG)-1;
2616 rv = CKR_ATTRIBUTE_TYPE_INVALID;
2617 break;
2620 case CKA_PRIME:
2621 switch (keytype) {
2622 case CKK_DSA:
2623 return (get_bigint_attr_from_object(
2624 OBJ_PRI_DSA_PRIME(object_p), template));
2625 case CKK_DH:
2626 return (get_bigint_attr_from_object(
2627 OBJ_PRI_DH_PRIME(object_p), template));
2628 default:
2629 template->ulValueLen = (CK_ULONG)-1;
2630 return (CKR_ATTRIBUTE_TYPE_INVALID);
2633 case CKA_SUBPRIME:
2634 switch (keytype) {
2635 case CKK_DSA:
2636 return (get_bigint_attr_from_object(
2637 OBJ_PRI_DSA_SUBPRIME(object_p), template));
2638 default:
2639 template->ulValueLen = (CK_ULONG)-1;
2640 return (CKR_ATTRIBUTE_TYPE_INVALID);
2643 case CKA_BASE:
2644 switch (keytype) {
2645 case CKK_DSA:
2646 return (get_bigint_attr_from_object(
2647 OBJ_PRI_DSA_BASE(object_p), template));
2648 case CKK_DH:
2649 return (get_bigint_attr_from_object(
2650 OBJ_PRI_DH_BASE(object_p), template));
2651 default:
2652 template->ulValueLen = (CK_ULONG)-1;
2653 return (CKR_ATTRIBUTE_TYPE_INVALID);
2656 case CKA_VALUE:
2657 switch (keytype) {
2658 case CKK_DSA:
2659 return (get_bigint_attr_from_object(
2660 OBJ_PRI_DSA_VALUE(object_p), template));
2661 case CKK_DH:
2662 return (get_bigint_attr_from_object(
2663 OBJ_PRI_DH_VALUE(object_p), template));
2664 case CKK_EC:
2665 return (get_bigint_attr_from_object(
2666 OBJ_PRI_EC_VALUE(object_p), template));
2667 default:
2668 template->ulValueLen = (CK_ULONG)-1;
2669 return (CKR_ATTRIBUTE_TYPE_INVALID);
2672 default:
2674 * First, get the value of the request attribute defined
2675 * in the list of common key attributes. If the request
2676 * attribute is not found in that list, then get the
2677 * attribute from the list of common attributes.
2679 rv = kernel_get_common_key_attrs(object_p, template);
2680 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
2681 rv = kernel_get_common_attrs(object_p, template);
2683 break;
2686 return (rv);
2691 * Get the value of a requested attribute of a Secret Key Object.
2693 * Rule: All the attributes in the secret key object can be revealed
2694 * except those marked with footnote number "7" when the object
2695 * has its CKA_SENSITIVE attribute set to TRUE or its
2696 * CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.).
2698 CK_RV
2699 kernel_get_secret_key_attribute(kernel_object_t *object_p,
2700 CK_ATTRIBUTE_PTR template)
2703 CK_RV rv = CKR_OK;
2704 CK_KEY_TYPE keytype = object_p->key_type;
2706 switch (template->type) {
2708 /* Key related boolean attributes */
2709 case CKA_SENSITIVE:
2710 return (get_bool_attr_from_object(object_p,
2711 SENSITIVE_BOOL_ON, template));
2713 case CKA_ENCRYPT:
2714 return (get_bool_attr_from_object(object_p,
2715 ENCRYPT_BOOL_ON, template));
2717 case CKA_DECRYPT:
2718 return (get_bool_attr_from_object(object_p,
2719 DECRYPT_BOOL_ON, template));
2721 case CKA_SIGN:
2722 return (get_bool_attr_from_object(object_p,
2723 SIGN_BOOL_ON, template));
2725 case CKA_VERIFY:
2726 return (get_bool_attr_from_object(object_p,
2727 VERIFY_BOOL_ON, template));
2729 case CKA_WRAP:
2730 return (get_bool_attr_from_object(object_p,
2731 WRAP_BOOL_ON, template));
2733 case CKA_UNWRAP:
2734 return (get_bool_attr_from_object(object_p,
2735 UNWRAP_BOOL_ON, template));
2737 case CKA_EXTRACTABLE:
2738 return (get_bool_attr_from_object(object_p,
2739 EXTRACTABLE_BOOL_ON, template));
2741 case CKA_ALWAYS_SENSITIVE:
2742 return (get_bool_attr_from_object(object_p,
2743 ALWAYS_SENSITIVE_BOOL_ON, template));
2745 case CKA_NEVER_EXTRACTABLE:
2746 return (get_bool_attr_from_object(object_p,
2747 NEVER_EXTRACTABLE_BOOL_ON, template));
2749 case CKA_VALUE:
2751 * If the specified attribute for the secret key object
2752 * cannot be revealed because the object is sensitive
2753 * or unextractable, then the ulValueLen is set to -1.
2755 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
2756 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
2757 template->ulValueLen = (CK_ULONG)-1;
2758 return (CKR_ATTRIBUTE_SENSITIVE);
2761 switch (keytype) {
2762 case CKK_RC4:
2763 case CKK_GENERIC_SECRET:
2764 case CKK_RC5:
2765 case CKK_DES:
2766 case CKK_DES2:
2767 case CKK_DES3:
2768 case CKK_CDMF:
2769 case CKK_AES:
2770 case CKK_BLOWFISH:
2772 * Copy secret key object attributes to template.
2774 if (template->pValue == NULL) {
2775 template->ulValueLen =
2776 OBJ_SEC_VALUE_LEN(object_p);
2777 return (CKR_OK);
2780 if (OBJ_SEC_VALUE(object_p) == NULL) {
2781 template->ulValueLen = 0;
2782 return (CKR_OK);
2785 if (template->ulValueLen >=
2786 OBJ_SEC_VALUE_LEN(object_p)) {
2787 (void) memcpy(template->pValue,
2788 OBJ_SEC_VALUE(object_p),
2789 OBJ_SEC_VALUE_LEN(object_p));
2790 template->ulValueLen =
2791 OBJ_SEC_VALUE_LEN(object_p);
2792 return (CKR_OK);
2793 } else {
2794 template->ulValueLen = (CK_ULONG)-1;
2795 return (CKR_BUFFER_TOO_SMALL);
2798 default:
2799 template->ulValueLen = (CK_ULONG)-1;
2800 rv = CKR_ATTRIBUTE_TYPE_INVALID;
2801 break;
2803 break;
2805 case CKA_VALUE_LEN:
2806 return (get_ulong_attr_from_object(OBJ_SEC_VALUE_LEN(object_p),
2807 template));
2809 default:
2811 * First, get the value of the request attribute defined
2812 * in the list of common key attributes. If the request
2813 * attribute is not found in that list, then get the
2814 * attribute from the list of common attributes.
2816 rv = kernel_get_common_key_attrs(object_p, template);
2817 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
2818 rv = kernel_get_common_attrs(object_p, template);
2820 break;
2823 return (rv);
2831 * Call the appropriate get attribute function according to the class
2832 * of object.
2834 * The caller of this function holds the lock on the object.
2836 CK_RV
2837 kernel_get_attribute(kernel_object_t *object_p, CK_ATTRIBUTE_PTR template)
2840 CK_RV rv = CKR_OK;
2841 CK_OBJECT_CLASS class = object_p->class;
2843 switch (class) {
2845 case CKO_PUBLIC_KEY:
2846 rv = kernel_get_public_key_attribute(object_p, template);
2847 break;
2849 case CKO_PRIVATE_KEY:
2850 rv = kernel_get_private_key_attribute(object_p, template);
2851 break;
2853 case CKO_SECRET_KEY:
2854 rv = kernel_get_secret_key_attribute(object_p, template);
2855 break;
2857 default:
2859 * If the specified attribute for the object is invalid
2860 * (the object does not possess such as attribute), then
2861 * the ulValueLen is modified to hold the value -1.
2863 template->ulValueLen = (CK_ULONG)-1;
2864 return (CKR_ATTRIBUTE_TYPE_INVALID);
2867 return (rv);
2872 * Set the value of an attribute that is common to all key objects
2873 * (i.e. public key, private key and secret key).
2875 CK_RV
2876 kernel_set_common_key_attribute(kernel_object_t *object_p,
2877 CK_ATTRIBUTE_PTR template, boolean_t copy, kernel_session_t *sp)
2880 kernel_slot_t *pslot = slot_table[sp->ses_slotid];
2881 CK_RV rv = CKR_OK;
2883 switch (template->type) {
2885 case CKA_LABEL:
2887 * Only the LABEL can be modified in the common storage
2888 * object attributes after the object is created.
2890 return (set_extra_attr_to_object(object_p,
2891 CKA_LABEL, template));
2893 case CKA_ID:
2894 return (set_extra_attr_to_object(object_p,
2895 CKA_ID, template));
2897 case CKA_START_DATE:
2898 return (set_extra_attr_to_object(object_p,
2899 CKA_START_DATE, template));
2901 case CKA_END_DATE:
2902 return (set_extra_attr_to_object(object_p,
2903 CKA_END_DATE, template));
2905 case CKA_DERIVE:
2906 return (set_bool_attr_to_object(object_p,
2907 DERIVE_BOOL_ON, template));
2909 case CKA_CLASS:
2910 case CKA_KEY_TYPE:
2911 case CKA_LOCAL:
2912 return (CKR_ATTRIBUTE_READ_ONLY);
2914 case CKA_PRIVATE:
2915 if (!copy) {
2916 /* called from C_SetAttributeValue() */
2917 return (CKR_ATTRIBUTE_READ_ONLY);
2920 /* called from C_CopyObject() */
2921 if ((*(CK_BBOOL *)template->pValue) != B_TRUE) {
2922 return (CKR_OK);
2925 (void) pthread_mutex_lock(&pslot->sl_mutex);
2927 * Cannot create a private object if the token
2928 * has a keystore and the user isn't logged in.
2930 if (pslot->sl_func_list.fl_object_create &&
2931 pslot->sl_state != CKU_USER) {
2932 rv = CKR_USER_NOT_LOGGED_IN;
2933 } else {
2934 rv = set_bool_attr_to_object(object_p,
2935 PRIVATE_BOOL_ON, template);
2937 (void) pthread_mutex_unlock(&pslot->sl_mutex);
2938 return (rv);
2940 case CKA_MODIFIABLE:
2941 if (copy) {
2942 rv = set_bool_attr_to_object(object_p,
2943 MODIFIABLE_BOOL_ON, template);
2944 } else {
2945 rv = CKR_ATTRIBUTE_READ_ONLY;
2947 return (rv);
2949 default:
2950 return (CKR_TEMPLATE_INCONSISTENT);
2957 * Set the value of an attribute of a Public Key Object.
2959 * Rule: The attributes marked with footnote number "8" in the PKCS11
2960 * spec may be modified (p.88 in PKCS11 spec.).
2962 CK_RV
2963 kernel_set_public_key_attribute(kernel_object_t *object_p,
2964 CK_ATTRIBUTE_PTR template, boolean_t copy, kernel_session_t *sp)
2966 CK_KEY_TYPE keytype = object_p->key_type;
2968 switch (template->type) {
2970 case CKA_SUBJECT:
2971 return (set_extra_attr_to_object(object_p,
2972 CKA_SUBJECT, template));
2974 case CKA_ENCRYPT:
2975 return (set_bool_attr_to_object(object_p,
2976 ENCRYPT_BOOL_ON, template));
2978 case CKA_VERIFY:
2979 return (set_bool_attr_to_object(object_p,
2980 VERIFY_BOOL_ON, template));
2982 case CKA_VERIFY_RECOVER:
2983 return (set_bool_attr_to_object(object_p,
2984 VERIFY_RECOVER_BOOL_ON, template));
2986 case CKA_WRAP:
2987 return (set_bool_attr_to_object(object_p,
2988 WRAP_BOOL_ON, template));
2990 case CKA_MODULUS:
2991 case CKA_MODULUS_BITS:
2992 case CKA_PUBLIC_EXPONENT:
2993 if (keytype == CKK_RSA)
2994 return (CKR_ATTRIBUTE_READ_ONLY);
2995 break;
2997 case CKA_SUBPRIME:
2998 case CKA_PRIME:
2999 case CKA_BASE:
3000 case CKA_VALUE:
3001 if (keytype == CKK_DSA)
3002 return (CKR_ATTRIBUTE_READ_ONLY);
3003 break;
3005 default:
3007 * Set the value of a common key attribute.
3009 return (kernel_set_common_key_attribute(object_p,
3010 template, copy, sp));
3015 * If we got this far, then the combination of key type
3016 * and requested attribute is invalid.
3018 return (CKR_ATTRIBUTE_TYPE_INVALID);
3023 * Set the value of an attribute of a Private Key Object.
3025 * Rule: The attributes marked with footnote number "8" in the PKCS11
3026 * spec may be modified (p.88 in PKCS11 spec.).
3028 CK_RV
3029 kernel_set_private_key_attribute(kernel_object_t *object_p,
3030 CK_ATTRIBUTE_PTR template, boolean_t copy, kernel_session_t *sp)
3032 CK_KEY_TYPE keytype = object_p->key_type;
3034 switch (template->type) {
3036 case CKA_SUBJECT:
3037 return (set_extra_attr_to_object(object_p,
3038 CKA_SUBJECT, template));
3040 case CKA_SENSITIVE:
3042 * Cannot set SENSITIVE to FALSE if it is already ON.
3044 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
3045 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
3046 return (CKR_ATTRIBUTE_READ_ONLY);
3049 if (*(CK_BBOOL *)template->pValue)
3050 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
3051 return (CKR_OK);
3053 case CKA_DECRYPT:
3054 return (set_bool_attr_to_object(object_p,
3055 DECRYPT_BOOL_ON, template));
3057 case CKA_SIGN:
3058 return (set_bool_attr_to_object(object_p,
3059 SIGN_BOOL_ON, template));
3061 case CKA_SIGN_RECOVER:
3062 return (set_bool_attr_to_object(object_p,
3063 SIGN_RECOVER_BOOL_ON, template));
3065 case CKA_UNWRAP:
3066 return (set_bool_attr_to_object(object_p,
3067 UNWRAP_BOOL_ON, template));
3069 case CKA_EXTRACTABLE:
3071 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
3073 if ((*(CK_BBOOL *)template->pValue) &&
3074 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
3075 return (CKR_ATTRIBUTE_READ_ONLY);
3078 if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
3079 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
3080 return (CKR_OK);
3082 case CKA_MODULUS:
3083 case CKA_PUBLIC_EXPONENT:
3084 case CKA_PRIVATE_EXPONENT:
3085 case CKA_PRIME_1:
3086 case CKA_PRIME_2:
3087 case CKA_EXPONENT_1:
3088 case CKA_EXPONENT_2:
3089 case CKA_COEFFICIENT:
3090 if (keytype == CKK_RSA) {
3091 return (CKR_ATTRIBUTE_READ_ONLY);
3093 break;
3095 case CKA_SUBPRIME:
3096 case CKA_PRIME:
3097 case CKA_BASE:
3098 case CKA_VALUE:
3099 if (keytype == CKK_DSA)
3100 return (CKR_ATTRIBUTE_READ_ONLY);
3101 break;
3103 default:
3105 * Set the value of a common key attribute.
3107 return (kernel_set_common_key_attribute(object_p,
3108 template, copy, sp));
3112 * If we got this far, then the combination of key type
3113 * and requested attribute is invalid.
3115 return (CKR_ATTRIBUTE_TYPE_INVALID);
3121 * Set the value of an attribute of a Secret Key Object.
3123 * Rule: The attributes marked with footnote number "8" in the PKCS11
3124 * spec may be modified (p.88 in PKCS11 spec.).
3126 CK_RV
3127 kernel_set_secret_key_attribute(kernel_object_t *object_p,
3128 CK_ATTRIBUTE_PTR template, boolean_t copy, kernel_session_t *sp)
3130 CK_KEY_TYPE keytype = object_p->key_type;
3132 switch (template->type) {
3134 case CKA_SENSITIVE:
3136 * Cannot set SENSITIVE to FALSE if it is already ON.
3138 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
3139 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
3140 return (CKR_ATTRIBUTE_READ_ONLY);
3143 if (*(CK_BBOOL *)template->pValue)
3144 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
3145 return (CKR_OK);
3147 case CKA_ENCRYPT:
3148 return (set_bool_attr_to_object(object_p,
3149 ENCRYPT_BOOL_ON, template));
3151 case CKA_DECRYPT:
3152 return (set_bool_attr_to_object(object_p,
3153 DECRYPT_BOOL_ON, template));
3155 case CKA_SIGN:
3156 return (set_bool_attr_to_object(object_p,
3157 SIGN_BOOL_ON, template));
3159 case CKA_VERIFY:
3160 return (set_bool_attr_to_object(object_p,
3161 VERIFY_BOOL_ON, template));
3163 case CKA_WRAP:
3164 return (set_bool_attr_to_object(object_p,
3165 WRAP_BOOL_ON, template));
3167 case CKA_UNWRAP:
3168 return (set_bool_attr_to_object(object_p,
3169 UNWRAP_BOOL_ON, template));
3171 case CKA_EXTRACTABLE:
3173 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
3175 if ((*(CK_BBOOL *)template->pValue) &&
3176 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
3177 return (CKR_ATTRIBUTE_READ_ONLY);
3180 if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
3181 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
3182 return (CKR_OK);
3184 case CKA_VALUE:
3185 return (CKR_ATTRIBUTE_READ_ONLY);
3187 case CKA_VALUE_LEN:
3188 if ((keytype == CKK_RC4) ||
3189 (keytype == CKK_GENERIC_SECRET) ||
3190 (keytype == CKK_AES) ||
3191 (keytype == CKK_BLOWFISH))
3192 return (CKR_ATTRIBUTE_READ_ONLY);
3193 break;
3195 default:
3197 * Set the value of a common key attribute.
3199 return (kernel_set_common_key_attribute(object_p,
3200 template, copy, sp));
3204 * If we got this far, then the combination of key type
3205 * and requested attribute is invalid.
3207 return (CKR_ATTRIBUTE_TYPE_INVALID);
3212 * Call the appropriate set attribute function according to the class
3213 * of object.
3215 * The caller of this function does not hold the lock on the original
3216 * object, since this function is setting the attribute on the new object
3217 * that is being modified.
3220 CK_RV
3221 kernel_set_attribute(kernel_object_t *object_p, CK_ATTRIBUTE_PTR template,
3222 boolean_t copy, kernel_session_t *sp)
3225 CK_RV rv = CKR_OK;
3226 CK_OBJECT_CLASS class = object_p->class;
3228 switch (class) {
3230 case CKO_PUBLIC_KEY:
3231 rv = kernel_set_public_key_attribute(object_p, template,
3232 copy, sp);
3233 break;
3235 case CKO_PRIVATE_KEY:
3236 rv = kernel_set_private_key_attribute(object_p, template,
3237 copy, sp);
3238 break;
3240 case CKO_SECRET_KEY:
3241 rv = kernel_set_secret_key_attribute(object_p, template,
3242 copy, sp);
3243 break;
3245 default:
3247 * If the template specifies a value of an attribute
3248 * which is incompatible with other existing attributes
3249 * of the object, then fails with return code
3250 * CKR_TEMPLATE_INCONSISTENT.
3252 rv = CKR_TEMPLATE_INCONSISTENT;
3253 break;
3256 return (rv);
3260 static CK_RV
3261 copy_bigint(biginteger_t *new_bigint, biginteger_t *old_bigint)
3263 new_bigint->big_value =
3264 malloc((sizeof (CK_BYTE) * new_bigint->big_value_len));
3266 if (new_bigint->big_value == NULL) {
3267 return (CKR_HOST_MEMORY);
3270 (void) memcpy(new_bigint->big_value, old_bigint->big_value,
3271 (sizeof (CK_BYTE) * new_bigint->big_value_len));
3273 return (CKR_OK);
3276 static void
3277 free_public_key_attr(public_key_obj_t *pbk, CK_KEY_TYPE key_type)
3279 if (pbk == NULL) {
3280 return;
3283 switch (key_type) {
3284 case CKK_RSA:
3285 bigint_attr_cleanup(KEY_PUB_RSA_MOD(pbk));
3286 bigint_attr_cleanup(KEY_PUB_RSA_PUBEXPO(pbk));
3287 break;
3288 case CKK_DSA:
3289 bigint_attr_cleanup(KEY_PUB_DSA_PRIME(pbk));
3290 bigint_attr_cleanup(KEY_PUB_DSA_SUBPRIME(pbk));
3291 bigint_attr_cleanup(KEY_PUB_DSA_BASE(pbk));
3292 bigint_attr_cleanup(KEY_PUB_DSA_VALUE(pbk));
3293 break;
3294 default:
3295 break;
3297 free(pbk);
3301 CK_RV
3302 kernel_copy_public_key_attr(public_key_obj_t *old_pub_key_obj_p,
3303 public_key_obj_t **new_pub_key_obj_p, CK_KEY_TYPE key_type)
3306 public_key_obj_t *pbk;
3307 CK_RV rv = CKR_OK;
3309 pbk = calloc(1, sizeof (public_key_obj_t));
3310 if (pbk == NULL) {
3311 return (CKR_HOST_MEMORY);
3314 switch (key_type) {
3315 case CKK_RSA:
3316 (void) memcpy(KEY_PUB_RSA(pbk),
3317 KEY_PUB_RSA(old_pub_key_obj_p),
3318 sizeof (rsa_pub_key_t));
3319 /* copy modulus */
3320 rv = copy_bigint(KEY_PUB_RSA_MOD(pbk),
3321 KEY_PUB_RSA_MOD(old_pub_key_obj_p));
3322 if (rv != CKR_OK) {
3323 free_public_key_attr(pbk, key_type);
3324 return (rv);
3326 /* copy public exponent */
3327 rv = copy_bigint(KEY_PUB_RSA_PUBEXPO(pbk),
3328 KEY_PUB_RSA_PUBEXPO(old_pub_key_obj_p));
3329 if (rv != CKR_OK) {
3330 free_public_key_attr(pbk, key_type);
3331 return (rv);
3333 break;
3334 case CKK_DSA:
3335 (void) memcpy(KEY_PUB_DSA(pbk),
3336 KEY_PUB_DSA(old_pub_key_obj_p),
3337 sizeof (dsa_pub_key_t));
3339 /* copy prime */
3340 rv = copy_bigint(KEY_PUB_DSA_PRIME(pbk),
3341 KEY_PUB_DSA_PRIME(old_pub_key_obj_p));
3342 if (rv != CKR_OK) {
3343 free_public_key_attr(pbk, key_type);
3344 return (rv);
3347 /* copy subprime */
3348 rv = copy_bigint(KEY_PUB_DSA_SUBPRIME(pbk),
3349 KEY_PUB_DSA_SUBPRIME(old_pub_key_obj_p));
3350 if (rv != CKR_OK) {
3351 free_public_key_attr(pbk, key_type);
3352 return (rv);
3355 /* copy base */
3356 rv = copy_bigint(KEY_PUB_DSA_BASE(pbk),
3357 KEY_PUB_DSA_BASE(old_pub_key_obj_p));
3358 if (rv != CKR_OK) {
3359 free_public_key_attr(pbk, key_type);
3360 return (rv);
3363 /* copy value */
3364 rv = copy_bigint(KEY_PUB_DSA_VALUE(pbk),
3365 KEY_PUB_DSA_VALUE(old_pub_key_obj_p));
3366 if (rv != CKR_OK) {
3367 free_public_key_attr(pbk, key_type);
3368 return (rv);
3370 break;
3371 default:
3372 break;
3374 *new_pub_key_obj_p = pbk;
3375 return (rv);
3379 static void
3380 free_private_key_attr(private_key_obj_t *pbk, CK_KEY_TYPE key_type)
3382 if (pbk == NULL) {
3383 return;
3386 switch (key_type) {
3387 case CKK_RSA:
3388 bigint_attr_cleanup(KEY_PRI_RSA_MOD(pbk));
3389 bigint_attr_cleanup(KEY_PRI_RSA_PUBEXPO(pbk));
3390 bigint_attr_cleanup(KEY_PRI_RSA_PRIEXPO(pbk));
3391 bigint_attr_cleanup(KEY_PRI_RSA_PRIME1(pbk));
3392 bigint_attr_cleanup(KEY_PRI_RSA_PRIME2(pbk));
3393 bigint_attr_cleanup(KEY_PRI_RSA_EXPO1(pbk));
3394 bigint_attr_cleanup(KEY_PRI_RSA_EXPO2(pbk));
3395 bigint_attr_cleanup(KEY_PRI_RSA_COEF(pbk));
3396 break;
3397 case CKK_DSA:
3398 bigint_attr_cleanup(KEY_PRI_DSA_PRIME(pbk));
3399 bigint_attr_cleanup(KEY_PRI_DSA_SUBPRIME(pbk));
3400 bigint_attr_cleanup(KEY_PRI_DSA_BASE(pbk));
3401 bigint_attr_cleanup(KEY_PRI_DSA_VALUE(pbk));
3402 break;
3403 default:
3404 break;
3406 free(pbk);
3409 CK_RV
3410 kernel_copy_private_key_attr(private_key_obj_t *old_pri_key_obj_p,
3411 private_key_obj_t **new_pri_key_obj_p, CK_KEY_TYPE key_type)
3413 CK_RV rv = CKR_OK;
3414 private_key_obj_t *pbk;
3416 pbk = calloc(1, sizeof (private_key_obj_t));
3417 if (pbk == NULL) {
3418 return (CKR_HOST_MEMORY);
3421 switch (key_type) {
3422 case CKK_RSA:
3423 (void) memcpy(KEY_PRI_RSA(pbk),
3424 KEY_PRI_RSA(old_pri_key_obj_p),
3425 sizeof (rsa_pri_key_t));
3426 /* copy modulus */
3427 rv = copy_bigint(KEY_PRI_RSA_MOD(pbk),
3428 KEY_PRI_RSA_MOD(old_pri_key_obj_p));
3429 if (rv != CKR_OK) {
3430 free_private_key_attr(pbk, key_type);
3431 return (rv);
3433 /* copy public exponent */
3434 rv = copy_bigint(KEY_PRI_RSA_PUBEXPO(pbk),
3435 KEY_PRI_RSA_PUBEXPO(old_pri_key_obj_p));
3436 if (rv != CKR_OK) {
3437 free_private_key_attr(pbk, key_type);
3438 return (rv);
3440 /* copy private exponent */
3441 rv = copy_bigint(KEY_PRI_RSA_PRIEXPO(pbk),
3442 KEY_PRI_RSA_PRIEXPO(old_pri_key_obj_p));
3443 if (rv != CKR_OK) {
3444 free_private_key_attr(pbk, key_type);
3445 return (rv);
3447 /* copy prime_1 */
3448 rv = copy_bigint(KEY_PRI_RSA_PRIME1(pbk),
3449 KEY_PRI_RSA_PRIME1(old_pri_key_obj_p));
3450 if (rv != CKR_OK) {
3451 free_private_key_attr(pbk, key_type);
3452 return (rv);
3454 /* copy prime_2 */
3455 rv = copy_bigint(KEY_PRI_RSA_PRIME2(pbk),
3456 KEY_PRI_RSA_PRIME2(old_pri_key_obj_p));
3457 if (rv != CKR_OK) {
3458 free_private_key_attr(pbk, key_type);
3459 return (rv);
3461 /* copy exponent_1 */
3462 rv = copy_bigint(KEY_PRI_RSA_EXPO1(pbk),
3463 KEY_PRI_RSA_EXPO1(old_pri_key_obj_p));
3464 if (rv != CKR_OK) {
3465 free_private_key_attr(pbk, key_type);
3466 return (rv);
3468 /* copy exponent_2 */
3469 rv = copy_bigint(KEY_PRI_RSA_EXPO2(pbk),
3470 KEY_PRI_RSA_EXPO2(old_pri_key_obj_p));
3471 if (rv != CKR_OK) {
3472 free_private_key_attr(pbk, key_type);
3473 return (rv);
3475 /* copy coefficient */
3476 rv = copy_bigint(KEY_PRI_RSA_COEF(pbk),
3477 KEY_PRI_RSA_COEF(old_pri_key_obj_p));
3478 if (rv != CKR_OK) {
3479 free_private_key_attr(pbk, key_type);
3480 return (rv);
3482 break;
3483 case CKK_DSA:
3484 (void) memcpy(KEY_PRI_DSA(pbk),
3485 KEY_PRI_DSA(old_pri_key_obj_p),
3486 sizeof (dsa_pri_key_t));
3488 /* copy prime */
3489 rv = copy_bigint(KEY_PRI_DSA_PRIME(pbk),
3490 KEY_PRI_DSA_PRIME(old_pri_key_obj_p));
3491 if (rv != CKR_OK) {
3492 free_private_key_attr(pbk, key_type);
3493 return (rv);
3496 /* copy subprime */
3497 rv = copy_bigint(KEY_PRI_DSA_SUBPRIME(pbk),
3498 KEY_PRI_DSA_SUBPRIME(old_pri_key_obj_p));
3499 if (rv != CKR_OK) {
3500 free_private_key_attr(pbk, key_type);
3501 return (rv);
3504 /* copy base */
3505 rv = copy_bigint(KEY_PRI_DSA_BASE(pbk),
3506 KEY_PRI_DSA_BASE(old_pri_key_obj_p));
3507 if (rv != CKR_OK) {
3508 free_private_key_attr(pbk, key_type);
3509 return (rv);
3512 /* copy value */
3513 rv = copy_bigint(KEY_PRI_DSA_VALUE(pbk),
3514 KEY_PRI_DSA_VALUE(old_pri_key_obj_p));
3515 if (rv != CKR_OK) {
3516 free_private_key_attr(pbk, key_type);
3517 return (rv);
3519 break;
3520 default:
3521 break;
3523 *new_pri_key_obj_p = pbk;
3524 return (rv);
3528 CK_RV
3529 kernel_copy_secret_key_attr(secret_key_obj_t *old_secret_key_obj_p,
3530 secret_key_obj_t **new_secret_key_obj_p)
3532 secret_key_obj_t *sk;
3534 sk = malloc(sizeof (secret_key_obj_t));
3535 if (sk == NULL) {
3536 return (CKR_HOST_MEMORY);
3538 (void) memcpy(sk, old_secret_key_obj_p, sizeof (secret_key_obj_t));
3540 /* copy the secret key value */
3541 sk->sk_value = malloc((sizeof (CK_BYTE) * sk->sk_value_len));
3542 if (sk->sk_value == NULL) {
3543 free(sk);
3544 return (CKR_HOST_MEMORY);
3546 (void) memcpy(sk->sk_value, old_secret_key_obj_p->sk_value,
3547 (sizeof (CK_BYTE) * sk->sk_value_len));
3549 *new_secret_key_obj_p = sk;
3551 return (CKR_OK);
3557 * If CKA_CLASS not given, guess CKA_CLASS using
3558 * attributes on template .
3560 * Some attributes are specific to an object class. If one or more
3561 * of these attributes are in the template, make a list of classes
3562 * that can have these attributes. This would speed up the search later,
3563 * because we can immediately skip an object if the class of that
3564 * object can not possibly contain one of the attributes.
3567 void
3568 kernel_process_find_attr(CK_OBJECT_CLASS *pclasses,
3569 CK_ULONG *num_result_pclasses, CK_ATTRIBUTE_PTR pTemplate,
3570 CK_ULONG ulCount)
3572 ulong_t i;
3573 int j;
3574 boolean_t pub_found = B_FALSE,
3575 priv_found = B_FALSE,
3576 secret_found = B_FALSE,
3577 domain_found = B_FALSE,
3578 hardware_found = B_FALSE,
3579 cert_found = B_FALSE;
3580 int num_pub_key_attrs, num_priv_key_attrs,
3581 num_secret_key_attrs, num_domain_attrs,
3582 num_hardware_attrs, num_cert_attrs;
3583 int num_pclasses = 0;
3585 for (i = 0; i < ulCount; i++) {
3586 if (pTemplate[i].type == CKA_CLASS) {
3588 * don't need to guess the class, it is specified.
3589 * Just record the class, and return.
3591 pclasses[0] =
3592 (*((CK_OBJECT_CLASS *)pTemplate[i].pValue));
3593 *num_result_pclasses = 1;
3594 return;
3598 num_pub_key_attrs =
3599 sizeof (PUB_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
3600 num_priv_key_attrs =
3601 sizeof (PRIV_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
3602 num_secret_key_attrs =
3603 sizeof (SECRET_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
3604 num_domain_attrs =
3605 sizeof (DOMAIN_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
3606 num_hardware_attrs =
3607 sizeof (HARDWARE_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
3608 num_cert_attrs =
3609 sizeof (CERT_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
3612 * Get the list of objects class that might contain
3613 * some attributes.
3615 for (i = 0; i < ulCount; i++) {
3617 * only check if this attribute can belong to public key object
3618 * class if public key object isn't already in the list
3620 if (!pub_found) {
3621 for (j = 0; j < num_pub_key_attrs; j++) {
3622 if (pTemplate[i].type == PUB_KEY_ATTRS[j]) {
3623 pub_found = B_TRUE;
3624 pclasses[num_pclasses++] =
3625 CKO_PUBLIC_KEY;
3626 break;
3631 if (!priv_found) {
3632 for (j = 0; j < num_priv_key_attrs; j++) {
3633 if (pTemplate[i].type == PRIV_KEY_ATTRS[j]) {
3634 priv_found = B_TRUE;
3635 pclasses[num_pclasses++] =
3636 CKO_PRIVATE_KEY;
3637 break;
3642 if (!secret_found) {
3643 for (j = 0; j < num_secret_key_attrs; j++) {
3644 if (pTemplate[i].type == SECRET_KEY_ATTRS[j]) {
3645 secret_found = B_TRUE;
3646 pclasses[num_pclasses++] =
3647 CKO_SECRET_KEY;
3648 break;
3653 if (!domain_found) {
3654 for (j = 0; j < num_domain_attrs; j++) {
3655 if (pTemplate[i].type == DOMAIN_ATTRS[j]) {
3656 domain_found = B_TRUE;
3657 pclasses[num_pclasses++] =
3658 CKO_DOMAIN_PARAMETERS;
3659 break;
3664 if (!hardware_found) {
3665 for (j = 0; j < num_hardware_attrs; j++) {
3666 if (pTemplate[i].type == HARDWARE_ATTRS[j]) {
3667 hardware_found = B_TRUE;
3668 pclasses[num_pclasses++] =
3669 CKO_HW_FEATURE;
3670 break;
3675 if (!cert_found) {
3676 for (j = 0; j < num_cert_attrs; j++) {
3677 if (pTemplate[i].type == CERT_ATTRS[j]) {
3678 cert_found = B_TRUE;
3679 pclasses[num_pclasses++] =
3680 CKO_CERTIFICATE;
3681 break;
3686 *num_result_pclasses = num_pclasses;
3690 boolean_t
3691 kernel_find_match_attrs(kernel_object_t *obj, CK_OBJECT_CLASS *pclasses,
3692 CK_ULONG num_pclasses, CK_ATTRIBUTE *template, CK_ULONG num_attr)
3694 ulong_t i;
3695 CK_ATTRIBUTE *tmpl_attr, *obj_attr;
3696 uint64_t attr_mask;
3697 biginteger_t *bigint;
3698 boolean_t compare_attr, compare_bigint, compare_boolean;
3701 * Check if the class of this object match with any
3702 * of object classes that can possibly contain the
3703 * requested attributes.
3705 if (num_pclasses > 0) {
3706 for (i = 0; i < num_pclasses; i++) {
3707 if (obj->class == pclasses[i]) {
3708 break;
3711 if (i == num_pclasses) {
3713 * this object can't possibly contain one or
3714 * more attributes, don't need to check this object
3716 return (B_FALSE);
3720 /* need to examine everything */
3721 for (i = 0; i < num_attr; i++) {
3722 tmpl_attr = &(template[i]);
3723 compare_attr = B_FALSE;
3724 compare_bigint = B_FALSE;
3725 compare_boolean = B_FALSE;
3726 switch (tmpl_attr->type) {
3727 /* First, check the most common attributes */
3728 case CKA_CLASS:
3729 if (*((CK_OBJECT_CLASS *)tmpl_attr->pValue) !=
3730 obj->class) {
3731 return (B_FALSE);
3733 break;
3734 case CKA_KEY_TYPE:
3735 if (*((CK_KEY_TYPE *)tmpl_attr->pValue) !=
3736 obj->key_type) {
3737 return (B_FALSE);
3739 break;
3740 case CKA_ENCRYPT:
3741 attr_mask = (obj->bool_attr_mask) & ENCRYPT_BOOL_ON;
3742 compare_boolean = B_TRUE;
3743 break;
3744 case CKA_DECRYPT:
3745 attr_mask = (obj->bool_attr_mask) & DECRYPT_BOOL_ON;
3746 compare_boolean = B_TRUE;
3747 break;
3748 case CKA_WRAP:
3749 attr_mask = (obj->bool_attr_mask) & WRAP_BOOL_ON;
3750 compare_boolean = B_TRUE;
3751 break;
3752 case CKA_UNWRAP:
3753 attr_mask = (obj->bool_attr_mask) & UNWRAP_BOOL_ON;
3754 compare_boolean = B_TRUE;
3755 break;
3756 case CKA_SIGN:
3757 attr_mask = (obj->bool_attr_mask) & SIGN_BOOL_ON;
3758 compare_boolean = B_TRUE;
3759 break;
3760 case CKA_SIGN_RECOVER:
3761 attr_mask = (obj->bool_attr_mask) &
3762 SIGN_RECOVER_BOOL_ON;
3763 compare_boolean = B_TRUE;
3764 break;
3765 case CKA_VERIFY:
3766 attr_mask = (obj->bool_attr_mask) & VERIFY_BOOL_ON;
3767 compare_boolean = B_TRUE;
3768 break;
3769 case CKA_VERIFY_RECOVER:
3770 attr_mask = (obj->bool_attr_mask) &
3771 VERIFY_RECOVER_BOOL_ON;
3772 compare_boolean = B_TRUE;
3773 break;
3774 case CKA_DERIVE:
3775 attr_mask = (obj->bool_attr_mask) & DERIVE_BOOL_ON;
3776 compare_boolean = B_TRUE;
3777 break;
3778 case CKA_LOCAL:
3779 attr_mask = (obj->bool_attr_mask) & LOCAL_BOOL_ON;
3780 compare_boolean = B_TRUE;
3781 break;
3782 case CKA_SENSITIVE:
3783 attr_mask = (obj->bool_attr_mask) & SENSITIVE_BOOL_ON;
3784 compare_boolean = B_TRUE;
3785 break;
3786 case CKA_SECONDARY_AUTH:
3787 attr_mask = (obj->bool_attr_mask) &
3788 SECONDARY_AUTH_BOOL_ON;
3789 compare_boolean = B_TRUE;
3790 break;
3791 case CKA_TRUSTED:
3792 attr_mask = (obj->bool_attr_mask) & TRUSTED_BOOL_ON;
3793 compare_boolean = B_TRUE;
3794 break;
3795 case CKA_EXTRACTABLE:
3796 attr_mask = (obj->bool_attr_mask) &
3797 EXTRACTABLE_BOOL_ON;
3798 compare_boolean = B_TRUE;
3799 break;
3800 case CKA_ALWAYS_SENSITIVE:
3801 attr_mask = (obj->bool_attr_mask) &
3802 ALWAYS_SENSITIVE_BOOL_ON;
3803 compare_boolean = B_TRUE;
3804 break;
3805 case CKA_NEVER_EXTRACTABLE:
3806 attr_mask = (obj->bool_attr_mask) &
3807 NEVER_EXTRACTABLE_BOOL_ON;
3808 compare_boolean = B_TRUE;
3809 break;
3810 case CKA_TOKEN:
3812 * CKA_TOKEN value is not applicable to an object
3813 * created in the library, it should only contain
3814 * the default value FALSE
3816 attr_mask = 0;
3817 compare_boolean = B_TRUE;
3818 break;
3819 case CKA_PRIVATE:
3820 attr_mask = (obj->bool_attr_mask) & PRIVATE_BOOL_ON;
3821 compare_boolean = B_TRUE;
3822 break;
3823 case CKA_MODIFIABLE:
3824 attr_mask = (obj->bool_attr_mask) & MODIFIABLE_BOOL_ON;
3825 compare_boolean = B_TRUE;
3826 break;
3827 case CKA_SUBJECT:
3828 case CKA_ID:
3829 case CKA_START_DATE:
3830 case CKA_END_DATE:
3831 case CKA_KEY_GEN_MECHANISM:
3832 case CKA_LABEL:
3833 /* find these attributes from extra_attrlistp */
3834 obj_attr = get_extra_attr(tmpl_attr->type, obj);
3835 compare_attr = B_TRUE;
3836 break;
3837 case CKA_VALUE_LEN:
3838 /* only secret key has this attribute */
3839 if (obj->class == CKO_SECRET_KEY) {
3840 if (*((CK_ULONG *)tmpl_attr->pValue) !=
3841 OBJ_SEC_VALUE_LEN(obj)) {
3842 return (B_FALSE);
3844 } else {
3845 return (B_FALSE);
3847 break;
3848 case CKA_VALUE:
3849 switch (obj->class) {
3850 case CKO_SECRET_KEY:
3852 * secret_key_obj_t is the same as
3853 * biginteger_t
3855 bigint = (biginteger_t *)OBJ_SEC(obj);
3856 break;
3857 case CKO_PRIVATE_KEY:
3858 if (obj->key_type == CKK_DSA) {
3859 bigint = OBJ_PRI_DSA_VALUE(obj);
3860 } else {
3861 return (B_FALSE);
3863 break;
3864 case CKO_PUBLIC_KEY:
3865 if (obj->key_type == CKK_DSA) {
3866 bigint = OBJ_PUB_DSA_VALUE(obj);
3867 } else {
3868 return (B_FALSE);
3870 break;
3871 default:
3872 return (B_FALSE);
3874 compare_bigint = B_TRUE;
3875 break;
3876 case CKA_MODULUS:
3877 /* only RSA public and private key have this attr */
3878 if (obj->key_type == CKK_RSA) {
3879 if (obj->class == CKO_PUBLIC_KEY) {
3880 bigint = OBJ_PUB_RSA_MOD(obj);
3881 } else if (obj->class == CKO_PRIVATE_KEY) {
3882 bigint = OBJ_PRI_RSA_MOD(obj);
3883 } else {
3884 return (B_FALSE);
3886 compare_bigint = B_TRUE;
3887 } else {
3888 return (B_FALSE);
3890 break;
3891 case CKA_MODULUS_BITS:
3892 /* only RSA public key has this attribute */
3893 if ((obj->key_type == CKK_RSA) &&
3894 (obj->class == CKO_PUBLIC_KEY)) {
3895 CK_ULONG mod_bits = OBJ_PUB_RSA_MOD_BITS(obj);
3896 if (mod_bits !=
3897 *((CK_ULONG *)tmpl_attr->pValue)) {
3898 return (B_FALSE);
3900 } else {
3901 return (B_FALSE);
3903 break;
3904 case CKA_PUBLIC_EXPONENT:
3905 /* only RSA public and private key have this attr */
3906 if (obj->key_type == CKK_RSA) {
3907 if (obj->class == CKO_PUBLIC_KEY) {
3908 bigint = OBJ_PUB_RSA_PUBEXPO(obj);
3909 } else if (obj->class == CKO_PRIVATE_KEY) {
3910 bigint = OBJ_PRI_RSA_PUBEXPO(obj);
3911 } else {
3912 return (B_FALSE);
3914 compare_bigint = B_TRUE;
3915 } else {
3916 return (B_FALSE);
3918 break;
3919 case CKA_PRIVATE_EXPONENT:
3920 /* only RSA private key has this attribute */
3921 if ((obj->key_type == CKK_RSA) &&
3922 (obj->class == CKO_PRIVATE_KEY)) {
3923 bigint = OBJ_PRI_RSA_PRIEXPO(obj);
3924 compare_bigint = B_TRUE;
3925 } else {
3926 return (B_FALSE);
3928 break;
3929 case CKA_PRIME_1:
3930 /* only RSA private key has this attribute */
3931 if ((obj->key_type == CKK_RSA) &&
3932 (obj->class == CKO_PRIVATE_KEY)) {
3933 bigint = OBJ_PRI_RSA_PRIME1(obj);
3934 compare_bigint = B_TRUE;
3935 } else {
3936 return (B_FALSE);
3938 break;
3939 case CKA_PRIME_2:
3940 /* only RSA private key has this attribute */
3941 if ((obj->key_type == CKK_RSA) &&
3942 (obj->class == CKO_PRIVATE_KEY)) {
3943 bigint = OBJ_PRI_RSA_PRIME2(obj);
3944 compare_bigint = B_TRUE;
3945 } else {
3946 return (B_FALSE);
3948 break;
3949 case CKA_EXPONENT_1:
3950 /* only RSA private key has this attribute */
3951 if ((obj->key_type == CKK_RSA) &&
3952 (obj->class == CKO_PRIVATE_KEY)) {
3953 bigint = OBJ_PRI_RSA_EXPO1(obj);
3954 compare_bigint = B_TRUE;
3955 } else {
3956 return (B_FALSE);
3958 break;
3959 case CKA_EXPONENT_2:
3960 /* only RSA private key has this attribute */
3961 if ((obj->key_type == CKK_RSA) &&
3962 (obj->class == CKO_PRIVATE_KEY)) {
3963 bigint = OBJ_PRI_RSA_EXPO2(obj);
3964 compare_bigint = B_TRUE;
3965 } else {
3966 return (B_FALSE);
3968 break;
3969 case CKA_COEFFICIENT:
3970 /* only RSA private key has this attribute */
3971 if ((obj->key_type == CKK_RSA) &&
3972 (obj->class == CKO_PRIVATE_KEY)) {
3973 bigint = OBJ_PRI_RSA_COEF(obj);
3974 compare_bigint = B_TRUE;
3975 } else {
3976 return (B_FALSE);
3978 break;
3979 case CKA_VALUE_BITS:
3980 return (B_FALSE);
3981 case CKA_PRIME:
3982 if (obj->class == CKO_PUBLIC_KEY) {
3983 switch (obj->key_type) {
3984 case CKK_DSA:
3985 bigint = OBJ_PUB_DSA_PRIME(obj);
3986 break;
3987 default:
3988 return (B_FALSE);
3990 } else if (obj->class == CKO_PRIVATE_KEY) {
3991 switch (obj->key_type) {
3992 case CKK_DSA:
3993 bigint = OBJ_PRI_DSA_PRIME(obj);
3994 break;
3995 default:
3996 return (B_FALSE);
3998 } else {
3999 return (B_FALSE);
4001 compare_bigint = B_TRUE;
4002 break;
4003 case CKA_SUBPRIME:
4004 if (obj->class == CKO_PUBLIC_KEY) {
4005 switch (obj->key_type) {
4006 case CKK_DSA:
4007 bigint = OBJ_PUB_DSA_SUBPRIME(obj);
4008 break;
4009 default:
4010 return (B_FALSE);
4012 } else if (obj->class == CKO_PRIVATE_KEY) {
4013 switch (obj->key_type) {
4014 case CKK_DSA:
4015 bigint = OBJ_PRI_DSA_SUBPRIME(obj);
4016 break;
4017 default:
4018 return (B_FALSE);
4020 } else {
4021 return (B_FALSE);
4023 compare_bigint = B_TRUE;
4024 break;
4025 case CKA_BASE:
4026 if (obj->class == CKO_PUBLIC_KEY) {
4027 switch (obj->key_type) {
4028 case CKK_DSA:
4029 bigint = OBJ_PUB_DSA_BASE(obj);
4030 break;
4031 default:
4032 return (B_FALSE);
4034 } else if (obj->class == CKO_PRIVATE_KEY) {
4035 switch (obj->key_type) {
4036 case CKK_DSA:
4037 bigint = OBJ_PRI_DSA_BASE(obj);
4038 break;
4039 default:
4040 return (B_FALSE);
4042 } else {
4043 return (B_FALSE);
4045 compare_bigint = B_TRUE;
4046 break;
4047 case CKA_PRIME_BITS:
4048 return (B_FALSE);
4049 case CKA_SUBPRIME_BITS:
4050 return (B_FALSE);
4051 default:
4053 * any other attributes are currently not supported.
4054 * so, it's not possible for them to be in the
4055 * object
4057 return (B_FALSE);
4059 if (compare_boolean) {
4060 CK_BBOOL bval;
4062 if (attr_mask) {
4063 bval = TRUE;
4064 } else {
4065 bval = FALSE;
4067 if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) {
4068 return (B_FALSE);
4070 } else if (compare_bigint) {
4071 if (bigint == NULL) {
4072 return (B_FALSE);
4074 if (tmpl_attr->ulValueLen != bigint->big_value_len) {
4075 return (B_FALSE);
4077 if (memcmp(tmpl_attr->pValue, bigint->big_value,
4078 tmpl_attr->ulValueLen) != 0) {
4079 return (B_FALSE);
4081 } else if (compare_attr) {
4082 if (obj_attr == NULL) {
4084 * The attribute type is valid, and its value
4085 * has not been initialized in the object. In
4086 * this case, it only matches the template's
4087 * attribute if the template's value length
4088 * is 0.
4090 if (tmpl_attr->ulValueLen != 0)
4091 return (B_FALSE);
4092 } else {
4093 if (tmpl_attr->ulValueLen !=
4094 obj_attr->ulValueLen) {
4095 return (B_FALSE);
4097 if (memcmp(tmpl_attr->pValue, obj_attr->pValue,
4098 tmpl_attr->ulValueLen) != 0) {
4099 return (B_FALSE);
4104 return (B_TRUE);
4107 CK_ATTRIBUTE_PTR
4108 get_extra_attr(CK_ATTRIBUTE_TYPE type, kernel_object_t *obj)
4110 CK_ATTRIBUTE_INFO_PTR tmp;
4112 tmp = obj->extra_attrlistp;
4113 while (tmp != NULL) {
4114 if (tmp->attr.type == type) {
4115 return (&(tmp->attr));
4117 tmp = tmp->next;
4119 /* if get there, the specified attribute is not found */
4120 return (NULL);