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