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