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