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]
22 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
29 #include <cryptoutil.h>
31 #include <security/cryptoki.h>
32 #include <sys/crypto/common.h>
33 #include <sys/crypto/ioctl.h>
34 #include "kernelGlobal.h"
35 #include "kernelObject.h"
36 #include "kernelSlot.h"
38 #define ENCODE_ATTR(type, value, len) { \
39 cur_attr->oa_type = type; \
40 (void) memcpy(ptr, value, len); \
41 cur_attr->oa_value = ptr; \
42 cur_attr->oa_value_len = len; \
47 * In order to fit everything on one line, the 'CRYPTO_' prefix
48 * has been dropped from the KCF #defines, e.g.
49 * CRYPTO_SUCCESS becomes SUCCESS.
52 static CK_RV error_number_table
[CRYPTO_LAST_ERROR
+1] = {
54 CKR_CANCEL
, /* CANCEL */
55 CKR_HOST_MEMORY
, /* HOST_MEMORY */
56 CKR_GENERAL_ERROR
, /* GENERAL_ERROR */
57 CKR_FUNCTION_FAILED
, /* FAILED */
58 CKR_ARGUMENTS_BAD
, /* ARGUMENTS_BAD */
59 CKR_ATTRIBUTE_READ_ONLY
, /* ATTRIBUTE_READ_ONLY */
60 CKR_ATTRIBUTE_SENSITIVE
, /* ATTRIBUTE_SENSITIVE */
61 CKR_ATTRIBUTE_TYPE_INVALID
, /* ATTRIBUTE_TYPE_INVALID */
62 CKR_ATTRIBUTE_VALUE_INVALID
, /* ATTRIBUTE_VALUE_INVALID */
63 CKR_FUNCTION_FAILED
, /* CANCELED */
64 CKR_DATA_INVALID
, /* DATA_INVALID */
65 CKR_DATA_LEN_RANGE
, /* DATA_LEN_RANGE */
66 CKR_DEVICE_ERROR
, /* DEVICE_ERROR */
67 CKR_DEVICE_MEMORY
, /* DEVICE_MEMORY */
68 CKR_DEVICE_REMOVED
, /* DEVICE_REMOVED */
69 CKR_ENCRYPTED_DATA_INVALID
, /* ENCRYPTED_DATA_INVALID */
70 CKR_ENCRYPTED_DATA_LEN_RANGE
, /* ENCRYPTED_DATA_LEN_RANGE */
71 CKR_KEY_HANDLE_INVALID
, /* KEY_HANDLE_INVALID */
72 CKR_KEY_SIZE_RANGE
, /* KEY_SIZE_RANGE */
73 CKR_KEY_TYPE_INCONSISTENT
, /* KEY_TYPE_INCONSISTENT */
74 CKR_KEY_NOT_NEEDED
, /* KEY_NOT_NEEDED */
75 CKR_KEY_CHANGED
, /* KEY_CHANGED */
76 CKR_KEY_NEEDED
, /* KEY_NEEDED */
77 CKR_KEY_INDIGESTIBLE
, /* KEY_INDIGESTIBLE */
78 CKR_KEY_FUNCTION_NOT_PERMITTED
, /* KEY_FUNCTION_NOT_PERMITTED */
79 CKR_KEY_NOT_WRAPPABLE
, /* KEY_NOT_WRAPPABLE */
80 CKR_KEY_UNEXTRACTABLE
, /* KEY_UNEXTRACTABLE */
81 CKR_MECHANISM_INVALID
, /* MECHANISM_INVALID */
82 CKR_MECHANISM_PARAM_INVALID
, /* MECHANISM_PARAM_INVALID */
83 CKR_OBJECT_HANDLE_INVALID
, /* OBJECT_HANDLE_INVALID */
84 CKR_OPERATION_ACTIVE
, /* OPERATION_ACTIVE */
85 CKR_OPERATION_NOT_INITIALIZED
, /* OPERATION_NOT_INITIALIZED */
86 CKR_PIN_INCORRECT
, /* PIN_INCORRECT */
87 CKR_PIN_INVALID
, /* PIN_INVALID */
88 CKR_PIN_LEN_RANGE
, /* PIN_LEN_RANGE */
89 CKR_PIN_EXPIRED
, /* PIN_EXPIRED */
90 CKR_PIN_LOCKED
, /* PIN_LOCKED */
91 CKR_SESSION_CLOSED
, /* SESSION_CLOSED */
92 CKR_SESSION_COUNT
, /* SESSION_COUNT */
93 CKR_SESSION_HANDLE_INVALID
, /* SESSION_HANDLE_INVALID */
94 CKR_SESSION_READ_ONLY
, /* SESSION_READ_ONLY */
95 CKR_SESSION_EXISTS
, /* SESSION_EXISTS */
96 CKR_SESSION_READ_ONLY_EXISTS
, /* SESSION_READ_ONLY_EXISTS */
97 CKR_SESSION_READ_WRITE_SO_EXISTS
, /* SESSION_READ_WRITE_SO_EXISTS */
98 CKR_SIGNATURE_INVALID
, /* SIGNATURE_INVALID */
99 CKR_SIGNATURE_LEN_RANGE
, /* SIGNATURE_LEN_RANGE */
100 CKR_TEMPLATE_INCOMPLETE
, /* TEMPLATE_INCOMPLETE */
101 CKR_TEMPLATE_INCONSISTENT
, /* TEMPLATE_INCONSISTENT */
102 CKR_UNWRAPPING_KEY_HANDLE_INVALID
, /* UNWRAPPING_KEY_HANDLE_INVALID */
103 CKR_UNWRAPPING_KEY_SIZE_RANGE
, /* UNWRAPPING_KEY_SIZE_RANGE */
104 CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT
, /* UNWRAPPING_KEY_TYPE_INCONSISTENT */
105 CKR_USER_ALREADY_LOGGED_IN
, /* USER_ALREADY_LOGGED_IN */
106 CKR_USER_NOT_LOGGED_IN
, /* USER_NOT_LOGGED_IN */
107 CKR_USER_PIN_NOT_INITIALIZED
, /* USER_PIN_NOT_INITIALIZED */
108 CKR_USER_TYPE_INVALID
, /* USER_TYPE_INVALID */
109 CKR_USER_ANOTHER_ALREADY_LOGGED_IN
, /* USER_ANOTHER_ALREADY_LOGGED_IN */
110 CKR_USER_TOO_MANY_TYPES
, /* USER_TOO_MANY_TYPES */
111 CKR_WRAPPED_KEY_INVALID
, /* WRAPPED_KEY_INVALID */
112 CKR_WRAPPED_KEY_LEN_RANGE
, /* WRAPPED_KEY_LEN_RANGE */
113 CKR_WRAPPING_KEY_HANDLE_INVALID
, /* WRAPPING_KEY_HANDLE_INVALID */
114 CKR_WRAPPING_KEY_SIZE_RANGE
, /* WRAPPING_KEY_SIZE_RANGE */
115 CKR_WRAPPING_KEY_TYPE_INCONSISTENT
, /* WRAPPING_KEY_TYPE_INCONSISTENT */
116 CKR_RANDOM_SEED_NOT_SUPPORTED
, /* RANDOM_SEED_NOT_SUPPORTED */
117 CKR_RANDOM_NO_RNG
, /* RANDOM_NO_RNG */
118 CKR_DOMAIN_PARAMS_INVALID
, /* DOMAIN_PARAMS_INVALID */
119 CKR_BUFFER_TOO_SMALL
, /* BUFFER_TOO_SMALL */
120 CKR_INFORMATION_SENSITIVE
, /* INFORMATION_SENSITIVE */
121 CKR_FUNCTION_NOT_SUPPORTED
, /* NOT_SUPPORTED */
122 CKR_GENERAL_ERROR
, /* QUEUED */
123 CKR_GENERAL_ERROR
, /* BUFFER_TOO_BIG */
124 CKR_OPERATION_NOT_INITIALIZED
, /* INVALID_CONTEXT */
125 CKR_GENERAL_ERROR
, /* INVALID_MAC */
126 CKR_GENERAL_ERROR
, /* MECH_NOT_SUPPORTED */
127 CKR_GENERAL_ERROR
, /* INCONSISTENT_ATTRIBUTE */
128 CKR_GENERAL_ERROR
, /* NO_PERMISSION */
129 CKR_SLOT_ID_INVALID
, /* INVALID_PROVIDER_ID */
130 CKR_GENERAL_ERROR
, /* VERSION_MISMATCH */
131 CKR_GENERAL_ERROR
, /* BUSY */
132 CKR_GENERAL_ERROR
, /* UNKNOWN_PROVIDER */
133 CKR_GENERAL_ERROR
, /* MODVERIFICATION_FAILED */
134 CKR_GENERAL_ERROR
, /* OLD_CTX_TEMPLATE */
135 CKR_GENERAL_ERROR
, /* WEAK_KEY */
136 CKR_GENERAL_ERROR
/* FIPS140_ERROR */
139 #if CRYPTO_LAST_ERROR != CRYPTO_FIPS140_ERROR
140 #error "Crypto to PKCS11 error mapping table needs to be updated!"
144 * Map KCF error codes into PKCS11 error codes.
147 crypto2pkcs11_error_number(uint_t n
)
149 if (n
>= sizeof (error_number_table
) / sizeof (error_number_table
[0]))
150 return (CKR_GENERAL_ERROR
);
152 return (error_number_table
[n
]);
155 #define MECH_HASH(type) (((uintptr_t)type) % KMECH_HASHTABLE_SIZE)
157 * Serialize writes to the hash table. We don't need a per bucket lock as
158 * there are only a few writes and we don't need the lock for reads.
160 pthread_mutex_t mechhash_mutex
= PTHREAD_MUTEX_INITIALIZER
;
163 kmech_hash_insert(CK_MECHANISM_TYPE type
, crypto_mech_type_t kmech
)
166 kmh_elem_t
*elem
, *cur
;
168 elem
= malloc(sizeof (kmh_elem_t
));
170 return (CKR_HOST_MEMORY
);
176 (void) pthread_mutex_lock(&mechhash_mutex
);
177 for (cur
= kernel_mechhash
[h
]; cur
!= NULL
; cur
= cur
->knext
) {
178 if (type
== cur
->type
) {
179 /* Some other thread beat us to it. */
180 (void) pthread_mutex_unlock(&mechhash_mutex
);
185 elem
->knext
= kernel_mechhash
[h
];
186 kernel_mechhash
[h
] = elem
;
187 (void) pthread_mutex_unlock(&mechhash_mutex
);
193 kernel_mech(CK_MECHANISM_TYPE type
, crypto_mech_type_t
*k_number
)
195 crypto_get_mechanism_number_t get_number
;
201 char buf
[11]; /* Num chars for representing ulong in ASCII */
204 * Search for an existing entry. No need to lock since we are
205 * just a reader and we never free the entries in the hash table.
208 for (elem
= kernel_mechhash
[h
]; elem
!= NULL
; elem
= elem
->knext
) {
209 if (type
== elem
->type
) {
210 *k_number
= elem
->kmech
;
215 if (type
>= CKM_VENDOR_DEFINED
) {
216 (void) snprintf(buf
, sizeof (buf
), "%#lx", type
);
219 string
= pkcs11_mech2str(type
);
223 return (CKR_MECHANISM_INVALID
);
225 get_number
.pn_mechanism_string
= (char *)string
;
226 get_number
.pn_mechanism_len
= strlen(string
) + 1;
228 while ((r
= ioctl(kernel_fd
, CRYPTO_GET_MECHANISM_NUMBER
,
234 rv
= CKR_MECHANISM_INVALID
;
236 if (get_number
.pn_return_value
!= CRYPTO_SUCCESS
) {
237 rv
= crypto2pkcs11_error_number(
238 get_number
.pn_return_value
);
245 *k_number
= get_number
.pn_internal_number
;
246 /* Add this to the hash table */
247 (void) kmech_hash_insert(type
, *k_number
);
255 * Return the value of a secret key object.
256 * This routine allocates memory for the value.
257 * A null pointer is returned on error.
260 get_symmetric_key_value(kernel_object_t
*key_p
)
264 switch (key_p
->class) {
268 cipherKey
= malloc(OBJ_SEC(key_p
)->sk_value_len
);
269 if (cipherKey
== NULL
)
272 (void) memcpy(cipherKey
, OBJ_SEC(key_p
)->sk_value
,
273 OBJ_SEC(key_p
)->sk_value_len
);
283 * Convert a RSA private key object into a crypto_key structure.
284 * Memory is allocated for each attribute stored in the crypto_key
285 * structure. Memory for the crypto_key structure is not
286 * allocated. Attributes can be freed by free_key_attributes().
289 get_rsa_private_key(kernel_object_t
*object_p
, crypto_key_t
*key
)
292 crypto_object_attribute_t
*attrs
, *cur_attr
;
296 (void) pthread_mutex_lock(&object_p
->object_mutex
);
297 if (object_p
->key_type
!= CKK_RSA
||
298 object_p
->class != CKO_PRIVATE_KEY
) {
299 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
300 return (CKR_ATTRIBUTE_TYPE_INVALID
);
304 RSA_PRI_ATTR_COUNT
* sizeof (crypto_object_attribute_t
));
306 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
307 return (CKR_HOST_MEMORY
);
310 key
->ck_format
= CRYPTO_KEY_ATTR_LIST
;
311 key
->ck_attrs
= attrs
;
315 * Allocate memory for each key attribute and set up the value
320 /* CKA_MODULUS is required. */
321 big
= OBJ_PRI_RSA_MOD(object_p
);
322 if (big
->big_value
== NULL
) {
323 rv
= CKR_ATTRIBUTE_TYPE_INVALID
;
326 if ((ptr
= malloc(big
->big_value_len
)) == NULL
) {
327 rv
= CKR_HOST_MEMORY
;
330 ENCODE_ATTR(CKA_MODULUS
, big
->big_value
, big
->big_value_len
);
334 /* CKA_PRIVATE_EXPONENT is required. */
335 big
= OBJ_PRI_RSA_PRIEXPO(object_p
);
336 if (big
->big_value
== NULL
) {
337 rv
= CKR_ATTRIBUTE_TYPE_INVALID
;
340 if ((ptr
= malloc(big
->big_value_len
)) == NULL
) {
341 rv
= CKR_HOST_MEMORY
;
344 ENCODE_ATTR(CKA_PRIVATE_EXPONENT
, big
->big_value
,
349 /* CKA_PRIME_1 is optional. */
350 big
= OBJ_PRI_RSA_PRIME1(object_p
);
351 if (big
->big_value
!= NULL
) {
352 if ((ptr
= malloc(big
->big_value_len
)) == NULL
) {
353 rv
= CKR_HOST_MEMORY
;
356 ENCODE_ATTR(CKA_PRIME_1
, big
->big_value
, big
->big_value_len
);
360 /* CKA_PRIME_2 is optional. */
361 big
= OBJ_PRI_RSA_PRIME2(object_p
);
362 if (big
->big_value
!= NULL
) {
363 if ((ptr
= malloc(big
->big_value_len
)) == NULL
) {
364 rv
= CKR_HOST_MEMORY
;
367 ENCODE_ATTR(CKA_PRIME_2
, big
->big_value
, big
->big_value_len
);
371 /* CKA_EXPONENT_1 is optional. */
372 big
= OBJ_PRI_RSA_EXPO1(object_p
);
373 if (big
->big_value
!= NULL
) {
374 if ((ptr
= malloc(big
->big_value_len
)) == NULL
) {
375 rv
= CKR_HOST_MEMORY
;
378 ENCODE_ATTR(CKA_EXPONENT_1
, big
->big_value
,
383 /* CKA_EXPONENT_2 is optional. */
384 big
= OBJ_PRI_RSA_EXPO2(object_p
);
385 if (big
->big_value
!= NULL
) {
386 if ((ptr
= malloc(big
->big_value_len
)) == NULL
) {
387 rv
= CKR_HOST_MEMORY
;
390 ENCODE_ATTR(CKA_EXPONENT_2
, big
->big_value
,
395 /* CKA_COEFFICIENT is optional. */
396 big
= OBJ_PRI_RSA_COEF(object_p
);
397 if (big
->big_value
!= NULL
) {
398 if ((ptr
= malloc(big
->big_value_len
)) == NULL
) {
399 rv
= CKR_HOST_MEMORY
;
402 ENCODE_ATTR(CKA_COEFFICIENT
, big
->big_value
,
407 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
411 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
412 free_key_attributes(key
);
417 * Convert a RSA public key object into a crypto_key structure.
418 * Memory is allocated for each attribute stored in the crypto_key
419 * structure. Memory for the crypto_key structure is not
420 * allocated. Attributes can be freed by free_key_attributes().
423 get_rsa_public_key(kernel_object_t
*object_p
, crypto_key_t
*key
)
426 crypto_object_attribute_t
*attrs
, *cur_attr
;
429 (void) pthread_mutex_lock(&object_p
->object_mutex
);
430 if (object_p
->key_type
!= CKK_RSA
||
431 object_p
->class != CKO_PUBLIC_KEY
) {
432 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
433 return (CKR_ATTRIBUTE_TYPE_INVALID
);
437 RSA_PUB_ATTR_COUNT
* sizeof (crypto_object_attribute_t
));
439 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
440 return (CKR_HOST_MEMORY
);
443 key
->ck_format
= CRYPTO_KEY_ATTR_LIST
;
444 key
->ck_count
= RSA_PUB_ATTR_COUNT
;
445 key
->ck_attrs
= attrs
;
448 big
= OBJ_PUB_RSA_PUBEXPO(object_p
);
449 if ((ptr
= malloc(big
->big_value_len
)) == NULL
)
451 ENCODE_ATTR(CKA_PUBLIC_EXPONENT
, big
->big_value
, big
->big_value_len
);
453 big
= OBJ_PUB_RSA_MOD(object_p
);
454 if ((ptr
= malloc(big
->big_value_len
)) == NULL
)
456 ENCODE_ATTR(CKA_MODULUS
, big
->big_value
, big
->big_value_len
);
458 if ((ptr
= malloc(sizeof (CK_ULONG
))) == NULL
)
460 ENCODE_ATTR(CKA_MODULUS_BITS
, &OBJ_PUB_RSA_MOD_BITS(object_p
),
463 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
467 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
468 free_key_attributes(key
);
469 return (CKR_HOST_MEMORY
);
473 * Free attribute storage in a crypto_key structure.
476 free_key_attributes(crypto_key_t
*key
)
480 if (key
->ck_format
== CRYPTO_KEY_ATTR_LIST
&&
481 (key
->ck_count
> 0) && key
->ck_attrs
!= NULL
) {
482 for (i
= 0; i
< key
->ck_count
; i
++) {
483 if (key
->ck_attrs
[i
].oa_value
!= NULL
) {
484 bzero(key
->ck_attrs
[i
].oa_value
,
485 key
->ck_attrs
[i
].oa_value_len
);
486 free(key
->ck_attrs
[i
].oa_value
);
495 * Convert a DSA private key object into a crypto_key structure.
496 * Memory is allocated for each attribute stored in the crypto_key
497 * structure. Memory for the crypto_key structure is not
498 * allocated. Attributes can be freed by free_dsa_key_attributes().
501 get_dsa_private_key(kernel_object_t
*object_p
, crypto_key_t
*key
)
504 crypto_object_attribute_t
*attrs
, *cur_attr
;
507 (void) pthread_mutex_lock(&object_p
->object_mutex
);
508 if (object_p
->key_type
!= CKK_DSA
||
509 object_p
->class != CKO_PRIVATE_KEY
) {
510 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
511 return (CKR_ATTRIBUTE_TYPE_INVALID
);
515 DSA_ATTR_COUNT
* sizeof (crypto_object_attribute_t
));
517 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
518 return (CKR_HOST_MEMORY
);
521 key
->ck_format
= CRYPTO_KEY_ATTR_LIST
;
522 key
->ck_count
= DSA_ATTR_COUNT
;
523 key
->ck_attrs
= attrs
;
526 big
= OBJ_PRI_DSA_PRIME(object_p
);
527 if ((ptr
= malloc(big
->big_value_len
)) == NULL
)
529 ENCODE_ATTR(CKA_PRIME
, big
->big_value
, big
->big_value_len
);
531 big
= OBJ_PRI_DSA_SUBPRIME(object_p
);
532 if ((ptr
= malloc(big
->big_value_len
)) == NULL
)
534 ENCODE_ATTR(CKA_SUBPRIME
, big
->big_value
, big
->big_value_len
);
536 big
= OBJ_PRI_DSA_BASE(object_p
);
537 if ((ptr
= malloc(big
->big_value_len
)) == NULL
)
539 ENCODE_ATTR(CKA_BASE
, big
->big_value
, big
->big_value_len
);
541 big
= OBJ_PRI_DSA_VALUE(object_p
);
542 if ((ptr
= malloc(big
->big_value_len
)) == NULL
)
544 ENCODE_ATTR(CKA_VALUE
, big
->big_value
, big
->big_value_len
);
546 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
550 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
551 free_key_attributes(key
);
552 return (CKR_HOST_MEMORY
);
557 * Convert a DSA public key object into a crypto_key structure.
558 * Memory is allocated for each attribute stored in the crypto_key
559 * structure. Memory for the crypto_key structure is not
560 * allocated. Attributes can be freed by free_dsa_key_attributes().
563 get_dsa_public_key(kernel_object_t
*object_p
, crypto_key_t
*key
)
566 crypto_object_attribute_t
*attrs
, *cur_attr
;
569 (void) pthread_mutex_lock(&object_p
->object_mutex
);
570 if (object_p
->key_type
!= CKK_DSA
||
571 object_p
->class != CKO_PUBLIC_KEY
) {
572 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
573 return (CKR_ATTRIBUTE_TYPE_INVALID
);
577 DSA_ATTR_COUNT
* sizeof (crypto_object_attribute_t
));
579 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
580 return (CKR_HOST_MEMORY
);
583 key
->ck_format
= CRYPTO_KEY_ATTR_LIST
;
584 key
->ck_count
= DSA_ATTR_COUNT
;
585 key
->ck_attrs
= attrs
;
588 big
= OBJ_PUB_DSA_PRIME(object_p
);
589 if ((ptr
= malloc(big
->big_value_len
)) == NULL
)
591 ENCODE_ATTR(CKA_PRIME
, big
->big_value
, big
->big_value_len
);
593 big
= OBJ_PUB_DSA_SUBPRIME(object_p
);
594 if ((ptr
= malloc(big
->big_value_len
)) == NULL
)
596 ENCODE_ATTR(CKA_SUBPRIME
, big
->big_value
, big
->big_value_len
);
598 big
= OBJ_PUB_DSA_BASE(object_p
);
599 if ((ptr
= malloc(big
->big_value_len
)) == NULL
)
601 ENCODE_ATTR(CKA_BASE
, big
->big_value
, big
->big_value_len
);
603 big
= OBJ_PUB_DSA_VALUE(object_p
);
604 if ((ptr
= malloc(big
->big_value_len
)) == NULL
)
606 ENCODE_ATTR(CKA_VALUE
, big
->big_value
, big
->big_value_len
);
608 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
612 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
613 free_key_attributes(key
);
614 return (CKR_HOST_MEMORY
);
619 * Convert a EC private key object into a crypto_key structure.
620 * Memory is allocated for each attribute stored in the crypto_key
621 * structure. Memory for the crypto_key structure is not
622 * allocated. Attributes can be freed by free_ec_key_attributes().
625 get_ec_private_key(kernel_object_t
*object_p
, crypto_key_t
*key
)
628 crypto_object_attribute_t
*attrs
, *cur_attr
;
633 (void) pthread_mutex_lock(&object_p
->object_mutex
);
634 if (object_p
->key_type
!= CKK_EC
||
635 object_p
->class != CKO_PRIVATE_KEY
) {
636 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
637 return (CKR_ATTRIBUTE_TYPE_INVALID
);
640 attrs
= calloc(EC_ATTR_COUNT
, sizeof (crypto_object_attribute_t
));
642 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
643 return (CKR_HOST_MEMORY
);
646 key
->ck_format
= CRYPTO_KEY_ATTR_LIST
;
647 key
->ck_count
= EC_ATTR_COUNT
;
648 key
->ck_attrs
= attrs
;
651 big
= OBJ_PRI_EC_VALUE(object_p
);
652 if ((ptr
= malloc(big
->big_value_len
)) == NULL
) {
653 rv
= CKR_HOST_MEMORY
;
656 ENCODE_ATTR(CKA_VALUE
, big
->big_value
, big
->big_value_len
);
658 tmp
.type
= CKA_EC_PARAMS
;
660 rv
= kernel_get_attribute(object_p
, &tmp
);
665 tmp
.pValue
= malloc(tmp
.ulValueLen
);
666 if (tmp
.pValue
== NULL
) {
667 rv
= CKR_HOST_MEMORY
;
671 rv
= kernel_get_attribute(object_p
, &tmp
);
677 cur_attr
->oa_type
= tmp
.type
;
678 cur_attr
->oa_value
= tmp
.pValue
;
679 cur_attr
->oa_value_len
= tmp
.ulValueLen
;
681 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
685 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
686 free_key_attributes(key
);
691 * Convert an EC public key object into a crypto_key structure.
692 * Memory is allocated for each attribute stored in the crypto_key
693 * structure. Memory for the crypto_key structure is not
694 * allocated. Attributes can be freed by free_ec_key_attributes().
697 get_ec_public_key(kernel_object_t
*object_p
, crypto_key_t
*key
)
700 crypto_object_attribute_t
*attrs
, *cur_attr
;
705 (void) pthread_mutex_lock(&object_p
->object_mutex
);
706 if (object_p
->key_type
!= CKK_EC
||
707 object_p
->class != CKO_PUBLIC_KEY
) {
708 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
709 return (CKR_ATTRIBUTE_TYPE_INVALID
);
712 attrs
= calloc(EC_ATTR_COUNT
, sizeof (crypto_object_attribute_t
));
714 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
715 return (CKR_HOST_MEMORY
);
718 key
->ck_format
= CRYPTO_KEY_ATTR_LIST
;
719 key
->ck_count
= EC_ATTR_COUNT
;
720 key
->ck_attrs
= attrs
;
723 big
= OBJ_PUB_EC_POINT(object_p
);
724 if ((ptr
= malloc(big
->big_value_len
)) == NULL
) {
725 rv
= CKR_HOST_MEMORY
;
728 ENCODE_ATTR(CKA_EC_POINT
, big
->big_value
, big
->big_value_len
);
730 tmp
.type
= CKA_EC_PARAMS
;
732 rv
= kernel_get_attribute(object_p
, &tmp
);
737 tmp
.pValue
= malloc(tmp
.ulValueLen
);
738 if (tmp
.pValue
== NULL
) {
739 rv
= CKR_HOST_MEMORY
;
743 rv
= kernel_get_attribute(object_p
, &tmp
);
749 cur_attr
->oa_type
= tmp
.type
;
750 cur_attr
->oa_value
= tmp
.pValue
;
751 cur_attr
->oa_value_len
= tmp
.ulValueLen
;
753 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
757 (void) pthread_mutex_unlock(&object_p
->object_mutex
);
758 free_key_attributes(key
);
763 * Convert an attribute template into an obj_attrs array.
764 * Memory is allocated for each attribute stored in the obj_attrs.
765 * The memory can be freed by free_object_attributes().
767 * If the boolean pointer is_token_obj is not NULL, the caller wants to
768 * retrieve the value of the CKA_TOKEN attribute if it is specified in the
770 * - When this routine is called thru C_CreateObject(), C_CopyObject(), or
771 * any key management function, is_token_obj should NOT be NULL.
772 * - When this routine is called thru C_GetAttributeValue() or
773 * C_SetAttributeValue(), "is_token_obj" should be NULL.
776 process_object_attributes(CK_ATTRIBUTE_PTR pTemplate
, CK_ULONG ulCount
,
777 caddr_t
*obj_attrs
, CK_BBOOL
*is_token_obj
)
779 crypto_object_attribute_t
*attrs
, *cur_attr
;
790 attrs
= calloc(1, ulCount
* sizeof (crypto_object_attribute_t
));
792 return (CKR_HOST_MEMORY
);
796 for (i
= 0; i
< ulCount
; i
++) {
798 * The length of long attributes must be set correctly
799 * so providers can determine whether they came from 32
800 * or 64-bit applications.
802 switch (pTemplate
[i
].type
) {
804 case CKA_CERTIFICATE_TYPE
:
806 case CKA_MODULUS_BITS
:
807 case CKA_HW_FEATURE_TYPE
:
808 value_len
= sizeof (ulong_t
);
809 if (pTemplate
[i
].pValue
!= NULL
&&
810 (pTemplate
[i
].ulValueLen
< value_len
)) {
811 rv
= CKR_ATTRIBUTE_VALUE_INVALID
;
817 value_len
= pTemplate
[i
].ulValueLen
;
820 cur_attr
->oa_type
= pTemplate
[i
].type
;
821 cur_attr
->oa_value_len
= value_len
;
822 cur_attr
->oa_value
= NULL
;
824 if ((pTemplate
[i
].pValue
!= NULL
) &&
825 (pTemplate
[i
].ulValueLen
> 0)) {
826 ptr
= malloc(pTemplate
[i
].ulValueLen
);
828 rv
= CKR_HOST_MEMORY
;
832 (void) memcpy(ptr
, pTemplate
[i
].pValue
,
833 pTemplate
[i
].ulValueLen
);
834 cur_attr
->oa_value
= ptr
;
838 if ((is_token_obj
!= NULL
) &&
839 (pTemplate
[i
].type
== CKA_TOKEN
)) {
840 /* Get the CKA_TOKEN attribute value. */
841 if (pTemplate
[i
].pValue
== NULL
) {
842 rv
= CKR_ATTRIBUTE_VALUE_INVALID
;
847 *(CK_BBOOL
*)pTemplate
[i
].pValue
;
854 *obj_attrs
= (char *)attrs
;
859 for (i
= 0; i
< cur_i
; i
++) {
860 if (cur_attr
->oa_value
!= NULL
) {
861 (void) free(cur_attr
->oa_value
);
872 * Copy the attribute values from obj_attrs to pTemplate.
873 * The obj_attrs is an image of the Template and is expected to have the
874 * same attributes in the same order and each one of the attribute pValue
875 * in obj_attr has enough space allocated for the corresponding valueLen
879 get_object_attributes(CK_ATTRIBUTE_PTR pTemplate
, CK_ULONG ulCount
,
882 crypto_object_attribute_t
*cur_attr
;
887 cur_attr
= (crypto_object_attribute_t
*)obj_attrs
;
888 for (i
= 0; i
< ulCount
; i
++) {
889 if (pTemplate
[i
].type
!= cur_attr
->oa_type
) {
890 /* The attribute type doesn't match, this is bad. */
891 rv
= CKR_FUNCTION_FAILED
;
895 pTemplate
[i
].ulValueLen
= cur_attr
->oa_value_len
;
897 if ((pTemplate
[i
].pValue
!= NULL
) &&
898 ((CK_LONG
)pTemplate
[i
].ulValueLen
!= -1)) {
899 (void) memcpy(pTemplate
[i
].pValue
, cur_attr
->oa_value
,
900 pTemplate
[i
].ulValueLen
);
909 * Free the attribute storage in a crypto_object_attribute_t structure.
912 free_object_attributes(caddr_t obj_attrs
, CK_ULONG ulCount
)
914 crypto_object_attribute_t
*cur_attr
;
917 if ((ulCount
== 0) || (obj_attrs
== NULL
)) {
922 cur_attr
= (crypto_object_attribute_t
*)obj_attrs
;
923 for (i
= 0; i
< ulCount
; i
++) {
924 /* XXX check that oa_value > 0 */
925 if (cur_attr
->oa_value
!= NULL
) {
926 free(cur_attr
->oa_value
);
935 * This function is called by process_found_objects(). It will check the
936 * CKA_PRIVATE and CKA_TOKEN attributes for the kernel object "oid", then
937 * initialize all the necessary fields in the object wrapper "objp".
940 create_new_tobj_in_lib(kernel_slot_t
*pslot
, kernel_session_t
*sp
,
941 kernel_object_t
*objp
, crypto_object_id_t oid
)
944 crypto_object_get_attribute_value_t obj_ga
;
945 boolean_t is_pri_obj
;
946 boolean_t is_token_obj
;
947 CK_BBOOL pri_value
, token_value
;
948 CK_ATTRIBUTE pTemplate
[2];
952 * Make a CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE ioctl call to get this
953 * kernel object's attribute values for CKA_PRIVATE and CKA_TOKEN.
955 obj_ga
.og_session
= sp
->k_session
;
956 obj_ga
.og_handle
= oid
;
959 pTemplate
[0].type
= CKA_PRIVATE
;
960 pTemplate
[0].pValue
= &pri_value
;
961 pTemplate
[0].ulValueLen
= sizeof (pri_value
);
962 pTemplate
[1].type
= CKA_TOKEN
;
963 pTemplate
[1].pValue
= &token_value
;
964 pTemplate
[1].ulValueLen
= sizeof (token_value
);
965 rv
= process_object_attributes(pTemplate
, 2, &obj_ga
.og_attributes
,
971 while ((r
= ioctl(kernel_fd
, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE
,
977 rv
= CKR_FUNCTION_FAILED
;
979 rv
= crypto2pkcs11_error_number(obj_ga
.og_return_value
);
983 rv
= get_object_attributes(pTemplate
, 2, obj_ga
.og_attributes
);
985 is_pri_obj
= *(CK_BBOOL
*)pTemplate
[0].pValue
;
986 is_token_obj
= *(CK_BBOOL
*)pTemplate
[1].pValue
;
990 free_object_attributes(obj_ga
.og_attributes
, 2);
995 /* Make sure it is a token object. */
997 rv
= CKR_ATTRIBUTE_VALUE_INVALID
;
1001 /* If it is a private object, make sure the user has logged in. */
1002 if (is_pri_obj
&& (pslot
->sl_state
!= CKU_USER
)) {
1003 rv
= CKR_ATTRIBUTE_VALUE_INVALID
;
1007 objp
->is_lib_obj
= B_FALSE
;
1008 objp
->k_handle
= oid
;
1009 objp
->bool_attr_mask
|= TOKEN_BOOL_ON
;
1011 objp
->bool_attr_mask
|= PRIVATE_BOOL_ON
;
1013 objp
->bool_attr_mask
&= ~PRIVATE_BOOL_ON
;
1016 (void) pthread_mutex_init(&objp
->object_mutex
, NULL
);
1017 objp
->magic_marker
= KERNELTOKEN_OBJECT_MAGIC
;
1018 objp
->session_handle
= (CK_SESSION_HANDLE
) sp
;
1024 * This function processes the kernel object handles returned from the
1025 * CRYPTO_OBJECT_FIND_UPDATE ioctl and returns an object handle list
1026 * and the number of object handles to the caller - C_FindObjects().
1027 * The caller acquires the slot lock and the session lock.
1030 process_found_objects(kernel_session_t
*cur_sp
, CK_OBJECT_HANDLE
*obj_found
,
1031 CK_ULONG
*found_obj_count
, crypto_object_find_update_t obj_fu
)
1034 crypto_object_id_t
*oid_p
;
1035 kernel_slot_t
*pslot
;
1036 kernel_object_t
*objp
;
1037 kernel_object_t
*objp1
;
1038 kernel_object_t
*new_tobj_list
= NULL
;
1039 kernel_session_t
*sp
;
1040 CK_ULONG num_obj_found
= 0;
1041 boolean_t is_in_lib
;
1044 if (obj_fu
.fu_count
== 0) {
1045 *found_obj_count
= 0;
1049 pslot
= slot_table
[cur_sp
->ses_slotid
];
1052 oid_p
= (crypto_object_id_t
*)obj_fu
.fu_handles
;
1053 for (i
= 0; i
< obj_fu
.fu_count
; i
++) {
1054 is_in_lib
= B_FALSE
;
1056 * Check if this oid has an object wrapper in the library
1057 * already. First, search the slot's token object list.
1059 objp
= pslot
->sl_tobj_list
;
1060 while (!is_in_lib
&& objp
) {
1061 if (objp
->k_handle
== *oid_p
) {
1069 * If it is not in the slot's token object list,
1070 * search it in all the sessions.
1073 sp
= pslot
->sl_sess_list
;
1074 while (!is_in_lib
&& sp
) {
1075 objp
= sp
->object_list
;
1076 while (!is_in_lib
&& objp
) {
1077 if (objp
->k_handle
== *oid_p
) {
1088 * If this object is in the library already, add its object
1089 * wrapper to the returned find object list.
1092 obj_found
[num_obj_found
++] = (CK_OBJECT_HANDLE
)objp
;
1096 * If we still do not find it in the library. This object
1097 * must be a token object pre-existed in the HW provider.
1098 * We need to create an object wrapper for it in the library.
1101 objp1
= calloc(1, sizeof (kernel_object_t
));
1102 if (objp1
== NULL
) {
1103 rv
= CKR_HOST_MEMORY
;
1106 rv
= create_new_tobj_in_lib(pslot
, cur_sp
, objp1
,
1110 /* Save the new object to the new_tobj_list. */
1111 if (new_tobj_list
== NULL
) {
1112 new_tobj_list
= objp1
;
1116 new_tobj_list
->prev
= objp1
;
1117 objp1
->next
= new_tobj_list
;
1119 new_tobj_list
= objp1
;
1123 * If create_new_tobj_in_lib() doesn't fail
1124 * with CKR_HOST_MEMORY, the failure should be
1125 * caused by the attributes' checking. We will
1126 * just ignore this object and continue on.
1129 if (rv
== CKR_HOST_MEMORY
) {
1135 /* Process next one */
1140 * Add the newly created token object wrappers to the found object
1141 * list and to the slot's token object list.
1143 if (new_tobj_list
!= NULL
) {
1144 /* Add to the obj_found array. */
1145 objp
= new_tobj_list
;
1147 obj_found
[num_obj_found
++] = (CK_OBJECT_HANDLE
)objp
;
1148 if (objp
->next
== NULL
) {
1154 /* Add to the beginning of the slot's token object list. */
1155 if (pslot
->sl_tobj_list
!= NULL
) {
1156 objp
->next
= pslot
->sl_tobj_list
;
1157 pslot
->sl_tobj_list
->prev
= objp
;
1159 pslot
->sl_tobj_list
= new_tobj_list
;
1162 *found_obj_count
= num_obj_found
;
1167 /* Free the newly created token object wrappers. */
1168 objp
= new_tobj_list
;
1171 (void) pthread_mutex_destroy(&objp
->object_mutex
);
1181 * Get the value of the CKA_PRIVATE attribute for the object just returned
1182 * from the HW provider. This function will be called by any function
1183 * that creates a new object, because the CKA_PRIVATE value of an object is
1184 * token specific. The CKA_PRIVATE attribute value of the new object will be
1185 * stored in the object structure in the library, which will be used later at
1186 * C_Logout to clean up all private objects.
1189 get_cka_private_value(kernel_session_t
*sp
, crypto_object_id_t oid
,
1190 CK_BBOOL
*is_pri_obj
)
1193 crypto_object_get_attribute_value_t obj_ga
;
1194 crypto_object_attribute_t obj_attr
;
1198 obj_ga
.og_session
= sp
->k_session
;
1199 obj_ga
.og_handle
= oid
;
1200 obj_ga
.og_count
= 1;
1202 obj_attr
.oa_type
= CKA_PRIVATE
;
1203 obj_attr
.oa_value
= (char *)&pri_value
;
1204 obj_attr
.oa_value_len
= sizeof (CK_BBOOL
);
1205 obj_ga
.og_attributes
= (char *)&obj_attr
;
1207 while ((r
= ioctl(kernel_fd
, CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE
,
1213 rv
= CKR_FUNCTION_FAILED
;
1215 rv
= crypto2pkcs11_error_number(obj_ga
.og_return_value
);
1219 *is_pri_obj
= *(CK_BBOOL
*)obj_attr
.oa_value
;
1227 get_mechanism_info(kernel_slot_t
*pslot
, CK_MECHANISM_TYPE type
,
1228 CK_MECHANISM_INFO_PTR pInfo
, uint32_t *k_mi_flags
)
1230 crypto_get_provider_mechanism_info_t mechanism_info
;
1232 CK_FLAGS flags
, mi_flags
;
1235 char buf
[11]; /* Num chars for representing ulong in ASCII */
1237 if (type
>= CKM_VENDOR_DEFINED
) {
1238 /* allocate/build a string containing the mechanism number */
1239 (void) snprintf(buf
, sizeof (buf
), "%#lx", type
);
1242 string
= pkcs11_mech2str(type
);
1246 return (CKR_MECHANISM_INVALID
);
1248 (void) strcpy(mechanism_info
.mi_mechanism_name
, string
);
1249 mechanism_info
.mi_provider_id
= pslot
->sl_provider_id
;
1251 while ((r
= ioctl(kernel_fd
, CRYPTO_GET_PROVIDER_MECHANISM_INFO
,
1252 &mechanism_info
)) < 0) {
1257 rv
= CKR_FUNCTION_FAILED
;
1259 rv
= crypto2pkcs11_error_number(
1260 mechanism_info
.mi_return_value
);
1268 * Atomic flags are not part of PKCS#11 so we filter
1271 mi_flags
= mechanism_info
.mi_flags
;
1272 mi_flags
&= ~(CRYPTO_FG_DIGEST_ATOMIC
| CRYPTO_FG_ENCRYPT_ATOMIC
|
1273 CRYPTO_FG_DECRYPT_ATOMIC
| CRYPTO_FG_MAC_ATOMIC
|
1274 CRYPTO_FG_SIGN_ATOMIC
| CRYPTO_FG_VERIFY_ATOMIC
|
1275 CRYPTO_FG_SIGN_RECOVER_ATOMIC
|
1276 CRYPTO_FG_VERIFY_RECOVER_ATOMIC
|
1277 CRYPTO_FG_ENCRYPT_MAC_ATOMIC
|
1278 CRYPTO_FG_MAC_DECRYPT_ATOMIC
);
1280 if (mi_flags
== 0) {
1281 return (CKR_MECHANISM_INVALID
);
1285 /* set the value of k_mi_flags first */
1286 *k_mi_flags
= mi_flags
;
1288 /* convert KEF flags into pkcs11 flags */
1290 if (mi_flags
& CRYPTO_FG_ENCRYPT
)
1291 flags
|= CKF_ENCRYPT
;
1292 if (mi_flags
& CRYPTO_FG_DECRYPT
) {
1293 flags
|= CKF_DECRYPT
;
1295 * Since we'll be emulating C_UnwrapKey() for some
1296 * cases, we can go ahead and claim CKF_UNWRAP
1298 flags
|= CKF_UNWRAP
;
1300 if (mi_flags
& CRYPTO_FG_DIGEST
)
1301 flags
|= CKF_DIGEST
;
1302 if (mi_flags
& CRYPTO_FG_SIGN
)
1304 if (mi_flags
& CRYPTO_FG_SIGN_RECOVER
)
1305 flags
|= CKF_SIGN_RECOVER
;
1306 if (mi_flags
& CRYPTO_FG_VERIFY
)
1307 flags
|= CKF_VERIFY
;
1308 if (mi_flags
& CRYPTO_FG_VERIFY_RECOVER
)
1309 flags
|= CKF_VERIFY_RECOVER
;
1310 if (mi_flags
& CRYPTO_FG_GENERATE
)
1311 flags
|= CKF_GENERATE
;
1312 if (mi_flags
& CRYPTO_FG_GENERATE_KEY_PAIR
)
1313 flags
|= CKF_GENERATE_KEY_PAIR
;
1314 if (mi_flags
& CRYPTO_FG_WRAP
)
1316 if (mi_flags
& CRYPTO_FG_UNWRAP
)
1317 flags
|= CKF_UNWRAP
;
1318 if (mi_flags
& CRYPTO_FG_DERIVE
)
1319 flags
|= CKF_DERIVE
;
1321 pInfo
->ulMinKeySize
= mechanism_info
.mi_min_key_size
;
1322 pInfo
->ulMaxKeySize
= mechanism_info
.mi_max_key_size
;
1323 pInfo
->flags
= flags
;