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