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