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