xref: /illumos-gate/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.c (revision 7f7322febbcfe774b7270abc3b191c094bfcc517)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <crypt.h>
30 #include <cryptoutil.h>
31 #include <pwd.h>
32 #include <pthread.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <strings.h>
36 #include <sys/types.h>
37 #include <sys/sysmacros.h>
38 #include <security/cryptoki.h>
39 #include "softGlobal.h"
40 #include "softCrypt.h"
41 #include "softSession.h"
42 #include "softObject.h"
43 #include "softKeys.h"
44 #include "softKeystore.h"
45 #include "softKeystoreUtil.h"
46 #include "softRandom.h"
47 #include "softMAC.h"
48 #include "softOps.h"
49 
50 soft_session_t token_session;
51 boolean_t soft_token_present = B_FALSE;
52 
53 
54 /*
55  * Generate a 16-byte Initialization Vector (IV).
56  */
57 CK_RV
58 soft_gen_iv(CK_BYTE *iv)
59 {
60 
61 	return (soft_nzero_random_generator(iv, 16));
62 
63 }
64 
65 
66 /*
67  * soft_gen_hashed_pin()
68  *
69  * Arguments:
70  *
71  *	pPin:	pointer to caller provided Pin
72  *	result:	output argument which contains the address of the
73  *		pointer to the hashed pin
74  *	salt:	input argument (if non-NULL), or
75  *		output argument (if NULL):
76  *		address of pointer to the "salt" of the hashed pin
77  *
78  * Description:
79  *
80  *	Generate a hashed pin using system provided crypt(3C) function.
81  *
82  * Returns:
83  *
84  *	0: no error
85  *	-1: some error occurred while generating the hashed pin
86  *
87  */
88 int
89 soft_gen_hashed_pin(CK_UTF8CHAR_PTR pPin, char **result, char **salt)
90 {
91 
92 	uid_t uid;
93 	struct passwd pwd, *pw;
94 	char pwdbuf[PWD_BUFFER_SIZE];
95 	boolean_t new_salt = B_FALSE;
96 
97 	/*
98 	 * We need to get the passwd entry of the application, which is required
99 	 * by the crypt_gensalt() below.
100 	 */
101 	uid = geteuid();
102 	if (getpwuid_r(uid, &pwd, pwdbuf, PWD_BUFFER_SIZE, &pw) != 0) {
103 		return (-1);
104 	}
105 
106 	if (*salt == NULL) {
107 		new_salt = B_TRUE;
108 		/*
109 		 * crypt_gensalt() will allocate memory to store the new salt.
110 		 * on return.
111 		 */
112 		if ((*salt = crypt_gensalt(NULL, pw)) == NULL) {
113 			return (-1);
114 		}
115 	}
116 
117 	if ((*result = crypt((char *)pPin, *salt)) == NULL) {
118 		if (new_salt)
119 			free(*salt);
120 		return (-1);
121 	}
122 
123 	return (0);
124 }
125 
126 /*
127  * Authenticate user's PIN for C_Login.
128  */
129 CK_RV
130 soft_verify_pin(CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
131 {
132 
133 	char	*user_cryptpin = NULL;
134 	char	*ks_cryptpin = NULL;
135 	char	*salt = NULL;
136 	uchar_t	*tmp_pin = NULL;
137 	boolean_t pin_initialized = B_FALSE;
138 	CK_RV	rv = CKR_OK;
139 
140 	/*
141 	 * Check to see if keystore is initialized.
142 	 */
143 	rv = soft_keystore_pin_initialized(&pin_initialized, &ks_cryptpin,
144 	    B_FALSE);
145 	if (rv != CKR_OK)
146 		return (rv);
147 
148 	/*
149 	 * Authenticate user's PIN for C_Login.
150 	 */
151 	if (pin_initialized) {
152 
153 		if (soft_keystore_get_pin_salt(&salt) < 0) {
154 			rv = CKR_FUNCTION_FAILED;
155 			goto cleanup;
156 		}
157 
158 		/*
159 		 * Generate the hashed value based on the user's supplied pin.
160 		 */
161 		tmp_pin = malloc(ulPinLen + 1);
162 		if (tmp_pin == NULL) {
163 			rv = CKR_HOST_MEMORY;
164 			goto cleanup;
165 		}
166 
167 		(void) memcpy(tmp_pin, pPin, ulPinLen);
168 		tmp_pin[ulPinLen] = '\0';
169 
170 		if (soft_gen_hashed_pin(tmp_pin, &user_cryptpin, &salt) < 0) {
171 			rv = CKR_FUNCTION_FAILED;
172 			goto cleanup;
173 		}
174 
175 		/*
176 		 * Compare hash value of the user supplied PIN with
177 		 * hash value of the keystore PIN.
178 		 */
179 		if (strcmp(user_cryptpin, ks_cryptpin) != 0) {
180 			rv = CKR_PIN_INCORRECT;
181 			goto cleanup;
182 		}
183 
184 		/*
185 		 * Provide the user's PIN to low-level keystore so that
186 		 * it can use it to generate encryption key as needed for
187 		 * encryption/decryption of the private objects in
188 		 * keystore.
189 		 */
190 		if (soft_keystore_authpin(tmp_pin) != 0) {
191 			rv = CKR_FUNCTION_FAILED;
192 		} else {
193 			rv = CKR_OK;
194 		}
195 		goto cleanup;
196 	} else {
197 		/*
198 		 * The PIN is not initialized in the keystore
199 		 * We will let it pass the authentication anyway but set the
200 		 * "userpin_change_needed" flag so that the application
201 		 * will get CKR_PIN_EXPIRED by other C_functions such as
202 		 * C_CreateObject, C_FindObjectInit, C_GenerateKey etc.
203 		 */
204 		soft_slot.userpin_change_needed = 1;
205 		rv = CKR_OK;
206 	}
207 
208 cleanup:
209 	if (salt)
210 		free(salt);
211 	if (tmp_pin)
212 		free(tmp_pin);
213 	if (ks_cryptpin)
214 		free(ks_cryptpin);
215 
216 	return (rv);
217 }
218 
219 /*
220  * The second level C_SetPIN function.
221  */
222 CK_RV
223 soft_setpin(CK_UTF8CHAR_PTR pOldPin, CK_ULONG ulOldPinLen,
224     CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewPinLen)
225 {
226 
227 	char	*user_cryptpin = NULL;
228 	char	*ks_cryptpin = NULL;
229 	char	*salt = NULL;
230 	boolean_t pin_initialized = B_FALSE;
231 	uchar_t	*tmp_old_pin = NULL, *tmp_new_pin = NULL;
232 	CK_RV	rv = CKR_OK;
233 
234 	/*
235 	 * Check to see if keystore is initialized.
236 	 */
237 	rv = soft_keystore_pin_initialized(&pin_initialized, &ks_cryptpin,
238 	    B_FALSE);
239 	if (rv != CKR_OK)
240 		return (rv);
241 
242 	/*
243 	 * Authenticate user's PIN for C_SetPIN.
244 	 */
245 	if (pin_initialized) {
246 		/*
247 		 * Generate the hashed value based on the user supplied PIN.
248 		 */
249 		if (soft_keystore_get_pin_salt(&salt) < 0) {
250 			rv = CKR_FUNCTION_FAILED;
251 			goto cleanup;
252 		}
253 
254 		tmp_old_pin = malloc(ulOldPinLen + 1);
255 		if (tmp_old_pin == NULL) {
256 			rv = CKR_HOST_MEMORY;
257 			goto cleanup;
258 		}
259 		(void) memcpy(tmp_old_pin, pOldPin, ulOldPinLen);
260 		tmp_old_pin[ulOldPinLen] = '\0';
261 
262 		if (soft_gen_hashed_pin(tmp_old_pin, &user_cryptpin,
263 		    &salt) < 0) {
264 			rv = CKR_FUNCTION_FAILED;
265 			goto cleanup;
266 		}
267 
268 		/*
269 		 * Compare hashed value of the user supplied PIN with the
270 		 * hashed value of the keystore PIN.
271 		 */
272 		if (strcmp(user_cryptpin, ks_cryptpin) != 0) {
273 			rv = CKR_PIN_INCORRECT;
274 			goto cleanup;
275 		}
276 	} else {
277 		/*
278 		 * This is the first time to setpin, the oldpin must be
279 		 * "changeme".
280 		 */
281 		if (strncmp("changeme", (const char *)pOldPin,
282 		    ulOldPinLen) != 0) {
283 			rv = CKR_PIN_INCORRECT;
284 			goto cleanup;
285 		}
286 	}
287 
288 	tmp_new_pin = malloc(ulNewPinLen + 1);
289 	if (tmp_new_pin == NULL) {
290 		rv = CKR_HOST_MEMORY;
291 		goto cleanup;
292 	}
293 	(void) memcpy(tmp_new_pin, pNewPin, ulNewPinLen);
294 	tmp_new_pin[ulNewPinLen] = '\0';
295 
296 	/*
297 	 * Set the new pin after the old pin is authenticated.
298 	 */
299 	if (soft_keystore_setpin(tmp_old_pin, tmp_new_pin, B_FALSE)) {
300 		rv = CKR_FUNCTION_FAILED;
301 		goto cleanup;
302 	} else {
303 		(void) pthread_mutex_lock(&soft_giant_mutex);
304 		soft_slot.userpin_change_needed = 0;
305 		(void) pthread_mutex_unlock(&soft_giant_mutex);
306 		rv = CKR_OK;
307 	}
308 
309 cleanup:
310 	if (salt)
311 		free(salt);
312 	if (ks_cryptpin)
313 		free(ks_cryptpin);
314 	if (tmp_old_pin)
315 		free(tmp_old_pin);
316 	if (tmp_new_pin)
317 		free(tmp_new_pin);
318 
319 	return (rv);
320 }
321 
322 /*
323  * soft_keystore_pack_obj()
324  *
325  * Arguments:
326  *
327  *	obj:	pointer to the soft_object_t of the token object to
328  *		be packed
329  *	ks_buf:	output argument which contains the address of the
330  *		pointer to the buf of the packed token object
331  *		soft_keystore_pack_obj() will allocate memory for the buf,
332  *		it is caller's responsibility to free it.
333  *	len:	output argument which contains the address of the
334  *		buffer length of the packed token object
335  *
336  * Description:
337  *
338  *	Pack the in-core token object into the keystore format.
339  *
340  * Returns:
341  *
342  *	CKR_OK: no error
343  *	Other: some error occurred while packing the object
344  *
345  */
346 CK_RV
347 soft_keystore_pack_obj(soft_object_t *obj, uchar_t **ks_buf, size_t *len)
348 {
349 	ks_obj_hdr_t hdr;
350 	ks_attr_hdr_t attr_hdr;
351 	CK_ATTRIBUTE_INFO_PTR extra_attr;
352 	int num_attrs = 0;
353 	ulong_t len_attrs = 0;
354 	size_t ks_len;
355 	uchar_t *buf, *buf1;
356 	CK_RV rv;
357 	int i;
358 
359 	(void) memset(&hdr, 0, sizeof (ks_obj_hdr_t));
360 
361 	/*
362 	 * The first part of the packed format contains
363 	 * the ks_obj_hdr_t struct.
364 	 */
365 	hdr.class = SWAP64((uint64_t)obj->class);
366 	hdr.key_type = SWAP64((uint64_t)obj->key_type);
367 	hdr.cert_type = SWAP64((uint64_t)obj->cert_type);
368 	hdr.bool_attr_mask = SWAP64(obj->bool_attr_mask);
369 	hdr.mechanism = SWAP64((uint64_t)obj->mechanism);
370 	hdr.object_type = obj->object_type;
371 
372 	/*
373 	 * The second part of the packed format contains
374 	 * the attributes from the extra atrribute list.
375 	 */
376 	extra_attr = obj->extra_attrlistp;
377 
378 	while (extra_attr) {
379 		num_attrs++;
380 		len_attrs += ROUNDUP(extra_attr->attr.ulValueLen, 8);
381 		extra_attr = extra_attr->next;
382 	}
383 	hdr.num_attrs = SWAP32(num_attrs);
384 	ks_len = soft_pack_object_size(obj);
385 	ks_len += sizeof (ks_obj_hdr_t) + len_attrs +
386 	    2 * num_attrs * sizeof (uint64_t);
387 	buf = calloc(1, ks_len);
388 	if (buf == NULL) {
389 		return (CKR_HOST_MEMORY);
390 	}
391 	(void) memcpy(buf, &hdr, sizeof (ks_obj_hdr_t));
392 	buf1 = buf + sizeof (ks_obj_hdr_t);
393 	extra_attr = obj->extra_attrlistp;
394 	for (i = 0; i < num_attrs; i++) {
395 		attr_hdr.type = SWAP64((uint64_t)extra_attr->attr.type);
396 		attr_hdr.ulValueLen =
397 		    SWAP64((uint64_t)extra_attr->attr.ulValueLen);
398 		(void) memcpy(buf1, &attr_hdr, sizeof (ks_attr_hdr_t));
399 		buf1 = buf1 + sizeof (ks_attr_hdr_t);
400 		(void) memcpy(buf1, extra_attr->attr.pValue,
401 		    extra_attr->attr.ulValueLen);
402 		buf1 = buf1 + ROUNDUP(extra_attr->attr.ulValueLen, 8);
403 		extra_attr = extra_attr->next;
404 	}
405 
406 	/*
407 	 * The third part of the packed format contains
408 	 * the key itself.
409 	 */
410 	rv = soft_pack_object(obj, buf1);
411 	*len = ks_len;
412 	*ks_buf = buf;
413 
414 	return (rv);
415 
416 }
417 
418 /*
419  * soft_keystore_unpack_obj()
420  *
421  * Arguments:
422  *
423  *	obj:	pointer to the soft_object_t to store the unpacked
424  *		token object
425  *	ks_obj:	input argument which contains the pointer to the
426  *		ks_obj_t struct of packed token object to be unpacked
427  *
428  * Description:
429  *
430  *	Unpack the token object in keystore format to in-core soft_object_t.
431  *
432  * Returns:
433  *
434  *	CKR_OK: no error
435  *	Other: some error occurred while unpacking the object
436  *
437  */
438 CK_RV
439 soft_keystore_unpack_obj(soft_object_t *obj, ks_obj_t *ks_obj)
440 {
441 
442 	CK_RV rv;
443 	ks_obj_hdr_t *hdr;
444 	ks_attr_hdr_t *attr_hdr;
445 	CK_ATTRIBUTE template;
446 	int i;
447 	uchar_t *buf;
448 
449 	/*
450 	 * Unpack the common area.
451 	 */
452 	(void) strcpy((char *)obj->ks_handle.name,
453 	    (char *)ks_obj->ks_handle.name);
454 	obj->ks_handle.public = ks_obj->ks_handle.public;
455 	/* LINTED: pointer alignment */
456 	hdr = (ks_obj_hdr_t *)ks_obj->buf;
457 	obj->version = ks_obj->obj_version;
458 	obj->class = (CK_OBJECT_CLASS)(SWAP64(hdr->class));
459 	obj->key_type = (CK_KEY_TYPE)(SWAP64(hdr->key_type));
460 	obj->cert_type = (CK_CERTIFICATE_TYPE)(SWAP64(hdr->cert_type));
461 	obj->bool_attr_mask = SWAP64(hdr->bool_attr_mask);
462 	obj->mechanism = (CK_MECHANISM_TYPE)(SWAP64(hdr->mechanism));
463 	obj->object_type = hdr->object_type;
464 
465 	/*
466 	 * Initialize other stuffs which were not from keystore.
467 	 */
468 	(void) pthread_mutex_init(&obj->object_mutex, NULL);
469 	obj->magic_marker = SOFTTOKEN_OBJECT_MAGIC;
470 	obj->session_handle = (CK_SESSION_HANDLE)NULL;
471 
472 	buf = ks_obj->buf + sizeof (ks_obj_hdr_t);
473 
474 	/*
475 	 * Unpack extra attribute list.
476 	 */
477 	for (i = 0; i < SWAP32(hdr->num_attrs); i++) {
478 		/* LINTED: pointer alignment */
479 		attr_hdr = (ks_attr_hdr_t *)buf;
480 		(void) memset(&template, 0, sizeof (CK_ATTRIBUTE));
481 		template.type = (CK_ATTRIBUTE_TYPE)(SWAP64(attr_hdr->type));
482 		template.ulValueLen = (CK_ULONG)(SWAP64(attr_hdr->ulValueLen));
483 		buf = buf + sizeof (ks_attr_hdr_t);
484 		/* Allocate storage for the value of the attribute. */
485 		if (template.ulValueLen > 0) {
486 			template.pValue = malloc(template.ulValueLen);
487 			if (template.pValue == NULL) {
488 				return (CKR_HOST_MEMORY);
489 			}
490 			(void) memcpy(template.pValue, buf,
491 			    template.ulValueLen);
492 		}
493 
494 		rv = soft_add_extra_attr(&template, obj);
495 		if (template.pValue) {
496 			free(template.pValue);
497 		}
498 
499 		if (rv != CKR_OK) {
500 			return (rv);
501 		}
502 
503 		buf = buf + ROUNDUP(template.ulValueLen, 8);
504 	}
505 
506 	/*
507 	 * Unpack the key itself.
508 	 */
509 	rv = soft_unpack_object(obj, buf);
510 	return (rv);
511 
512 }
513 
514 
515 /*
516  * soft_unpack_obj_attribute()
517  *
518  * Arguments:
519  *
520  *	buf:	contains the packed data (attributes) from keystore
521  *	key_dest: the key attribute will be unpacked and save in key_dest
522  *	cert_dest: the certificate attribute will be unpacked an
523  *		   in cert_dest
524  *	offset: length of the current attribute occupies.
525  *		The caller should use this returned "offset" to
526  *		advance the buffer pointer to next attribute.
527  *	cert:	TRUE for certificate (use cert_dest)
528  *		FALSE for key (use key_dest)
529  *
530  * Description:
531  *
532  *	Unpack the attribute from keystore format to the big integer format.
533  *
534  * Returns:
535  *
536  *	CKR_OK: no error
537  *	Other: some error occurred while unpacking the object attribute
538  *
539  */
540 CK_RV
541 soft_unpack_obj_attribute(uchar_t *buf, biginteger_t *key_dest,
542     cert_attr_t **cert_dest, ulong_t *offset, boolean_t cert)
543 {
544 
545 	CK_RV rv;
546 	CK_ATTRIBUTE template;
547 
548 	/* LINTED: pointer alignment */
549 	template.ulValueLen = SWAP64(*(uint64_t *)buf);
550 	buf = buf + sizeof (uint64_t);
551 	template.pValue = malloc(template.ulValueLen);
552 	if (template.pValue == NULL) {
553 		return (CKR_HOST_MEMORY);
554 	}
555 
556 	(void) memcpy(template.pValue, buf, template.ulValueLen);
557 	if (cert) {
558 		rv = get_cert_attr_from_template(cert_dest, &template);
559 	} else {
560 		rv = get_bigint_attr_from_template(key_dest, &template);
561 	}
562 
563 	free(template.pValue);
564 	if (rv != CKR_OK) {
565 		return (rv);
566 	}
567 
568 	*offset = sizeof (uint64_t) + template.ulValueLen;
569 	return (CKR_OK);
570 }
571 
572 
573 /*
574  * Calculate the total buffer length required to store the
575  * object key (the third part) in a keystore format.
576  */
577 ulong_t
578 soft_pack_object_size(soft_object_t *objp)
579 {
580 
581 	CK_OBJECT_CLASS class = objp->class;
582 	CK_KEY_TYPE	keytype = objp->key_type;
583 	CK_CERTIFICATE_TYPE certtype = objp->cert_type;
584 
585 	switch (class) {
586 	case CKO_PUBLIC_KEY:
587 		switch (keytype) {
588 		case CKK_RSA:
589 			/*
590 			 * modulus_bits + modulus_len + modulus +
591 			 * pubexpo_len + pubexpo
592 			 */
593 			return (ROUNDUP(((biginteger_t *)
594 			    OBJ_PUB_RSA_MOD(objp))->big_value_len, 8) +
595 			    ROUNDUP(((biginteger_t *)
596 			    OBJ_PUB_RSA_PUBEXPO(objp))->big_value_len, 8) +
597 			    3 * sizeof (uint64_t));
598 
599 		case CKK_DSA:
600 			/*
601 			 * prime_len + prime + subprime_len + subprime +
602 			 * base_len + base + value_len + value
603 			 */
604 			return (ROUNDUP(((biginteger_t *)
605 			    OBJ_PUB_DSA_PRIME(objp))->big_value_len, 8) +
606 			    ROUNDUP(((biginteger_t *)
607 			    OBJ_PUB_DSA_SUBPRIME(objp))->big_value_len, 8) +
608 			    ROUNDUP(((biginteger_t *)
609 			    OBJ_PUB_DSA_BASE(objp))->big_value_len, 8) +
610 			    ROUNDUP(((biginteger_t *)
611 			    OBJ_PUB_DSA_VALUE(objp))->big_value_len, 8) +
612 			    4 * sizeof (uint64_t));
613 
614 		case CKK_DH:
615 			/*
616 			 * prime_len + prime + base_len + base +
617 			 * value_len + value
618 			 */
619 			return (ROUNDUP(((biginteger_t *)
620 			    OBJ_PUB_DH_PRIME(objp))->big_value_len, 8) +
621 			    ROUNDUP(((biginteger_t *)
622 			    OBJ_PUB_DH_BASE(objp))->big_value_len, 8) +
623 			    ROUNDUP(((biginteger_t *)
624 			    OBJ_PUB_DH_VALUE(objp))->big_value_len, 8) +
625 			    3 * sizeof (uint64_t));
626 
627 		case CKK_X9_42_DH:
628 			/*
629 			 * prime_len + prime + base_len + base +
630 			 * subprime_len + subprime + value_len + value
631 			 */
632 			return (ROUNDUP(((biginteger_t *)
633 			    OBJ_PUB_DH942_PRIME(objp))->big_value_len, 8) +
634 			    ROUNDUP(((biginteger_t *)
635 			    OBJ_PUB_DH942_BASE(objp))->big_value_len, 8) +
636 			    ROUNDUP(((biginteger_t *)
637 			    OBJ_PUB_DH942_SUBPRIME(objp))->big_value_len, 8) +
638 			    ROUNDUP(((biginteger_t *)
639 			    OBJ_PUB_DH942_VALUE(objp))->big_value_len, 8) +
640 			    4 * sizeof (uint64_t));
641 		} /* keytype */
642 
643 		break;
644 
645 	case CKO_PRIVATE_KEY:
646 		switch (keytype) {
647 		case CKK_RSA:
648 			/*
649 			 * modulus_len + modulus + pubexpo_len + pubexpo +
650 			 * priexpo_len + priexpo + prime1_len + prime1 +
651 			 * prime2_len + prime2 + expo1_len + expo1 +
652 			 * expo2_len + expo2 + coef_len + coef
653 			 */
654 			return (ROUNDUP(((biginteger_t *)
655 			    OBJ_PRI_RSA_MOD(objp))->big_value_len, 8) +
656 			    ROUNDUP(((biginteger_t *)
657 			    OBJ_PRI_RSA_PUBEXPO(objp))->big_value_len, 8) +
658 			    ROUNDUP(((biginteger_t *)
659 			    OBJ_PRI_RSA_PRIEXPO(objp))->big_value_len, 8) +
660 			    ROUNDUP(((biginteger_t *)
661 			    OBJ_PRI_RSA_PRIME1(objp))->big_value_len, 8) +
662 			    ROUNDUP(((biginteger_t *)
663 			    OBJ_PRI_RSA_PRIME2(objp))->big_value_len, 8) +
664 			    ROUNDUP(((biginteger_t *)
665 			    OBJ_PRI_RSA_EXPO1(objp))->big_value_len, 8) +
666 			    ROUNDUP(((biginteger_t *)
667 			    OBJ_PRI_RSA_EXPO2(objp))->big_value_len, 8) +
668 			    ROUNDUP(((biginteger_t *)
669 			    OBJ_PRI_RSA_COEF(objp))->big_value_len, 8) +
670 			    8 * sizeof (uint64_t));
671 
672 		case CKK_DSA:
673 			/*
674 			 * prime_len + prime + subprime_len + subprime +
675 			 * base_len + base + value_len + value
676 			 */
677 			return (ROUNDUP(((biginteger_t *)
678 			    OBJ_PRI_DSA_PRIME(objp))->big_value_len, 8) +
679 			    ROUNDUP(((biginteger_t *)
680 			    OBJ_PRI_DSA_SUBPRIME(objp))->big_value_len, 8) +
681 			    ROUNDUP(((biginteger_t *)
682 			    OBJ_PRI_DSA_BASE(objp))->big_value_len, 8) +
683 			    ROUNDUP(((biginteger_t *)
684 			    OBJ_PRI_DSA_VALUE(objp))->big_value_len, 8) +
685 			    4 * sizeof (uint64_t));
686 
687 		case CKK_DH:
688 			/*
689 			 * value_bits + prime_len + prime + base_len + base +
690 			 * value_len + value
691 			 */
692 			return (ROUNDUP(((biginteger_t *)
693 			    OBJ_PRI_DH_PRIME(objp))->big_value_len, 8) +
694 			    ROUNDUP(((biginteger_t *)
695 			    OBJ_PRI_DH_BASE(objp))->big_value_len, 8) +
696 			    ROUNDUP(((biginteger_t *)
697 			    OBJ_PRI_DH_VALUE(objp))->big_value_len, 8) +
698 			    4 * sizeof (uint64_t));
699 
700 		case CKK_X9_42_DH:
701 			/*
702 			 * prime_len + prime + base_len + base +
703 			 * subprime_len + subprime + value_len + value
704 			 */
705 			return (ROUNDUP(((biginteger_t *)
706 			    OBJ_PRI_DH942_PRIME(objp))->big_value_len, 8) +
707 			    ROUNDUP(((biginteger_t *)
708 			    OBJ_PRI_DH942_BASE(objp))->big_value_len, 8) +
709 			    ROUNDUP(((biginteger_t *)
710 			    OBJ_PRI_DH942_SUBPRIME(objp))->big_value_len, 8) +
711 			    ROUNDUP(((biginteger_t *)
712 			    OBJ_PRI_DH942_VALUE(objp))->big_value_len, 8) +
713 			    4 * sizeof (uint64_t));
714 
715 		} /* keytype */
716 
717 		break;
718 
719 	case CKO_SECRET_KEY:
720 		/*
721 		 * value_len + value
722 		 */
723 		return (ROUNDUP(OBJ_SEC_VALUE_LEN(objp), 8) +
724 			sizeof (uint64_t));
725 
726 	case CKO_CERTIFICATE:
727 		switch (certtype) {
728 		case CKC_X_509:
729 			/*
730 			 * subject_len + subject + value_len + value
731 			 */
732 			return (ROUNDUP(((cert_attr_t *)
733 				X509_CERT_SUBJECT(objp))->length, 8) +
734 				ROUNDUP(((cert_attr_t *)
735 				X509_CERT_VALUE(objp))->length, 8) +
736 				2 * sizeof (uint64_t));
737 
738 		case CKC_X_509_ATTR_CERT:
739 			/*
740 			 * owner_len + owner + value_len + value
741 			 */
742 			return (ROUNDUP(((cert_attr_t *)
743 				X509_ATTR_CERT_OWNER(objp))->length, 8) +
744 				ROUNDUP(((cert_attr_t *)
745 				X509_ATTR_CERT_VALUE(objp))->length, 8) +
746 				2 * sizeof (uint64_t));
747 		}
748 		return (0);
749 
750 	case CKO_DOMAIN_PARAMETERS:
751 
752 		return (0);
753 	}
754 	return (0);
755 }
756 
757 /*
758  * Pack the object key (the third part) from the soft_object_t
759  * into the keystore format.
760  */
761 CK_RV
762 soft_pack_object(soft_object_t *objp, uchar_t *buf)
763 {
764 
765 	CK_OBJECT_CLASS class = objp->class;
766 	CK_KEY_TYPE	keytype = objp->key_type;
767 	CK_CERTIFICATE_TYPE certtype = objp->cert_type;
768 	uint64_t tmp_val;
769 
770 	switch (class) {
771 	case CKO_PUBLIC_KEY:
772 		switch (keytype) {
773 		case CKK_RSA:
774 			/* modulus_bits */
775 			tmp_val = SWAP64((uint64_t)OBJ_PUB_RSA_MOD_BITS(objp));
776 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
777 			buf = buf + sizeof (uint64_t);
778 
779 			/* modulus_len + modulus */
780 			tmp_val = SWAP64((uint64_t)(((biginteger_t *)
781 			    OBJ_PUB_RSA_MOD(objp))->big_value_len));
782 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
783 			buf = buf + sizeof (uint64_t);
784 
785 			(void) memcpy(buf, (char *)(((biginteger_t *)
786 			    OBJ_PUB_RSA_MOD(objp))->big_value),
787 			    ((biginteger_t *)
788 			    OBJ_PUB_RSA_MOD(objp))->big_value_len);
789 			buf = buf + ROUNDUP(((biginteger_t *)
790 			    OBJ_PUB_RSA_MOD(objp))->big_value_len, 8);
791 
792 			/* pubexpo_len + pubexpo */
793 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
794 			    OBJ_PUB_RSA_PUBEXPO(objp))->big_value_len);
795 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
796 			buf = buf + sizeof (uint64_t);
797 
798 			(void) memcpy(buf, (char *)(((biginteger_t *)
799 			    OBJ_PUB_RSA_PUBEXPO(objp))->big_value),
800 			    ((biginteger_t *)
801 			    OBJ_PUB_RSA_PUBEXPO(objp))->big_value_len);
802 			break;
803 
804 		case CKK_DSA:
805 			/* prime_len + prime */
806 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
807 			    OBJ_PUB_DSA_PRIME(objp))->big_value_len);
808 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
809 			buf = buf + sizeof (uint64_t);
810 
811 			(void) memcpy(buf, (char *)((biginteger_t *)
812 			    OBJ_PUB_DSA_PRIME(objp))->big_value,
813 			    ((biginteger_t *)
814 			    OBJ_PUB_DSA_PRIME(objp))->big_value_len);
815 			buf = buf + ROUNDUP(((biginteger_t *)
816 			    OBJ_PUB_DSA_PRIME(objp))->big_value_len, 8);
817 
818 			/* subprime_len + subprime */
819 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
820 			    OBJ_PUB_DSA_SUBPRIME(objp))->big_value_len);
821 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
822 			buf = buf + sizeof (uint64_t);
823 
824 			(void) memcpy(buf, (char *)((biginteger_t *)
825 			    OBJ_PUB_DSA_SUBPRIME(objp))->big_value,
826 			    ((biginteger_t *)
827 			    OBJ_PUB_DSA_SUBPRIME(objp))->big_value_len);
828 			buf = buf + ROUNDUP(((biginteger_t *)
829 			    OBJ_PUB_DSA_SUBPRIME(objp))->big_value_len, 8);
830 
831 			/* base_len + base */
832 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
833 			    OBJ_PUB_DSA_BASE(objp))->big_value_len);
834 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
835 			buf = buf + sizeof (uint64_t);
836 
837 			(void) memcpy(buf, (char *)((biginteger_t *)
838 			    OBJ_PUB_DSA_BASE(objp))->big_value,
839 			    ((biginteger_t *)
840 			    OBJ_PUB_DSA_BASE(objp))->big_value_len);
841 			buf = buf + ROUNDUP(((biginteger_t *)
842 			    OBJ_PUB_DSA_BASE(objp))->big_value_len, 8);
843 
844 			/* value_len + value */
845 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
846 			    OBJ_PUB_DSA_VALUE(objp))->big_value_len);
847 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
848 			buf = buf + sizeof (uint64_t);
849 
850 			(void) memcpy(buf, (char *)((biginteger_t *)
851 			    OBJ_PUB_DSA_VALUE(objp))->big_value,
852 			    ((biginteger_t *)
853 			    OBJ_PUB_DSA_VALUE(objp))->big_value_len);
854 
855 			break;
856 
857 		case CKK_DH:
858 			/* prime_len + prime */
859 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
860 			    OBJ_PUB_DH_PRIME(objp))->big_value_len);
861 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
862 			buf = buf + sizeof (uint64_t);
863 
864 			(void) memcpy(buf, (char *)((biginteger_t *)
865 			    OBJ_PUB_DH_PRIME(objp))->big_value,
866 			    ((biginteger_t *)
867 			    OBJ_PUB_DH_PRIME(objp))->big_value_len);
868 			buf = buf + ROUNDUP(((biginteger_t *)
869 			    OBJ_PUB_DH_PRIME(objp))->big_value_len, 8);
870 
871 			/* base_len + base */
872 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
873 			    OBJ_PUB_DH_BASE(objp))->big_value_len);
874 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
875 			buf = buf + sizeof (uint64_t);
876 
877 			(void) memcpy(buf, (char *)((biginteger_t *)
878 			    OBJ_PUB_DH_BASE(objp))->big_value,
879 			    ((biginteger_t *)
880 			    OBJ_PUB_DH_BASE(objp))->big_value_len);
881 			buf = buf + ROUNDUP(((biginteger_t *)
882 			    OBJ_PUB_DH_BASE(objp))->big_value_len, 8);
883 
884 			/* value_len + value */
885 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
886 			    OBJ_PUB_DH_VALUE(objp))->big_value_len);
887 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
888 			buf = buf + sizeof (uint64_t);
889 
890 			(void) memcpy(buf, (char *)((biginteger_t *)
891 			    OBJ_PUB_DH_VALUE(objp))->big_value,
892 			    ((biginteger_t *)
893 			    OBJ_PUB_DH_VALUE(objp))->big_value_len);
894 
895 			break;
896 
897 		case CKK_X9_42_DH:
898 			/* prime_len +  prime */
899 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
900 			    OBJ_PUB_DH942_PRIME(objp))->big_value_len);
901 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
902 			buf = buf + sizeof (uint64_t);
903 
904 			(void) memcpy(buf, (char *)((biginteger_t *)
905 			    OBJ_PUB_DH942_PRIME(objp))->big_value,
906 			    ((biginteger_t *)
907 			    OBJ_PUB_DH942_PRIME(objp))->big_value_len);
908 			buf = buf + ROUNDUP(((biginteger_t *)
909 			    OBJ_PUB_DH942_PRIME(objp))->big_value_len, 8);
910 
911 			/* base_len + base */
912 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
913 			    OBJ_PUB_DH942_BASE(objp))->big_value_len);
914 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
915 			buf = buf + sizeof (uint64_t);
916 
917 			(void) memcpy(buf, (char *)((biginteger_t *)
918 			    OBJ_PUB_DH942_BASE(objp))->big_value,
919 			    ((biginteger_t *)
920 			    OBJ_PUB_DH942_BASE(objp))->big_value_len);
921 			buf = buf + ROUNDUP(((biginteger_t *)
922 			    OBJ_PUB_DH942_BASE(objp))->big_value_len, 8);
923 
924 			/* subprime_len + subprime */
925 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
926 			    OBJ_PUB_DH942_SUBPRIME(objp))->big_value_len);
927 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
928 			buf = buf + sizeof (uint64_t);
929 
930 			(void) memcpy(buf, (char *)((biginteger_t *)
931 			    OBJ_PUB_DH942_SUBPRIME(objp))->big_value,
932 			    ((biginteger_t *)
933 			    OBJ_PUB_DH942_SUBPRIME(objp))->big_value_len);
934 			buf = buf + ROUNDUP(((biginteger_t *)
935 			    OBJ_PUB_DH942_SUBPRIME(objp))->big_value_len, 8);
936 
937 			/* value_len + value */
938 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
939 			    OBJ_PUB_DH942_VALUE(objp))->big_value_len);
940 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
941 			buf = buf + sizeof (uint64_t);
942 
943 			(void) memcpy(buf, (char *)((biginteger_t *)
944 			    OBJ_PUB_DH942_VALUE(objp))->big_value,
945 			    ((biginteger_t *)
946 			    OBJ_PUB_DH942_VALUE(objp))->big_value_len);
947 
948 			break;
949 		} /* keytype */
950 
951 		break;
952 
953 	case CKO_PRIVATE_KEY:
954 		switch (keytype) {
955 		case CKK_RSA:
956 			/* modulus_len + modulus */
957 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
958 			    OBJ_PRI_RSA_MOD(objp))->big_value_len);
959 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
960 			buf = buf + sizeof (uint64_t);
961 
962 			(void) memcpy(buf, (char *)((biginteger_t *)
963 			    OBJ_PRI_RSA_MOD(objp))->big_value,
964 			    ((biginteger_t *)
965 			    OBJ_PRI_RSA_MOD(objp))->big_value_len);
966 			buf = buf + ROUNDUP(((biginteger_t *)
967 			    OBJ_PRI_RSA_MOD(objp))->big_value_len, 8);
968 
969 			/* pubexpo_len + pubexpo */
970 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
971 			    OBJ_PRI_RSA_PUBEXPO(objp))->big_value_len);
972 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
973 			buf = buf + sizeof (uint64_t);
974 
975 			(void) memcpy(buf, (char *)((biginteger_t *)
976 			    OBJ_PRI_RSA_PUBEXPO(objp))->big_value,
977 			    ((biginteger_t *)
978 			    OBJ_PRI_RSA_PUBEXPO(objp))->big_value_len);
979 			buf = buf + ROUNDUP(((biginteger_t *)
980 			    OBJ_PRI_RSA_PUBEXPO(objp))->big_value_len, 8);
981 
982 			/* priexpo_len + priexpo */
983 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
984 			    OBJ_PRI_RSA_PRIEXPO(objp))->big_value_len);
985 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
986 			buf = buf + sizeof (uint64_t);
987 
988 			(void) memcpy(buf, (char *)((biginteger_t *)
989 			    OBJ_PRI_RSA_PRIEXPO(objp))->big_value,
990 			    ((biginteger_t *)
991 			    OBJ_PRI_RSA_PRIEXPO(objp))->big_value_len);
992 			buf = buf + ROUNDUP(((biginteger_t *)
993 			    OBJ_PRI_RSA_PRIEXPO(objp))->big_value_len, 8);
994 
995 			/* prime1_len + prime1 */
996 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
997 			    OBJ_PRI_RSA_PRIME1(objp))->big_value_len);
998 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
999 			buf = buf + sizeof (uint64_t);
1000 
1001 			(void) memcpy(buf, (char *)((biginteger_t *)
1002 			    OBJ_PRI_RSA_PRIME1(objp))->big_value,
1003 			    ((biginteger_t *)
1004 			    OBJ_PRI_RSA_PRIME1(objp))->big_value_len);
1005 			buf = buf + ROUNDUP(((biginteger_t *)
1006 			    OBJ_PRI_RSA_PRIME1(objp))->big_value_len, 8);
1007 
1008 			/* prime2_len + prime2 */
1009 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1010 			    OBJ_PRI_RSA_PRIME2(objp))->big_value_len);
1011 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1012 			buf = buf + sizeof (uint64_t);
1013 
1014 			(void) memcpy(buf, (char *)((biginteger_t *)
1015 			    OBJ_PRI_RSA_PRIME2(objp))->big_value,
1016 			    ((biginteger_t *)
1017 			    OBJ_PRI_RSA_PRIME2(objp))->big_value_len);
1018 			buf = buf + ROUNDUP(((biginteger_t *)
1019 			    OBJ_PRI_RSA_PRIME2(objp))->big_value_len, 8);
1020 
1021 			/* expo1_len + expo1 */
1022 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1023 			    OBJ_PRI_RSA_EXPO1(objp))->big_value_len);
1024 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1025 			buf = buf + sizeof (uint64_t);
1026 
1027 			(void) memcpy(buf, (char *)((biginteger_t *)
1028 			    OBJ_PRI_RSA_EXPO1(objp))->big_value,
1029 			    ((biginteger_t *)
1030 			    OBJ_PRI_RSA_EXPO1(objp))->big_value_len);
1031 			buf = buf + ROUNDUP(((biginteger_t *)
1032 			    OBJ_PRI_RSA_EXPO1(objp))->big_value_len, 8);
1033 
1034 			/* expo2_len + expo2 */
1035 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1036 			    OBJ_PRI_RSA_EXPO2(objp))->big_value_len);
1037 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1038 			buf = buf + sizeof (uint64_t);
1039 
1040 			(void) memcpy(buf, (char *)((biginteger_t *)
1041 			    OBJ_PRI_RSA_EXPO2(objp))->big_value,
1042 			    ((biginteger_t *)
1043 			    OBJ_PRI_RSA_EXPO2(objp))->big_value_len);
1044 			buf = buf + ROUNDUP(((biginteger_t *)
1045 			    OBJ_PRI_RSA_EXPO2(objp))->big_value_len, 8);
1046 
1047 			/* coef_len + coef */
1048 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1049 			    OBJ_PRI_RSA_COEF(objp))->big_value_len);
1050 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1051 			buf = buf + sizeof (uint64_t);
1052 
1053 			(void) memcpy(buf, (char *)((biginteger_t *)
1054 			    OBJ_PRI_RSA_COEF(objp))->big_value,
1055 			    ((biginteger_t *)
1056 			    OBJ_PRI_RSA_COEF(objp))->big_value_len);
1057 			buf = buf + ROUNDUP(((biginteger_t *)
1058 			    OBJ_PRI_RSA_COEF(objp))->big_value_len, 8);
1059 
1060 			break;
1061 
1062 		case CKK_DSA:
1063 			/* prime_len + prime */
1064 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1065 			    OBJ_PRI_DSA_PRIME(objp))->big_value_len);
1066 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1067 			buf = buf + sizeof (uint64_t);
1068 
1069 			(void) memcpy(buf, (char *)((biginteger_t *)
1070 			    OBJ_PRI_DSA_PRIME(objp))->big_value,
1071 			    ((biginteger_t *)
1072 			    OBJ_PRI_DSA_PRIME(objp))->big_value_len);
1073 			buf = buf + ROUNDUP(((biginteger_t *)
1074 			    OBJ_PRI_DSA_PRIME(objp))->big_value_len, 8);
1075 
1076 			/* subprime_len + subprime */
1077 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1078 			    OBJ_PRI_DSA_SUBPRIME(objp))->big_value_len);
1079 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1080 			buf = buf + sizeof (uint64_t);
1081 
1082 			(void) memcpy(buf, (char *)((biginteger_t *)
1083 			    OBJ_PRI_DSA_SUBPRIME(objp))->big_value,
1084 			    ((biginteger_t *)
1085 			    OBJ_PRI_DSA_SUBPRIME(objp))->big_value_len);
1086 			buf = buf + ROUNDUP(((biginteger_t *)
1087 			    OBJ_PRI_DSA_SUBPRIME(objp))->big_value_len, 8);
1088 
1089 			/* base_len + base */
1090 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1091 			    OBJ_PRI_DSA_BASE(objp))->big_value_len);
1092 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1093 			buf = buf + sizeof (uint64_t);
1094 
1095 			(void) memcpy(buf, (char *)((biginteger_t *)
1096 			    OBJ_PRI_DSA_BASE(objp))->big_value,
1097 			    ((biginteger_t *)
1098 			    OBJ_PRI_DSA_BASE(objp))->big_value_len);
1099 			buf = buf + ROUNDUP(((biginteger_t *)
1100 			    OBJ_PRI_DSA_BASE(objp))->big_value_len, 8);
1101 
1102 			/* value_len + value */
1103 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1104 			    OBJ_PRI_DSA_VALUE(objp))->big_value_len);
1105 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1106 			buf = buf + sizeof (uint64_t);
1107 
1108 			(void) memcpy(buf, (char *)((biginteger_t *)
1109 			    OBJ_PRI_DSA_VALUE(objp))->big_value,
1110 			    ((biginteger_t *)
1111 			    OBJ_PRI_DSA_VALUE(objp))->big_value_len);
1112 
1113 			break;
1114 
1115 		case CKK_DH:
1116 			/* value_bits */
1117 			tmp_val = SWAP64((uint64_t)OBJ_PRI_DH_VAL_BITS(objp));
1118 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1119 			buf = buf + sizeof (uint64_t);
1120 
1121 			/* prime_len + prime */
1122 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1123 			    OBJ_PRI_DH_PRIME(objp))->big_value_len);
1124 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1125 			buf = buf + sizeof (uint64_t);
1126 
1127 			(void) memcpy(buf, (char *)((biginteger_t *)
1128 			    OBJ_PRI_DH_PRIME(objp))->big_value,
1129 			    ((biginteger_t *)
1130 			    OBJ_PRI_DH_PRIME(objp))->big_value_len);
1131 			buf = buf + ROUNDUP(((biginteger_t *)
1132 			    OBJ_PRI_DH_PRIME(objp))->big_value_len, 8);
1133 
1134 			/* base_len + base */
1135 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1136 			    OBJ_PRI_DH_BASE(objp))->big_value_len);
1137 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1138 			buf = buf + sizeof (uint64_t);
1139 
1140 			(void) memcpy(buf, (char *)((biginteger_t *)
1141 			    OBJ_PRI_DH_BASE(objp))->big_value,
1142 			    ((biginteger_t *)
1143 			    OBJ_PRI_DH_BASE(objp))->big_value_len);
1144 			buf = buf + ROUNDUP(((biginteger_t *)
1145 			    OBJ_PRI_DH_BASE(objp))->big_value_len, 8);
1146 
1147 			/* value_len + value */
1148 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1149 			    OBJ_PRI_DH_VALUE(objp))->big_value_len);
1150 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1151 			buf = buf + sizeof (uint64_t);
1152 
1153 			(void) memcpy(buf, (char *)((biginteger_t *)
1154 			    OBJ_PRI_DH_VALUE(objp))->big_value,
1155 			    ((biginteger_t *)
1156 			    OBJ_PRI_DH_VALUE(objp))->big_value_len);
1157 
1158 			break;
1159 
1160 		case CKK_X9_42_DH:
1161 			/* prime_len + prime */
1162 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1163 			    OBJ_PRI_DH942_PRIME(objp))->big_value_len);
1164 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1165 			buf = buf + sizeof (uint64_t);
1166 
1167 			(void) memcpy(buf, (char *)((biginteger_t *)
1168 			    OBJ_PRI_DH942_PRIME(objp))->big_value,
1169 			    ((biginteger_t *)
1170 			    OBJ_PRI_DH942_PRIME(objp))->big_value_len);
1171 			buf = buf + ROUNDUP(((biginteger_t *)
1172 			    OBJ_PRI_DH942_PRIME(objp))->big_value_len, 8);
1173 
1174 			/* base_len + base */
1175 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1176 			    OBJ_PRI_DH942_BASE(objp))->big_value_len);
1177 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1178 			buf = buf + sizeof (uint64_t);
1179 
1180 			(void) memcpy(buf, (char *)((biginteger_t *)
1181 			    OBJ_PRI_DH942_BASE(objp))->big_value,
1182 			    ((biginteger_t *)
1183 			    OBJ_PRI_DH942_BASE(objp))->big_value_len);
1184 			buf = buf + ROUNDUP(((biginteger_t *)
1185 			    OBJ_PRI_DH942_BASE(objp))->big_value_len, 8);
1186 
1187 			/* subprime_len + subprime */
1188 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1189 			    OBJ_PRI_DH942_SUBPRIME(objp))->big_value_len);
1190 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1191 			buf = buf + sizeof (uint64_t);
1192 
1193 			(void) memcpy(buf, (char *)((biginteger_t *)
1194 			    OBJ_PRI_DH942_SUBPRIME(objp))->big_value,
1195 			    ((biginteger_t *)
1196 			    OBJ_PRI_DH942_SUBPRIME(objp))->big_value_len);
1197 			buf = buf + ROUNDUP(((biginteger_t *)
1198 			    OBJ_PRI_DH942_SUBPRIME(objp))->big_value_len, 8);
1199 
1200 			/* value_len + value */
1201 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1202 			    OBJ_PRI_DH942_VALUE(objp))->big_value_len);
1203 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1204 			buf = buf + sizeof (uint64_t);
1205 
1206 			(void) memcpy(buf, (char *)((biginteger_t *)
1207 			    OBJ_PRI_DH942_VALUE(objp))->big_value,
1208 			    ((biginteger_t *)
1209 			    OBJ_PRI_DH942_VALUE(objp))->big_value_len);
1210 
1211 			break;
1212 
1213 		} /* keytype */
1214 
1215 		break;
1216 
1217 	case CKO_SECRET_KEY:
1218 		/* value_len  + value */
1219 		tmp_val = SWAP64((uint64_t)OBJ_SEC_VALUE_LEN(objp));
1220 		(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1221 		buf = buf + sizeof (uint64_t);
1222 
1223 		if (OBJ_SEC_VALUE_LEN(objp) > 0) {
1224 			(void) memcpy(buf, (char *)OBJ_SEC_VALUE(objp),
1225 			    OBJ_SEC_VALUE_LEN(objp));
1226 			buf = buf + ROUNDUP(OBJ_SEC_VALUE_LEN(objp), 8);
1227 		}
1228 
1229 		break;
1230 
1231 	case CKO_CERTIFICATE:
1232 
1233 		switch (certtype) {
1234 		case CKC_X_509:
1235 			/* subject_len + subject */
1236 			tmp_val = SWAP64((uint64_t)(((cert_attr_t *)
1237 			    X509_CERT_SUBJECT(objp))->length));
1238 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1239 			buf = buf + sizeof (uint64_t);
1240 
1241 			(void) memcpy(buf, (char *)((cert_attr_t *)
1242 			    X509_CERT_SUBJECT(objp))->value,
1243 			    ((cert_attr_t *)
1244 			    X509_CERT_SUBJECT(objp))->length);
1245 			buf = buf + ROUNDUP(((cert_attr_t *)
1246 			    X509_CERT_SUBJECT(objp))->length, 8);
1247 
1248 			/* value_len + value */
1249 			tmp_val = SWAP64((uint64_t)(((cert_attr_t *)
1250 			    X509_CERT_VALUE(objp))->length));
1251 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1252 			buf = buf + sizeof (uint64_t);
1253 
1254 			(void) memcpy(buf, (char *)((cert_attr_t *)
1255 			    X509_CERT_VALUE(objp))->value,
1256 			    ((cert_attr_t *)
1257 			    X509_CERT_VALUE(objp))->length);
1258 			break;
1259 
1260 		case CKC_X_509_ATTR_CERT:
1261 			/* owner_len + owner */
1262 			tmp_val = SWAP64((uint64_t)(((cert_attr_t *)
1263 			    X509_ATTR_CERT_OWNER(objp))->length));
1264 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1265 			buf = buf + sizeof (uint64_t);
1266 
1267 			(void) memcpy(buf, (char *)((cert_attr_t *)
1268 			    X509_ATTR_CERT_OWNER(objp))->value,
1269 			    ((cert_attr_t *)
1270 			    X509_ATTR_CERT_OWNER(objp))->length);
1271 			buf = buf + ROUNDUP(((cert_attr_t *)
1272 			    X509_ATTR_CERT_OWNER(objp))->length, 8);
1273 
1274 			/* value_len + value */
1275 			tmp_val = SWAP64((uint64_t)(((cert_attr_t *)
1276 			    X509_ATTR_CERT_VALUE(objp))->length));
1277 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1278 			buf = buf + sizeof (uint64_t);
1279 
1280 			(void) memcpy(buf, (char *)((cert_attr_t *)
1281 			    X509_ATTR_CERT_VALUE(objp))->value,
1282 			    ((cert_attr_t *)
1283 			    X509_ATTR_CERT_VALUE(objp))->length);
1284 			break;
1285 		}
1286 		break;
1287 
1288 	case CKO_DOMAIN_PARAMETERS:
1289 
1290 		return (0);
1291 	}
1292 	return (CKR_OK);
1293 }
1294 
1295 /*
1296  * Unpack the object key in keystore format (the third part)
1297  * into soft_object_t.
1298  */
1299 CK_RV
1300 soft_unpack_object(soft_object_t *objp, uchar_t *buf)
1301 {
1302 
1303 	public_key_obj_t  *pbk;
1304 	private_key_obj_t *pvk;
1305 	secret_key_obj_t  *sck;
1306 	certificate_obj_t *cert;
1307 	CK_OBJECT_CLASS class = objp->class;
1308 	CK_KEY_TYPE	keytype = objp->key_type;
1309 	CK_CERTIFICATE_TYPE certtype = objp->cert_type;
1310 
1311 	biginteger_t	modulus;
1312 	biginteger_t	pubexpo;
1313 	biginteger_t	prime;
1314 	biginteger_t	subprime;
1315 	biginteger_t	base;
1316 	biginteger_t	value;
1317 
1318 	biginteger_t	priexpo;
1319 	biginteger_t	prime1;
1320 	biginteger_t	prime2;
1321 	biginteger_t	expo1;
1322 	biginteger_t	expo2;
1323 	biginteger_t	coef;
1324 	CK_RV 		rv = CKR_OK;
1325 	ulong_t offset = 0;
1326 	uint64_t tmp_val;
1327 
1328 	/* prevent bigint_attr_cleanup from freeing invalid attr value */
1329 	(void) memset(&modulus, 0x0, sizeof (biginteger_t));
1330 	(void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1331 	(void) memset(&prime, 0x0, sizeof (biginteger_t));
1332 	(void) memset(&subprime, 0x0, sizeof (biginteger_t));
1333 	(void) memset(&base, 0x0, sizeof (biginteger_t));
1334 	(void) memset(&value, 0x0, sizeof (biginteger_t));
1335 
1336 	(void) memset(&priexpo, 0x0, sizeof (biginteger_t));
1337 	(void) memset(&prime1, 0x0, sizeof (biginteger_t));
1338 	(void) memset(&prime2, 0x0, sizeof (biginteger_t));
1339 	(void) memset(&expo1, 0x0, sizeof (biginteger_t));
1340 	(void) memset(&expo2, 0x0, sizeof (biginteger_t));
1341 	(void) memset(&coef, 0x0, sizeof (biginteger_t));
1342 
1343 	switch (class) {
1344 
1345 	case CKO_PUBLIC_KEY:
1346 		/* Allocate storage for Public Key Object. */
1347 		pbk = calloc(1, sizeof (public_key_obj_t));
1348 		if (pbk == NULL) {
1349 			rv =  CKR_HOST_MEMORY;
1350 			return (rv);
1351 		}
1352 
1353 		objp->object_class_u.public_key = pbk;
1354 
1355 		switch (keytype) {
1356 		case CKK_RSA:			/* modulus_bits */
1357 			(void) memcpy(&tmp_val, buf, sizeof (uint64_t));
1358 			KEY_PUB_RSA_MOD_BITS(pbk) = (CK_ULONG)(SWAP64(tmp_val));
1359 			buf = buf + sizeof (uint64_t);
1360 
1361 			/* modulus */
1362 			if ((rv = soft_unpack_obj_attribute(buf, &modulus,
1363 			    NULL, &offset, B_FALSE)) != CKR_OK)
1364 				goto pub_cleanup;
1365 
1366 			copy_bigint_attr(&modulus, KEY_PUB_RSA_MOD(pbk));
1367 
1368 			buf += ROUNDUP(offset, 8);
1369 
1370 			/* pubexpo */
1371 			if ((rv = soft_unpack_obj_attribute(buf, &pubexpo,
1372 			    NULL, &offset, B_FALSE)) != CKR_OK)
1373 				goto pub_cleanup;
1374 
1375 			copy_bigint_attr(&pubexpo, KEY_PUB_RSA_PUBEXPO(pbk));
1376 
1377 			break;
1378 
1379 		case CKK_DSA:
1380 			/* prime */
1381 			if ((rv = soft_unpack_obj_attribute(buf, &prime,
1382 			    NULL, &offset, B_FALSE)) != CKR_OK)
1383 				goto pub_cleanup;
1384 
1385 			copy_bigint_attr(&prime, KEY_PUB_DSA_PRIME(pbk));
1386 
1387 			buf += ROUNDUP(offset, 8);
1388 
1389 			/* subprime */
1390 			if ((rv = soft_unpack_obj_attribute(buf, &subprime,
1391 			    NULL, &offset, B_FALSE)) != CKR_OK)
1392 				goto pub_cleanup;
1393 
1394 			copy_bigint_attr(&subprime, KEY_PUB_DSA_SUBPRIME(pbk));
1395 
1396 			buf += ROUNDUP(offset, 8);
1397 
1398 			/* base */
1399 			if ((rv = soft_unpack_obj_attribute(buf, &base,
1400 			    NULL, &offset, B_FALSE)) != CKR_OK)
1401 				goto pub_cleanup;
1402 
1403 			copy_bigint_attr(&base, KEY_PUB_DSA_BASE(pbk));
1404 
1405 			buf += ROUNDUP(offset, 8);
1406 
1407 			/* value */
1408 			if ((rv = soft_unpack_obj_attribute(buf, &value,
1409 			    NULL, &offset, B_FALSE)) != CKR_OK)
1410 				goto pub_cleanup;
1411 
1412 			copy_bigint_attr(&value, KEY_PUB_DSA_VALUE(pbk));
1413 
1414 			break;
1415 
1416 		case CKK_DH:
1417 			/* prime */
1418 			if ((rv = soft_unpack_obj_attribute(buf, &prime,
1419 			    NULL, &offset, B_FALSE)) != CKR_OK)
1420 				goto pub_cleanup;
1421 
1422 			copy_bigint_attr(&prime, KEY_PUB_DH_PRIME(pbk));
1423 
1424 			buf += ROUNDUP(offset, 8);
1425 
1426 			/* base */
1427 			if ((rv = soft_unpack_obj_attribute(buf, &base,
1428 			    NULL, &offset, B_FALSE)) != CKR_OK)
1429 				goto pub_cleanup;
1430 
1431 			copy_bigint_attr(&base, KEY_PUB_DH_BASE(pbk));
1432 
1433 			buf += ROUNDUP(offset, 8);
1434 
1435 			/* value */
1436 			if ((rv = soft_unpack_obj_attribute(buf, &value,
1437 			    NULL, &offset, B_FALSE)) != CKR_OK)
1438 				goto pub_cleanup;
1439 
1440 			copy_bigint_attr(&value, KEY_PUB_DH_VALUE(pbk));
1441 
1442 			break;
1443 
1444 		case CKK_X9_42_DH:
1445 			/* prime */
1446 			if ((rv = soft_unpack_obj_attribute(buf, &prime,
1447 			    NULL, &offset, B_FALSE)) != CKR_OK)
1448 				goto pub_cleanup;
1449 
1450 			copy_bigint_attr(&prime, KEY_PUB_DH942_PRIME(pbk));
1451 
1452 			buf += ROUNDUP(offset, 8);
1453 
1454 			/* base */
1455 			if ((rv = soft_unpack_obj_attribute(buf, &base,
1456 			    NULL, &offset, B_FALSE)) != CKR_OK)
1457 				goto pub_cleanup;
1458 
1459 			copy_bigint_attr(&base, KEY_PUB_DH942_BASE(pbk));
1460 
1461 			buf += ROUNDUP(offset, 8);
1462 
1463 			/* subprime */
1464 			if ((rv = soft_unpack_obj_attribute(buf, &subprime,
1465 			    NULL, &offset, B_FALSE)) != CKR_OK)
1466 				goto pub_cleanup;
1467 
1468 			copy_bigint_attr(&subprime,
1469 			    KEY_PUB_DH942_SUBPRIME(pbk));
1470 
1471 			buf += ROUNDUP(offset, 8);
1472 
1473 			/* value */
1474 			if ((rv = soft_unpack_obj_attribute(buf, &value,
1475 			    NULL, &offset, B_FALSE)) != CKR_OK)
1476 				goto pub_cleanup;
1477 
1478 			copy_bigint_attr(&value, KEY_PUB_DH942_VALUE(pbk));
1479 
1480 			break;
1481 		} /* keytype */
1482 
1483 		break;
1484 
1485 	case CKO_PRIVATE_KEY:
1486 		/* Allocate storage for Private Key Object. */
1487 		pvk = calloc(1, sizeof (private_key_obj_t));
1488 		if (pvk == NULL) {
1489 			rv = CKR_HOST_MEMORY;
1490 			return (rv);
1491 		}
1492 
1493 		objp->object_class_u.private_key = pvk;
1494 
1495 		switch (keytype) {
1496 		case CKK_RSA:
1497 			/* modulus */
1498 			if ((rv = soft_unpack_obj_attribute(buf, &modulus,
1499 			    NULL, &offset, B_FALSE)) != CKR_OK)
1500 				goto pri_cleanup;
1501 
1502 			copy_bigint_attr(&modulus, KEY_PRI_RSA_MOD(pvk));
1503 
1504 			buf += ROUNDUP(offset, 8);
1505 
1506 			/* pubexpo */
1507 			if ((rv = soft_unpack_obj_attribute(buf, &pubexpo,
1508 			    NULL, &offset, B_FALSE)) != CKR_OK)
1509 				goto pri_cleanup;
1510 
1511 			copy_bigint_attr(&pubexpo, KEY_PRI_RSA_PUBEXPO(pvk));
1512 
1513 			buf += ROUNDUP(offset, 8);
1514 
1515 			/* priexpo */
1516 			if ((rv = soft_unpack_obj_attribute(buf, &priexpo,
1517 			    NULL, &offset, B_FALSE)) != CKR_OK)
1518 				goto pri_cleanup;
1519 
1520 			copy_bigint_attr(&priexpo, KEY_PRI_RSA_PRIEXPO(pvk));
1521 
1522 			buf += ROUNDUP(offset, 8);
1523 
1524 			/* prime1 */
1525 			if ((rv = soft_unpack_obj_attribute(buf, &prime1,
1526 			    NULL, &offset, B_FALSE)) != CKR_OK)
1527 				goto pri_cleanup;
1528 
1529 			copy_bigint_attr(&prime1, KEY_PRI_RSA_PRIME1(pvk));
1530 
1531 			buf += ROUNDUP(offset, 8);
1532 
1533 			/* prime2 */
1534 			if ((rv = soft_unpack_obj_attribute(buf, &prime2,
1535 			    NULL, &offset, B_FALSE)) != CKR_OK)
1536 				goto pri_cleanup;
1537 
1538 			copy_bigint_attr(&prime2, KEY_PRI_RSA_PRIME2(pvk));
1539 
1540 			buf += ROUNDUP(offset, 8);
1541 
1542 			/* expo1 */
1543 			if ((rv = soft_unpack_obj_attribute(buf, &expo1,
1544 			    NULL, &offset, B_FALSE)) != CKR_OK)
1545 				goto pri_cleanup;
1546 
1547 			copy_bigint_attr(&expo1, KEY_PRI_RSA_EXPO1(pvk));
1548 
1549 			buf += ROUNDUP(offset, 8);
1550 
1551 			/* expo2 */
1552 			if ((rv = soft_unpack_obj_attribute(buf, &expo2,
1553 			    NULL, &offset, B_FALSE)) != CKR_OK)
1554 				goto pri_cleanup;
1555 
1556 			copy_bigint_attr(&expo2, KEY_PRI_RSA_EXPO2(pvk));
1557 
1558 			buf += ROUNDUP(offset, 8);
1559 
1560 			/* coef */
1561 			if ((rv = soft_unpack_obj_attribute(buf, &coef,
1562 			    NULL, &offset, B_FALSE)) != CKR_OK)
1563 				goto pri_cleanup;
1564 
1565 			copy_bigint_attr(&coef, KEY_PRI_RSA_COEF(pvk));
1566 
1567 			break;
1568 
1569 		case CKK_DSA:
1570 			/* prime */
1571 			if ((rv = soft_unpack_obj_attribute(buf, &prime,
1572 			    NULL, &offset, B_FALSE)) != CKR_OK)
1573 				goto pri_cleanup;
1574 
1575 			copy_bigint_attr(&prime, KEY_PRI_DSA_PRIME(pvk));
1576 
1577 			buf += ROUNDUP(offset, 8);
1578 
1579 			/* subprime */
1580 			if ((rv = soft_unpack_obj_attribute(buf, &subprime,
1581 			    NULL, &offset, B_FALSE)) != CKR_OK)
1582 				goto pri_cleanup;
1583 
1584 			copy_bigint_attr(&subprime, KEY_PRI_DSA_SUBPRIME(pvk));
1585 
1586 			buf += ROUNDUP(offset, 8);
1587 
1588 			/* base */
1589 			if ((rv = soft_unpack_obj_attribute(buf, &base,
1590 			    NULL, &offset, B_FALSE)) != CKR_OK)
1591 				goto pri_cleanup;
1592 
1593 			copy_bigint_attr(&base, KEY_PRI_DSA_BASE(pvk));
1594 
1595 			buf += ROUNDUP(offset, 8);
1596 
1597 			/* value */
1598 			if ((rv = soft_unpack_obj_attribute(buf, &value,
1599 			    NULL, &offset, B_FALSE)) != CKR_OK)
1600 				goto pri_cleanup;
1601 
1602 			copy_bigint_attr(&value, KEY_PRI_DSA_VALUE(pvk));
1603 
1604 			break;
1605 
1606 		case CKK_DH:
1607 			/* value_bits */
1608 			(void) memcpy(&tmp_val, buf, sizeof (uint64_t));
1609 			KEY_PRI_DH_VAL_BITS(pvk) = (CK_ULONG)(SWAP64(tmp_val));
1610 			buf = buf + sizeof (uint64_t);
1611 
1612 			/* prime */
1613 			if ((rv = soft_unpack_obj_attribute(buf, &prime,
1614 			    NULL, &offset, B_FALSE)) != CKR_OK)
1615 				goto pri_cleanup;
1616 
1617 			copy_bigint_attr(&prime, KEY_PRI_DH_PRIME(pvk));
1618 
1619 			buf += ROUNDUP(offset, 8);
1620 
1621 			/* base */
1622 			if ((rv = soft_unpack_obj_attribute(buf, &base,
1623 			    NULL, &offset, B_FALSE)) != CKR_OK)
1624 				goto pri_cleanup;
1625 
1626 			copy_bigint_attr(&base, KEY_PRI_DH_BASE(pvk));
1627 
1628 			buf += ROUNDUP(offset, 8);
1629 
1630 			/* value */
1631 			if ((rv = soft_unpack_obj_attribute(buf, &value,
1632 			    NULL, &offset, B_FALSE)) != CKR_OK)
1633 				goto pri_cleanup;
1634 
1635 			copy_bigint_attr(&value, KEY_PRI_DH_VALUE(pvk));
1636 
1637 			break;
1638 
1639 		case CKK_X9_42_DH:
1640 			/* prime */
1641 			if ((rv = soft_unpack_obj_attribute(buf, &prime,
1642 			    NULL, &offset, B_FALSE)) != CKR_OK)
1643 				goto pri_cleanup;
1644 
1645 			copy_bigint_attr(&prime, KEY_PRI_DH942_PRIME(pvk));
1646 
1647 			buf += ROUNDUP(offset, 8);
1648 
1649 			/* base */
1650 			if ((rv = soft_unpack_obj_attribute(buf, &base,
1651 			    NULL, &offset, B_FALSE)) != CKR_OK)
1652 				goto pri_cleanup;
1653 
1654 			copy_bigint_attr(&base, KEY_PRI_DH942_BASE(pvk));
1655 
1656 			buf += ROUNDUP(offset, 8);
1657 
1658 			/* subprime */
1659 			if ((rv = soft_unpack_obj_attribute(buf, &subprime,
1660 			    NULL, &offset, B_FALSE)) != CKR_OK)
1661 				goto pri_cleanup;
1662 
1663 			copy_bigint_attr(&subprime, KEY_PRI_DH942_BASE(pvk));
1664 
1665 			buf += ROUNDUP(offset, 8);
1666 
1667 			/* value */
1668 			if ((rv = soft_unpack_obj_attribute(buf, &value,
1669 			    NULL, &offset, B_FALSE)) != CKR_OK)
1670 				goto pri_cleanup;
1671 
1672 			copy_bigint_attr(&value, KEY_PRI_DH942_VALUE(pvk));
1673 
1674 			break;
1675 		} /* keytype */
1676 
1677 		break;
1678 
1679 	case CKO_SECRET_KEY:
1680 		/* Allocate storage for Secret Key Object. */
1681 		sck = calloc(1, sizeof (secret_key_obj_t));
1682 		if (sck == NULL) {
1683 			return (CKR_HOST_MEMORY);
1684 		}
1685 
1686 		objp->object_class_u.secret_key = sck;
1687 
1688 		/* value */
1689 		(void) memcpy((void *)&tmp_val, buf, sizeof (uint64_t));
1690 		OBJ_SEC_VALUE_LEN(objp) = (CK_ULONG)(SWAP64(tmp_val));
1691 		buf = buf + sizeof (uint64_t);
1692 
1693 		if (OBJ_SEC_VALUE_LEN(objp) > 0) {
1694 			OBJ_SEC_VALUE(objp) = malloc(OBJ_SEC_VALUE_LEN(objp));
1695 			if (OBJ_SEC_VALUE(objp) == NULL) {
1696 				free(sck);
1697 				return (CKR_HOST_MEMORY);
1698 			}
1699 			(void) memcpy(OBJ_SEC_VALUE(objp), buf,
1700 			    OBJ_SEC_VALUE_LEN(objp));
1701 
1702 			buf = buf + ROUNDUP(OBJ_SEC_VALUE_LEN(objp), 8);
1703 		}
1704 
1705 		return (rv);
1706 
1707 	case CKO_CERTIFICATE:
1708 		/* Allocate storage for Certificate Object. */
1709 		cert = calloc(1, sizeof (certificate_obj_t));
1710 		if (cert == NULL) {
1711 			return (CKR_HOST_MEMORY);
1712 		}
1713 		(void) memset((void *)cert, 0, sizeof (certificate_obj_t));
1714 
1715 		cert->certificate_type = certtype;
1716 		objp->object_class_u.certificate = cert;
1717 
1718 		switch (certtype) {
1719 		case CKC_X_509:
1720 			/* subject */
1721 			if ((rv = soft_unpack_obj_attribute(buf, NULL,
1722 			    &cert->cert_type_u.x509.subject,
1723 				&offset, B_TRUE)) != CKR_OK) {
1724 				free(cert);
1725 				return (rv);
1726 			}
1727 
1728 			buf += ROUNDUP(offset, 8);
1729 
1730 			/* value */
1731 			if ((rv = soft_unpack_obj_attribute(buf, NULL,
1732 			    &cert->cert_type_u.x509.value,
1733 				&offset, B_TRUE)) != CKR_OK) {
1734 				free(cert);
1735 				return (rv);
1736 			}
1737 
1738 			break;
1739 
1740 		case CKC_X_509_ATTR_CERT:
1741 			/* owner */
1742 			if ((rv = soft_unpack_obj_attribute(buf, NULL,
1743 			    &cert->cert_type_u.x509_attr.owner,
1744 				&offset, B_TRUE)) != CKR_OK) {
1745 				free(cert);
1746 				return (rv);
1747 			}
1748 
1749 			buf += ROUNDUP(offset, 8);
1750 
1751 			/* value */
1752 			if ((rv = soft_unpack_obj_attribute(buf, NULL,
1753 			    &cert->cert_type_u.x509_attr.value,
1754 				&offset, B_TRUE)) != CKR_OK) {
1755 				free(cert);
1756 				return (rv);
1757 			}
1758 
1759 			break;
1760 		}
1761 
1762 		return (rv);
1763 
1764 	case CKO_DOMAIN_PARAMETERS:
1765 
1766 		break;
1767 	}
1768 
1769 pub_cleanup:
1770 	/*
1771 	 * cleanup the storage allocated to the local variables.
1772 	 */
1773 	if (rv != CKR_OK)
1774 		free(pbk);
1775 	bigint_attr_cleanup(&modulus);
1776 	bigint_attr_cleanup(&pubexpo);
1777 	bigint_attr_cleanup(&prime);
1778 	bigint_attr_cleanup(&subprime);
1779 	bigint_attr_cleanup(&base);
1780 	bigint_attr_cleanup(&value);
1781 	return (rv);
1782 
1783 pri_cleanup:
1784 	/*
1785 	 * cleanup the storage allocated to the local variables.
1786 	 */
1787 	if (rv != CKR_OK)
1788 		free(pvk);
1789 	bigint_attr_cleanup(&modulus);
1790 	bigint_attr_cleanup(&priexpo);
1791 	bigint_attr_cleanup(&prime);
1792 	bigint_attr_cleanup(&subprime);
1793 	bigint_attr_cleanup(&base);
1794 	bigint_attr_cleanup(&value);
1795 	bigint_attr_cleanup(&pubexpo);
1796 	bigint_attr_cleanup(&prime1);
1797 	bigint_attr_cleanup(&prime2);
1798 	bigint_attr_cleanup(&expo1);
1799 	bigint_attr_cleanup(&expo2);
1800 	bigint_attr_cleanup(&coef);
1801 	return (rv);
1802 }
1803 
1804 
1805 /*
1806  * Store the token object to a keystore file.
1807  */
1808 CK_RV
1809 soft_put_object_to_keystore(soft_object_t *objp)
1810 {
1811 
1812 	uchar_t *buf;
1813 	size_t len;
1814 	CK_RV rv;
1815 
1816 	rv = soft_keystore_pack_obj(objp, &buf, &len);
1817 	if (rv != CKR_OK)
1818 		return (rv);
1819 
1820 	if (objp->object_type == TOKEN_PUBLIC) {
1821 		if ((soft_keystore_put_new_obj(buf, len, B_TRUE,
1822 		    B_FALSE, &objp->ks_handle)) == -1) {
1823 			free(buf);
1824 			return (CKR_FUNCTION_FAILED);
1825 		}
1826 	} else {
1827 		if ((soft_keystore_put_new_obj(buf, len, B_FALSE,
1828 		    B_FALSE, &objp->ks_handle)) == -1) {
1829 			free(buf);
1830 			return (CKR_FUNCTION_FAILED);
1831 		}
1832 	}
1833 	free(buf);
1834 	return (CKR_OK);
1835 
1836 }
1837 
1838 /*
1839  * Modify the in-core token object and then write it to
1840  * a keystore file.
1841  */
1842 CK_RV
1843 soft_modify_object_to_keystore(soft_object_t *objp)
1844 {
1845 
1846 	uchar_t *buf;
1847 	size_t len;
1848 	CK_RV rv;
1849 
1850 	rv = soft_keystore_pack_obj(objp, &buf, &len);
1851 	if (rv != CKR_OK)
1852 		return (rv);
1853 
1854 	/* B_TRUE: caller has held a writelock on the keystore */
1855 	if (soft_keystore_modify_obj(&objp->ks_handle, buf, len,
1856 	    B_TRUE) < 0) {
1857 		return (CKR_FUNCTION_FAILED);
1858 	}
1859 
1860 	free(buf);
1861 	return (CKR_OK);
1862 
1863 }
1864 
1865 /*
1866  * Read the token object from the keystore file.
1867  */
1868 CK_RV
1869 soft_get_token_objects_from_keystore(ks_search_type_t type)
1870 {
1871 	CK_RV rv;
1872 	ks_obj_t	*ks_obj = NULL, *ks_obj_next;
1873 	soft_object_t *new_objp = NULL;
1874 
1875 	/* Load the token object from keystore based on the object type */
1876 	rv = soft_keystore_get_objs(type, &ks_obj, B_FALSE);
1877 	if (rv != CKR_OK) {
1878 		return (rv);
1879 	}
1880 
1881 	while (ks_obj) {
1882 
1883 		new_objp = calloc(1, sizeof (soft_object_t));
1884 		if (new_objp == NULL) {
1885 			rv = CKR_HOST_MEMORY;
1886 			goto cleanup;
1887 		}
1888 		/* Convert the keystore format to memory format */
1889 		rv = soft_keystore_unpack_obj(new_objp, ks_obj);
1890 		if (rv != CKR_OK) {
1891 			if (new_objp->class == CKO_CERTIFICATE)
1892 				soft_cleanup_cert_object(new_objp);
1893 			else
1894 				soft_cleanup_object(new_objp);
1895 			goto cleanup;
1896 		}
1897 
1898 		soft_add_token_object_to_slot(new_objp);
1899 
1900 		/* Free the ks_obj list */
1901 		ks_obj_next = ks_obj->next;
1902 		if (ks_obj->buf)
1903 			free(ks_obj->buf);
1904 		free(ks_obj);
1905 		ks_obj = ks_obj_next;
1906 	}
1907 
1908 	return (CKR_OK);
1909 
1910 cleanup:
1911 	while (ks_obj) {
1912 		ks_obj_next = ks_obj->next;
1913 		free(ks_obj->buf);
1914 		free(ks_obj);
1915 		ks_obj = ks_obj_next;
1916 	}
1917 	return (rv);
1918 }
1919 
1920 /*
1921  * soft_gen_crypt_key()
1922  *
1923  * Arguments:
1924  *
1925  *	pPIN:	pointer to caller provided Pin
1926  *	key:	output argument which contains the address of the
1927  *		pointer to encryption key in the soft_object_t.
1928  *		It is caller's responsibility to call soft_delete_object()
1929  *		if this key is no longer in use.
1930  *	saltdata: input argument (if non-NULL), or
1931  *		  output argument (if NULL):
1932  *		  address of pointer to the "salt" of the encryption key
1933  *
1934  * Description:
1935  *
1936  *	Generate an encryption key of the input PIN.
1937  *
1938  * Returns:
1939  *
1940  *	CKR_OK: no error
1941  *	Other: some error occurred while generating the encryption key
1942  *
1943  */
1944 CK_RV
1945 soft_gen_crypt_key(uchar_t *pPIN, soft_object_t **key, CK_BYTE **saltdata)
1946 {
1947 	CK_OBJECT_CLASS class = CKO_SECRET_KEY;
1948 	CK_ATTRIBUTE tmpl[5];
1949 	int attrs = 0;
1950 	CK_RV rv;
1951 	CK_MECHANISM Mechanism;
1952 	CK_PKCS5_PBKD2_PARAMS params;
1953 	CK_BYTE		salt[PBKD2_SALT_SIZE];
1954 	CK_ULONG	keylen = AES_MIN_KEY_BYTES;
1955 	CK_KEY_TYPE keytype = CKK_AES;
1956 	static CK_BBOOL truevalue = TRUE;
1957 	soft_object_t *secret_key;
1958 	CK_OBJECT_HANDLE hKey;
1959 	CK_ULONG	passwd_size;
1960 
1961 	if (pPIN == NULL)
1962 		return (CKR_FUNCTION_FAILED);
1963 
1964 	tmpl[attrs].type = CKA_CLASS;
1965 	tmpl[attrs].pValue = &class;
1966 	tmpl[attrs].ulValueLen = sizeof (class);
1967 	attrs++;
1968 
1969 	tmpl[attrs].type = CKA_KEY_TYPE;
1970 	tmpl[attrs].pValue = &keytype;
1971 	tmpl[attrs].ulValueLen = sizeof (keytype);
1972 	attrs++;
1973 
1974 	tmpl[attrs].type = CKA_ENCRYPT;
1975 	tmpl[attrs].pValue = &truevalue;
1976 	tmpl[attrs].ulValueLen = sizeof (CK_BBOOL);
1977 	attrs++;
1978 
1979 	tmpl[attrs].type = CKA_DECRYPT;
1980 	tmpl[attrs].pValue = &truevalue;
1981 	tmpl[attrs].ulValueLen = sizeof (CK_BBOOL);
1982 	attrs++;
1983 
1984 	tmpl[attrs].type = CKA_VALUE_LEN;
1985 	tmpl[attrs].pValue = &keylen;
1986 	tmpl[attrs].ulValueLen = sizeof (keylen);
1987 	attrs++;
1988 
1989 	if (*saltdata == NULL) {
1990 		bzero(salt, sizeof (salt));
1991 		(void) soft_nzero_random_generator(salt, sizeof (salt));
1992 		*saltdata = malloc(PBKD2_SALT_SIZE);
1993 		if (*saltdata == NULL)
1994 			return (CKR_HOST_MEMORY);
1995 		(void) memcpy(*saltdata, salt, PBKD2_SALT_SIZE);
1996 	} else {
1997 		bzero(salt, sizeof (salt));
1998 		(void) memcpy(salt, *saltdata, PBKD2_SALT_SIZE);
1999 	}
2000 
2001 	Mechanism.mechanism = CKM_PKCS5_PBKD2;
2002 	Mechanism.pParameter = &params;
2003 	Mechanism.ulParameterLen = sizeof (params);
2004 	passwd_size = (CK_ULONG)strlen((const char *)pPIN);
2005 
2006 	params.saltSource = CKZ_SALT_SPECIFIED;
2007 	params.pSaltSourceData = (void *)salt;
2008 	params.ulSaltSourceDataLen = sizeof (salt);
2009 	params.iterations = PBKD2_ITERATIONS;
2010 	params.prf = CKP_PKCS5_PBKD2_HMAC_SHA1;
2011 	params.pPrfData = NULL;
2012 	params.ulPrfDataLen = 0;
2013 	params.pPassword = (CK_UTF8CHAR_PTR)pPIN;
2014 	params.ulPasswordLen = &passwd_size;
2015 
2016 	rv = soft_gen_keyobject(tmpl, attrs, &hKey, &token_session,
2017 	    CKO_SECRET_KEY, CKK_AES, 0, SOFT_GEN_KEY, B_TRUE);
2018 
2019 	if (rv != CKR_OK) {
2020 		return (rv);
2021 	}
2022 
2023 	/* Obtain the secret object pointer. */
2024 	secret_key = (soft_object_t *)hKey;
2025 	keylen = OBJ_SEC_VALUE_LEN(secret_key);
2026 	if ((OBJ_SEC_VALUE(secret_key) = malloc(keylen)) == NULL) {
2027 		soft_delete_object(&token_session, secret_key, B_FALSE);
2028 		return (CKR_HOST_MEMORY);
2029 	}
2030 
2031 	rv = soft_generate_pkcs5_pbkdf2_key(&token_session, &Mechanism,
2032 	    secret_key);
2033 
2034 	if (rv != CKR_OK)
2035 		soft_delete_object(&token_session, secret_key, B_FALSE);
2036 	else
2037 		*key = secret_key;
2038 
2039 	return (rv);
2040 
2041 }
2042 
2043 /*
2044  * soft_gen_hmac_key()
2045  *
2046  * Arguments:
2047  *
2048  *	pPIN:	pointer to caller provided Pin
2049  *	key:	output argument which contains the address of the
2050  *		pointer to hmac key in the soft_object_t.
2051  *		It is caller's responsibility to call soft_delete_object()
2052  *		if this key is no longer in use.
2053  *	saltdata: input argument (if non-NULL), or
2054  *                output argument (if NULL):
2055  *                address of pointer to the "salt" of the hmac key
2056  *
2057  * Description:
2058  *
2059  *	Generate a hmac key of the input PIN.
2060  *
2061  * Returns:
2062  *
2063  *	CKR_OK: no error
2064  *	Other: some error occurred while generating the hmac key
2065  *
2066  */
2067 CK_RV
2068 soft_gen_hmac_key(uchar_t *pPIN, soft_object_t **key, CK_BYTE **saltdata)
2069 {
2070 	CK_OBJECT_CLASS class = CKO_SECRET_KEY;
2071 	CK_ATTRIBUTE tmpl[5];
2072 	int attrs = 0;
2073 	CK_RV rv;
2074 	CK_MECHANISM Mechanism;
2075 	CK_PKCS5_PBKD2_PARAMS params;
2076 	CK_BYTE		salt[PBKD2_SALT_SIZE];
2077 	CK_ULONG	keylen = 16;
2078 	CK_KEY_TYPE keytype = CKK_GENERIC_SECRET;
2079 	static CK_BBOOL truevalue = TRUE;
2080 	soft_object_t *secret_key;
2081 	CK_OBJECT_HANDLE hKey;
2082 	CK_ULONG	passwd_size;
2083 
2084 	if (pPIN == NULL)
2085 		return (CKR_FUNCTION_FAILED);
2086 
2087 	tmpl[attrs].type = CKA_CLASS;
2088 	tmpl[attrs].pValue = &class;
2089 	tmpl[attrs].ulValueLen = sizeof (class);
2090 	attrs++;
2091 
2092 	tmpl[attrs].type = CKA_KEY_TYPE;
2093 	tmpl[attrs].pValue = &keytype;
2094 	tmpl[attrs].ulValueLen = sizeof (keytype);
2095 	attrs++;
2096 
2097 	tmpl[attrs].type = CKA_SIGN;
2098 	tmpl[attrs].pValue = &truevalue;
2099 	tmpl[attrs].ulValueLen = sizeof (CK_BBOOL);
2100 	attrs++;
2101 
2102 	tmpl[attrs].type = CKA_VERIFY;
2103 	tmpl[attrs].pValue = &truevalue;
2104 	tmpl[attrs].ulValueLen = sizeof (CK_BBOOL);
2105 	attrs++;
2106 
2107 	tmpl[attrs].type = CKA_VALUE_LEN;
2108 	tmpl[attrs].pValue = &keylen;
2109 	tmpl[attrs].ulValueLen = sizeof (keylen);
2110 	attrs++;
2111 
2112 	if (*saltdata == NULL) {
2113 		bzero(salt, sizeof (salt));
2114 		(void) soft_nzero_random_generator(salt, sizeof (salt));
2115 		*saltdata = malloc(PBKD2_SALT_SIZE);
2116 		if (*saltdata == NULL)
2117 			return (CKR_HOST_MEMORY);
2118 		(void) memcpy(*saltdata, salt, PBKD2_SALT_SIZE);
2119 	} else {
2120 		bzero(salt, sizeof (salt));
2121 		(void) memcpy(salt, *saltdata, PBKD2_SALT_SIZE);
2122 	}
2123 
2124 	Mechanism.mechanism = CKM_PKCS5_PBKD2;
2125 	Mechanism.pParameter = &params;
2126 	Mechanism.ulParameterLen = sizeof (params);
2127 	passwd_size = (CK_ULONG)strlen((const char *)pPIN);
2128 
2129 	params.saltSource = CKZ_SALT_SPECIFIED;
2130 	params.pSaltSourceData = (void *)salt;
2131 	params.ulSaltSourceDataLen = sizeof (salt);
2132 	params.iterations = PBKD2_ITERATIONS;
2133 	params.prf = CKP_PKCS5_PBKD2_HMAC_SHA1;
2134 	params.pPrfData = NULL;
2135 	params.ulPrfDataLen = 0;
2136 	params.pPassword = (CK_UTF8CHAR_PTR)pPIN;
2137 	params.ulPasswordLen = &passwd_size;
2138 
2139 	rv = soft_gen_keyobject(tmpl, attrs, &hKey, &token_session,
2140 	    CKO_SECRET_KEY, CKK_GENERIC_SECRET, 0, SOFT_GEN_KEY, B_TRUE);
2141 
2142 	if (rv != CKR_OK) {
2143 		return (rv);
2144 	}
2145 
2146 	/* Obtain the secret object pointer. */
2147 	secret_key = (soft_object_t *)hKey;
2148 	keylen = OBJ_SEC_VALUE_LEN(secret_key);
2149 	if ((OBJ_SEC_VALUE(secret_key) = malloc(keylen)) == NULL) {
2150 		soft_delete_object(&token_session, secret_key, B_FALSE);
2151 		return (CKR_HOST_MEMORY);
2152 	}
2153 
2154 	rv = soft_generate_pkcs5_pbkdf2_key(&token_session, &Mechanism,
2155 	    secret_key);
2156 
2157 	if (rv != CKR_OK)
2158 		soft_delete_object(&token_session, secret_key, B_FALSE);
2159 	else
2160 		*key = secret_key;
2161 
2162 	return (rv);
2163 
2164 }
2165 
2166 /*
2167  * The token session is just a psuedo session (a place holder)
2168  * to hold some information during encryption/decryption and
2169  * sign/verify operations when writing/reading the keystore
2170  * token object.
2171  */
2172 CK_RV
2173 soft_init_token_session(void)
2174 {
2175 
2176 
2177 	token_session.magic_marker = SOFTTOKEN_SESSION_MAGIC;
2178 	token_session.pApplication = NULL_PTR;
2179 	token_session.Notify = NULL;
2180 	token_session.flags = CKF_SERIAL_SESSION;
2181 	token_session.state = CKS_RO_PUBLIC_SESSION;
2182 	token_session.object_list = NULL;
2183 	token_session.ses_refcnt = 0;
2184 	token_session.ses_close_sync = 0;
2185 
2186 	/* Initialize the lock for the token session */
2187 	if (pthread_mutex_init(&token_session.session_mutex, NULL) != 0) {
2188 		return (CKR_CANT_LOCK);
2189 	}
2190 
2191 	(void) pthread_cond_init(&token_session.ses_free_cond, NULL);
2192 
2193 	return (CKR_OK);
2194 
2195 }
2196 
2197 void
2198 soft_destroy_token_session(void)
2199 {
2200 
2201 	(void) pthread_cond_destroy(&token_session.ses_free_cond);
2202 	(void) pthread_mutex_destroy(&token_session.session_mutex);
2203 
2204 }
2205 
2206 /*
2207  * Encrypt/Decrypt the private token object when dealing with the keystore.
2208  * This function only applies to the private token object.
2209  */
2210 CK_RV
2211 soft_keystore_crypt(soft_object_t *key_p, uchar_t *ivec, boolean_t encrypt,
2212 	CK_BYTE_PTR in, CK_ULONG in_len, CK_BYTE_PTR out, CK_ULONG_PTR out_len)
2213 {
2214 	CK_MECHANISM	mech;
2215 	soft_aes_ctx_t *soft_aes_ctx;
2216 	CK_RV rv;
2217 	CK_ULONG tmplen, tmplen1;
2218 
2219 	/*
2220 	 * The caller will pass NULL for "out" (output buffer) to find out
2221 	 * the output buffer size that it need to allocate for the encrption
2222 	 * or decryption.
2223 	 */
2224 	if (out == NULL) {
2225 		mech.mechanism = CKM_AES_CBC_PAD;
2226 		mech.pParameter = (void *)ivec;
2227 		mech.ulParameterLen = AES_BLOCK_LEN;
2228 
2229 		if (encrypt)
2230 			rv = soft_aes_crypt_init_common(&token_session, &mech,
2231 			    key_p, B_TRUE);
2232 		else
2233 			rv = soft_aes_crypt_init_common(&token_session, &mech,
2234 			    key_p, B_FALSE);
2235 
2236 		if (rv != CKR_OK)
2237 			return (rv);
2238 
2239 
2240 		(void) pthread_mutex_lock(&token_session.session_mutex);
2241 
2242 		if (encrypt)
2243 			soft_aes_ctx =
2244 			    (soft_aes_ctx_t *)token_session.encrypt.context;
2245 		else
2246 			soft_aes_ctx =
2247 			    (soft_aes_ctx_t *)token_session.decrypt.context;
2248 
2249 		/* Copy Initialization Vector (IV) into the context. */
2250 		(void) memcpy(soft_aes_ctx->ivec, ivec, AES_BLOCK_LEN);
2251 
2252 		/* Allocate a context for AES cipher-block chaining. */
2253 		soft_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init(
2254 		    soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len,
2255 		    soft_aes_ctx->ivec);
2256 
2257 		if (soft_aes_ctx->aes_cbc == NULL) {
2258 			bzero(soft_aes_ctx->key_sched,
2259 			    soft_aes_ctx->keysched_len);
2260 			free(soft_aes_ctx->key_sched);
2261 			if (encrypt) {
2262 				free(token_session.encrypt.context);
2263 				token_session.encrypt.context = NULL;
2264 			} else {
2265 				free(token_session.encrypt.context);
2266 				token_session.encrypt.context = NULL;
2267 			}
2268 
2269 			(void) pthread_mutex_unlock(&token_session.
2270 			    session_mutex);
2271 			return (CKR_HOST_MEMORY);
2272 		}
2273 
2274 		(void) pthread_mutex_unlock(&token_session.session_mutex);
2275 		/*
2276 		 * Since out == NULL, the soft_aes_xxcrypt_common() will
2277 		 * simply return the output buffer length to the caller.
2278 		 */
2279 		if (encrypt) {
2280 			rv = soft_aes_encrypt_common(&token_session, in,
2281 			    in_len, out, out_len, B_FALSE);
2282 		} else {
2283 			rv = soft_aes_decrypt_common(&token_session, in,
2284 			    in_len, out, out_len, B_FALSE);
2285 		}
2286 
2287 	} else {
2288 		/*
2289 		 * The caller has allocated the output buffer, so that we
2290 		 * are doing the real encryption/decryption this time.
2291 		 */
2292 		tmplen = *out_len;
2293 		if (encrypt) {
2294 			rv = soft_aes_encrypt_common(&token_session, in,
2295 			    in_len, out, &tmplen, B_TRUE);
2296 			if (rv == CKR_OK) {
2297 				tmplen1 = *out_len - tmplen;
2298 				rv = soft_encrypt_final(&token_session,
2299 				    out+tmplen, &tmplen1);
2300 				*out_len = tmplen + tmplen1;
2301 			}
2302 		} else {
2303 			rv = soft_aes_decrypt_common(&token_session, in,
2304 			    in_len, out, &tmplen, B_TRUE);
2305 			if (rv == CKR_OK) {
2306 				tmplen1 = *out_len - tmplen;
2307 				rv = soft_decrypt_final(&token_session,
2308 				    out+tmplen, &tmplen1);
2309 				*out_len = tmplen + tmplen1;
2310 			}
2311 		}
2312 	}
2313 
2314 	return (rv);
2315 
2316 }
2317 
2318 /*
2319  * Sign/Verify the private token object for checking its data integrity
2320  * when dealing with the keystore.
2321  * This function only applies to the private token object.
2322  */
2323 CK_RV
2324 soft_keystore_hmac(soft_object_t *key_p, boolean_t sign,
2325 	CK_BYTE_PTR in, CK_ULONG in_len, CK_BYTE_PTR out, CK_ULONG_PTR out_len)
2326 {
2327 	CK_MECHANISM mech;
2328 	CK_RV rv;
2329 
2330 	mech.mechanism = CKM_MD5_HMAC;
2331 	mech.pParameter = NULL_PTR;
2332 	mech.ulParameterLen = 0;
2333 
2334 	rv = soft_hmac_sign_verify_init_common(&token_session, &mech,
2335 	    key_p, sign);
2336 
2337 	if (rv != CKR_OK)
2338 		return (rv);
2339 
2340 	if (sign) {
2341 		rv = soft_sign(&token_session, in, in_len, out, out_len);
2342 	} else {
2343 		rv = soft_verify(&token_session, in, in_len, out, *out_len);
2344 	}
2345 
2346 	return (rv);
2347 }
2348