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