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