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