xref: /illumos-gate/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeysUtil.c (revision 63f91fbc3c024870d86dc3332a4a0080fb29bc40)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  *
25  * Copyright 2020 Joyent, Inc.
26  */
27 
28 #include <pthread.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <strings.h>
32 #include <sys/types.h>
33 #include <security/cryptoki.h>
34 #include <sys/crypto/common.h>
35 #include <aes_impl.h>
36 #include <blowfish_impl.h>
37 #include <des_impl.h>
38 #include <arcfour.h>
39 #include <cryptoutil.h>
40 #include "softGlobal.h"
41 #include "softSession.h"
42 #include "softObject.h"
43 #include "softDSA.h"
44 #include "softRSA.h"
45 #include "softDH.h"
46 #include "softEC.h"
47 #include "softMAC.h"
48 #include "softOps.h"
49 #include "softKeys.h"
50 #include "softKeystore.h"
51 #include "softSSL.h"
52 #include "softASN1.h"
53 
54 
55 #define	local_min(a, b)	((a) < (b) ? (a) : (b))
56 
57 static CK_RV
58 soft_pkcs12_pbe(soft_session_t *, CK_MECHANISM_PTR, soft_object_t *);
59 
60 /*
61  * Create a temporary key object struct by filling up its template attributes.
62  */
63 CK_RV
64 soft_gen_keyobject(CK_ATTRIBUTE_PTR pTemplate,  CK_ULONG ulCount,
65     soft_object_t **objp, soft_session_t *sp,
66     CK_OBJECT_CLASS class, CK_KEY_TYPE key_type, CK_ULONG keylen, CK_ULONG mode,
67     boolean_t internal)
68 {
69 	CK_RV rv;
70 	soft_object_t *new_objp = NULL;
71 
72 	new_objp = calloc(1, sizeof (soft_object_t));
73 	if (new_objp == NULL) {
74 		return (CKR_HOST_MEMORY);
75 	}
76 
77 	new_objp->extra_attrlistp = NULL;
78 
79 	/*
80 	 * Validate attribute template and fill in the attributes
81 	 * in the soft_object_t.
82 	 */
83 	rv = soft_build_key(pTemplate, ulCount, new_objp, class, key_type,
84 	    keylen, mode);
85 	if (rv != CKR_OK) {
86 		goto fail_cleanup1;
87 	}
88 
89 	/*
90 	 * If generating a key is an internal request (i.e. not a C_XXX
91 	 * API request), then skip the following checks.
92 	 */
93 	if (!internal) {
94 		rv = soft_pin_expired_check(new_objp);
95 		if (rv != CKR_OK) {
96 			goto fail_cleanup2;
97 		}
98 
99 		rv = soft_object_write_access_check(sp, new_objp);
100 		if (rv != CKR_OK) {
101 			goto fail_cleanup2;
102 		}
103 	}
104 
105 	/* Initialize the rest of stuffs in soft_object_t. */
106 	(void) pthread_mutex_init(&new_objp->object_mutex, NULL);
107 	new_objp->magic_marker = SOFTTOKEN_OBJECT_MAGIC;
108 
109 	/* Write the new token object to the keystore */
110 	if (IS_TOKEN_OBJECT(new_objp)) {
111 		new_objp->version = 1;
112 		new_objp->session_handle = CK_INVALID_HANDLE;
113 		soft_add_token_object_to_slot(new_objp);
114 
115 		set_objecthandle(new_objp);
116 		*objp = new_objp;
117 
118 		return (CKR_OK);
119 	}
120 
121 	new_objp->session_handle = sp->handle;
122 
123 	/* Add the new object to the session's object list. */
124 	soft_add_object_to_session(new_objp, sp);
125 
126 	set_objecthandle(new_objp);
127 	*objp = new_objp;
128 
129 	return (CKR_OK);
130 
131 fail_cleanup2:
132 	/*
133 	 * When any error occurs after soft_build_key(), we will need to
134 	 * clean up the memory allocated by the soft_build_key().
135 	 */
136 	soft_cleanup_object(new_objp);
137 
138 fail_cleanup1:
139 	if (new_objp) {
140 		/*
141 		 * The storage allocated inside of this object should have
142 		 * been cleaned up by the soft_build_key() if it failed.
143 		 * Therefore, we can safely free the object.
144 		 */
145 		free(new_objp);
146 	}
147 
148 	return (rv);
149 }
150 
151 CK_RV
152 soft_genkey(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
153     CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey)
154 {
155 
156 	CK_RV rv = CKR_OK;
157 	soft_object_t *secret_key;
158 	CK_KEY_TYPE key_type;
159 	CK_ULONG keylen = 0;
160 	CK_ULONG i;
161 	int des_strength = 0;
162 	int retry = 0;
163 	int keyfound = 0;
164 	boolean_t is_ssl_mech = B_FALSE;
165 
166 	switch (pMechanism->mechanism) {
167 	case CKM_DES_KEY_GEN:
168 		key_type = CKK_DES;
169 		break;
170 
171 	case CKM_DES2_KEY_GEN:
172 		key_type = CKK_DES2;
173 		break;
174 
175 	case CKM_DES3_KEY_GEN:
176 		key_type = CKK_DES3;
177 		break;
178 
179 	case CKM_AES_KEY_GEN:
180 		key_type = CKK_AES;
181 		break;
182 
183 	case CKM_BLOWFISH_KEY_GEN:
184 		key_type = CKK_BLOWFISH;
185 		break;
186 
187 	case CKM_RC4_KEY_GEN:
188 		key_type = CKK_RC4;
189 		break;
190 
191 	case CKM_SSL3_PRE_MASTER_KEY_GEN:
192 	case CKM_TLS_PRE_MASTER_KEY_GEN:
193 		if (pMechanism->pParameter == NULL ||
194 		    pMechanism->ulParameterLen != sizeof (CK_VERSION))
195 			return (CKR_TEMPLATE_INCOMPLETE);
196 		is_ssl_mech = B_TRUE;
197 		key_type = CKK_GENERIC_SECRET;
198 		keylen = 48;
199 		break;
200 
201 	case CKM_PKCS5_PBKD2:
202 		keyfound = 0;
203 		for (i = 0; i < ulCount && !keyfound; i++) {
204 			if (pTemplate[i].type == CKA_KEY_TYPE &&
205 			    pTemplate[i].pValue != NULL) {
206 				key_type = *((CK_KEY_TYPE*)pTemplate[i].pValue);
207 				keyfound = 1;
208 			}
209 		}
210 		if (!keyfound)
211 			return (CKR_TEMPLATE_INCOMPLETE);
212 		/*
213 		 * Make sure that parameters were given for this
214 		 * mechanism.
215 		 */
216 		if (pMechanism->pParameter == NULL ||
217 		    pMechanism->ulParameterLen !=
218 		    sizeof (CK_PKCS5_PBKD2_PARAMS))
219 			return (CKR_TEMPLATE_INCOMPLETE);
220 		break;
221 
222 	case CKM_PBE_SHA1_RC4_128:
223 		keyfound = 0;
224 		for (i = 0; i < ulCount; i++) {
225 			if (pTemplate[i].type == CKA_KEY_TYPE &&
226 			    pTemplate[i].pValue != NULL) {
227 				key_type = *((CK_KEY_TYPE*)pTemplate[i].pValue);
228 				keyfound = 1;
229 			}
230 			if (pTemplate[i].type == CKA_VALUE_LEN &&
231 			    pTemplate[i].pValue != NULL) {
232 				keylen = *((CK_ULONG*)pTemplate[i].pValue);
233 			}
234 		}
235 		/* If a keytype was specified, it had better be CKK_RC4 */
236 		if (keyfound && key_type != CKK_RC4)
237 			return (CKR_TEMPLATE_INCONSISTENT);
238 		else if (!keyfound)
239 			key_type = CKK_RC4;
240 
241 		/* If key length was specified, it better be 16 bytes */
242 		if (keylen != 0 && keylen != 16)
243 			return (CKR_TEMPLATE_INCONSISTENT);
244 
245 		/*
246 		 * Make sure that parameters were given for this
247 		 * mechanism.
248 		 */
249 		if (pMechanism->pParameter == NULL ||
250 		    pMechanism->ulParameterLen !=
251 		    sizeof (CK_PBE_PARAMS))
252 			return (CKR_TEMPLATE_INCOMPLETE);
253 		break;
254 	default:
255 		return (CKR_MECHANISM_INVALID);
256 	}
257 
258 	/* Create a new object for secret key. */
259 	rv = soft_gen_keyobject(pTemplate, ulCount, &secret_key, session_p,
260 	    CKO_SECRET_KEY, key_type, keylen, SOFT_GEN_KEY, B_FALSE);
261 
262 	if (rv != CKR_OK) {
263 		return (rv);
264 	}
265 
266 	switch (pMechanism->mechanism) {
267 	case CKM_DES_KEY_GEN:
268 		/*
269 		 * Set up key value len since it is not a required
270 		 * attribute for C_GenerateKey.
271 		 */
272 		keylen = OBJ_SEC_VALUE_LEN(secret_key) = DES_KEYSIZE;
273 		des_strength = DES;
274 		break;
275 
276 	case CKM_DES2_KEY_GEN:
277 		/*
278 		 * Set up key value len since it is not a required
279 		 * attribute for C_GenerateKey.
280 		 */
281 		keylen = OBJ_SEC_VALUE_LEN(secret_key) = DES2_KEYSIZE;
282 		des_strength = DES2;
283 		break;
284 
285 	case CKM_DES3_KEY_GEN:
286 		/*
287 		 * Set up key value len since it is not a required
288 		 * attribute for C_GenerateKey.
289 		 */
290 		keylen = OBJ_SEC_VALUE_LEN(secret_key) = DES3_KEYSIZE;
291 		des_strength = DES3;
292 		break;
293 
294 	case CKM_SSL3_PRE_MASTER_KEY_GEN:
295 	case CKM_TLS_PRE_MASTER_KEY_GEN:
296 		secret_key->bool_attr_mask |= DERIVE_BOOL_ON;
297 	/* FALLTHRU */
298 
299 	case CKM_AES_KEY_GEN:
300 	case CKM_BLOWFISH_KEY_GEN:
301 	case CKM_PBE_SHA1_RC4_128:
302 	case CKM_RC4_KEY_GEN:
303 		keylen = OBJ_SEC_VALUE_LEN(secret_key);
304 		break;
305 
306 	case CKM_PKCS5_PBKD2:
307 		/*
308 		 * PKCS#11 does not allow one to specify key
309 		 * sizes for DES and 3DES, so we must set it here
310 		 * when using PBKD2 algorithms.
311 		 */
312 		if (key_type == CKK_DES) {
313 			OBJ_SEC_VALUE_LEN(secret_key) = DES_KEYSIZE;
314 			des_strength = DES;
315 		} else if (key_type == CKK_DES3) {
316 			OBJ_SEC_VALUE_LEN(secret_key) = DES3_KEYSIZE;
317 			des_strength = DES3;
318 		}
319 
320 		keylen = OBJ_SEC_VALUE_LEN(secret_key);
321 		break;
322 	}
323 
324 	if ((OBJ_SEC_VALUE(secret_key) = malloc(keylen)) == NULL) {
325 		if (IS_TOKEN_OBJECT(secret_key))
326 			soft_delete_token_object(secret_key, B_FALSE, B_FALSE);
327 		else
328 			soft_delete_object(session_p, secret_key,
329 			    B_FALSE, B_FALSE);
330 
331 		return (CKR_HOST_MEMORY);
332 	}
333 	switch (pMechanism->mechanism) {
334 	case CKM_PBE_SHA1_RC4_128:
335 		/*
336 		 * Use the PBE algorithm described in PKCS#11 section
337 		 * 12.33 to derive the key.
338 		 */
339 		rv = soft_pkcs12_pbe(session_p, pMechanism, secret_key);
340 		break;
341 	case CKM_PKCS5_PBKD2:
342 		/* Generate keys using PKCS#5 PBKD2 algorithm */
343 		rv = soft_generate_pkcs5_pbkdf2_key(session_p, pMechanism,
344 		    secret_key);
345 		if (rv == CKR_OK && des_strength > 0) {
346 			/* Perform weak key checking for DES and DES3. */
347 			if (des_keycheck(OBJ_SEC_VALUE(secret_key),
348 			    des_strength, OBJ_SEC_VALUE(secret_key)) ==
349 			    B_FALSE) {
350 				/* We got a weak secret key. */
351 				rv = CKR_FUNCTION_FAILED;
352 			}
353 		}
354 		break;
355 	default:
356 		do {
357 			/* If this fails, bail out */
358 			rv = CKR_OK;
359 			if (pkcs11_get_urandom(
360 			    OBJ_SEC_VALUE(secret_key), keylen) < 0) {
361 				rv = CKR_DEVICE_ERROR;
362 				break;
363 			}
364 
365 			/* Perform weak key checking for DES and DES3. */
366 			if (des_strength > 0) {
367 				rv = CKR_OK;
368 				if (des_keycheck(OBJ_SEC_VALUE(secret_key),
369 				    des_strength, OBJ_SEC_VALUE(secret_key)) ==
370 				    B_FALSE) {
371 					/* We got a weak key, retry! */
372 					retry++;
373 					rv = CKR_FUNCTION_FAILED;
374 				}
375 			}
376 			/*
377 			 * Copy over the SSL client version For SSL mechs
378 			 * The first two bytes of the key is the version
379 			 */
380 			if (is_ssl_mech)
381 				bcopy(pMechanism->pParameter,
382 				    OBJ_SEC_VALUE(secret_key),
383 				    sizeof (CK_VERSION));
384 
385 		} while (rv != CKR_OK && retry < KEYGEN_RETRY);
386 		if (retry == KEYGEN_RETRY)
387 			rv = CKR_FUNCTION_FAILED;
388 		break;
389 	}
390 
391 	if (rv != CKR_OK)
392 		if (IS_TOKEN_OBJECT(secret_key))
393 			soft_delete_token_object(secret_key, B_FALSE, B_FALSE);
394 		else
395 			soft_delete_object(session_p, secret_key,
396 			    B_FALSE, B_FALSE);
397 
398 	if (IS_TOKEN_OBJECT(secret_key)) {
399 		/*
400 		 * All the info has been filled, so we can write to
401 		 * keystore now.
402 		 */
403 		rv = soft_put_object_to_keystore(secret_key);
404 		if (rv != CKR_OK)
405 			soft_delete_token_object(secret_key, B_FALSE, B_FALSE);
406 	}
407 
408 	*phKey = secret_key->handle;
409 	return (rv);
410 }
411 
412 CK_RV
413 soft_genkey_pair(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
414     CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicAttrCount,
415     CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateAttrCount,
416     CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey)
417 {
418 
419 	CK_RV rv;
420 	soft_object_t *public_key, *private_key;
421 	CK_KEY_TYPE key_type;
422 
423 	switch (pMechanism->mechanism) {
424 
425 	case CKM_RSA_PKCS_KEY_PAIR_GEN:
426 		key_type = CKK_RSA;
427 		break;
428 
429 	case CKM_DSA_KEY_PAIR_GEN:
430 		key_type = CKK_DSA;
431 		break;
432 
433 	case CKM_DH_PKCS_KEY_PAIR_GEN:
434 		key_type = CKK_DH;
435 		break;
436 
437 	case CKM_EC_KEY_PAIR_GEN:
438 		key_type = CKK_EC;
439 		break;
440 
441 	default:
442 		return (CKR_MECHANISM_INVALID);
443 	}
444 
445 	/* Create a new object for public key. */
446 	rv = soft_gen_keyobject(pPublicKeyTemplate, ulPublicAttrCount,
447 	    &public_key, session_p, CKO_PUBLIC_KEY, key_type, 0,
448 	    SOFT_GEN_KEY, B_FALSE);
449 
450 	if (rv != CKR_OK) {
451 		return (rv);
452 	}
453 
454 	/* Create a new object for private key. */
455 	rv = soft_gen_keyobject(pPrivateKeyTemplate, ulPrivateAttrCount,
456 	    &private_key, session_p, CKO_PRIVATE_KEY, key_type, 0,
457 	    SOFT_GEN_KEY, B_FALSE);
458 
459 	if (rv != CKR_OK) {
460 		/*
461 		 * Both public key and private key must be successful.
462 		 */
463 		if (IS_TOKEN_OBJECT(public_key))
464 			soft_delete_token_object(public_key, B_FALSE, B_FALSE);
465 		else
466 			soft_delete_object(session_p, public_key,
467 			    B_FALSE, B_FALSE);
468 		return (rv);
469 	}
470 
471 	/*
472 	 * At this point, both public key and private key objects
473 	 * are settled with the application specified attributes.
474 	 * We are ready to generate the rest of key attributes based
475 	 * on the existing attributes.
476 	 */
477 
478 	switch (key_type) {
479 	case CKK_RSA:
480 		rv = soft_rsa_genkey_pair(public_key, private_key);
481 		break;
482 
483 	case CKK_DSA:
484 		rv = soft_dsa_genkey_pair(public_key, private_key);
485 		break;
486 
487 	case CKK_DH:
488 		rv = soft_dh_genkey_pair(public_key, private_key);
489 		private_key->bool_attr_mask |= DERIVE_BOOL_ON;
490 		break;
491 	case CKK_EC:
492 		rv = soft_ec_genkey_pair(public_key, private_key);
493 		private_key->bool_attr_mask |= DERIVE_BOOL_ON;
494 		break;
495 	}
496 
497 	if (rv != CKR_OK) {
498 		if (IS_TOKEN_OBJECT(public_key)) {
499 			soft_delete_token_object(public_key, B_FALSE, B_FALSE);
500 			soft_delete_token_object(private_key, B_FALSE, B_FALSE);
501 		} else {
502 			soft_delete_object(session_p, public_key,
503 			    B_FALSE, B_FALSE);
504 			soft_delete_object(session_p, private_key,
505 			    B_FALSE, B_FALSE);
506 		}
507 		return (rv);
508 	}
509 
510 	if (IS_TOKEN_OBJECT(public_key)) {
511 		/*
512 		 * All the info has been filled, so we can write to
513 		 * keystore now.
514 		 */
515 		rv = soft_put_object_to_keystore(public_key);
516 		if (rv != CKR_OK) {
517 			soft_delete_token_object(public_key, B_FALSE, B_FALSE);
518 			soft_delete_token_object(private_key, B_FALSE, B_FALSE);
519 			return (rv);
520 		}
521 	}
522 
523 	if (IS_TOKEN_OBJECT(private_key)) {
524 		rv = soft_put_object_to_keystore(private_key);
525 		if (rv != CKR_OK) {
526 			/*
527 			 * We also need to delete the public token object
528 			 * from keystore.
529 			 */
530 			soft_delete_token_object(public_key, B_TRUE, B_FALSE);
531 			soft_delete_token_object(private_key, B_FALSE, B_FALSE);
532 		}
533 	}
534 
535 	*phPublicKey = public_key->handle;
536 	*phPrivateKey = private_key->handle;
537 
538 	return (rv);
539 }
540 
541 
542 CK_RV
543 soft_key_derive_check_length(soft_object_t *secret_key, CK_ULONG max_keylen)
544 {
545 
546 	switch (secret_key->key_type) {
547 	case CKK_GENERIC_SECRET:
548 		if (OBJ_SEC_VALUE_LEN(secret_key) == 0) {
549 			OBJ_SEC_VALUE_LEN(secret_key) = max_keylen;
550 			return (CKR_OK);
551 		} else if (OBJ_SEC_VALUE_LEN(secret_key) > max_keylen) {
552 			return (CKR_ATTRIBUTE_VALUE_INVALID);
553 		}
554 		break;
555 	case CKK_RC4:
556 	case CKK_AES:
557 	case CKK_BLOWFISH:
558 		if ((OBJ_SEC_VALUE_LEN(secret_key) == 0) ||
559 		    (OBJ_SEC_VALUE_LEN(secret_key) > max_keylen)) {
560 			/* RC4 and AES has variable key length */
561 			return (CKR_ATTRIBUTE_VALUE_INVALID);
562 		}
563 		break;
564 	case CKK_DES:
565 		if (OBJ_SEC_VALUE_LEN(secret_key) == 0) {
566 			/* DES has a well-defined length */
567 			OBJ_SEC_VALUE_LEN(secret_key) = DES_KEYSIZE;
568 			return (CKR_OK);
569 		} else if (OBJ_SEC_VALUE_LEN(secret_key) != DES_KEYSIZE) {
570 			return (CKR_ATTRIBUTE_VALUE_INVALID);
571 		}
572 		break;
573 	case CKK_DES2:
574 		if (OBJ_SEC_VALUE_LEN(secret_key) == 0) {
575 			/* DES2 has a well-defined length */
576 			OBJ_SEC_VALUE_LEN(secret_key) = DES2_KEYSIZE;
577 			return (CKR_OK);
578 		} else if (OBJ_SEC_VALUE_LEN(secret_key) != DES2_KEYSIZE) {
579 			return (CKR_ATTRIBUTE_VALUE_INVALID);
580 		}
581 		break;
582 
583 	default:
584 		return (CKR_MECHANISM_INVALID);
585 	}
586 
587 	return (CKR_OK);
588 }
589 
590 /*
591  * PKCS#11 (12.33) says that v = 512 bits (64 bytes) for SHA1
592  * PBE methods.
593  */
594 #define	PKCS12_BUFFER_SIZE 64
595 /*
596  * PKCS#12 defines 3 different ID bytes to be used for
597  * deriving keys for different operations.
598  */
599 #define	PBE_ID_ENCRYPT	1
600 #define	PBE_ID_IV	2
601 #define	PBE_ID_MAC	3
602 #define	PBE_CEIL(a, b)	(((a)/(b)) + (((a)%(b)) > 0))
603 
604 static CK_RV
605 soft_pkcs12_pbe(soft_session_t *session_p,
606     CK_MECHANISM_PTR pMechanism, soft_object_t *derived_key)
607 {
608 	CK_RV rv = CKR_OK;
609 	CK_PBE_PARAMS *params = pMechanism->pParameter;
610 	CK_ULONG c, i, j, k;
611 	CK_ULONG hashSize;
612 	CK_ULONG buffSize;
613 	/*
614 	 * Terse variable names are used to make following
615 	 * the PKCS#12 spec easier.
616 	 */
617 	CK_BYTE *A = NULL;
618 	CK_BYTE *Ai = NULL;
619 	CK_BYTE *B = NULL;
620 	CK_BYTE *D = NULL;
621 	CK_BYTE *I = NULL, *S, *P;
622 	CK_BYTE *keybuf = NULL;
623 	CK_ULONG Alen, Ilen, Slen, Plen, AiLen, Blen, Dlen;
624 	CK_ULONG keysize = OBJ_SEC_VALUE_LEN(derived_key);
625 	CK_MECHANISM digest_mech;
626 
627 	/* U = hash function output bits */
628 	if (pMechanism->mechanism == CKM_PBE_SHA1_RC4_128) {
629 		hashSize = SHA1_HASH_SIZE;
630 		buffSize = PKCS12_BUFFER_SIZE;
631 		digest_mech.mechanism = CKM_SHA_1;
632 		digest_mech.pParameter = NULL;
633 		digest_mech.ulParameterLen = 0;
634 	} else {
635 		/* we only support 1 PBE mech for now */
636 		return (CKR_MECHANISM_INVALID);
637 	}
638 	keybuf = OBJ_SEC_VALUE(derived_key);
639 
640 	Blen = Dlen = buffSize;
641 	D = (CK_BYTE *)malloc(Dlen);
642 	if (D == NULL) {
643 		rv = CKR_HOST_MEMORY;
644 		goto cleanup;
645 	}
646 
647 	B = (CK_BYTE *)malloc(Blen);
648 	if (B == NULL) {
649 		rv = CKR_HOST_MEMORY;
650 		goto cleanup;
651 	}
652 
653 	/*
654 	 * Initialize some values and create some buffers
655 	 * that we need later.
656 	 *
657 	 * Slen = buffSize * CEIL(SaltLength/buffSize)
658 	 */
659 	Slen = buffSize * PBE_CEIL(params->ulSaltLen, buffSize);
660 
661 	/*
662 	 * Plen = buffSize * CEIL(PasswordLength/buffSize)
663 	 */
664 	Plen = buffSize * PBE_CEIL(params->ulPasswordLen, buffSize);
665 
666 	/*
667 	 * From step 4: I = S + P, so: Ilen = Slen + Plen
668 	 */
669 	Ilen = Slen + Plen;
670 	I = (CK_BYTE *)malloc(Ilen);
671 	if (I == NULL) {
672 		rv = CKR_HOST_MEMORY;
673 		goto cleanup;
674 	}
675 
676 	S = I;
677 	P = I + Slen;
678 
679 	/*
680 	 * Step 1.
681 	 * We are only interested in deriving keys for encrypt/decrypt
682 	 * for now, so construct the "D"iversifier accordingly.
683 	 */
684 	(void) memset(D, PBE_ID_ENCRYPT, Dlen);
685 
686 	/*
687 	 * Step 2.
688 	 * Concatenate copies of the salt together to make S.
689 	 */
690 	for (i = 0; i < Slen; i += params->ulSaltLen) {
691 		(void) memcpy(S+i, params->pSalt,
692 		    ((Slen - i) > params->ulSaltLen ?
693 		    params->ulSaltLen : (Slen - i)));
694 	}
695 
696 	/*
697 	 * Step 3.
698 	 * Concatenate copies of the password together to make
699 	 * a string P.
700 	 */
701 	for (i = 0; i < Plen; i += params->ulPasswordLen) {
702 		(void) memcpy(P+i, params->pPassword,
703 		    ((Plen - i) > params->ulPasswordLen ?
704 		    params->ulPasswordLen : (Plen - i)));
705 	}
706 
707 	/*
708 	 * Step 4.
709 	 * I = S+P - this is now done because S and P are
710 	 * pointers into I.
711 	 *
712 	 * Step 5.
713 	 * c= CEIL[n/u]
714 	 * where n = pseudorandom bits of output desired.
715 	 */
716 	c = PBE_CEIL(keysize, hashSize);
717 
718 	/*
719 	 * Step 6.
720 	 */
721 	Alen = c * hashSize;
722 	A = (CK_BYTE *)malloc(Alen);
723 	if (A == NULL) {
724 		rv = CKR_HOST_MEMORY;
725 		goto cleanup;
726 	}
727 	AiLen = hashSize;
728 	Ai = (CK_BYTE *)malloc(AiLen);
729 	if (Ai == NULL) {
730 		rv = CKR_HOST_MEMORY;
731 		goto cleanup;
732 	}
733 
734 	/*
735 	 * Step 6a.
736 	 * Ai = Hr(D+I)
737 	 */
738 	for (i = 0; i < c; i++) {
739 		(void) pthread_mutex_lock(&session_p->session_mutex);
740 
741 		if (session_p->sign.flags & CRYPTO_OPERATION_ACTIVE) {
742 			(void) pthread_mutex_unlock(&session_p->session_mutex);
743 			rv = CKR_OPERATION_ACTIVE;
744 			goto cleanup;
745 		}
746 		session_p->sign.flags |= CRYPTO_OPERATION_ACTIVE;
747 		(void) pthread_mutex_unlock(&session_p->session_mutex);
748 
749 		for (j = 0; j < params->ulIteration; j++) {
750 			rv = soft_digest_init(session_p, &digest_mech);
751 			if (rv != CKR_OK)
752 				goto digest_done;
753 
754 			if (j == 0) {
755 				rv = soft_digest_update(session_p, D, Dlen);
756 				if (rv != CKR_OK)
757 					goto digest_done;
758 
759 				rv = soft_digest_update(session_p, I, Ilen);
760 			} else {
761 				rv = soft_digest_update(session_p, Ai, AiLen);
762 			}
763 			if (rv != CKR_OK)
764 				goto digest_done;
765 
766 			rv = soft_digest_final(session_p, Ai, &AiLen);
767 			if (rv != CKR_OK)
768 				goto digest_done;
769 		}
770 digest_done:
771 		(void) pthread_mutex_lock(&session_p->session_mutex);
772 		session_p->sign.flags &= ~CRYPTO_OPERATION_ACTIVE;
773 		(void) pthread_mutex_unlock(&session_p->session_mutex);
774 
775 		if (rv != CKR_OK)
776 			goto cleanup;
777 		/*
778 		 * Step 6b.
779 		 * Concatenate Ai to make B
780 		 */
781 		for (j = 0; j < Blen; j += hashSize) {
782 			(void) memcpy(B+j, Ai, ((Blen - j > hashSize) ?
783 			    hashSize : Blen - j));
784 		}
785 
786 		/*
787 		 * Step 6c.
788 		 */
789 		k = Ilen / Blen;
790 		for (j = 0; j < k; j++) {
791 			uchar_t idx;
792 			CK_ULONG m, q = 1, cbit = 0;
793 
794 			for (m = Blen - 1; m >= (CK_ULONG)0; m--, q = 0) {
795 				idx = m + j*Blen;
796 
797 				q += (CK_ULONG)I[idx] + (CK_ULONG)B[m];
798 				q += cbit;
799 				I[idx] = (CK_BYTE)(q & 0xff);
800 				cbit = (q > 0xff);
801 			}
802 		}
803 
804 		/*
805 		 * Step 7.
806 		 *  A += Ai
807 		 */
808 		(void) memcpy(A + i*hashSize, Ai, AiLen);
809 	}
810 
811 	/*
812 	 * Step 8.
813 	 * The final output of this process is the A buffer
814 	 */
815 	(void) memcpy(keybuf, A, keysize);
816 
817 cleanup:
818 	freezero(A, Alen);
819 	freezero(Ai, AiLen);
820 	freezero(B, Blen);
821 	freezero(D, Dlen);
822 	freezero(I, Ilen);
823 	return (rv);
824 }
825 
826 CK_RV
827 soft_derivekey(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
828     soft_object_t *basekey_p, CK_ATTRIBUTE_PTR pTemplate,
829     CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
830 {
831 
832 	CK_RV rv = CKR_OK;
833 	soft_object_t *secret_key;
834 	CK_MECHANISM digest_mech;
835 	CK_BYTE hash[SHA512_DIGEST_LENGTH]; /* space enough for all mechs */
836 	CK_ULONG hash_len = SHA512_DIGEST_LENGTH;
837 	CK_ULONG secret_key_len;
838 	CK_ULONG hash_size;
839 
840 	switch (pMechanism->mechanism) {
841 	case CKM_DH_PKCS_DERIVE:
842 		if (phKey == NULL_PTR)
843 			return (CKR_ARGUMENTS_BAD);
844 
845 		/*
846 		 * Create a new object for secret key. The key type should
847 		 * be provided in the template.
848 		 */
849 		rv = soft_gen_keyobject(pTemplate, ulAttributeCount,
850 		    &secret_key, session_p, CKO_SECRET_KEY, (CK_KEY_TYPE)~0UL,
851 		    0, SOFT_DERIVE_KEY_DH, B_FALSE);
852 
853 		if (rv != CKR_OK) {
854 			return (rv);
855 		}
856 
857 		rv = soft_dh_key_derive(basekey_p, secret_key,
858 		    (CK_BYTE *)pMechanism->pParameter,
859 		    pMechanism->ulParameterLen);
860 
861 		if (rv != CKR_OK) {
862 			if (IS_TOKEN_OBJECT(secret_key))
863 				soft_delete_token_object(secret_key, B_FALSE,
864 				    B_FALSE);
865 			else
866 				soft_delete_object(session_p, secret_key,
867 				    B_FALSE, B_FALSE);
868 			return (rv);
869 		}
870 
871 		break;
872 
873 	case CKM_ECDH1_DERIVE:
874 		if (phKey == NULL_PTR)
875 			return (CKR_ARGUMENTS_BAD);
876 
877 		/*
878 		 * Create a new object for secret key. The key type should
879 		 * be provided in the template.
880 		 */
881 		rv = soft_gen_keyobject(pTemplate, ulAttributeCount,
882 		    &secret_key, session_p, CKO_SECRET_KEY, (CK_KEY_TYPE)~0UL,
883 		    0, SOFT_DERIVE_KEY_DH, B_FALSE);
884 
885 		if (rv != CKR_OK) {
886 			return (rv);
887 		}
888 
889 		rv = soft_ec_key_derive(basekey_p, secret_key,
890 		    (CK_BYTE *)pMechanism->pParameter,
891 		    pMechanism->ulParameterLen);
892 
893 		if (rv != CKR_OK) {
894 			if (IS_TOKEN_OBJECT(secret_key))
895 				soft_delete_token_object(secret_key, B_FALSE,
896 				    B_FALSE);
897 			else
898 				soft_delete_object(session_p, secret_key,
899 				    B_FALSE, B_FALSE);
900 			return (rv);
901 		}
902 
903 		break;
904 
905 	case CKM_SHA1_KEY_DERIVATION:
906 		hash_size = SHA1_HASH_SIZE;
907 		digest_mech.mechanism = CKM_SHA_1;
908 		goto common;
909 
910 	case CKM_MD5_KEY_DERIVATION:
911 		hash_size = MD5_HASH_SIZE;
912 		digest_mech.mechanism = CKM_MD5;
913 		goto common;
914 
915 	case CKM_SHA256_KEY_DERIVATION:
916 		hash_size = SHA256_DIGEST_LENGTH;
917 		digest_mech.mechanism = CKM_SHA256;
918 		goto common;
919 
920 	case CKM_SHA384_KEY_DERIVATION:
921 		hash_size = SHA384_DIGEST_LENGTH;
922 		digest_mech.mechanism = CKM_SHA384;
923 		goto common;
924 
925 	case CKM_SHA512_KEY_DERIVATION:
926 		hash_size = SHA512_DIGEST_LENGTH;
927 		digest_mech.mechanism = CKM_SHA512;
928 		goto common;
929 
930 	case CKM_SHA512_224_KEY_DERIVATION:
931 		hash_size = SHA512_224_DIGEST_LENGTH;
932 		digest_mech.mechanism = CKM_SHA512_224;
933 		goto common;
934 
935 	case CKM_SHA512_256_KEY_DERIVATION:
936 		hash_size = SHA512_256_DIGEST_LENGTH;
937 		digest_mech.mechanism = CKM_SHA512_256;
938 		goto common;
939 
940 common:
941 		if (phKey == NULL_PTR)
942 			return (CKR_ARGUMENTS_BAD);
943 
944 		/*
945 		 * Create a new object for secret key. The key type is optional
946 		 * to be provided in the template. If it is not specified in
947 		 * the template, the default is CKK_GENERIC_SECRET.
948 		 */
949 		rv = soft_gen_keyobject(pTemplate, ulAttributeCount,
950 		    &secret_key, session_p, CKO_SECRET_KEY,
951 		    (CK_KEY_TYPE)CKK_GENERIC_SECRET, 0,
952 		    SOFT_DERIVE_KEY_OTHER, B_FALSE);
953 
954 		if (rv != CKR_OK) {
955 			return (rv);
956 		}
957 
958 		/* Validate the key type and key length */
959 		rv = soft_key_derive_check_length(secret_key, hash_size);
960 		if (rv != CKR_OK) {
961 			if (IS_TOKEN_OBJECT(secret_key))
962 				soft_delete_token_object(secret_key, B_FALSE,
963 				    B_FALSE);
964 			else
965 				soft_delete_object(session_p, secret_key,
966 				    B_FALSE, B_FALSE);
967 			return (rv);
968 		}
969 
970 		/*
971 		 * Derive the secret key by digesting the value of another
972 		 * secret key (base key) with SHA-1 or MD5.
973 		 */
974 		rv = soft_digest_init_internal(session_p, &digest_mech);
975 		if (rv != CKR_OK) {
976 			if (IS_TOKEN_OBJECT(secret_key))
977 				soft_delete_token_object(secret_key, B_FALSE,
978 				    B_FALSE);
979 			else
980 				soft_delete_object(session_p, secret_key,
981 				    B_FALSE, B_FALSE);
982 			return (rv);
983 		}
984 
985 		rv = soft_digest(session_p, OBJ_SEC_VALUE(basekey_p),
986 		    OBJ_SEC_VALUE_LEN(basekey_p), hash, &hash_len);
987 
988 		(void) pthread_mutex_lock(&session_p->session_mutex);
989 		/* soft_digest_common() has freed the digest context */
990 		session_p->digest.flags = 0;
991 		(void) pthread_mutex_unlock(&session_p->session_mutex);
992 
993 		if (rv != CKR_OK) {
994 			if (IS_TOKEN_OBJECT(secret_key))
995 				soft_delete_token_object(secret_key, B_FALSE,
996 				    B_FALSE);
997 			else
998 				soft_delete_object(session_p, secret_key,
999 				    B_FALSE, B_FALSE);
1000 			return (rv);
1001 		}
1002 
1003 		secret_key_len = OBJ_SEC_VALUE_LEN(secret_key);
1004 
1005 		if ((OBJ_SEC_VALUE(secret_key) = malloc(secret_key_len)) ==
1006 		    NULL) {
1007 			if (IS_TOKEN_OBJECT(secret_key))
1008 				soft_delete_token_object(secret_key, B_FALSE,
1009 				    B_FALSE);
1010 			else
1011 				soft_delete_object(session_p, secret_key,
1012 				    B_FALSE, B_FALSE);
1013 			return (CKR_HOST_MEMORY);
1014 		}
1015 
1016 		/*
1017 		 * The key produced by this mechanism will be of the
1018 		 * specified type and length.
1019 		 * The truncation removes extra bytes from the leading
1020 		 * of the digested key value.
1021 		 */
1022 		(void) memcpy(OBJ_SEC_VALUE(secret_key),
1023 		    (hash + hash_len - secret_key_len),
1024 		    secret_key_len);
1025 
1026 		break;
1027 
1028 	/*
1029 	 * The key sensitivity and extractability rules for the generated
1030 	 * keys will be enforced inside soft_ssl_master_key_derive() and
1031 	 * soft_ssl_key_and_mac_derive()
1032 	 */
1033 	case CKM_SSL3_MASTER_KEY_DERIVE:
1034 	case CKM_SSL3_MASTER_KEY_DERIVE_DH:
1035 	case CKM_TLS_MASTER_KEY_DERIVE:
1036 	case CKM_TLS_MASTER_KEY_DERIVE_DH:
1037 		if (phKey == NULL_PTR)
1038 			return (CKR_ARGUMENTS_BAD);
1039 		return (soft_ssl_master_key_derive(session_p, pMechanism,
1040 		    basekey_p, pTemplate, ulAttributeCount, phKey));
1041 
1042 	case CKM_SSL3_KEY_AND_MAC_DERIVE:
1043 	case CKM_TLS_KEY_AND_MAC_DERIVE:
1044 		/* These mechanisms do not use phKey */
1045 		return (soft_ssl_key_and_mac_derive(session_p, pMechanism,
1046 		    basekey_p, pTemplate, ulAttributeCount));
1047 
1048 	case CKM_TLS_PRF:
1049 		/* This mechanism does not use phKey */
1050 		if (pMechanism->pParameter == NULL ||
1051 		    pMechanism->ulParameterLen != sizeof (CK_TLS_PRF_PARAMS) ||
1052 		    phKey != NULL)
1053 			return (CKR_ARGUMENTS_BAD);
1054 
1055 		if (pTemplate != NULL)
1056 			return (CKR_TEMPLATE_INCONSISTENT);
1057 
1058 		return (derive_tls_prf(
1059 		    (CK_TLS_PRF_PARAMS_PTR)pMechanism->pParameter, basekey_p));
1060 
1061 	default:
1062 		return (CKR_MECHANISM_INVALID);
1063 	}
1064 
1065 	soft_derive_enforce_flags(basekey_p, secret_key);
1066 
1067 	if (IS_TOKEN_OBJECT(secret_key)) {
1068 		/*
1069 		 * All the info has been filled, so we can write to
1070 		 * keystore now.
1071 		 */
1072 		rv = soft_put_object_to_keystore(secret_key);
1073 		if (rv != CKR_OK)
1074 			soft_delete_token_object(secret_key, B_FALSE, B_FALSE);
1075 	}
1076 
1077 	/*
1078 	 * Some mechanisms don't use phKey either because they create
1079 	 * multiple key objects and instead populate a structure passed in
1080 	 * as a field in their pParameter parameter with the resulting key
1081 	 * objects (e.g. CKM_TLS_KEY_AND_MAC_DERIVE) or they instead write
1082 	 * their result to an output buffer passed in their pParameter
1083 	 * parameter (e.g. CKM_TLS_PRF). All such mechanisms return prior
1084 	 * to reaching here. The remaining mechanisms (which do use phKey)
1085 	 * should have already validated phKey is not NULL prior to doing
1086 	 * their key derivation.
1087 	 */
1088 	*phKey = secret_key->handle;
1089 
1090 	return (rv);
1091 }
1092 
1093 
1094 /*
1095  * Perform key derivation rules on key's sensitivity and extractability.
1096  */
1097 void
1098 soft_derive_enforce_flags(soft_object_t *basekey, soft_object_t *newkey)
1099 {
1100 
1101 	boolean_t new_sensitive = B_FALSE;
1102 	boolean_t new_extractable = B_FALSE;
1103 
1104 	/*
1105 	 * The sensitive and extractable bits have been set when
1106 	 * the newkey was built.
1107 	 */
1108 	if (newkey->bool_attr_mask & SENSITIVE_BOOL_ON) {
1109 		new_sensitive = B_TRUE;
1110 	}
1111 
1112 	if (newkey->bool_attr_mask & EXTRACTABLE_BOOL_ON) {
1113 		new_extractable = B_TRUE;
1114 	}
1115 
1116 	/* Derive the CKA_ALWAYS_SENSITIVE flag */
1117 	if (!basekey->bool_attr_mask & ALWAYS_SENSITIVE_BOOL_ON) {
1118 		/*
1119 		 * If the base key has its CKA_ALWAYS_SENSITIVE set to
1120 		 * FALSE, then the derived key will as well.
1121 		 */
1122 		newkey->bool_attr_mask &= ~ALWAYS_SENSITIVE_BOOL_ON;
1123 	} else {
1124 		/*
1125 		 * If the base key has its CKA_ALWAYS_SENSITIVE set to TRUE,
1126 		 * then the derived key has the CKA_ALWAYS_SENSITIVE set to
1127 		 * the same value as its CKA_SENSITIVE;
1128 		 */
1129 		if (new_sensitive) {
1130 			newkey->bool_attr_mask |= ALWAYS_SENSITIVE_BOOL_ON;
1131 		} else {
1132 			newkey->bool_attr_mask &= ~ALWAYS_SENSITIVE_BOOL_ON;
1133 		}
1134 	}
1135 
1136 	/* Derive the CKA_NEVER_EXTRACTABLE flag */
1137 	if (!basekey->bool_attr_mask & NEVER_EXTRACTABLE_BOOL_ON) {
1138 		/*
1139 		 * If the base key has its CKA_NEVER_EXTRACTABLE set to
1140 		 * FALSE, then the derived key will as well.
1141 		 */
1142 		newkey->bool_attr_mask &= ~NEVER_EXTRACTABLE_BOOL_ON;
1143 	} else {
1144 		/*
1145 		 * If the base key has its CKA_NEVER_EXTRACTABLE set to TRUE,
1146 		 * then the derived key has the CKA_NEVER_EXTRACTABLE set to
1147 		 * the opposite value from its CKA_EXTRACTABLE;
1148 		 */
1149 		if (new_extractable) {
1150 			newkey->bool_attr_mask &= ~NEVER_EXTRACTABLE_BOOL_ON;
1151 		} else {
1152 			newkey->bool_attr_mask |= NEVER_EXTRACTABLE_BOOL_ON;
1153 		}
1154 	}
1155 
1156 	/* Set the CKA_LOCAL flag to false */
1157 	newkey->bool_attr_mask &= ~LOCAL_BOOL_ON;
1158 }
1159 
1160 
1161 /*
1162  * do_prf
1163  *
1164  * This routine implements Step 3. of the PBKDF2 function
1165  * defined in PKCS#5 for generating derived keys from a
1166  * password.
1167  *
1168  * Currently, PRF is always SHA_1_HMAC.
1169  */
1170 static CK_RV
1171 do_prf(soft_session_t *session_p, CK_PKCS5_PBKD2_PARAMS_PTR params,
1172     soft_object_t *hmac_key, CK_BYTE *newsalt, CK_ULONG saltlen,
1173     CK_BYTE *blockdata, CK_ULONG blocklen)
1174 {
1175 	CK_RV rv = CKR_OK;
1176 	CK_MECHANISM digest_mech = {CKM_SHA_1_HMAC, NULL, 0};
1177 	CK_BYTE buffer[2][SHA1_HASH_SIZE];
1178 	CK_ULONG hmac_outlen = SHA1_HASH_SIZE;
1179 	CK_ULONG inlen;
1180 	CK_BYTE *input, *output;
1181 	CK_ULONG i, j;
1182 
1183 	input = newsalt;
1184 	inlen = saltlen;
1185 
1186 	output = buffer[1];
1187 	(void) pthread_mutex_lock(&session_p->session_mutex);
1188 
1189 	if (session_p->sign.flags & CRYPTO_OPERATION_ACTIVE) {
1190 		(void) pthread_mutex_unlock(&session_p->session_mutex);
1191 		return (CKR_OPERATION_ACTIVE);
1192 	}
1193 	session_p->sign.flags |= CRYPTO_OPERATION_ACTIVE;
1194 	(void) pthread_mutex_unlock(&session_p->session_mutex);
1195 
1196 	for (i = 0; i < params->iterations; i++) {
1197 		/*
1198 		 * The key doesn't change, its always the
1199 		 * password iniitally given.
1200 		 */
1201 		rv = soft_sign_init(session_p, &digest_mech, hmac_key);
1202 
1203 		if (rv != CKR_OK) {
1204 			goto cleanup;
1205 		}
1206 
1207 		/* Call PRF function (SHA1_HMAC for now). */
1208 		rv = soft_sign(session_p, input, inlen, output, &hmac_outlen);
1209 
1210 		if (rv != CKR_OK) {
1211 			goto cleanup;
1212 		}
1213 		/*
1214 		 * The first time, initialize the output buffer
1215 		 * with the HMAC signature.
1216 		 */
1217 		if (i == 0) {
1218 			(void) memcpy(blockdata, output,
1219 			    local_min(blocklen, hmac_outlen));
1220 		} else {
1221 			/*
1222 			 * XOR the existing data with output from PRF.
1223 			 *
1224 			 * Only XOR up to the length of the blockdata,
1225 			 * it may be less than a full hmac buffer when
1226 			 * the final block is being computed.
1227 			 */
1228 			for (j = 0; j < hmac_outlen && j < blocklen; j++)
1229 				blockdata[j] ^= output[j];
1230 		}
1231 		/* Output from previous PRF is input for next round */
1232 		input = output;
1233 		inlen = hmac_outlen;
1234 
1235 		/*
1236 		 * Switch buffers to avoid overuse of memcpy.
1237 		 * Initially we used buffer[1], so after the end of
1238 		 * the first iteration (i==0), we switch to buffer[0]
1239 		 * and continue swapping with each iteration.
1240 		 */
1241 		output = buffer[i%2];
1242 	}
1243 cleanup:
1244 	(void) pthread_mutex_lock(&session_p->session_mutex);
1245 	session_p->sign.flags &= ~CRYPTO_OPERATION_ACTIVE;
1246 	(void) pthread_mutex_unlock(&session_p->session_mutex);
1247 
1248 	return (rv);
1249 }
1250 
1251 static CK_RV
1252 soft_create_hmac_key(soft_session_t *session_p,  CK_BYTE *passwd,
1253     CK_ULONG passwd_len, soft_object_t **keyp)
1254 {
1255 	CK_RV rv = CKR_OK;
1256 	CK_OBJECT_CLASS keyclass = CKO_SECRET_KEY;
1257 	CK_KEY_TYPE keytype = CKK_GENERIC_SECRET;
1258 	CK_BBOOL True = TRUE;
1259 	CK_ATTRIBUTE keytemplate[4];
1260 
1261 	/*
1262 	 * We must initialize each template member individually
1263 	 * because at the time of initial coding for ON10, the
1264 	 * compiler was using the "-xc99=%none" option
1265 	 * which prevents us from being able to declare the whole
1266 	 * template in place as usual.
1267 	 */
1268 	keytemplate[0].type = CKA_CLASS;
1269 	keytemplate[0].pValue = &keyclass;
1270 	keytemplate[0].ulValueLen =  sizeof (keyclass);
1271 
1272 	keytemplate[1].type = CKA_KEY_TYPE;
1273 	keytemplate[1].pValue = &keytype;
1274 	keytemplate[1].ulValueLen =  sizeof (keytype);
1275 
1276 	keytemplate[2].type = CKA_SIGN;
1277 	keytemplate[2].pValue = &True;
1278 	keytemplate[2].ulValueLen =  sizeof (True);
1279 
1280 	keytemplate[3].type = CKA_VALUE;
1281 	keytemplate[3].pValue = passwd;
1282 	keytemplate[3].ulValueLen = passwd_len;
1283 	/*
1284 	 * Create a generic key object to be used for HMAC operations.
1285 	 * The "value" for this key is the password from the
1286 	 * mechanism parameter structure.
1287 	 */
1288 	rv = soft_gen_keyobject(keytemplate,
1289 	    sizeof (keytemplate)/sizeof (CK_ATTRIBUTE), keyp, session_p,
1290 	    CKO_SECRET_KEY, (CK_KEY_TYPE)CKK_GENERIC_SECRET, 0,
1291 	    SOFT_CREATE_OBJ, B_TRUE);
1292 
1293 	return (rv);
1294 }
1295 
1296 CK_RV
1297 soft_generate_pkcs5_pbkdf2_key(soft_session_t *session_p,
1298     CK_MECHANISM_PTR pMechanism, soft_object_t *secret_key)
1299 {
1300 	CK_RV rv = CKR_OK;
1301 	CK_PKCS5_PBKD2_PARAMS	*params =
1302 	    (CK_PKCS5_PBKD2_PARAMS *)pMechanism->pParameter;
1303 	CK_ULONG hLen = SHA1_HASH_SIZE;
1304 	CK_ULONG dkLen, i;
1305 	CK_ULONG blocks, remainder;
1306 	soft_object_t *hmac_key = NULL;
1307 	CK_BYTE *salt = NULL;
1308 	CK_BYTE *keydata = NULL;
1309 
1310 	params = (CK_PKCS5_PBKD2_PARAMS_PTR) pMechanism->pParameter;
1311 
1312 	if (params->prf != CKP_PKCS5_PBKD2_HMAC_SHA1)
1313 		return (CKR_MECHANISM_PARAM_INVALID);
1314 
1315 	if (params->pPrfData != NULL || params->ulPrfDataLen != 0)
1316 		return (CKR_DATA_INVALID);
1317 
1318 	if (params->saltSource != CKZ_SALT_SPECIFIED ||
1319 	    params->iterations == 0)
1320 		return (CKR_MECHANISM_PARAM_INVALID);
1321 
1322 	/*
1323 	 * Create a key object to use for HMAC operations.
1324 	 */
1325 	rv = soft_create_hmac_key(session_p, params->pPassword,
1326 	    *params->ulPasswordLen, &hmac_key);
1327 
1328 	if (rv != CKR_OK)
1329 		return (rv);
1330 
1331 	/* Step 1. */
1332 	dkLen = OBJ_SEC_VALUE_LEN(secret_key);  /* length of desired key */
1333 
1334 	if (dkLen > ((((u_longlong_t)1)<<32)-1)*hLen) {
1335 		(void) soft_delete_object(session_p, hmac_key, B_FALSE,
1336 		    B_FALSE);
1337 		return (CKR_KEY_SIZE_RANGE);
1338 	}
1339 
1340 	/* Step 2. */
1341 	blocks = dkLen / hLen;
1342 
1343 	/* crude "Ceiling" function to adjust the number of blocks to use */
1344 	if (blocks * hLen != dkLen)
1345 		blocks++;
1346 
1347 	remainder = dkLen - ((blocks - 1) * hLen);
1348 
1349 	/* Step 3 */
1350 	salt = (CK_BYTE *)malloc(params->ulSaltSourceDataLen + 4);
1351 	if (salt == NULL) {
1352 		(void) soft_delete_object(session_p, hmac_key, B_FALSE,
1353 		    B_FALSE);
1354 		return (CKR_HOST_MEMORY);
1355 	}
1356 	/*
1357 	 * Nothing in PKCS#5 says you cannot pass an empty
1358 	 * salt, so we will allow for this and not return error
1359 	 * if the salt is not specified.
1360 	 */
1361 	if (params->pSaltSourceData != NULL && params->ulSaltSourceDataLen > 0)
1362 		(void) memcpy(salt, params->pSaltSourceData,
1363 		    params->ulSaltSourceDataLen);
1364 
1365 	/*
1366 	 * Get pointer to the data section of the key,
1367 	 * this will be used below as output from the
1368 	 * PRF iteration/concatenations so that when the
1369 	 * blocks are all iterated, the secret_key will
1370 	 * have the resulting derived key value.
1371 	 */
1372 	keydata = (CK_BYTE *)OBJ_SEC_VALUE(secret_key);
1373 
1374 	/* Step 4. */
1375 	for (i = 0; i < blocks && (rv == CKR_OK); i++) {
1376 		CK_BYTE *s;
1377 
1378 		s = salt + params->ulSaltSourceDataLen;
1379 
1380 		/*
1381 		 * Append the block index to the salt as input
1382 		 * to the PRF.  Block index should start at 1
1383 		 * not 0.
1384 		 */
1385 		*s++ = ((i+1) >> 24) & 0xff;
1386 		*s++ = ((i+1) >> 16) & 0xff;
1387 		*s++ = ((i+1) >> 8) & 0xff;
1388 		*s   = ((i+1)) & 0xff;
1389 
1390 		/*
1391 		 * Adjust the key pointer so we always append the
1392 		 * PRF output to the current key.
1393 		 */
1394 		rv = do_prf(session_p, params, hmac_key,
1395 		    salt, params->ulSaltSourceDataLen + 4, keydata,
1396 		    ((i + 1) == blocks ? remainder : hLen));
1397 
1398 		keydata += hLen;
1399 	}
1400 	(void) soft_delete_object(session_p, hmac_key, B_FALSE, B_FALSE);
1401 	freezero(salt, params->ulSaltSourceDataLen);
1402 
1403 	return (rv);
1404 }
1405 
1406 CK_RV
1407 soft_wrapkey(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
1408     soft_object_t *wrappingKey_p, soft_object_t *hkey_p,
1409     CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen)
1410 {
1411 	CK_RV		rv = CKR_OK;
1412 	CK_ULONG	plain_len = 0;
1413 	CK_BYTE_PTR	plain_data = NULL;
1414 	CK_ULONG	padded_len = 0;
1415 	CK_BYTE_PTR	padded_data = NULL;
1416 	CK_ULONG	wkey_blksz = 1;		/* so modulo will work right */
1417 
1418 	/* Check if the mechanism is supported. */
1419 	switch (pMechanism->mechanism) {
1420 	case CKM_DES_CBC_PAD:
1421 	case CKM_DES3_CBC_PAD:
1422 	case CKM_AES_CBC_PAD:
1423 		/*
1424 		 * Secret key mechs with padding can be used to wrap secret
1425 		 * keys and private keys only.  See PKCS#11, * sec 11.14,
1426 		 * C_WrapKey and secs 12.* for each mechanism's wrapping/
1427 		 * unwrapping constraints.
1428 		 */
1429 		if (hkey_p->class != CKO_SECRET_KEY && hkey_p->class !=
1430 		    CKO_PRIVATE_KEY)
1431 			return (CKR_MECHANISM_INVALID);
1432 		break;
1433 	case CKM_RSA_PKCS:
1434 	case CKM_RSA_X_509:
1435 	case CKM_DES_ECB:
1436 	case CKM_DES3_ECB:
1437 	case CKM_AES_ECB:
1438 	case CKM_DES_CBC:
1439 	case CKM_DES3_CBC:
1440 	case CKM_AES_CBC:
1441 	case CKM_AES_CTR:
1442 	case CKM_BLOWFISH_CBC:
1443 		/*
1444 		 * Unpadded secret key mechs and private key mechs are only
1445 		 * defined for wrapping secret keys.  See PKCS#11 refs above.
1446 		 */
1447 		if (hkey_p->class != CKO_SECRET_KEY)
1448 			return (CKR_MECHANISM_INVALID);
1449 		break;
1450 	default:
1451 		return (CKR_MECHANISM_INVALID);
1452 	}
1453 
1454 	if (hkey_p->class == CKO_SECRET_KEY) {
1455 		plain_data = OBJ_SEC_VALUE(hkey_p);
1456 		plain_len = OBJ_SEC_VALUE_LEN(hkey_p);
1457 	} else {
1458 		/*
1459 		 * BER-encode the object to be wrapped:  call first with
1460 		 * plain_data = NULL to get the size needed, allocate that
1461 		 * much space, call again to fill space with actual data.
1462 		 */
1463 		rv = soft_object_to_asn1(hkey_p, NULL, &plain_len);
1464 		if (rv != CKR_OK)
1465 			return (rv);
1466 		if ((plain_data = malloc(plain_len)) == NULL)
1467 			return (CKR_HOST_MEMORY);
1468 		(void) memset(plain_data, 0x0, plain_len);
1469 		rv = soft_object_to_asn1(hkey_p, plain_data, &plain_len);
1470 		if (rv != CKR_OK)
1471 			goto cleanup_wrap;
1472 	}
1473 
1474 	/*
1475 	 * For unpadded ECB and CBC mechanisms, the object needs to be
1476 	 * padded to the wrapping key's blocksize prior to the encryption.
1477 	 */
1478 	padded_len = plain_len;
1479 	padded_data = plain_data;
1480 
1481 	switch (pMechanism->mechanism) {
1482 	case CKM_DES_ECB:
1483 	case CKM_DES3_ECB:
1484 	case CKM_AES_ECB:
1485 	case CKM_DES_CBC:
1486 	case CKM_DES3_CBC:
1487 	case CKM_AES_CBC:
1488 	case CKM_BLOWFISH_CBC:
1489 		/* Find the block size of the wrapping key. */
1490 		if (wrappingKey_p->class == CKO_SECRET_KEY) {
1491 			switch (wrappingKey_p->key_type) {
1492 			case CKK_DES:
1493 			case CKK_DES2:
1494 			case CKK_DES3:
1495 				wkey_blksz = DES_BLOCK_LEN;
1496 				break;
1497 			case CKK_AES:
1498 				wkey_blksz = AES_BLOCK_LEN;
1499 				break;
1500 			case CKK_BLOWFISH:
1501 				wkey_blksz = BLOWFISH_BLOCK_LEN;
1502 				break;
1503 			default:
1504 				break;
1505 			}
1506 		} else {
1507 			rv = CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
1508 			goto cleanup_wrap;
1509 		}
1510 
1511 		/* Extend the plain text data to block size boundary.  */
1512 		if ((padded_len % wkey_blksz) != 0) {
1513 			padded_len += (wkey_blksz - (plain_len % wkey_blksz));
1514 			if ((padded_data = malloc(padded_len)) == NULL) {
1515 				rv = CKR_HOST_MEMORY;
1516 				goto cleanup_wrap;
1517 			}
1518 			(void) memset(padded_data, 0x0, padded_len);
1519 			(void) memcpy(padded_data, plain_data, plain_len);
1520 		}
1521 		break;
1522 	default:
1523 		break;
1524 	}
1525 
1526 	rv = soft_encrypt_init(session_p, pMechanism, wrappingKey_p);
1527 	if (rv != CKR_OK)
1528 		goto cleanup_wrap;
1529 
1530 	rv = soft_encrypt(session_p, padded_data, padded_len,
1531 	    pWrappedKey, pulWrappedKeyLen);
1532 
1533 cleanup_wrap:
1534 	if (padded_data != NULL && padded_len != plain_len) {
1535 		/* Clear buffer before returning to memory pool. */
1536 		freezero(padded_data, padded_len);
1537 	}
1538 
1539 	if ((hkey_p->class != CKO_SECRET_KEY) && (plain_data != NULL)) {
1540 		/* Clear buffer before returning to memory pool. */
1541 		freezero(plain_data, plain_len);
1542 	}
1543 
1544 	return (rv);
1545 }
1546 
1547 /*
1548  * Quick check for whether unwrapped key length is appropriate for key type
1549  * and whether it needs to be truncated (in case the wrapping function had
1550  * to pad the key prior to wrapping).
1551  */
1552 static CK_RV
1553 soft_unwrap_secret_len_check(CK_KEY_TYPE keytype, CK_MECHANISM_TYPE mechtype,
1554     CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount)
1555 {
1556 	CK_ULONG	i;
1557 	boolean_t	isValueLen = B_FALSE;
1558 
1559 	/*
1560 	 * Based on the key type and the mech used to unwrap, need to
1561 	 * determine if CKA_VALUE_LEN should or should not be specified.
1562 	 * PKCS#11 v2.11 restricts CKA_VALUE_LEN from being specified
1563 	 * for C_UnwrapKey for all mechs and key types, but v2.20 loosens
1564 	 * that restriction, perhaps because it makes it impossible to
1565 	 * determine the original length of unwrapped variable-length secret
1566 	 * keys, such as RC4, AES, and GENERIC_SECRET.  These variable-length
1567 	 * secret keys would have been padded with trailing null-bytes so
1568 	 * that they could be successfully wrapped with *_ECB and *_CBC
1569 	 * mechanisms.  Hence for unwrapping with these mechs, CKA_VALUE_LEN
1570 	 * must be specified.  For unwrapping with other mechs, such as
1571 	 * *_CBC_PAD, the CKA_VALUE_LEN is not needed.
1572 	 */
1573 
1574 	/* Find out if template has CKA_VALUE_LEN. */
1575 	for (i = 0; i < ulAttributeCount; i++) {
1576 		if (pTemplate[i].type == CKA_VALUE_LEN &&
1577 		    pTemplate[i].pValue != NULL) {
1578 			isValueLen = B_TRUE;
1579 			break;
1580 		}
1581 	}
1582 
1583 	/* Does its presence  conflict with the mech type and key type? */
1584 	switch (mechtype) {
1585 	case CKM_DES_ECB:
1586 	case CKM_DES3_ECB:
1587 	case CKM_AES_ECB:
1588 	case CKM_DES_CBC:
1589 	case CKM_DES3_CBC:
1590 	case CKM_AES_CBC:
1591 	case CKM_BLOWFISH_CBC:
1592 		/*
1593 		 * CKA_VALUE_LEN must be specified
1594 		 * if keytype is CKK_RC4, CKK_AES and CKK_GENERIC_SECRET
1595 		 * and must not be specified otherwise
1596 		 */
1597 		switch (keytype) {
1598 		case CKK_DES:
1599 		case CKK_DES2:
1600 		case CKK_DES3:
1601 			if (isValueLen)
1602 				return (CKR_TEMPLATE_INCONSISTENT);
1603 			break;
1604 		case CKK_GENERIC_SECRET:
1605 		case CKK_RC4:
1606 		case CKK_AES:
1607 		case CKK_BLOWFISH:
1608 			if (!isValueLen)
1609 				return (CKR_TEMPLATE_INCOMPLETE);
1610 			break;
1611 		default:
1612 			return (CKR_FUNCTION_NOT_SUPPORTED);
1613 		}
1614 		break;
1615 	default:
1616 		/* CKA_VALUE_LEN must not be specified */
1617 		if (isValueLen)
1618 			return (CKR_TEMPLATE_INCONSISTENT);
1619 		break;
1620 	}
1621 
1622 	return (CKR_OK);
1623 }
1624 
1625 CK_RV
1626 soft_unwrapkey(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
1627     soft_object_t *unwrappingkey_p, CK_BYTE_PTR pWrappedKey,
1628     CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate,
1629     CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
1630 {
1631 	CK_RV			rv = CKR_OK;
1632 	CK_OBJECT_CLASS		new_obj_class = ~0UL;
1633 	int			i = 0;
1634 	soft_object_t		*new_objp = NULL;
1635 	boolean_t		persistent = B_FALSE;
1636 	CK_BYTE_PTR		plain_data = NULL;
1637 	CK_ULONG		plain_len = 0;
1638 	secret_key_obj_t	*sck = NULL;
1639 
1640 	/* Scan the attribute template for the object class. */
1641 	if (pTemplate != NULL && ulAttributeCount != 0) {
1642 		for (i = 0; i < ulAttributeCount; i++) {
1643 			if (pTemplate[i].type == CKA_CLASS) {
1644 				new_obj_class =
1645 				    *((CK_OBJECT_CLASS *)pTemplate[i].pValue);
1646 				break;
1647 			}
1648 		}
1649 		if (new_obj_class == ~0UL)
1650 			return (CKR_TEMPLATE_INCOMPLETE);
1651 	}
1652 
1653 	/*
1654 	 * Check if the mechanism is supported, and now that the new
1655 	 * object's class is known, the mechanism selected should be
1656 	 * capable of doing the unwrap.
1657 	 */
1658 	switch (pMechanism->mechanism) {
1659 	case CKM_RSA_PKCS:
1660 	case CKM_RSA_X_509:
1661 	case CKM_DES_ECB:
1662 	case CKM_DES3_ECB:
1663 	case CKM_AES_ECB:
1664 	case CKM_DES_CBC:
1665 	case CKM_DES3_CBC:
1666 	case CKM_AES_CBC:
1667 	case CKM_BLOWFISH_CBC:
1668 		if (new_obj_class != CKO_SECRET_KEY)
1669 			return (CKR_MECHANISM_INVALID);
1670 		break;
1671 	case CKM_DES_CBC_PAD:
1672 	case CKM_DES3_CBC_PAD:
1673 	case CKM_AES_CBC_PAD:
1674 		if (new_obj_class != CKO_SECRET_KEY && new_obj_class !=
1675 		    CKO_PRIVATE_KEY)
1676 			return (CKR_MECHANISM_INVALID);
1677 		break;
1678 	default:
1679 		return (CKR_MECHANISM_INVALID);
1680 	}
1681 
1682 	/* Create a new object based on the attribute template. */
1683 	rv = soft_gen_keyobject(pTemplate, ulAttributeCount,
1684 	    &new_objp, session_p, (CK_OBJECT_CLASS)~0UL,
1685 	    (CK_KEY_TYPE)~0UL, 0, SOFT_UNWRAP_KEY, B_FALSE);
1686 	if (rv != CKR_OK)
1687 		return (rv);
1688 
1689 	/*
1690 	 * New key will have CKA_ALWAYS_SENSITIVE and CKA_NEVER_EXTRACTABLE
1691 	 * both set to FALSE.  CKA_EXTRACTABLE will be set _by_default_ to
1692 	 * true -- leaving the possibility that it may be set FALSE by the
1693 	 * supplied attribute template.  If the precise template cannot be
1694 	 * supported, unwrap fails.  PKCS#11 spec, Sec. 11.14, C_UnwrapKey.
1695 	 *
1696 	 * Therefore, check the new object's NEVER_EXTRACTABLE_BOOL_ON and
1697 	 * ALWAYS_SENSITVE_BOOL_ON; if they are TRUE, the template must
1698 	 * have supplied them and therefore we cannot honor the unwrap.
1699 	 */
1700 	if ((new_objp->bool_attr_mask & NEVER_EXTRACTABLE_BOOL_ON) ||
1701 	    (new_objp->bool_attr_mask & ALWAYS_SENSITIVE_BOOL_ON)) {
1702 		rv = CKR_TEMPLATE_INCONSISTENT;
1703 		goto cleanup_unwrap;
1704 	}
1705 
1706 	rv = soft_decrypt_init(session_p, pMechanism, unwrappingkey_p);
1707 	if (rv != CKR_OK)
1708 		goto cleanup_unwrap;
1709 
1710 	/* First get the length of the plain data */
1711 	rv = soft_decrypt(session_p, pWrappedKey, ulWrappedKeyLen, NULL,
1712 	    &plain_len);
1713 	if (rv != CKR_OK)
1714 		goto cleanup_unwrap;
1715 
1716 	/* Allocate space for the unwrapped data */
1717 	if ((plain_data = malloc(plain_len)) == NULL) {
1718 		rv = CKR_HOST_MEMORY;
1719 		goto cleanup_unwrap;
1720 	}
1721 	(void) memset(plain_data, 0x0, plain_len);
1722 
1723 	/* Perform actual decryption into the allocated space. */
1724 	rv = soft_decrypt(session_p, pWrappedKey, ulWrappedKeyLen, plain_data,
1725 	    &plain_len);
1726 	if (rv != CKR_OK)
1727 		goto cleanup_unwrap;
1728 
1729 	if (new_objp->class == CKO_SECRET_KEY) {
1730 		/*
1731 		 * Since no ASN.1 encoding is done for secret keys, check for
1732 		 * appropriateness and copy decrypted buffer to the key object.
1733 		 */
1734 
1735 		/* Check keytype and mechtype don't conflict with valuelen */
1736 		rv = soft_unwrap_secret_len_check(new_objp->key_type,
1737 		    pMechanism->mechanism, pTemplate, ulAttributeCount);
1738 		if (rv != CKR_OK)
1739 			goto cleanup_unwrap;
1740 
1741 		/*
1742 		 * Allocate the secret key structure if not already there;
1743 		 * it will exist for variable length keys since CKA_VALUE_LEN
1744 		 * is specified and saved, but not for fixed length keys.
1745 		 */
1746 		if (OBJ_SEC(new_objp) == NULL) {
1747 			if ((sck = calloc(1, sizeof (secret_key_obj_t))) ==
1748 			    NULL) {
1749 				rv = CKR_HOST_MEMORY;
1750 				goto cleanup_unwrap;
1751 			}
1752 			OBJ_SEC(new_objp) = sck;
1753 		}
1754 
1755 		switch (new_objp->key_type) {
1756 		/* Fixed length secret keys don't have CKA_VALUE_LEN */
1757 		case CKK_DES:
1758 			OBJ_SEC_VALUE_LEN(new_objp) = DES_KEYSIZE;
1759 			break;
1760 		case CKK_DES2:
1761 			OBJ_SEC_VALUE_LEN(new_objp) = DES2_KEYSIZE;
1762 			break;
1763 		case CKK_DES3:
1764 			OBJ_SEC_VALUE_LEN(new_objp) = DES3_KEYSIZE;
1765 			break;
1766 
1767 		/*
1768 		 * Variable length secret keys.  CKA_VALUE_LEN must be
1769 		 * provided by the template when mech is *_ECB or *_CBC, and
1770 		 * should already have been set during soft_gen_keyobject().
1771 		 * Otherwise we don't need CKA_VALUE_LEN.
1772 		 */
1773 		case CKK_GENERIC_SECRET:
1774 		case CKK_RC4:
1775 		case CKK_AES:
1776 		case CKK_BLOWFISH:
1777 			break;
1778 		default:
1779 			rv = CKR_WRAPPED_KEY_INVALID;
1780 			goto cleanup_unwrap;
1781 		};
1782 
1783 		if (OBJ_SEC_VALUE_LEN(new_objp) == 0) {
1784 			/* No CKA_VALUE_LEN set so set it now and save data */
1785 			OBJ_SEC_VALUE_LEN(new_objp) = plain_len;
1786 			OBJ_SEC_VALUE(new_objp) = plain_data;
1787 		} else if (OBJ_SEC_VALUE_LEN(new_objp) == plain_len) {
1788 			/* No need to truncate, just save the data */
1789 			OBJ_SEC_VALUE(new_objp) = plain_data;
1790 		} else if (OBJ_SEC_VALUE_LEN(new_objp) > plain_len) {
1791 			/* Length can't be bigger than what was decrypted */
1792 			rv = CKR_WRAPPED_KEY_LEN_RANGE;
1793 			goto cleanup_unwrap;
1794 		} else {	/* betw 0 and plain_len, hence padded */
1795 			/* Truncate the data before saving. */
1796 			OBJ_SEC_VALUE(new_objp) = realloc(plain_data,
1797 			    OBJ_SEC_VALUE_LEN(new_objp));
1798 			if (OBJ_SEC_VALUE(new_objp) == NULL) {
1799 				rv = CKR_HOST_MEMORY;
1800 				goto cleanup_unwrap;
1801 			}
1802 		}
1803 	} else {
1804 		/* BER-decode the object to be unwrapped. */
1805 		rv = soft_asn1_to_object(new_objp, plain_data, plain_len);
1806 		if (rv != CKR_OK)
1807 			goto cleanup_unwrap;
1808 	}
1809 
1810 	/* If it needs to be persistent, write it to the keystore */
1811 	if (IS_TOKEN_OBJECT(new_objp)) {
1812 		persistent = B_TRUE;
1813 		rv = soft_put_object_to_keystore(new_objp);
1814 		if (rv != CKR_OK)
1815 			goto cleanup_unwrap;
1816 	}
1817 
1818 	if (new_objp->class != CKO_SECRET_KEY) {
1819 		/* Clear buffer before returning to memory pool. */
1820 		freezero(plain_data, plain_len);
1821 	}
1822 
1823 	*phKey = (CK_OBJECT_HANDLE)new_objp;
1824 
1825 	return (CKR_OK);
1826 
1827 cleanup_unwrap:
1828 	/* The decrypted private key buffer must be freed explicitly. */
1829 	if ((new_objp->class != CKO_SECRET_KEY) && (plain_data != NULL)) {
1830 		/* Clear buffer before returning to memory pool. */
1831 		freezero(plain_data, plain_len);
1832 	}
1833 
1834 	/* sck and new_objp are indirectly free()d inside these functions */
1835 	if (IS_TOKEN_OBJECT(new_objp))
1836 		soft_delete_token_object(new_objp, persistent, B_FALSE);
1837 	else
1838 		soft_delete_object(session_p, new_objp, B_FALSE, B_FALSE);
1839 
1840 	return (rv);
1841 }
1842