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