8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / pkcs11 / pkcs11_softtoken / common / softKeysUtil.c
bloba48ade7224675013fe17d62cdfd531f3c1a1ee3a
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 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <pthread.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <strings.h>
30 #include <sys/types.h>
31 #include <security/cryptoki.h>
32 #include <sys/crypto/common.h>
33 #include <aes_impl.h>
34 #include <blowfish_impl.h>
35 #include <des_impl.h>
36 #include <arcfour.h>
37 #include <cryptoutil.h>
38 #include "softGlobal.h"
39 #include "softSession.h"
40 #include "softObject.h"
41 #include "softDSA.h"
42 #include "softRSA.h"
43 #include "softDH.h"
44 #include "softEC.h"
45 #include "softMAC.h"
46 #include "softOps.h"
47 #include "softKeys.h"
48 #include "softKeystore.h"
49 #include "softSSL.h"
50 #include "softASN1.h"
53 #define local_min(a, b) ((a) < (b) ? (a) : (b))
55 static CK_RV
56 soft_pkcs12_pbe(soft_session_t *, CK_MECHANISM_PTR, soft_object_t *);
59 * Create a temporary key object struct by filling up its template attributes.
61 CK_RV
62 soft_gen_keyobject(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
63 CK_ULONG *objecthandle_p, soft_session_t *sp,
64 CK_OBJECT_CLASS class, CK_KEY_TYPE key_type, CK_ULONG keylen, CK_ULONG mode,
65 boolean_t internal)
68 CK_RV rv;
69 soft_object_t *new_objp = NULL;
71 new_objp = calloc(1, sizeof (soft_object_t));
72 if (new_objp == NULL) {
73 return (CKR_HOST_MEMORY);
76 new_objp->extra_attrlistp = NULL;
79 * Validate attribute template and fill in the attributes
80 * in the soft_object_t.
82 rv = soft_build_key(pTemplate, ulCount, new_objp, class, key_type,
83 keylen, mode);
84 if (rv != CKR_OK) {
85 goto fail_cleanup1;
89 * If generating a key is an internal request (i.e. not a C_XXX
90 * API request), then skip the following checks.
92 if (!internal) {
93 rv = soft_pin_expired_check(new_objp);
94 if (rv != CKR_OK) {
95 goto fail_cleanup2;
98 rv = soft_object_write_access_check(sp, new_objp);
99 if (rv != CKR_OK) {
100 goto fail_cleanup2;
104 /* Initialize the rest of stuffs in soft_object_t. */
105 (void) pthread_mutex_init(&new_objp->object_mutex, NULL);
106 new_objp->magic_marker = SOFTTOKEN_OBJECT_MAGIC;
108 /* Write the new token object to the keystore */
109 if (IS_TOKEN_OBJECT(new_objp)) {
110 new_objp->version = 1;
111 new_objp->session_handle = (CK_SESSION_HANDLE)NULL;
112 soft_add_token_object_to_slot(new_objp);
114 * Type casting the address of an object struct to
115 * an object handle.
117 *objecthandle_p = (CK_ULONG)new_objp;
119 return (CKR_OK);
122 new_objp->session_handle = (CK_SESSION_HANDLE)sp;
124 /* Add the new object to the session's object list. */
125 soft_add_object_to_session(new_objp, sp);
127 /* Type casting the address of an object struct to an object handle. */
128 *objecthandle_p = (CK_ULONG)new_objp;
130 return (CKR_OK);
132 fail_cleanup2:
134 * When any error occurs after soft_build_key(), we will need to
135 * clean up the memory allocated by the soft_build_key().
137 soft_cleanup_object(new_objp);
139 fail_cleanup1:
140 if (new_objp) {
142 * The storage allocated inside of this object should have
143 * been cleaned up by the soft_build_key() if it failed.
144 * Therefore, we can safely free the object.
146 free(new_objp);
149 return (rv);
152 CK_RV
153 soft_genkey(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
154 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey)
157 CK_RV rv = CKR_OK;
158 soft_object_t *secret_key;
159 CK_KEY_TYPE key_type;
160 CK_ULONG keylen = 0;
161 CK_ULONG i;
162 int des_strength = 0;
163 int retry = 0;
164 int keyfound = 0;
165 boolean_t is_ssl_mech = B_FALSE;
167 switch (pMechanism->mechanism) {
168 case CKM_DES_KEY_GEN:
169 key_type = CKK_DES;
170 break;
172 case CKM_DES2_KEY_GEN:
173 key_type = CKK_DES2;
174 break;
176 case CKM_DES3_KEY_GEN:
177 key_type = CKK_DES3;
178 break;
180 case CKM_AES_KEY_GEN:
181 key_type = CKK_AES;
182 break;
184 case CKM_BLOWFISH_KEY_GEN:
185 key_type = CKK_BLOWFISH;
186 break;
188 case CKM_RC4_KEY_GEN:
189 key_type = CKK_RC4;
190 break;
192 case CKM_SSL3_PRE_MASTER_KEY_GEN:
193 case CKM_TLS_PRE_MASTER_KEY_GEN:
194 if (pMechanism->pParameter == NULL ||
195 pMechanism->ulParameterLen != sizeof (CK_VERSION))
196 return (CKR_TEMPLATE_INCOMPLETE);
197 is_ssl_mech = B_TRUE;
198 key_type = CKK_GENERIC_SECRET;
199 keylen = 48;
200 break;
202 case CKM_PKCS5_PBKD2:
203 keyfound = 0;
204 for (i = 0; i < ulCount && !keyfound; i++) {
205 if (pTemplate[i].type == CKA_KEY_TYPE &&
206 pTemplate[i].pValue != NULL) {
207 key_type = *((CK_KEY_TYPE*)pTemplate[i].pValue);
208 keyfound = 1;
211 if (!keyfound)
212 return (CKR_TEMPLATE_INCOMPLETE);
214 * Make sure that parameters were given for this
215 * mechanism.
217 if (pMechanism->pParameter == NULL ||
218 pMechanism->ulParameterLen !=
219 sizeof (CK_PKCS5_PBKD2_PARAMS))
220 return (CKR_TEMPLATE_INCOMPLETE);
221 break;
223 case CKM_PBE_SHA1_RC4_128:
224 keyfound = 0;
225 for (i = 0; i < ulCount; i++) {
226 if (pTemplate[i].type == CKA_KEY_TYPE &&
227 pTemplate[i].pValue != NULL) {
228 key_type = *((CK_KEY_TYPE*)pTemplate[i].pValue);
229 keyfound = 1;
231 if (pTemplate[i].type == CKA_VALUE_LEN &&
232 pTemplate[i].pValue != NULL) {
233 keylen = *((CK_ULONG*)pTemplate[i].pValue);
236 /* If a keytype was specified, it had better be CKK_RC4 */
237 if (keyfound && key_type != CKK_RC4)
238 return (CKR_TEMPLATE_INCONSISTENT);
239 else if (!keyfound)
240 key_type = CKK_RC4;
242 /* If key length was specified, it better be 16 bytes */
243 if (keylen != 0 && keylen != 16)
244 return (CKR_TEMPLATE_INCONSISTENT);
247 * Make sure that parameters were given for this
248 * mechanism.
250 if (pMechanism->pParameter == NULL ||
251 pMechanism->ulParameterLen !=
252 sizeof (CK_PBE_PARAMS))
253 return (CKR_TEMPLATE_INCOMPLETE);
254 break;
255 default:
256 return (CKR_MECHANISM_INVALID);
259 /* Create a new object for secret key. */
260 rv = soft_gen_keyobject(pTemplate, ulCount, phKey, session_p,
261 CKO_SECRET_KEY, key_type, keylen, SOFT_GEN_KEY, B_FALSE);
263 if (rv != CKR_OK) {
264 return (rv);
267 /* Obtain the secret object pointer. */
268 secret_key = (soft_object_t *)*phKey;
270 switch (pMechanism->mechanism) {
271 case CKM_DES_KEY_GEN:
273 * Set up key value len since it is not a required
274 * attribute for C_GenerateKey.
276 keylen = OBJ_SEC_VALUE_LEN(secret_key) = DES_KEYSIZE;
277 des_strength = DES;
278 break;
280 case CKM_DES2_KEY_GEN:
282 * Set up key value len since it is not a required
283 * attribute for C_GenerateKey.
285 keylen = OBJ_SEC_VALUE_LEN(secret_key) = DES2_KEYSIZE;
286 des_strength = DES2;
287 break;
289 case CKM_DES3_KEY_GEN:
291 * Set up key value len since it is not a required
292 * attribute for C_GenerateKey.
294 keylen = OBJ_SEC_VALUE_LEN(secret_key) = DES3_KEYSIZE;
295 des_strength = DES3;
296 break;
298 case CKM_SSL3_PRE_MASTER_KEY_GEN:
299 case CKM_TLS_PRE_MASTER_KEY_GEN:
300 secret_key->bool_attr_mask |= DERIVE_BOOL_ON;
301 /* FALLTHRU */
303 case CKM_AES_KEY_GEN:
304 case CKM_BLOWFISH_KEY_GEN:
305 case CKM_PBE_SHA1_RC4_128:
306 case CKM_RC4_KEY_GEN:
307 keylen = OBJ_SEC_VALUE_LEN(secret_key);
308 break;
310 case CKM_PKCS5_PBKD2:
312 * PKCS#11 does not allow one to specify key
313 * sizes for DES and 3DES, so we must set it here
314 * when using PBKD2 algorithms.
316 if (key_type == CKK_DES) {
317 OBJ_SEC_VALUE_LEN(secret_key) = DES_KEYSIZE;
318 des_strength = DES;
319 } else if (key_type == CKK_DES3) {
320 OBJ_SEC_VALUE_LEN(secret_key) = DES3_KEYSIZE;
321 des_strength = DES3;
324 keylen = OBJ_SEC_VALUE_LEN(secret_key);
325 break;
328 if ((OBJ_SEC_VALUE(secret_key) = malloc(keylen)) == NULL) {
329 if (IS_TOKEN_OBJECT(secret_key))
330 soft_delete_token_object(secret_key, B_FALSE, B_FALSE);
331 else
332 soft_delete_object(session_p, secret_key,
333 B_FALSE, B_FALSE);
335 return (CKR_HOST_MEMORY);
337 switch (pMechanism->mechanism) {
338 case CKM_PBE_SHA1_RC4_128:
340 * Use the PBE algorithm described in PKCS#11 section
341 * 12.33 to derive the key.
343 rv = soft_pkcs12_pbe(session_p, pMechanism, secret_key);
344 break;
345 case CKM_PKCS5_PBKD2:
346 /* Generate keys using PKCS#5 PBKD2 algorithm */
347 rv = soft_generate_pkcs5_pbkdf2_key(session_p, pMechanism,
348 secret_key);
349 if (rv == CKR_OK && des_strength > 0) {
350 /* Perform weak key checking for DES and DES3. */
351 if (des_keycheck(OBJ_SEC_VALUE(secret_key),
352 des_strength, OBJ_SEC_VALUE(secret_key)) ==
353 B_FALSE) {
354 /* We got a weak secret key. */
355 rv = CKR_FUNCTION_FAILED;
358 break;
359 default:
360 do {
361 /* If this fails, bail out */
362 rv = CKR_OK;
363 if (pkcs11_get_urandom(
364 OBJ_SEC_VALUE(secret_key), keylen) < 0) {
365 rv = CKR_DEVICE_ERROR;
366 break;
369 /* Perform weak key checking for DES and DES3. */
370 if (des_strength > 0) {
371 rv = CKR_OK;
372 if (des_keycheck(OBJ_SEC_VALUE(secret_key),
373 des_strength, OBJ_SEC_VALUE(secret_key)) ==
374 B_FALSE) {
375 /* We got a weak key, retry! */
376 retry++;
377 rv = CKR_FUNCTION_FAILED;
381 * Copy over the SSL client version For SSL mechs
382 * The first two bytes of the key is the version
384 if (is_ssl_mech)
385 bcopy(pMechanism->pParameter,
386 OBJ_SEC_VALUE(secret_key),
387 sizeof (CK_VERSION));
389 } while (rv != CKR_OK && retry < KEYGEN_RETRY);
390 if (retry == KEYGEN_RETRY)
391 rv = CKR_FUNCTION_FAILED;
392 break;
395 if (rv != CKR_OK)
396 if (IS_TOKEN_OBJECT(secret_key))
397 soft_delete_token_object(secret_key, B_FALSE, B_FALSE);
398 else
399 soft_delete_object(session_p, secret_key,
400 B_FALSE, B_FALSE);
402 if (IS_TOKEN_OBJECT(secret_key)) {
404 * All the info has been filled, so we can write to
405 * keystore now.
407 rv = soft_put_object_to_keystore(secret_key);
408 if (rv != CKR_OK)
409 soft_delete_token_object(secret_key, B_FALSE, B_FALSE);
412 return (rv);
415 CK_RV
416 soft_genkey_pair(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
417 CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicAttrCount,
418 CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateAttrCount,
419 CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey)
422 CK_RV rv;
423 soft_object_t *public_key, *private_key;
424 CK_KEY_TYPE key_type;
426 switch (pMechanism->mechanism) {
428 case CKM_RSA_PKCS_KEY_PAIR_GEN:
429 key_type = CKK_RSA;
430 break;
432 case CKM_DSA_KEY_PAIR_GEN:
433 key_type = CKK_DSA;
434 break;
436 case CKM_DH_PKCS_KEY_PAIR_GEN:
437 key_type = CKK_DH;
438 break;
440 case CKM_EC_KEY_PAIR_GEN:
441 key_type = CKK_EC;
442 break;
444 default:
445 return (CKR_MECHANISM_INVALID);
448 /* Create a new object for public key. */
449 rv = soft_gen_keyobject(pPublicKeyTemplate, ulPublicAttrCount,
450 phPublicKey, session_p, CKO_PUBLIC_KEY, key_type, 0,
451 SOFT_GEN_KEY, B_FALSE);
453 if (rv != CKR_OK) {
454 return (rv);
457 /* Obtain the public object pointer. */
458 public_key = (soft_object_t *)*phPublicKey;
460 /* Create a new object for private key. */
461 rv = soft_gen_keyobject(pPrivateKeyTemplate, ulPrivateAttrCount,
462 phPrivateKey, session_p, CKO_PRIVATE_KEY, key_type, 0,
463 SOFT_GEN_KEY, B_FALSE);
465 if (rv != CKR_OK) {
467 * Both public key and private key must be successful.
469 if (IS_TOKEN_OBJECT(public_key))
470 soft_delete_token_object(public_key, B_FALSE, B_FALSE);
471 else
472 soft_delete_object(session_p, public_key,
473 B_FALSE, B_FALSE);
474 return (rv);
477 /* Obtain the private object pointer. */
478 private_key = (soft_object_t *)*phPrivateKey;
481 * At this point, both public key and private key objects
482 * are settled with the application specified attributes.
483 * We are ready to generate the rest of key attributes based
484 * on the existing attributes.
487 switch (key_type) {
488 case CKK_RSA:
489 rv = soft_rsa_genkey_pair(public_key, private_key);
490 break;
492 case CKK_DSA:
493 rv = soft_dsa_genkey_pair(public_key, private_key);
494 break;
496 case CKK_DH:
497 rv = soft_dh_genkey_pair(public_key, private_key);
498 private_key->bool_attr_mask |= DERIVE_BOOL_ON;
499 break;
500 case CKK_EC:
501 rv = soft_ec_genkey_pair(public_key, private_key);
502 private_key->bool_attr_mask |= DERIVE_BOOL_ON;
503 break;
506 if (rv != CKR_OK) {
507 if (IS_TOKEN_OBJECT(public_key)) {
508 soft_delete_token_object(public_key, B_FALSE, B_FALSE);
509 soft_delete_token_object(private_key, B_FALSE, B_FALSE);
510 } else {
511 soft_delete_object(session_p, public_key,
512 B_FALSE, B_FALSE);
513 soft_delete_object(session_p, private_key,
514 B_FALSE, B_FALSE);
516 return (rv);
519 if (IS_TOKEN_OBJECT(public_key)) {
521 * All the info has been filled, so we can write to
522 * keystore now.
524 rv = soft_put_object_to_keystore(public_key);
525 if (rv != CKR_OK) {
526 soft_delete_token_object(public_key, B_FALSE, B_FALSE);
527 soft_delete_token_object(private_key, B_FALSE, B_FALSE);
528 return (rv);
532 if (IS_TOKEN_OBJECT(private_key)) {
533 rv = soft_put_object_to_keystore(private_key);
534 if (rv != CKR_OK) {
536 * We also need to delete the public token object
537 * from keystore.
539 soft_delete_token_object(public_key, B_TRUE, B_FALSE);
540 soft_delete_token_object(private_key, B_FALSE, B_FALSE);
544 return (rv);
548 CK_RV
549 soft_key_derive_check_length(soft_object_t *secret_key, CK_ULONG max_keylen)
552 switch (secret_key->key_type) {
553 case CKK_GENERIC_SECRET:
554 if (OBJ_SEC_VALUE_LEN(secret_key) == 0) {
555 OBJ_SEC_VALUE_LEN(secret_key) = max_keylen;
556 return (CKR_OK);
557 } else if (OBJ_SEC_VALUE_LEN(secret_key) > max_keylen) {
558 return (CKR_ATTRIBUTE_VALUE_INVALID);
560 break;
561 case CKK_RC4:
562 case CKK_AES:
563 case CKK_BLOWFISH:
564 if ((OBJ_SEC_VALUE_LEN(secret_key) == 0) ||
565 (OBJ_SEC_VALUE_LEN(secret_key) > max_keylen)) {
566 /* RC4 and AES has variable key length */
567 return (CKR_ATTRIBUTE_VALUE_INVALID);
569 break;
570 case CKK_DES:
571 if (OBJ_SEC_VALUE_LEN(secret_key) == 0) {
572 /* DES has a well-defined length */
573 OBJ_SEC_VALUE_LEN(secret_key) = DES_KEYSIZE;
574 return (CKR_OK);
575 } else if (OBJ_SEC_VALUE_LEN(secret_key) != DES_KEYSIZE) {
576 return (CKR_ATTRIBUTE_VALUE_INVALID);
578 break;
579 case CKK_DES2:
580 if (OBJ_SEC_VALUE_LEN(secret_key) == 0) {
581 /* DES2 has a well-defined length */
582 OBJ_SEC_VALUE_LEN(secret_key) = DES2_KEYSIZE;
583 return (CKR_OK);
584 } else if (OBJ_SEC_VALUE_LEN(secret_key) != DES2_KEYSIZE) {
585 return (CKR_ATTRIBUTE_VALUE_INVALID);
587 break;
589 default:
590 return (CKR_MECHANISM_INVALID);
593 return (CKR_OK);
597 * PKCS#11 (12.33) says that v = 512 bits (64 bytes) for SHA1
598 * PBE methods.
600 #define PKCS12_BUFFER_SIZE 64
602 * PKCS#12 defines 3 different ID bytes to be used for
603 * deriving keys for different operations.
605 #define PBE_ID_ENCRYPT 1
606 #define PBE_ID_IV 2
607 #define PBE_ID_MAC 3
608 #define PBE_CEIL(a, b) (((a)/(b)) + (((a)%(b)) > 0))
610 static CK_RV
611 soft_pkcs12_pbe(soft_session_t *session_p,
612 CK_MECHANISM_PTR pMechanism,
613 soft_object_t *derived_key)
615 CK_RV rv = CKR_OK;
616 CK_PBE_PARAMS *params = pMechanism->pParameter;
617 CK_ULONG c, i, j, k;
618 CK_ULONG hashSize;
619 CK_ULONG buffSize;
621 * Terse variable names are used to make following
622 * the PKCS#12 spec easier.
624 CK_BYTE *A = NULL;
625 CK_BYTE *Ai = NULL;
626 CK_BYTE *B = NULL;
627 CK_BYTE *D = NULL;
628 CK_BYTE *I = NULL, *S, *P;
629 CK_BYTE *keybuf = NULL;
630 CK_ULONG Alen, Ilen, Slen, Plen, AiLen, Blen, Dlen;
631 CK_ULONG keysize = OBJ_SEC_VALUE_LEN(derived_key);
632 CK_MECHANISM digest_mech;
634 /* U = hash function output bits */
635 if (pMechanism->mechanism == CKM_PBE_SHA1_RC4_128) {
636 hashSize = SHA1_HASH_SIZE;
637 buffSize = PKCS12_BUFFER_SIZE;
638 digest_mech.mechanism = CKM_SHA_1;
639 digest_mech.pParameter = NULL;
640 digest_mech.ulParameterLen = 0;
641 } else {
642 /* we only support 1 PBE mech for now */
643 return (CKR_MECHANISM_INVALID);
645 keybuf = OBJ_SEC_VALUE(derived_key);
647 Blen = Dlen = buffSize;
648 D = (CK_BYTE *)malloc(Dlen);
649 if (D == NULL) {
650 rv = CKR_HOST_MEMORY;
651 goto cleanup;
654 B = (CK_BYTE *)malloc(Blen);
655 if (B == NULL) {
656 rv = CKR_HOST_MEMORY;
657 goto cleanup;
661 * Initialize some values and create some buffers
662 * that we need later.
664 * Slen = buffSize * CEIL(SaltLength/buffSize)
666 Slen = buffSize * PBE_CEIL(params->ulSaltLen, buffSize);
669 * Plen = buffSize * CEIL(PasswordLength/buffSize)
671 Plen = buffSize * PBE_CEIL(params->ulPasswordLen, buffSize);
674 * From step 4: I = S + P, so: Ilen = Slen + Plen
676 Ilen = Slen + Plen;
677 I = (CK_BYTE *)malloc(Ilen);
678 if (I == NULL) {
679 rv = CKR_HOST_MEMORY;
680 goto cleanup;
683 S = I;
684 P = I + Slen;
687 * Step 1.
688 * We are only interested in deriving keys for encrypt/decrypt
689 * for now, so construct the "D"iversifier accordingly.
691 (void) memset(D, PBE_ID_ENCRYPT, Dlen);
694 * Step 2.
695 * Concatenate copies of the salt together to make S.
697 for (i = 0; i < Slen; i += params->ulSaltLen) {
698 (void) memcpy(S+i, params->pSalt,
699 ((Slen - i) > params->ulSaltLen ?
700 params->ulSaltLen : (Slen - i)));
704 * Step 3.
705 * Concatenate copies of the password together to make
706 * a string P.
708 for (i = 0; i < Plen; i += params->ulPasswordLen) {
709 (void) memcpy(P+i, params->pPassword,
710 ((Plen - i) > params->ulPasswordLen ?
711 params->ulPasswordLen : (Plen - i)));
715 * Step 4.
716 * I = S+P - this is now done because S and P are
717 * pointers into I.
719 * Step 5.
720 * c= CEIL[n/u]
721 * where n = pseudorandom bits of output desired.
723 c = PBE_CEIL(keysize, hashSize);
726 * Step 6.
728 Alen = c * hashSize;
729 A = (CK_BYTE *)malloc(Alen);
730 if (A == NULL) {
731 rv = CKR_HOST_MEMORY;
732 goto cleanup;
734 AiLen = hashSize;
735 Ai = (CK_BYTE *)malloc(AiLen);
736 if (Ai == NULL) {
737 rv = CKR_HOST_MEMORY;
738 goto cleanup;
742 * Step 6a.
743 * Ai = Hr(D+I)
745 for (i = 0; i < c; i++) {
746 (void) pthread_mutex_lock(&session_p->session_mutex);
748 if (session_p->sign.flags & CRYPTO_OPERATION_ACTIVE) {
749 (void) pthread_mutex_unlock(&session_p->session_mutex);
750 rv = CKR_OPERATION_ACTIVE;
751 goto cleanup;
753 session_p->sign.flags |= CRYPTO_OPERATION_ACTIVE;
754 (void) pthread_mutex_unlock(&session_p->session_mutex);
756 for (j = 0; j < params->ulIteration; j++) {
757 rv = soft_digest_init(session_p, &digest_mech);
758 if (rv != CKR_OK)
759 goto digest_done;
761 if (j == 0) {
762 rv = soft_digest_update(session_p, D, Dlen);
763 if (rv != CKR_OK)
764 goto digest_done;
766 rv = soft_digest_update(session_p, I, Ilen);
767 } else {
768 rv = soft_digest_update(session_p, Ai, AiLen);
770 if (rv != CKR_OK)
771 goto digest_done;
773 rv = soft_digest_final(session_p, Ai, &AiLen);
774 if (rv != CKR_OK)
775 goto digest_done;
777 digest_done:
778 (void) pthread_mutex_lock(&session_p->session_mutex);
779 session_p->sign.flags &= ~CRYPTO_OPERATION_ACTIVE;
780 (void) pthread_mutex_unlock(&session_p->session_mutex);
782 if (rv != CKR_OK)
783 goto cleanup;
785 * Step 6b.
786 * Concatenate Ai to make B
788 for (j = 0; j < Blen; j += hashSize) {
789 (void) memcpy(B+j, Ai, ((Blen - j > hashSize) ?
790 hashSize : Blen - j));
794 * Step 6c.
796 k = Ilen / Blen;
797 for (j = 0; j < k; j++) {
798 uchar_t idx;
799 CK_ULONG m, q = 1, cbit = 0;
801 for (m = Blen - 1; m >= (CK_ULONG)0; m--, q = 0) {
802 idx = m + j*Blen;
804 q += (CK_ULONG)I[idx] + (CK_ULONG)B[m];
805 q += cbit;
806 I[idx] = (CK_BYTE)(q & 0xff);
807 cbit = (q > 0xff);
812 * Step 7.
813 * A += Ai
815 (void) memcpy(A + i*hashSize, Ai, AiLen);
819 * Step 8.
820 * The final output of this process is the A buffer
822 (void) memcpy(keybuf, A, keysize);
824 cleanup:
825 if (A) {
826 bzero(A, Alen);
827 free(A);
829 if (Ai) {
830 bzero(Ai, AiLen);
831 free(Ai);
833 if (B) {
834 bzero(B, Blen);
835 free(B);
837 if (D) {
838 bzero(D, Dlen);
839 free(D);
841 if (I) {
842 bzero(I, Ilen);
843 free(I);
845 return (rv);
848 CK_RV
849 soft_derivekey(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
850 soft_object_t *basekey_p, CK_ATTRIBUTE_PTR pTemplate,
851 CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
854 CK_RV rv = CKR_OK;
855 soft_object_t *secret_key;
856 CK_MECHANISM digest_mech;
857 CK_BYTE hash[SHA512_DIGEST_LENGTH]; /* space enough for all mechs */
858 CK_ULONG hash_len = SHA512_DIGEST_LENGTH;
859 CK_ULONG secret_key_len;
860 CK_ULONG hash_size;
862 switch (pMechanism->mechanism) {
863 case CKM_DH_PKCS_DERIVE:
865 * Create a new object for secret key. The key type should
866 * be provided in the template.
868 rv = soft_gen_keyobject(pTemplate, ulAttributeCount,
869 phKey, session_p, CKO_SECRET_KEY, (CK_KEY_TYPE)~0UL, 0,
870 SOFT_DERIVE_KEY_DH, B_FALSE);
872 if (rv != CKR_OK) {
873 return (rv);
876 /* Obtain the secret object pointer. */
877 secret_key = (soft_object_t *)*phKey;
879 rv = soft_dh_key_derive(basekey_p, secret_key,
880 (CK_BYTE *)pMechanism->pParameter,
881 pMechanism->ulParameterLen);
883 if (rv != CKR_OK) {
884 if (IS_TOKEN_OBJECT(secret_key))
885 soft_delete_token_object(secret_key, B_FALSE,
886 B_FALSE);
887 else
888 soft_delete_object(session_p, secret_key,
889 B_FALSE, B_FALSE);
890 return (rv);
893 break;
895 case CKM_ECDH1_DERIVE:
897 * Create a new object for secret key. The key type should
898 * be provided in the template.
900 rv = soft_gen_keyobject(pTemplate, ulAttributeCount,
901 phKey, session_p, CKO_SECRET_KEY, (CK_KEY_TYPE)~0UL, 0,
902 SOFT_DERIVE_KEY_DH, B_FALSE);
904 if (rv != CKR_OK) {
905 return (rv);
908 /* Obtain the secret object pointer. */
909 secret_key = (soft_object_t *)*phKey;
911 rv = soft_ec_key_derive(basekey_p, secret_key,
912 (CK_BYTE *)pMechanism->pParameter,
913 pMechanism->ulParameterLen);
915 if (rv != CKR_OK) {
916 if (IS_TOKEN_OBJECT(secret_key))
917 soft_delete_token_object(secret_key, B_FALSE,
918 B_FALSE);
919 else
920 soft_delete_object(session_p, secret_key,
921 B_FALSE, B_FALSE);
922 return (rv);
925 break;
927 case CKM_SHA1_KEY_DERIVATION:
928 hash_size = SHA1_HASH_SIZE;
929 digest_mech.mechanism = CKM_SHA_1;
930 goto common;
932 case CKM_MD5_KEY_DERIVATION:
933 hash_size = MD5_HASH_SIZE;
934 digest_mech.mechanism = CKM_MD5;
935 goto common;
937 case CKM_SHA256_KEY_DERIVATION:
938 hash_size = SHA256_DIGEST_LENGTH;
939 digest_mech.mechanism = CKM_SHA256;
940 goto common;
942 case CKM_SHA384_KEY_DERIVATION:
943 hash_size = SHA384_DIGEST_LENGTH;
944 digest_mech.mechanism = CKM_SHA384;
945 goto common;
947 case CKM_SHA512_KEY_DERIVATION:
948 hash_size = SHA512_DIGEST_LENGTH;
949 digest_mech.mechanism = CKM_SHA512;
950 goto common;
952 common:
954 * Create a new object for secret key. The key type is optional
955 * to be provided in the template. If it is not specified in
956 * the template, the default is CKK_GENERIC_SECRET.
958 rv = soft_gen_keyobject(pTemplate, ulAttributeCount,
959 phKey, session_p, CKO_SECRET_KEY,
960 (CK_KEY_TYPE)CKK_GENERIC_SECRET, 0,
961 SOFT_DERIVE_KEY_OTHER, B_FALSE);
963 if (rv != CKR_OK) {
964 return (rv);
967 /* Obtain the secret object pointer. */
968 secret_key = (soft_object_t *)*phKey;
970 /* Validate the key type and key length */
971 rv = soft_key_derive_check_length(secret_key, hash_size);
972 if (rv != CKR_OK) {
973 if (IS_TOKEN_OBJECT(secret_key))
974 soft_delete_token_object(secret_key, B_FALSE,
975 B_FALSE);
976 else
977 soft_delete_object(session_p, secret_key,
978 B_FALSE, B_FALSE);
979 return (rv);
983 * Derive the secret key by digesting the value of another
984 * secret key (base key) with SHA-1 or MD5.
986 rv = soft_digest_init_internal(session_p, &digest_mech);
987 if (rv != CKR_OK) {
988 if (IS_TOKEN_OBJECT(secret_key))
989 soft_delete_token_object(secret_key, B_FALSE,
990 B_FALSE);
991 else
992 soft_delete_object(session_p, secret_key,
993 B_FALSE, B_FALSE);
994 return (rv);
997 rv = soft_digest(session_p, OBJ_SEC_VALUE(basekey_p),
998 OBJ_SEC_VALUE_LEN(basekey_p), hash, &hash_len);
1000 (void) pthread_mutex_lock(&session_p->session_mutex);
1001 /* soft_digest_common() has freed the digest context */
1002 session_p->digest.flags = 0;
1003 (void) pthread_mutex_unlock(&session_p->session_mutex);
1005 if (rv != CKR_OK) {
1006 if (IS_TOKEN_OBJECT(secret_key))
1007 soft_delete_token_object(secret_key, B_FALSE,
1008 B_FALSE);
1009 else
1010 soft_delete_object(session_p, secret_key,
1011 B_FALSE, B_FALSE);
1012 return (rv);
1015 secret_key_len = OBJ_SEC_VALUE_LEN(secret_key);
1017 if ((OBJ_SEC_VALUE(secret_key) = malloc(secret_key_len)) ==
1018 NULL) {
1019 if (IS_TOKEN_OBJECT(secret_key))
1020 soft_delete_token_object(secret_key, B_FALSE,
1021 B_FALSE);
1022 else
1023 soft_delete_object(session_p, secret_key,
1024 B_FALSE, B_FALSE);
1025 return (CKR_HOST_MEMORY);
1029 * The key produced by this mechanism will be of the
1030 * specified type and length.
1031 * The truncation removes extra bytes from the leading
1032 * of the digested key value.
1034 (void) memcpy(OBJ_SEC_VALUE(secret_key),
1035 (hash + hash_len - secret_key_len),
1036 secret_key_len);
1038 break;
1041 * The key sensitivity and extractability rules for the generated
1042 * keys will be enforced inside soft_ssl_master_key_derive() and
1043 * soft_ssl_key_and_mac_derive()
1045 case CKM_SSL3_MASTER_KEY_DERIVE:
1046 case CKM_SSL3_MASTER_KEY_DERIVE_DH:
1047 case CKM_TLS_MASTER_KEY_DERIVE:
1048 case CKM_TLS_MASTER_KEY_DERIVE_DH:
1049 if (phKey == NULL_PTR)
1050 return (CKR_ARGUMENTS_BAD);
1051 return (soft_ssl_master_key_derive(session_p, pMechanism,
1052 basekey_p, pTemplate, ulAttributeCount, phKey));
1054 case CKM_SSL3_KEY_AND_MAC_DERIVE:
1055 case CKM_TLS_KEY_AND_MAC_DERIVE:
1056 return (soft_ssl_key_and_mac_derive(session_p, pMechanism,
1057 basekey_p, pTemplate, ulAttributeCount));
1059 case CKM_TLS_PRF:
1060 if (pMechanism->pParameter == NULL ||
1061 pMechanism->ulParameterLen != sizeof (CK_TLS_PRF_PARAMS) ||
1062 phKey != NULL)
1063 return (CKR_ARGUMENTS_BAD);
1065 if (pTemplate != NULL)
1066 return (CKR_TEMPLATE_INCONSISTENT);
1068 return (derive_tls_prf(
1069 (CK_TLS_PRF_PARAMS_PTR)pMechanism->pParameter, basekey_p));
1071 default:
1072 return (CKR_MECHANISM_INVALID);
1075 soft_derive_enforce_flags(basekey_p, secret_key);
1077 if (IS_TOKEN_OBJECT(secret_key)) {
1079 * All the info has been filled, so we can write to
1080 * keystore now.
1082 rv = soft_put_object_to_keystore(secret_key);
1083 if (rv != CKR_OK)
1084 soft_delete_token_object(secret_key, B_FALSE, B_FALSE);
1087 return (rv);
1092 * Perform key derivation rules on key's sensitivity and extractability.
1094 void
1095 soft_derive_enforce_flags(soft_object_t *basekey, soft_object_t *newkey)
1098 boolean_t new_sensitive = B_FALSE;
1099 boolean_t new_extractable = B_FALSE;
1102 * The sensitive and extractable bits have been set when
1103 * the newkey was built.
1105 if (newkey->bool_attr_mask & SENSITIVE_BOOL_ON) {
1106 new_sensitive = B_TRUE;
1109 if (newkey->bool_attr_mask & EXTRACTABLE_BOOL_ON) {
1110 new_extractable = B_TRUE;
1113 /* Derive the CKA_ALWAYS_SENSITIVE flag */
1114 if (!basekey->bool_attr_mask & ALWAYS_SENSITIVE_BOOL_ON) {
1116 * If the base key has its CKA_ALWAYS_SENSITIVE set to
1117 * FALSE, then the derived key will as well.
1119 newkey->bool_attr_mask &= ~ALWAYS_SENSITIVE_BOOL_ON;
1120 } else {
1122 * If the base key has its CKA_ALWAYS_SENSITIVE set to TRUE,
1123 * then the derived key has the CKA_ALWAYS_SENSITIVE set to
1124 * the same value as its CKA_SENSITIVE;
1126 if (new_sensitive) {
1127 newkey->bool_attr_mask |= ALWAYS_SENSITIVE_BOOL_ON;
1128 } else {
1129 newkey->bool_attr_mask &= ~ALWAYS_SENSITIVE_BOOL_ON;
1133 /* Derive the CKA_NEVER_EXTRACTABLE flag */
1134 if (!basekey->bool_attr_mask & NEVER_EXTRACTABLE_BOOL_ON) {
1136 * If the base key has its CKA_NEVER_EXTRACTABLE set to
1137 * FALSE, then the derived key will as well.
1139 newkey->bool_attr_mask &= ~NEVER_EXTRACTABLE_BOOL_ON;
1140 } else {
1142 * If the base key has its CKA_NEVER_EXTRACTABLE set to TRUE,
1143 * then the derived key has the CKA_NEVER_EXTRACTABLE set to
1144 * the opposite value from its CKA_EXTRACTABLE;
1146 if (new_extractable) {
1147 newkey->bool_attr_mask &= ~NEVER_EXTRACTABLE_BOOL_ON;
1148 } else {
1149 newkey->bool_attr_mask |= NEVER_EXTRACTABLE_BOOL_ON;
1153 /* Set the CKA_LOCAL flag to false */
1154 newkey->bool_attr_mask &= ~LOCAL_BOOL_ON;
1159 * do_prf
1161 * This routine implements Step 3. of the PBKDF2 function
1162 * defined in PKCS#5 for generating derived keys from a
1163 * password.
1165 * Currently, PRF is always SHA_1_HMAC.
1167 static CK_RV
1168 do_prf(soft_session_t *session_p,
1169 CK_PKCS5_PBKD2_PARAMS_PTR params,
1170 soft_object_t *hmac_key,
1171 CK_BYTE *newsalt, CK_ULONG saltlen,
1172 CK_BYTE *blockdata, CK_ULONG blocklen)
1174 CK_RV rv = CKR_OK;
1175 CK_MECHANISM digest_mech = {CKM_SHA_1_HMAC, NULL, 0};
1176 CK_BYTE buffer[2][SHA1_HASH_SIZE];
1177 CK_ULONG hmac_outlen = SHA1_HASH_SIZE;
1178 CK_ULONG inlen;
1179 CK_BYTE *input, *output;
1180 CK_ULONG i, j;
1182 input = newsalt;
1183 inlen = saltlen;
1185 output = buffer[1];
1186 (void) pthread_mutex_lock(&session_p->session_mutex);
1188 if (session_p->sign.flags & CRYPTO_OPERATION_ACTIVE) {
1189 (void) pthread_mutex_unlock(&session_p->session_mutex);
1190 return (CKR_OPERATION_ACTIVE);
1192 session_p->sign.flags |= CRYPTO_OPERATION_ACTIVE;
1193 (void) pthread_mutex_unlock(&session_p->session_mutex);
1195 for (i = 0; i < params->iterations; i++) {
1197 * The key doesn't change, its always the
1198 * password iniitally given.
1200 rv = soft_sign_init(session_p, &digest_mech, hmac_key);
1202 if (rv != CKR_OK) {
1203 goto cleanup;
1206 /* Call PRF function (SHA1_HMAC for now). */
1207 rv = soft_sign(session_p, input, inlen, output, &hmac_outlen);
1209 if (rv != CKR_OK) {
1210 goto cleanup;
1213 * The first time, initialize the output buffer
1214 * with the HMAC signature.
1216 if (i == 0) {
1217 (void) memcpy(blockdata, output,
1218 local_min(blocklen, hmac_outlen));
1219 } else {
1221 * XOR the existing data with output from PRF.
1223 * Only XOR up to the length of the blockdata,
1224 * it may be less than a full hmac buffer when
1225 * the final block is being computed.
1227 for (j = 0; j < hmac_outlen && j < blocklen; j++)
1228 blockdata[j] ^= output[j];
1230 /* Output from previous PRF is input for next round */
1231 input = output;
1232 inlen = hmac_outlen;
1235 * Switch buffers to avoid overuse of memcpy.
1236 * Initially we used buffer[1], so after the end of
1237 * the first iteration (i==0), we switch to buffer[0]
1238 * and continue swapping with each iteration.
1240 output = buffer[i%2];
1242 cleanup:
1243 (void) pthread_mutex_lock(&session_p->session_mutex);
1244 session_p->sign.flags &= ~CRYPTO_OPERATION_ACTIVE;
1245 (void) pthread_mutex_unlock(&session_p->session_mutex);
1247 return (rv);
1250 static CK_RV
1251 soft_create_hmac_key(soft_session_t *session_p, CK_BYTE *passwd,
1252 CK_ULONG passwd_len, CK_OBJECT_HANDLE_PTR phKey)
1254 CK_RV rv = CKR_OK;
1255 CK_OBJECT_CLASS keyclass = CKO_SECRET_KEY;
1256 CK_KEY_TYPE keytype = CKK_GENERIC_SECRET;
1257 CK_BBOOL True = TRUE;
1258 CK_ATTRIBUTE keytemplate[4];
1260 * We must initialize each template member individually
1261 * because at the time of initial coding for ON10, the
1262 * compiler was using the "-xc99=%none" option
1263 * which prevents us from being able to declare the whole
1264 * template in place as usual.
1266 keytemplate[0].type = CKA_CLASS;
1267 keytemplate[0].pValue = &keyclass;
1268 keytemplate[0].ulValueLen = sizeof (keyclass);
1270 keytemplate[1].type = CKA_KEY_TYPE;
1271 keytemplate[1].pValue = &keytype;
1272 keytemplate[1].ulValueLen = sizeof (keytype);
1274 keytemplate[2].type = CKA_SIGN;
1275 keytemplate[2].pValue = &True;
1276 keytemplate[2].ulValueLen = sizeof (True);
1278 keytemplate[3].type = CKA_VALUE;
1279 keytemplate[3].pValue = passwd;
1280 keytemplate[3].ulValueLen = passwd_len;
1282 * Create a generic key object to be used for HMAC operations.
1283 * The "value" for this key is the password from the
1284 * mechanism parameter structure.
1286 rv = soft_gen_keyobject(keytemplate,
1287 sizeof (keytemplate)/sizeof (CK_ATTRIBUTE), phKey, session_p,
1288 CKO_SECRET_KEY, (CK_KEY_TYPE)CKK_GENERIC_SECRET, 0,
1289 SOFT_CREATE_OBJ, B_TRUE);
1291 return (rv);
1294 CK_RV
1295 soft_generate_pkcs5_pbkdf2_key(soft_session_t *session_p,
1296 CK_MECHANISM_PTR pMechanism,
1297 soft_object_t *secret_key)
1299 CK_RV rv = CKR_OK;
1300 CK_PKCS5_PBKD2_PARAMS *params =
1301 (CK_PKCS5_PBKD2_PARAMS *)pMechanism->pParameter;
1302 CK_ULONG hLen = SHA1_HASH_SIZE;
1303 CK_ULONG dkLen, i;
1304 CK_ULONG blocks, remainder;
1305 CK_OBJECT_HANDLE phKey = 0;
1306 soft_object_t *hmac_key = NULL;
1307 CK_BYTE *salt = NULL;
1308 CK_BYTE *keydata = NULL;
1310 params = (CK_PKCS5_PBKD2_PARAMS_PTR) pMechanism->pParameter;
1312 if (params->prf != CKP_PKCS5_PBKD2_HMAC_SHA1)
1313 return (CKR_MECHANISM_PARAM_INVALID);
1315 if (params->pPrfData != NULL || params->ulPrfDataLen != 0)
1316 return (CKR_DATA_INVALID);
1318 if (params->saltSource != CKZ_SALT_SPECIFIED ||
1319 params->iterations == 0)
1320 return (CKR_MECHANISM_PARAM_INVALID);
1323 * Create a key object to use for HMAC operations.
1325 rv = soft_create_hmac_key(session_p, params->pPassword,
1326 *params->ulPasswordLen, &phKey);
1328 if (rv != CKR_OK)
1329 return (rv);
1331 hmac_key = (soft_object_t *)phKey;
1333 /* Step 1. */
1334 dkLen = OBJ_SEC_VALUE_LEN(secret_key); /* length of desired key */
1336 if (dkLen > ((((u_longlong_t)1)<<32)-1)*hLen) {
1337 (void) soft_delete_object(session_p, hmac_key, B_FALSE,
1338 B_FALSE);
1339 return (CKR_KEY_SIZE_RANGE);
1342 /* Step 2. */
1343 blocks = dkLen / hLen;
1345 /* crude "Ceiling" function to adjust the number of blocks to use */
1346 if (blocks * hLen != dkLen)
1347 blocks++;
1349 remainder = dkLen - ((blocks - 1) * hLen);
1351 /* Step 3 */
1352 salt = (CK_BYTE *)malloc(params->ulSaltSourceDataLen + 4);
1353 if (salt == NULL) {
1354 (void) soft_delete_object(session_p, hmac_key, B_FALSE,
1355 B_FALSE);
1356 return (CKR_HOST_MEMORY);
1359 * Nothing in PKCS#5 says you cannot pass an empty
1360 * salt, so we will allow for this and not return error
1361 * if the salt is not specified.
1363 if (params->pSaltSourceData != NULL && params->ulSaltSourceDataLen > 0)
1364 (void) memcpy(salt, params->pSaltSourceData,
1365 params->ulSaltSourceDataLen);
1368 * Get pointer to the data section of the key,
1369 * this will be used below as output from the
1370 * PRF iteration/concatenations so that when the
1371 * blocks are all iterated, the secret_key will
1372 * have the resulting derived key value.
1374 keydata = (CK_BYTE *)OBJ_SEC_VALUE(secret_key);
1376 /* Step 4. */
1377 for (i = 0; i < blocks && (rv == CKR_OK); i++) {
1378 CK_BYTE *s;
1380 s = salt + params->ulSaltSourceDataLen;
1383 * Append the block index to the salt as input
1384 * to the PRF. Block index should start at 1
1385 * not 0.
1387 *s++ = ((i+1) >> 24) & 0xff;
1388 *s++ = ((i+1) >> 16) & 0xff;
1389 *s++ = ((i+1) >> 8) & 0xff;
1390 *s = ((i+1)) & 0xff;
1393 * Adjust the key pointer so we always append the
1394 * PRF output to the current key.
1396 rv = do_prf(session_p, params, hmac_key,
1397 salt, params->ulSaltSourceDataLen + 4, keydata,
1398 ((i + 1) == blocks ? remainder : hLen));
1400 keydata += hLen;
1402 (void) soft_delete_object(session_p, hmac_key, B_FALSE, B_FALSE);
1403 free(salt);
1405 return (rv);
1408 CK_RV
1409 soft_wrapkey(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
1410 soft_object_t *wrappingKey_p, soft_object_t *hkey_p,
1411 CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen)
1413 CK_RV rv = CKR_OK;
1414 CK_ULONG plain_len = 0;
1415 CK_BYTE_PTR plain_data = NULL;
1416 CK_ULONG padded_len = 0;
1417 CK_BYTE_PTR padded_data = NULL;
1418 CK_ULONG wkey_blksz = 1; /* so modulo will work right */
1420 /* Check if the mechanism is supported. */
1421 switch (pMechanism->mechanism) {
1422 case CKM_DES_CBC_PAD:
1423 case CKM_DES3_CBC_PAD:
1424 case CKM_AES_CBC_PAD:
1426 * Secret key mechs with padding can be used to wrap secret
1427 * keys and private keys only. See PKCS#11, * sec 11.14,
1428 * C_WrapKey and secs 12.* for each mechanism's wrapping/
1429 * unwrapping constraints.
1431 if (hkey_p->class != CKO_SECRET_KEY && hkey_p->class !=
1432 CKO_PRIVATE_KEY)
1433 return (CKR_MECHANISM_INVALID);
1434 break;
1435 case CKM_RSA_PKCS:
1436 case CKM_RSA_X_509:
1437 case CKM_DES_ECB:
1438 case CKM_DES3_ECB:
1439 case CKM_AES_ECB:
1440 case CKM_DES_CBC:
1441 case CKM_DES3_CBC:
1442 case CKM_AES_CBC:
1443 case CKM_AES_CTR:
1444 case CKM_BLOWFISH_CBC:
1446 * Unpadded secret key mechs and private key mechs are only
1447 * defined for wrapping secret keys. See PKCS#11 refs above.
1449 if (hkey_p->class != CKO_SECRET_KEY)
1450 return (CKR_MECHANISM_INVALID);
1451 break;
1452 default:
1453 return (CKR_MECHANISM_INVALID);
1456 if (hkey_p->class == CKO_SECRET_KEY) {
1457 plain_data = OBJ_SEC_VALUE(hkey_p);
1458 plain_len = OBJ_SEC_VALUE_LEN(hkey_p);
1459 } else {
1461 * BER-encode the object to be wrapped: call first with
1462 * plain_data = NULL to get the size needed, allocate that
1463 * much space, call again to fill space with actual data.
1465 rv = soft_object_to_asn1(hkey_p, NULL, &plain_len);
1466 if (rv != CKR_OK)
1467 return (rv);
1468 if ((plain_data = malloc(plain_len)) == NULL)
1469 return (CKR_HOST_MEMORY);
1470 (void) memset(plain_data, 0x0, plain_len);
1471 rv = soft_object_to_asn1(hkey_p, plain_data, &plain_len);
1472 if (rv != CKR_OK)
1473 goto cleanup_wrap;
1477 * For unpadded ECB and CBC mechanisms, the object needs to be
1478 * padded to the wrapping key's blocksize prior to the encryption.
1480 padded_len = plain_len;
1481 padded_data = plain_data;
1483 switch (pMechanism->mechanism) {
1484 case CKM_DES_ECB:
1485 case CKM_DES3_ECB:
1486 case CKM_AES_ECB:
1487 case CKM_DES_CBC:
1488 case CKM_DES3_CBC:
1489 case CKM_AES_CBC:
1490 case CKM_BLOWFISH_CBC:
1491 /* Find the block size of the wrapping key. */
1492 if (wrappingKey_p->class == CKO_SECRET_KEY) {
1493 switch (wrappingKey_p->key_type) {
1494 case CKK_DES:
1495 case CKK_DES2:
1496 case CKK_DES3:
1497 wkey_blksz = DES_BLOCK_LEN;
1498 break;
1499 case CKK_AES:
1500 wkey_blksz = AES_BLOCK_LEN;
1501 break;
1502 case CKK_BLOWFISH:
1503 wkey_blksz = BLOWFISH_BLOCK_LEN;
1504 break;
1505 default:
1506 break;
1508 } else {
1509 rv = CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
1510 goto cleanup_wrap;
1513 /* Extend the plain text data to block size boundary. */
1514 if ((padded_len % wkey_blksz) != 0) {
1515 padded_len += (wkey_blksz - (plain_len % wkey_blksz));
1516 if ((padded_data = malloc(padded_len)) == NULL) {
1517 rv = CKR_HOST_MEMORY;
1518 goto cleanup_wrap;
1520 (void) memset(padded_data, 0x0, padded_len);
1521 (void) memcpy(padded_data, plain_data, plain_len);
1523 break;
1524 default:
1525 break;
1528 rv = soft_encrypt_init(session_p, pMechanism, wrappingKey_p);
1529 if (rv != CKR_OK)
1530 goto cleanup_wrap;
1532 rv = soft_encrypt(session_p, padded_data, padded_len,
1533 pWrappedKey, pulWrappedKeyLen);
1535 cleanup_wrap:
1536 if (padded_data != NULL && padded_len != plain_len) {
1537 /* Clear buffer before returning to memory pool. */
1538 (void) memset(padded_data, 0x0, padded_len);
1539 free(padded_data);
1542 if ((hkey_p->class != CKO_SECRET_KEY) && (plain_data != NULL)) {
1543 /* Clear buffer before returning to memory pool. */
1544 (void) memset(plain_data, 0x0, plain_len);
1545 free(plain_data);
1548 return (rv);
1552 * Quick check for whether unwrapped key length is appropriate for key type
1553 * and whether it needs to be truncated (in case the wrapping function had
1554 * to pad the key prior to wrapping).
1556 static CK_RV
1557 soft_unwrap_secret_len_check(CK_KEY_TYPE keytype, CK_MECHANISM_TYPE mechtype,
1558 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount)
1560 CK_ULONG i;
1561 boolean_t isValueLen = B_FALSE;
1564 * Based on the key type and the mech used to unwrap, need to
1565 * determine if CKA_VALUE_LEN should or should not be specified.
1566 * PKCS#11 v2.11 restricts CKA_VALUE_LEN from being specified
1567 * for C_UnwrapKey for all mechs and key types, but v2.20 loosens
1568 * that restriction, perhaps because it makes it impossible to
1569 * determine the original length of unwrapped variable-length secret
1570 * keys, such as RC4, AES, and GENERIC_SECRET. These variable-length
1571 * secret keys would have been padded with trailing null-bytes so
1572 * that they could be successfully wrapped with *_ECB and *_CBC
1573 * mechanisms. Hence for unwrapping with these mechs, CKA_VALUE_LEN
1574 * must be specified. For unwrapping with other mechs, such as
1575 * *_CBC_PAD, the CKA_VALUE_LEN is not needed.
1578 /* Find out if template has CKA_VALUE_LEN. */
1579 for (i = 0; i < ulAttributeCount; i++) {
1580 if (pTemplate[i].type == CKA_VALUE_LEN &&
1581 pTemplate[i].pValue != NULL) {
1582 isValueLen = B_TRUE;
1583 break;
1587 /* Does its presence conflict with the mech type and key type? */
1588 switch (mechtype) {
1589 case CKM_DES_ECB:
1590 case CKM_DES3_ECB:
1591 case CKM_AES_ECB:
1592 case CKM_DES_CBC:
1593 case CKM_DES3_CBC:
1594 case CKM_AES_CBC:
1595 case CKM_BLOWFISH_CBC:
1597 * CKA_VALUE_LEN must be specified
1598 * if keytype is CKK_RC4, CKK_AES and CKK_GENERIC_SECRET
1599 * and must not be specified otherwise
1601 switch (keytype) {
1602 case CKK_DES:
1603 case CKK_DES2:
1604 case CKK_DES3:
1605 if (isValueLen)
1606 return (CKR_TEMPLATE_INCONSISTENT);
1607 break;
1608 case CKK_GENERIC_SECRET:
1609 case CKK_RC4:
1610 case CKK_AES:
1611 case CKK_BLOWFISH:
1612 if (!isValueLen)
1613 return (CKR_TEMPLATE_INCOMPLETE);
1614 break;
1615 default:
1616 return (CKR_FUNCTION_NOT_SUPPORTED);
1618 break;
1619 default:
1620 /* CKA_VALUE_LEN must not be specified */
1621 if (isValueLen)
1622 return (CKR_TEMPLATE_INCONSISTENT);
1623 break;
1626 return (CKR_OK);
1629 CK_RV
1630 soft_unwrapkey(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
1631 soft_object_t *unwrappingkey_p,
1632 CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen,
1633 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
1634 CK_OBJECT_HANDLE_PTR phKey)
1636 CK_RV rv = CKR_OK;
1637 CK_OBJECT_CLASS new_obj_class = ~0UL;
1638 int i = 0;
1639 soft_object_t *new_objp = NULL;
1640 boolean_t persistent = B_FALSE;
1641 CK_BYTE_PTR plain_data = NULL;
1642 CK_ULONG plain_len = 0;
1643 secret_key_obj_t *sck = NULL;
1645 /* Scan the attribute template for the object class. */
1646 if (pTemplate != NULL && ulAttributeCount != 0) {
1647 for (i = 0; i < ulAttributeCount; i++) {
1648 if (pTemplate[i].type == CKA_CLASS) {
1649 new_obj_class =
1650 *((CK_OBJECT_CLASS *)pTemplate[i].pValue);
1651 break;
1654 if (new_obj_class == ~0UL)
1655 return (CKR_TEMPLATE_INCOMPLETE);
1659 * Check if the mechanism is supported, and now that the new
1660 * object's class is known, the mechanism selected should be
1661 * capable of doing the unwrap.
1663 switch (pMechanism->mechanism) {
1664 case CKM_RSA_PKCS:
1665 case CKM_RSA_X_509:
1666 case CKM_DES_ECB:
1667 case CKM_DES3_ECB:
1668 case CKM_AES_ECB:
1669 case CKM_DES_CBC:
1670 case CKM_DES3_CBC:
1671 case CKM_AES_CBC:
1672 case CKM_BLOWFISH_CBC:
1673 if (new_obj_class != CKO_SECRET_KEY)
1674 return (CKR_MECHANISM_INVALID);
1675 break;
1676 case CKM_DES_CBC_PAD:
1677 case CKM_DES3_CBC_PAD:
1678 case CKM_AES_CBC_PAD:
1679 if (new_obj_class != CKO_SECRET_KEY && new_obj_class !=
1680 CKO_PRIVATE_KEY)
1681 return (CKR_MECHANISM_INVALID);
1682 break;
1683 default:
1684 return (CKR_MECHANISM_INVALID);
1687 /* Create a new object based on the attribute template. */
1688 rv = soft_gen_keyobject(pTemplate, ulAttributeCount,
1689 (CK_ULONG *)&new_objp, session_p, (CK_OBJECT_CLASS)~0UL,
1690 (CK_KEY_TYPE)~0UL, 0, SOFT_UNWRAP_KEY, B_FALSE);
1691 if (rv != CKR_OK)
1692 return (rv);
1695 * New key will have CKA_ALWAYS_SENSITIVE and CKA_NEVER_EXTRACTABLE
1696 * both set to FALSE. CKA_EXTRACTABLE will be set _by_default_ to
1697 * true -- leaving the possibility that it may be set FALSE by the
1698 * supplied attribute template. If the precise template cannot be
1699 * supported, unwrap fails. PKCS#11 spec, Sec. 11.14, C_UnwrapKey.
1701 * Therefore, check the new object's NEVER_EXTRACTABLE_BOOL_ON and
1702 * ALWAYS_SENSITVE_BOOL_ON; if they are TRUE, the template must
1703 * have supplied them and therefore we cannot honor the unwrap.
1705 if ((new_objp->bool_attr_mask & NEVER_EXTRACTABLE_BOOL_ON) ||
1706 (new_objp->bool_attr_mask & ALWAYS_SENSITIVE_BOOL_ON)) {
1707 rv = CKR_TEMPLATE_INCONSISTENT;
1708 goto cleanup_unwrap;
1711 rv = soft_decrypt_init(session_p, pMechanism, unwrappingkey_p);
1712 if (rv != CKR_OK)
1713 goto cleanup_unwrap;
1715 /* First get the length of the plain data */
1716 rv = soft_decrypt(session_p, pWrappedKey, ulWrappedKeyLen, NULL,
1717 &plain_len);
1718 if (rv != CKR_OK)
1719 goto cleanup_unwrap;
1721 /* Allocate space for the unwrapped data */
1722 if ((plain_data = malloc(plain_len)) == NULL) {
1723 rv = CKR_HOST_MEMORY;
1724 goto cleanup_unwrap;
1726 (void) memset(plain_data, 0x0, plain_len);
1728 /* Perform actual decryption into the allocated space. */
1729 rv = soft_decrypt(session_p, pWrappedKey, ulWrappedKeyLen, plain_data,
1730 &plain_len);
1731 if (rv != CKR_OK)
1732 goto cleanup_unwrap;
1734 if (new_objp->class == CKO_SECRET_KEY) {
1736 * Since no ASN.1 encoding is done for secret keys, check for
1737 * appropriateness and copy decrypted buffer to the key object.
1740 /* Check keytype and mechtype don't conflict with valuelen */
1741 rv = soft_unwrap_secret_len_check(new_objp->key_type,
1742 pMechanism->mechanism, pTemplate, ulAttributeCount);
1743 if (rv != CKR_OK)
1744 goto cleanup_unwrap;
1747 * Allocate the secret key structure if not already there;
1748 * it will exist for variable length keys since CKA_VALUE_LEN
1749 * is specified and saved, but not for fixed length keys.
1751 if (OBJ_SEC(new_objp) == NULL) {
1752 if ((sck = calloc(1, sizeof (secret_key_obj_t))) ==
1753 NULL) {
1754 rv = CKR_HOST_MEMORY;
1755 goto cleanup_unwrap;
1757 OBJ_SEC(new_objp) = sck;
1760 switch (new_objp->key_type) {
1761 /* Fixed length secret keys don't have CKA_VALUE_LEN */
1762 case CKK_DES:
1763 OBJ_SEC_VALUE_LEN(new_objp) = DES_KEYSIZE;
1764 break;
1765 case CKK_DES2:
1766 OBJ_SEC_VALUE_LEN(new_objp) = DES2_KEYSIZE;
1767 break;
1768 case CKK_DES3:
1769 OBJ_SEC_VALUE_LEN(new_objp) = DES3_KEYSIZE;
1770 break;
1773 * Variable length secret keys. CKA_VALUE_LEN must be
1774 * provided by the template when mech is *_ECB or *_CBC, and
1775 * should already have been set during soft_gen_keyobject().
1776 * Otherwise we don't need CKA_VALUE_LEN.
1778 case CKK_GENERIC_SECRET:
1779 case CKK_RC4:
1780 case CKK_AES:
1781 case CKK_BLOWFISH:
1782 break;
1783 default:
1784 rv = CKR_WRAPPED_KEY_INVALID;
1785 goto cleanup_unwrap;
1788 if (OBJ_SEC_VALUE_LEN(new_objp) == 0) {
1789 /* No CKA_VALUE_LEN set so set it now and save data */
1790 OBJ_SEC_VALUE_LEN(new_objp) = plain_len;
1791 OBJ_SEC_VALUE(new_objp) = plain_data;
1792 } else if (OBJ_SEC_VALUE_LEN(new_objp) == plain_len) {
1793 /* No need to truncate, just save the data */
1794 OBJ_SEC_VALUE(new_objp) = plain_data;
1795 } else if (OBJ_SEC_VALUE_LEN(new_objp) > plain_len) {
1796 /* Length can't be bigger than what was decrypted */
1797 rv = CKR_WRAPPED_KEY_LEN_RANGE;
1798 goto cleanup_unwrap;
1799 } else { /* betw 0 and plain_len, hence padded */
1800 /* Truncate the data before saving. */
1801 OBJ_SEC_VALUE(new_objp) = realloc(plain_data,
1802 OBJ_SEC_VALUE_LEN(new_objp));
1803 if (OBJ_SEC_VALUE(new_objp) == NULL) {
1804 rv = CKR_HOST_MEMORY;
1805 goto cleanup_unwrap;
1808 } else {
1809 /* BER-decode the object to be unwrapped. */
1810 rv = soft_asn1_to_object(new_objp, plain_data, plain_len);
1811 if (rv != CKR_OK)
1812 goto cleanup_unwrap;
1815 /* If it needs to be persistent, write it to the keystore */
1816 if (IS_TOKEN_OBJECT(new_objp)) {
1817 persistent = B_TRUE;
1818 rv = soft_put_object_to_keystore(new_objp);
1819 if (rv != CKR_OK)
1820 goto cleanup_unwrap;
1823 if (new_objp->class != CKO_SECRET_KEY) {
1824 /* Clear buffer before returning to memory pool. */
1825 (void) memset(plain_data, 0x0, plain_len);
1826 free(plain_data);
1829 *phKey = (CK_OBJECT_HANDLE)new_objp;
1831 return (CKR_OK);
1833 cleanup_unwrap:
1834 /* The decrypted private key buffer must be freed explicitly. */
1835 if ((new_objp->class != CKO_SECRET_KEY) && (plain_data != NULL)) {
1836 /* Clear buffer before returning to memory pool. */
1837 (void) memset(plain_data, 0x0, plain_len);
1838 free(plain_data);
1841 /* sck and new_objp are indirectly free()d inside these functions */
1842 if (IS_TOKEN_OBJECT(new_objp))
1843 soft_delete_token_object(new_objp, persistent, B_FALSE);
1844 else
1845 soft_delete_object(session_p, new_objp, B_FALSE, B_FALSE);
1847 return (rv);