xref: /titanic_41/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeysUtil.c (revision e5803b76927480e8f9b67b22201c484ccf4c2bcf)
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 
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"
51 
52 
53 #define	local_min(a, b)	((a) < (b) ? (a) : (b))
54 
55 static CK_RV
56 soft_pkcs12_pbe(soft_session_t *, CK_MECHANISM_PTR, soft_object_t *);
57 
58 /*
59  * Create a temporary key object struct by filling up its template attributes.
60  */
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)
66 {
67 
68 	CK_RV rv;
69 	soft_object_t *new_objp = NULL;
70 
71 	new_objp = calloc(1, sizeof (soft_object_t));
72 	if (new_objp == NULL) {
73 		return (CKR_HOST_MEMORY);
74 	}
75 
76 	new_objp->extra_attrlistp = NULL;
77 
78 	/*
79 	 * Validate attribute template and fill in the attributes
80 	 * in the soft_object_t.
81 	 */
82 	rv = soft_build_key(pTemplate, ulCount, new_objp, class, key_type,
83 	    keylen, mode);
84 	if (rv != CKR_OK) {
85 		goto fail_cleanup1;
86 	}
87 
88 	/*
89 	 * If generating a key is an internal request (i.e. not a C_XXX
90 	 * API request), then skip the following checks.
91 	 */
92 	if (!internal) {
93 		rv = soft_pin_expired_check(new_objp);
94 		if (rv != CKR_OK) {
95 			goto fail_cleanup2;
96 		}
97 
98 		rv = soft_object_write_access_check(sp, new_objp);
99 		if (rv != CKR_OK) {
100 			goto fail_cleanup2;
101 		}
102 	}
103 
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;
107 
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);
113 		/*
114 		 * Type casting the address of an object struct to
115 		 * an object handle.
116 		 */
117 		*objecthandle_p = (CK_ULONG)new_objp;
118 
119 		return (CKR_OK);
120 	}
121 
122 	new_objp->session_handle = (CK_SESSION_HANDLE)sp;
123 
124 	/* Add the new object to the session's object list. */
125 	soft_add_object_to_session(new_objp, sp);
126 
127 	/* Type casting the address of an object struct to an object handle. */
128 	*objecthandle_p =  (CK_ULONG)new_objp;
129 
130 	return (CKR_OK);
131 
132 fail_cleanup2:
133 	/*
134 	 * When any error occurs after soft_build_key(), we will need to
135 	 * clean up the memory allocated by the soft_build_key().
136 	 */
137 	soft_cleanup_object(new_objp);
138 
139 fail_cleanup1:
140 	if (new_objp) {
141 		/*
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.
145 		 */
146 		free(new_objp);
147 	}
148 
149 	return (rv);
150 }
151 
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)
155 {
156 
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;
166 
167 	switch (pMechanism->mechanism) {
168 	case CKM_DES_KEY_GEN:
169 		key_type = CKK_DES;
170 		break;
171 
172 	case CKM_DES2_KEY_GEN:
173 		key_type = CKK_DES2;
174 		break;
175 
176 	case CKM_DES3_KEY_GEN:
177 		key_type = CKK_DES3;
178 		break;
179 
180 	case CKM_AES_KEY_GEN:
181 		key_type = CKK_AES;
182 		break;
183 
184 	case CKM_BLOWFISH_KEY_GEN:
185 		key_type = CKK_BLOWFISH;
186 		break;
187 
188 	case CKM_RC4_KEY_GEN:
189 		key_type = CKK_RC4;
190 		break;
191 
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;
201 
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;
209 			}
210 		}
211 		if (!keyfound)
212 			return (CKR_TEMPLATE_INCOMPLETE);
213 		/*
214 		 * Make sure that parameters were given for this
215 		 * mechanism.
216 		 */
217 		if (pMechanism->pParameter == NULL ||
218 		    pMechanism->ulParameterLen !=
219 		    sizeof (CK_PKCS5_PBKD2_PARAMS))
220 			return (CKR_TEMPLATE_INCOMPLETE);
221 		break;
222 
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;
230 			}
231 			if (pTemplate[i].type == CKA_VALUE_LEN &&
232 			    pTemplate[i].pValue != NULL) {
233 				keylen = *((CK_ULONG*)pTemplate[i].pValue);
234 			}
235 		}
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;
241 
242 		/* If key length was specified, it better be 16 bytes */
243 		if (keylen != 0 && keylen != 16)
244 			return (CKR_TEMPLATE_INCONSISTENT);
245 
246 		/*
247 		 * Make sure that parameters were given for this
248 		 * mechanism.
249 		 */
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);
257 	}
258 
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);
262 
263 	if (rv != CKR_OK) {
264 		return (rv);
265 	}
266 
267 	/* Obtain the secret object pointer. */
268 	secret_key = (soft_object_t *)*phKey;
269 
270 	switch (pMechanism->mechanism) {
271 	case CKM_DES_KEY_GEN:
272 		/*
273 		 * Set up key value len since it is not a required
274 		 * attribute for C_GenerateKey.
275 		 */
276 		keylen = OBJ_SEC_VALUE_LEN(secret_key) = DES_KEYSIZE;
277 		des_strength = DES;
278 		break;
279 
280 	case CKM_DES2_KEY_GEN:
281 		/*
282 		 * Set up key value len since it is not a required
283 		 * attribute for C_GenerateKey.
284 		 */
285 		keylen = OBJ_SEC_VALUE_LEN(secret_key) = DES2_KEYSIZE;
286 		des_strength = DES2;
287 		break;
288 
289 	case CKM_DES3_KEY_GEN:
290 		/*
291 		 * Set up key value len since it is not a required
292 		 * attribute for C_GenerateKey.
293 		 */
294 		keylen = OBJ_SEC_VALUE_LEN(secret_key) = DES3_KEYSIZE;
295 		des_strength = DES3;
296 		break;
297 
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 */
302 
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;
309 
310 	case CKM_PKCS5_PBKD2:
311 		/*
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.
315 		 */
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;
322 		}
323 
324 		keylen = OBJ_SEC_VALUE_LEN(secret_key);
325 		break;
326 	}
327 
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);
334 
335 		return (CKR_HOST_MEMORY);
336 	}
337 	switch (pMechanism->mechanism) {
338 	case CKM_PBE_SHA1_RC4_128:
339 		/*
340 		 * Use the PBE algorithm described in PKCS#11 section
341 		 * 12.33 to derive the key.
342 		 */
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;
356 			}
357 		}
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;
367 			}
368 
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;
378 				}
379 			}
380 			/*
381 			 * Copy over the SSL client version For SSL mechs
382 			 * The first two bytes of the key is the version
383 			 */
384 			if (is_ssl_mech)
385 				bcopy(pMechanism->pParameter,
386 				    OBJ_SEC_VALUE(secret_key),
387 				    sizeof (CK_VERSION));
388 
389 		} while (rv != CKR_OK && retry < KEYGEN_RETRY);
390 		if (retry == KEYGEN_RETRY)
391 			rv = CKR_FUNCTION_FAILED;
392 		break;
393 	}
394 
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);
401 
402 	if (IS_TOKEN_OBJECT(secret_key)) {
403 		/*
404 		 * All the info has been filled, so we can write to
405 		 * keystore now.
406 		 */
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);
410 	}
411 
412 	return (rv);
413 }
414 
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)
420 {
421 
422 	CK_RV rv;
423 	soft_object_t *public_key, *private_key;
424 	CK_KEY_TYPE key_type;
425 
426 	switch (pMechanism->mechanism) {
427 
428 	case CKM_RSA_PKCS_KEY_PAIR_GEN:
429 		key_type = CKK_RSA;
430 		break;
431 
432 	case CKM_DSA_KEY_PAIR_GEN:
433 		key_type = CKK_DSA;
434 		break;
435 
436 	case CKM_DH_PKCS_KEY_PAIR_GEN:
437 		key_type = CKK_DH;
438 		break;
439 
440 	case CKM_EC_KEY_PAIR_GEN:
441 		key_type = CKK_EC;
442 		break;
443 
444 	default:
445 		return (CKR_MECHANISM_INVALID);
446 	}
447 
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);
452 
453 	if (rv != CKR_OK) {
454 		return (rv);
455 	}
456 
457 	/* Obtain the public object pointer. */
458 	public_key = (soft_object_t *)*phPublicKey;
459 
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);
464 
465 	if (rv != CKR_OK) {
466 		/*
467 		 * Both public key and private key must be successful.
468 		 */
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);
475 	}
476 
477 	/* Obtain the private object pointer. */
478 	private_key = (soft_object_t *)*phPrivateKey;
479 
480 	/*
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.
485 	 */
486 
487 	switch (key_type) {
488 	case CKK_RSA:
489 		rv = soft_rsa_genkey_pair(public_key, private_key);
490 		break;
491 
492 	case CKK_DSA:
493 		rv = soft_dsa_genkey_pair(public_key, private_key);
494 		break;
495 
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;
504 	}
505 
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);
515 		}
516 		return (rv);
517 	}
518 
519 	if (IS_TOKEN_OBJECT(public_key)) {
520 		/*
521 		 * All the info has been filled, so we can write to
522 		 * keystore now.
523 		 */
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);
529 		}
530 	}
531 
532 	if (IS_TOKEN_OBJECT(private_key)) {
533 		rv = soft_put_object_to_keystore(private_key);
534 		if (rv != CKR_OK) {
535 			/*
536 			 * We also need to delete the public token object
537 			 * from keystore.
538 			 */
539 			soft_delete_token_object(public_key, B_TRUE, B_FALSE);
540 			soft_delete_token_object(private_key, B_FALSE, B_FALSE);
541 		}
542 	}
543 
544 	return (rv);
545 }
546 
547 
548 CK_RV
549 soft_key_derive_check_length(soft_object_t *secret_key, CK_ULONG max_keylen)
550 {
551 
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);
559 		}
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);
568 		}
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);
577 		}
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);
586 		}
587 		break;
588 
589 	default:
590 		return (CKR_MECHANISM_INVALID);
591 	}
592 
593 	return (CKR_OK);
594 }
595 
596 /*
597  * PKCS#11 (12.33) says that v = 512 bits (64 bytes) for SHA1
598  * PBE methods.
599  */
600 #define	PKCS12_BUFFER_SIZE 64
601 /*
602  * PKCS#12 defines 3 different ID bytes to be used for
603  * deriving keys for different operations.
604  */
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))
609 
610 static CK_RV
611 soft_pkcs12_pbe(soft_session_t *session_p,
612 		CK_MECHANISM_PTR pMechanism,
613 		soft_object_t *derived_key)
614 {
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;
620 	/*
621 	 * Terse variable names are used to make following
622 	 * the PKCS#12 spec easier.
623 	 */
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;
633 
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);
644 	}
645 	keybuf = OBJ_SEC_VALUE(derived_key);
646 
647 	Blen = Dlen = buffSize;
648 	D = (CK_BYTE *)malloc(Dlen);
649 	if (D == NULL) {
650 		rv = CKR_HOST_MEMORY;
651 		goto cleanup;
652 	}
653 
654 	B = (CK_BYTE *)malloc(Blen);
655 	if (B == NULL) {
656 		rv = CKR_HOST_MEMORY;
657 		goto cleanup;
658 	}
659 
660 	/*
661 	 * Initialize some values and create some buffers
662 	 * that we need later.
663 	 *
664 	 * Slen = buffSize * CEIL(SaltLength/buffSize)
665 	 */
666 	Slen = buffSize * PBE_CEIL(params->ulSaltLen, buffSize);
667 
668 	/*
669 	 * Plen = buffSize * CEIL(PasswordLength/buffSize)
670 	 */
671 	Plen = buffSize * PBE_CEIL(params->ulPasswordLen, buffSize);
672 
673 	/*
674 	 * From step 4: I = S + P, so: Ilen = Slen + Plen
675 	 */
676 	Ilen = Slen + Plen;
677 	I = (CK_BYTE *)malloc(Ilen);
678 	if (I == NULL) {
679 		rv = CKR_HOST_MEMORY;
680 		goto cleanup;
681 	}
682 
683 	S = I;
684 	P = I + Slen;
685 
686 	/*
687 	 * Step 1.
688 	 * We are only interested in deriving keys for encrypt/decrypt
689 	 * for now, so construct the "D"iversifier accordingly.
690 	 */
691 	(void) memset(D, PBE_ID_ENCRYPT, Dlen);
692 
693 	/*
694 	 * Step 2.
695 	 * Concatenate copies of the salt together to make S.
696 	 */
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)));
701 	}
702 
703 	/*
704 	 * Step 3.
705 	 * Concatenate copies of the password together to make
706 	 * a string P.
707 	 */
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)));
712 	}
713 
714 	/*
715 	 * Step 4.
716 	 * I = S+P - this is now done because S and P are
717 	 * pointers into I.
718 	 *
719 	 * Step 5.
720 	 * c= CEIL[n/u]
721 	 * where n = pseudorandom bits of output desired.
722 	 */
723 	c = PBE_CEIL(keysize, hashSize);
724 
725 	/*
726 	 * Step 6.
727 	 */
728 	Alen = c * hashSize;
729 	A = (CK_BYTE *)malloc(Alen);
730 	if (A == NULL) {
731 		rv = CKR_HOST_MEMORY;
732 		goto cleanup;
733 	}
734 	AiLen = hashSize;
735 	Ai = (CK_BYTE *)malloc(AiLen);
736 	if (Ai == NULL) {
737 		rv = CKR_HOST_MEMORY;
738 		goto cleanup;
739 	}
740 
741 	/*
742 	 * Step 6a.
743 	 * Ai = Hr(D+I)
744 	 */
745 	for (i = 0; i < c; i++) {
746 		(void) pthread_mutex_lock(&session_p->session_mutex);
747 
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;
752 		}
753 		session_p->sign.flags |= CRYPTO_OPERATION_ACTIVE;
754 		(void) pthread_mutex_unlock(&session_p->session_mutex);
755 
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;
760 
761 			if (j == 0) {
762 				rv = soft_digest_update(session_p, D, Dlen);
763 				if (rv != CKR_OK)
764 					goto digest_done;
765 
766 				rv = soft_digest_update(session_p, I, Ilen);
767 			} else {
768 				rv = soft_digest_update(session_p, Ai, AiLen);
769 			}
770 			if (rv != CKR_OK)
771 				goto digest_done;
772 
773 			rv = soft_digest_final(session_p, Ai, &AiLen);
774 			if (rv != CKR_OK)
775 				goto digest_done;
776 		}
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);
781 
782 		if (rv != CKR_OK)
783 			goto cleanup;
784 		/*
785 		 * Step 6b.
786 		 * Concatenate Ai to make B
787 		 */
788 		for (j = 0; j < Blen; j += hashSize) {
789 			(void) memcpy(B+j, Ai, ((Blen - j > hashSize) ?
790 			    hashSize : Blen - j));
791 		}
792 
793 		/*
794 		 * Step 6c.
795 		 */
796 		k = Ilen / Blen;
797 		for (j = 0; j < k; j++) {
798 			uchar_t idx;
799 			CK_ULONG m, q = 1, cbit = 0;
800 
801 			for (m = Blen - 1; m >= (CK_ULONG)0; m--, q = 0) {
802 				idx = m + j*Blen;
803 
804 				q += (CK_ULONG)I[idx] + (CK_ULONG)B[m];
805 				q += cbit;
806 				I[idx] = (CK_BYTE)(q & 0xff);
807 				cbit = (q > 0xff);
808 			}
809 		}
810 
811 		/*
812 		 * Step 7.
813 		 *  A += Ai
814 		 */
815 		(void) memcpy(A + i*hashSize, Ai, AiLen);
816 	}
817 
818 	/*
819 	 * Step 8.
820 	 * The final output of this process is the A buffer
821 	 */
822 	(void) memcpy(keybuf, A, keysize);
823 
824 cleanup:
825 	if (A) {
826 		bzero(A, Alen);
827 		free(A);
828 	}
829 	if (Ai) {
830 		bzero(Ai, AiLen);
831 		free(Ai);
832 	}
833 	if (B) {
834 		bzero(B, Blen);
835 		free(B);
836 	}
837 	if (D) {
838 		bzero(D, Dlen);
839 		free(D);
840 	}
841 	if (I) {
842 		bzero(I, Ilen);
843 		free(I);
844 	}
845 	return (rv);
846 }
847 
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)
852 {
853 
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;
861 
862 	switch (pMechanism->mechanism) {
863 	case CKM_DH_PKCS_DERIVE:
864 		/*
865 		 * Create a new object for secret key. The key type should
866 		 * be provided in the template.
867 		 */
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);
871 
872 		if (rv != CKR_OK) {
873 			return (rv);
874 		}
875 
876 		/* Obtain the secret object pointer. */
877 		secret_key = (soft_object_t *)*phKey;
878 
879 		rv = soft_dh_key_derive(basekey_p, secret_key,
880 		    (CK_BYTE *)pMechanism->pParameter,
881 		    pMechanism->ulParameterLen);
882 
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);
891 		}
892 
893 		break;
894 
895 	case CKM_ECDH1_DERIVE:
896 		/*
897 		 * Create a new object for secret key. The key type should
898 		 * be provided in the template.
899 		 */
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);
903 
904 		if (rv != CKR_OK) {
905 			return (rv);
906 		}
907 
908 		/* Obtain the secret object pointer. */
909 		secret_key = (soft_object_t *)*phKey;
910 
911 		rv = soft_ec_key_derive(basekey_p, secret_key,
912 		    (CK_BYTE *)pMechanism->pParameter,
913 		    pMechanism->ulParameterLen);
914 
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);
923 		}
924 
925 		break;
926 
927 	case CKM_SHA1_KEY_DERIVATION:
928 		hash_size = SHA1_HASH_SIZE;
929 		digest_mech.mechanism = CKM_SHA_1;
930 		goto common;
931 
932 	case CKM_MD5_KEY_DERIVATION:
933 		hash_size = MD5_HASH_SIZE;
934 		digest_mech.mechanism = CKM_MD5;
935 		goto common;
936 
937 	case CKM_SHA256_KEY_DERIVATION:
938 		hash_size = SHA256_DIGEST_LENGTH;
939 		digest_mech.mechanism = CKM_SHA256;
940 		goto common;
941 
942 	case CKM_SHA384_KEY_DERIVATION:
943 		hash_size = SHA384_DIGEST_LENGTH;
944 		digest_mech.mechanism = CKM_SHA384;
945 		goto common;
946 
947 	case CKM_SHA512_KEY_DERIVATION:
948 		hash_size = SHA512_DIGEST_LENGTH;
949 		digest_mech.mechanism = CKM_SHA512;
950 		goto common;
951 
952 common:
953 		/*
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.
957 		 */
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);
962 
963 		if (rv != CKR_OK) {
964 			return (rv);
965 		}
966 
967 		/* Obtain the secret object pointer. */
968 		secret_key = (soft_object_t *)*phKey;
969 
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);
980 		}
981 
982 		/*
983 		 * Derive the secret key by digesting the value of another
984 		 * secret key (base key) with SHA-1 or MD5.
985 		 */
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);
995 		}
996 
997 		rv = soft_digest(session_p, OBJ_SEC_VALUE(basekey_p),
998 		    OBJ_SEC_VALUE_LEN(basekey_p), hash, &hash_len);
999 
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);
1004 
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);
1013 		}
1014 
1015 		secret_key_len = OBJ_SEC_VALUE_LEN(secret_key);
1016 
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);
1026 		}
1027 
1028 		/*
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.
1033 		 */
1034 		(void) memcpy(OBJ_SEC_VALUE(secret_key),
1035 		    (hash + hash_len - secret_key_len),
1036 		    secret_key_len);
1037 
1038 		break;
1039 
1040 	/*
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()
1044 	 */
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));
1053 
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));
1058 
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);
1064 
1065 		if (pTemplate != NULL)
1066 			return (CKR_TEMPLATE_INCONSISTENT);
1067 
1068 		return (derive_tls_prf(
1069 		    (CK_TLS_PRF_PARAMS_PTR)pMechanism->pParameter, basekey_p));
1070 
1071 	default:
1072 		return (CKR_MECHANISM_INVALID);
1073 	}
1074 
1075 	soft_derive_enforce_flags(basekey_p, secret_key);
1076 
1077 	if (IS_TOKEN_OBJECT(secret_key)) {
1078 		/*
1079 		 * All the info has been filled, so we can write to
1080 		 * keystore now.
1081 		 */
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);
1085 	}
1086 
1087 	return (rv);
1088 }
1089 
1090 
1091 /*
1092  * Perform key derivation rules on key's sensitivity and extractability.
1093  */
1094 void
1095 soft_derive_enforce_flags(soft_object_t *basekey, soft_object_t *newkey)
1096 {
1097 
1098 	boolean_t new_sensitive = B_FALSE;
1099 	boolean_t new_extractable = B_FALSE;
1100 
1101 	/*
1102 	 * The sensitive and extractable bits have been set when
1103 	 * the newkey was built.
1104 	 */
1105 	if (newkey->bool_attr_mask & SENSITIVE_BOOL_ON) {
1106 		new_sensitive = B_TRUE;
1107 	}
1108 
1109 	if (newkey->bool_attr_mask & EXTRACTABLE_BOOL_ON) {
1110 		new_extractable = B_TRUE;
1111 	}
1112 
1113 	/* Derive the CKA_ALWAYS_SENSITIVE flag */
1114 	if (!basekey->bool_attr_mask & ALWAYS_SENSITIVE_BOOL_ON) {
1115 		/*
1116 		 * If the base key has its CKA_ALWAYS_SENSITIVE set to
1117 		 * FALSE, then the derived key will as well.
1118 		 */
1119 		newkey->bool_attr_mask &= ~ALWAYS_SENSITIVE_BOOL_ON;
1120 	} else {
1121 		/*
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;
1125 		 */
1126 		if (new_sensitive) {
1127 			newkey->bool_attr_mask |= ALWAYS_SENSITIVE_BOOL_ON;
1128 		} else {
1129 			newkey->bool_attr_mask &= ~ALWAYS_SENSITIVE_BOOL_ON;
1130 		}
1131 	}
1132 
1133 	/* Derive the CKA_NEVER_EXTRACTABLE flag */
1134 	if (!basekey->bool_attr_mask & NEVER_EXTRACTABLE_BOOL_ON) {
1135 		/*
1136 		 * If the base key has its CKA_NEVER_EXTRACTABLE set to
1137 		 * FALSE, then the derived key will as well.
1138 		 */
1139 		newkey->bool_attr_mask &= ~NEVER_EXTRACTABLE_BOOL_ON;
1140 	} else {
1141 		/*
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;
1145 		 */
1146 		if (new_extractable) {
1147 			newkey->bool_attr_mask &= ~NEVER_EXTRACTABLE_BOOL_ON;
1148 		} else {
1149 			newkey->bool_attr_mask |= NEVER_EXTRACTABLE_BOOL_ON;
1150 		}
1151 	}
1152 
1153 	/* Set the CKA_LOCAL flag to false */
1154 	newkey->bool_attr_mask &= ~LOCAL_BOOL_ON;
1155 }
1156 
1157 
1158 /*
1159  * do_prf
1160  *
1161  * This routine implements Step 3. of the PBKDF2 function
1162  * defined in PKCS#5 for generating derived keys from a
1163  * password.
1164  *
1165  * Currently, PRF is always SHA_1_HMAC.
1166  */
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)
1173 {
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;
1181 
1182 	input = newsalt;
1183 	inlen = saltlen;
1184 
1185 	output = buffer[1];
1186 	(void) pthread_mutex_lock(&session_p->session_mutex);
1187 
1188 	if (session_p->sign.flags & CRYPTO_OPERATION_ACTIVE) {
1189 		(void) pthread_mutex_unlock(&session_p->session_mutex);
1190 		return (CKR_OPERATION_ACTIVE);
1191 	}
1192 	session_p->sign.flags |= CRYPTO_OPERATION_ACTIVE;
1193 	(void) pthread_mutex_unlock(&session_p->session_mutex);
1194 
1195 	for (i = 0; i < params->iterations; i++) {
1196 		/*
1197 		 * The key doesn't change, its always the
1198 		 * password iniitally given.
1199 		 */
1200 		rv = soft_sign_init(session_p, &digest_mech, hmac_key);
1201 
1202 		if (rv != CKR_OK) {
1203 			goto cleanup;
1204 		}
1205 
1206 		/* Call PRF function (SHA1_HMAC for now). */
1207 		rv = soft_sign(session_p, input, inlen, output, &hmac_outlen);
1208 
1209 		if (rv != CKR_OK) {
1210 			goto cleanup;
1211 		}
1212 		/*
1213 		 * The first time, initialize the output buffer
1214 		 * with the HMAC signature.
1215 		 */
1216 		if (i == 0) {
1217 			(void) memcpy(blockdata, output,
1218 			    local_min(blocklen, hmac_outlen));
1219 		} else {
1220 			/*
1221 			 * XOR the existing data with output from PRF.
1222 			 *
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.
1226 			 */
1227 			for (j = 0; j < hmac_outlen && j < blocklen; j++)
1228 				blockdata[j] ^= output[j];
1229 		}
1230 		/* Output from previous PRF is input for next round */
1231 		input = output;
1232 		inlen = hmac_outlen;
1233 
1234 		/*
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.
1239 		 */
1240 		output = buffer[i%2];
1241 	}
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);
1246 
1247 	return (rv);
1248 }
1249 
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)
1253 {
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];
1259 	/*
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.
1265 	 */
1266 	keytemplate[0].type = CKA_CLASS;
1267 	keytemplate[0].pValue = &keyclass;
1268 	keytemplate[0].ulValueLen =  sizeof (keyclass);
1269 
1270 	keytemplate[1].type = CKA_KEY_TYPE;
1271 	keytemplate[1].pValue = &keytype;
1272 	keytemplate[1].ulValueLen =  sizeof (keytype);
1273 
1274 	keytemplate[2].type = CKA_SIGN;
1275 	keytemplate[2].pValue = &True;
1276 	keytemplate[2].ulValueLen =  sizeof (True);
1277 
1278 	keytemplate[3].type = CKA_VALUE;
1279 	keytemplate[3].pValue = passwd;
1280 	keytemplate[3].ulValueLen = passwd_len;
1281 	/*
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.
1285 	 */
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);
1290 
1291 	return (rv);
1292 }
1293 
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)
1298 {
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;
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, &phKey);
1327 
1328 	if (rv != CKR_OK)
1329 		return (rv);
1330 
1331 	hmac_key = (soft_object_t *)phKey;
1332 
1333 	/* Step 1. */
1334 	dkLen = OBJ_SEC_VALUE_LEN(secret_key);  /* length of desired key */
1335 
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);
1340 	}
1341 
1342 	/* Step 2. */
1343 	blocks = dkLen / hLen;
1344 
1345 	/* crude "Ceiling" function to adjust the number of blocks to use */
1346 	if (blocks * hLen != dkLen)
1347 		blocks++;
1348 
1349 	remainder = dkLen - ((blocks - 1) * hLen);
1350 
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);
1357 	}
1358 	/*
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.
1362 	 */
1363 	if (params->pSaltSourceData != NULL && params->ulSaltSourceDataLen > 0)
1364 		(void) memcpy(salt, params->pSaltSourceData,
1365 		    params->ulSaltSourceDataLen);
1366 
1367 	/*
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.
1373 	 */
1374 	keydata = (CK_BYTE *)OBJ_SEC_VALUE(secret_key);
1375 
1376 	/* Step 4. */
1377 	for (i = 0; i < blocks && (rv == CKR_OK); i++) {
1378 		CK_BYTE *s;
1379 
1380 		s = salt + params->ulSaltSourceDataLen;
1381 
1382 		/*
1383 		 * Append the block index to the salt as input
1384 		 * to the PRF.  Block index should start at 1
1385 		 * not 0.
1386 		 */
1387 		*s++ = ((i+1) >> 24) & 0xff;
1388 		*s++ = ((i+1) >> 16) & 0xff;
1389 		*s++ = ((i+1) >> 8) & 0xff;
1390 		*s   = ((i+1)) & 0xff;
1391 
1392 		/*
1393 		 * Adjust the key pointer so we always append the
1394 		 * PRF output to the current key.
1395 		 */
1396 		rv = do_prf(session_p, params, hmac_key,
1397 		    salt, params->ulSaltSourceDataLen + 4, keydata,
1398 		    ((i + 1) == blocks ? remainder : hLen));
1399 
1400 		keydata += hLen;
1401 	}
1402 	(void) soft_delete_object(session_p, hmac_key, B_FALSE, B_FALSE);
1403 	free(salt);
1404 
1405 	return (rv);
1406 }
1407 
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)
1412 {
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 */
1419 
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:
1425 		/*
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.
1430 		 */
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:
1445 		/*
1446 		 * Unpadded secret key mechs and private key mechs are only
1447 		 * defined for wrapping secret keys.  See PKCS#11 refs above.
1448 		 */
1449 		if (hkey_p->class != CKO_SECRET_KEY)
1450 			return (CKR_MECHANISM_INVALID);
1451 		break;
1452 	default:
1453 		return (CKR_MECHANISM_INVALID);
1454 	}
1455 
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 {
1460 		/*
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.
1464 		 */
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;
1474 	}
1475 
1476 	/*
1477 	 * For unpadded ECB and CBC mechanisms, the object needs to be
1478 	 * padded to the wrapping key's blocksize prior to the encryption.
1479 	 */
1480 	padded_len = plain_len;
1481 	padded_data = plain_data;
1482 
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;
1507 			}
1508 		} else {
1509 			rv = CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
1510 			goto cleanup_wrap;
1511 		}
1512 
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;
1519 			}
1520 			(void) memset(padded_data, 0x0, padded_len);
1521 			(void) memcpy(padded_data, plain_data, plain_len);
1522 		}
1523 		break;
1524 	default:
1525 		break;
1526 	}
1527 
1528 	rv = soft_encrypt_init(session_p, pMechanism, wrappingKey_p);
1529 	if (rv != CKR_OK)
1530 		goto cleanup_wrap;
1531 
1532 	rv = soft_encrypt(session_p, padded_data, padded_len,
1533 	    pWrappedKey, pulWrappedKeyLen);
1534 
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);
1540 	}
1541 
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);
1546 	}
1547 
1548 	return (rv);
1549 }
1550 
1551 /*
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).
1555  */
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)
1559 {
1560 	CK_ULONG	i;
1561 	boolean_t	isValueLen = B_FALSE;
1562 
1563 	/*
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.
1576 	 */
1577 
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;
1584 		}
1585 	}
1586 
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:
1596 		/*
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
1600 		 */
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);
1617 		}
1618 		break;
1619 	default:
1620 		/* CKA_VALUE_LEN must not be specified */
1621 		if (isValueLen)
1622 			return (CKR_TEMPLATE_INCONSISTENT);
1623 		break;
1624 	}
1625 
1626 	return (CKR_OK);
1627 }
1628 
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)
1635 {
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;
1644 
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;
1652 			}
1653 		}
1654 		if (new_obj_class == ~0UL)
1655 			return (CKR_TEMPLATE_INCOMPLETE);
1656 	}
1657 
1658 	/*
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.
1662 	 */
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);
1685 	}
1686 
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);
1693 
1694 	/*
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.
1700 	 *
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.
1704 	 */
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;
1709 	}
1710 
1711 	rv = soft_decrypt_init(session_p, pMechanism, unwrappingkey_p);
1712 	if (rv != CKR_OK)
1713 		goto cleanup_unwrap;
1714 
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;
1720 
1721 	/* Allocate space for the unwrapped data */
1722 	if ((plain_data = malloc(plain_len)) == NULL) {
1723 		rv = CKR_HOST_MEMORY;
1724 		goto cleanup_unwrap;
1725 	}
1726 	(void) memset(plain_data, 0x0, plain_len);
1727 
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;
1733 
1734 	if (new_objp->class == CKO_SECRET_KEY) {
1735 		/*
1736 		 * Since no ASN.1 encoding is done for secret keys, check for
1737 		 * appropriateness and copy decrypted buffer to the key object.
1738 		 */
1739 
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;
1745 
1746 		/*
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.
1750 		 */
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;
1756 			}
1757 			OBJ_SEC(new_objp) = sck;
1758 		}
1759 
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;
1771 
1772 		/*
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.
1777 		 */
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;
1786 		};
1787 
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;
1806 			}
1807 		}
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;
1813 	}
1814 
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;
1821 	}
1822 
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);
1827 	}
1828 
1829 	*phKey = (CK_OBJECT_HANDLE)new_objp;
1830 
1831 	return (CKR_OK);
1832 
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);
1839 	}
1840 
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);
1846 
1847 	return (rv);
1848 }
1849