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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <crypt.h>
30 #include <cryptoutil.h>
31 #include <pwd.h>
32 #include <pthread.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <strings.h>
36 #include <sys/types.h>
37 #include <sys/sysmacros.h>
38 #include <security/cryptoki.h>
39 #include "softGlobal.h"
40 #include "softCrypt.h"
41 #include "softSession.h"
42 #include "softObject.h"
43 #include "softKeys.h"
44 #include "softKeystore.h"
45 #include "softKeystoreUtil.h"
46 #include "softRandom.h"
47 #include "softMAC.h"
48 #include "softOps.h"
49 
50 soft_session_t token_session;
51 boolean_t soft_token_present = B_FALSE;
52 
53 
54 /*
55  * Generate a 16-byte Initialization Vector (IV).
56  */
57 CK_RV
58 soft_gen_iv(CK_BYTE *iv)
59 {
60 
61 	return (soft_nzero_random_generator(iv, 16));
62 
63 }
64 
65 #define	PWD_BUFFER_SIZE	1024
66 
67 /*
68  * soft_gen_hashed_pin()
69  *
70  * Arguments:
71  *
72  *	pPin:	pointer to caller provided Pin
73  *	result:	output argument which contains the address of the
74  *		pointer to the hashed pin
75  *	salt:	input argument (if non-NULL), or
76  *		output argument (if NULL):
77  *		address of pointer to the "salt" of the hashed pin
78  *
79  * Description:
80  *
81  *	Generate a hashed pin using system provided crypt(3C) function.
82  *
83  * Returns:
84  *
85  *	0: no error
86  *	-1: some error occurred while generating the hashed pin
87  *
88  */
89 int
90 soft_gen_hashed_pin(CK_UTF8CHAR_PTR pPin, char **result, char **salt)
91 {
92 
93 	uid_t uid;
94 	struct passwd pwd, *pw;
95 	char pwdbuf[PWD_BUFFER_SIZE];
96 	boolean_t new_salt = B_FALSE;
97 
98 	/*
99 	 * We need to get the passwd entry of the application, which is required
100 	 * by the crypt_gensalt() below.
101 	 */
102 	uid = geteuid();
103 	if (getpwuid_r(uid, &pwd, pwdbuf, PWD_BUFFER_SIZE, &pw) != 0) {
104 		return (-1);
105 	}
106 
107 	if (*salt == NULL) {
108 		new_salt = B_TRUE;
109 		/*
110 		 * crypt_gensalt() will allocate memory to store the new salt.
111 		 * on return.
112 		 */
113 		if ((*salt = crypt_gensalt(NULL, pw)) == NULL) {
114 			return (-1);
115 		}
116 	}
117 
118 	if ((*result = crypt((char *)pPin, *salt)) == NULL) {
119 		if (new_salt)
120 			free(*salt);
121 		return (-1);
122 	}
123 
124 	return (0);
125 }
126 
127 /*
128  * Authenticate user's PIN for C_Login.
129  */
130 CK_RV
131 soft_verify_pin(CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
132 {
133 
134 	char	*user_cryptpin = NULL;
135 	char	*ks_cryptpin = NULL;
136 	char	*salt = NULL;
137 	uchar_t	*tmp_pin = NULL;
138 	boolean_t pin_initialized = B_FALSE;
139 	CK_RV	rv = CKR_OK;
140 
141 	/*
142 	 * Check to see if keystore is initialized.
143 	 */
144 	rv = soft_keystore_pin_initialized(&pin_initialized, &ks_cryptpin,
145 	    B_FALSE);
146 	if (rv != CKR_OK)
147 		return (rv);
148 
149 	/*
150 	 * Authenticate user's PIN for C_Login.
151 	 */
152 	if (pin_initialized) {
153 
154 		if (soft_keystore_get_pin_salt(&salt) < 0) {
155 			rv = CKR_FUNCTION_FAILED;
156 			goto cleanup;
157 		}
158 
159 		/*
160 		 * Generate the hashed value based on the user's supplied pin.
161 		 */
162 		tmp_pin = malloc(ulPinLen + 1);
163 		if (tmp_pin == NULL) {
164 			rv = CKR_HOST_MEMORY;
165 			goto cleanup;
166 		}
167 
168 		(void) memcpy(tmp_pin, pPin, ulPinLen);
169 		tmp_pin[ulPinLen] = '\0';
170 
171 		if (soft_gen_hashed_pin(tmp_pin, &user_cryptpin, &salt) < 0) {
172 			rv = CKR_FUNCTION_FAILED;
173 			goto cleanup;
174 		}
175 
176 		/*
177 		 * Compare hash value of the user supplied PIN with
178 		 * hash value of the keystore PIN.
179 		 */
180 		if (strcmp(user_cryptpin, ks_cryptpin) != 0) {
181 			rv = CKR_PIN_INCORRECT;
182 			goto cleanup;
183 		}
184 
185 		/*
186 		 * Provide the user's PIN to low-level keystore so that
187 		 * it can use it to generate encryption key as needed for
188 		 * encryption/decryption of the private objects in
189 		 * keystore.
190 		 */
191 		if (soft_keystore_authpin(tmp_pin) != 0) {
192 			rv = CKR_FUNCTION_FAILED;
193 		} else {
194 			rv = CKR_OK;
195 		}
196 		goto cleanup;
197 	} else {
198 		/*
199 		 * The PIN is not initialized in the keystore
200 		 * We will let it pass the authentication anyway but set the
201 		 * "userpin_change_needed" flag so that the application
202 		 * will get CKR_PIN_EXPIRED by other C_functions such as
203 		 * C_CreateObject, C_FindObjectInit, C_GenerateKey etc.
204 		 */
205 		soft_slot.userpin_change_needed = 1;
206 		rv = CKR_OK;
207 	}
208 
209 cleanup:
210 	if (salt)
211 		free(salt);
212 	if (tmp_pin)
213 		free(tmp_pin);
214 	if (ks_cryptpin)
215 		free(ks_cryptpin);
216 
217 	return (rv);
218 }
219 
220 /*
221  * The second level C_SetPIN function.
222  */
223 CK_RV
224 soft_setpin(CK_UTF8CHAR_PTR pOldPin, CK_ULONG ulOldPinLen,
225     CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewPinLen)
226 {
227 
228 	char	*user_cryptpin = NULL;
229 	char	*ks_cryptpin = NULL;
230 	char	*salt = NULL;
231 	boolean_t pin_initialized = B_FALSE;
232 	uchar_t	*tmp_old_pin = NULL, *tmp_new_pin = NULL;
233 	CK_RV	rv = CKR_OK;
234 
235 	/*
236 	 * Check to see if keystore is initialized.
237 	 */
238 	rv = soft_keystore_pin_initialized(&pin_initialized, &ks_cryptpin,
239 	    B_FALSE);
240 	if (rv != CKR_OK)
241 		return (rv);
242 
243 	/*
244 	 * Authenticate user's PIN for C_SetPIN.
245 	 */
246 	if (pin_initialized) {
247 		/*
248 		 * Generate the hashed value based on the user supplied PIN.
249 		 */
250 		if (soft_keystore_get_pin_salt(&salt) < 0) {
251 			rv = CKR_FUNCTION_FAILED;
252 			goto cleanup;
253 		}
254 
255 		tmp_old_pin = malloc(ulOldPinLen + 1);
256 		if (tmp_old_pin == NULL) {
257 			rv = CKR_HOST_MEMORY;
258 			goto cleanup;
259 		}
260 		(void) memcpy(tmp_old_pin, pOldPin, ulOldPinLen);
261 		tmp_old_pin[ulOldPinLen] = '\0';
262 
263 		if (soft_gen_hashed_pin(tmp_old_pin, &user_cryptpin,
264 		    &salt) < 0) {
265 			rv = CKR_FUNCTION_FAILED;
266 			goto cleanup;
267 		}
268 
269 		/*
270 		 * Compare hashed value of the user supplied PIN with the
271 		 * hashed value of the keystore PIN.
272 		 */
273 		if (strcmp(user_cryptpin, ks_cryptpin) != 0) {
274 			rv = CKR_PIN_INCORRECT;
275 			goto cleanup;
276 		}
277 	} else {
278 		/*
279 		 * This is the first time to setpin, the oldpin must be
280 		 * "changeme".
281 		 */
282 		if (strncmp("changeme", (const char *)pOldPin,
283 		    ulOldPinLen) != 0) {
284 			rv = CKR_PIN_INCORRECT;
285 			goto cleanup;
286 		}
287 	}
288 
289 	tmp_new_pin = malloc(ulNewPinLen + 1);
290 	if (tmp_new_pin == NULL) {
291 		rv = CKR_HOST_MEMORY;
292 		goto cleanup;
293 	}
294 	(void) memcpy(tmp_new_pin, pNewPin, ulNewPinLen);
295 	tmp_new_pin[ulNewPinLen] = '\0';
296 
297 	/*
298 	 * Set the new pin after the old pin is authenticated.
299 	 */
300 	if (soft_keystore_setpin(tmp_old_pin, tmp_new_pin, B_FALSE)) {
301 		rv = CKR_FUNCTION_FAILED;
302 		goto cleanup;
303 	} else {
304 		(void) pthread_mutex_lock(&soft_giant_mutex);
305 		soft_slot.userpin_change_needed = 0;
306 		(void) pthread_mutex_unlock(&soft_giant_mutex);
307 		rv = CKR_OK;
308 	}
309 
310 cleanup:
311 	if (salt)
312 		free(salt);
313 	if (ks_cryptpin)
314 		free(ks_cryptpin);
315 	if (tmp_old_pin)
316 		free(tmp_old_pin);
317 	if (tmp_new_pin)
318 		free(tmp_new_pin);
319 
320 	return (rv);
321 }
322 
323 /*
324  * soft_keystore_pack_obj()
325  *
326  * Arguments:
327  *
328  *	obj:	pointer to the soft_object_t of the token object to
329  *		be packed
330  *	ks_buf:	output argument which contains the address of the
331  *		pointer to the buf of the packed token object
332  *		soft_keystore_pack_obj() will allocate memory for the buf,
333  *		it is caller's responsibility to free it.
334  *	len:	output argument which contains the address of the
335  *		buffer length of the packed token object
336  *
337  * Description:
338  *
339  *	Pack the in-core token object into the keystore format.
340  *
341  * Returns:
342  *
343  *	CKR_OK: no error
344  *	Other: some error occurred while packing the object
345  *
346  */
347 CK_RV
348 soft_keystore_pack_obj(soft_object_t *obj, uchar_t **ks_buf, size_t *len)
349 {
350 	ks_obj_hdr_t hdr;
351 	ks_attr_hdr_t attr_hdr;
352 	CK_ATTRIBUTE_INFO_PTR extra_attr;
353 	int num_attrs = 0;
354 	ulong_t len_attrs = 0;
355 	size_t ks_len;
356 	uchar_t *buf, *buf1;
357 	CK_RV rv;
358 	int i;
359 
360 	(void) memset(&hdr, 0, sizeof (ks_obj_hdr_t));
361 
362 	/*
363 	 * The first part of the packed format contains
364 	 * the ks_obj_hdr_t struct.
365 	 */
366 	hdr.class = SWAP64((uint64_t)obj->class);
367 	hdr.key_type = SWAP64((uint64_t)obj->key_type);
368 	hdr.cert_type = SWAP64((uint64_t)obj->cert_type);
369 	hdr.bool_attr_mask = SWAP64(obj->bool_attr_mask);
370 	hdr.mechanism = SWAP64((uint64_t)obj->mechanism);
371 	hdr.object_type = obj->object_type;
372 
373 	/*
374 	 * The second part of the packed format contains
375 	 * the attributes from the extra atrribute list.
376 	 */
377 	extra_attr = obj->extra_attrlistp;
378 
379 	while (extra_attr) {
380 		num_attrs++;
381 		len_attrs += ROUNDUP(extra_attr->attr.ulValueLen, 8);
382 		extra_attr = extra_attr->next;
383 	}
384 	hdr.num_attrs = SWAP32(num_attrs);
385 	ks_len = soft_pack_object_size(obj);
386 	ks_len += sizeof (ks_obj_hdr_t) + len_attrs +
387 	    2 * num_attrs * sizeof (uint64_t);
388 	buf = calloc(1, ks_len);
389 	if (buf == NULL) {
390 		return (CKR_HOST_MEMORY);
391 	}
392 	(void) memcpy(buf, &hdr, sizeof (ks_obj_hdr_t));
393 	buf1 = buf + sizeof (ks_obj_hdr_t);
394 	extra_attr = obj->extra_attrlistp;
395 	for (i = 0; i < num_attrs; i++) {
396 		attr_hdr.type = SWAP64((uint64_t)extra_attr->attr.type);
397 		attr_hdr.ulValueLen =
398 		    SWAP64((uint64_t)extra_attr->attr.ulValueLen);
399 		(void) memcpy(buf1, &attr_hdr, sizeof (ks_attr_hdr_t));
400 		buf1 = buf1 + sizeof (ks_attr_hdr_t);
401 		(void) memcpy(buf1, extra_attr->attr.pValue,
402 		    extra_attr->attr.ulValueLen);
403 		buf1 = buf1 + ROUNDUP(extra_attr->attr.ulValueLen, 8);
404 		extra_attr = extra_attr->next;
405 	}
406 
407 	/*
408 	 * The third part of the packed format contains
409 	 * the key itself.
410 	 */
411 	rv = soft_pack_object(obj, buf1);
412 	*len = ks_len;
413 	*ks_buf = buf;
414 
415 	return (rv);
416 
417 }
418 
419 /*
420  * soft_keystore_unpack_obj()
421  *
422  * Arguments:
423  *
424  *	obj:	pointer to the soft_object_t to store the unpacked
425  *		token object
426  *	ks_obj:	input argument which contains the pointer to the
427  *		ks_obj_t struct of packed token object to be unpacked
428  *
429  * Description:
430  *
431  *	Unpack the token object in keystore format to in-core soft_object_t.
432  *
433  * Returns:
434  *
435  *	CKR_OK: no error
436  *	Other: some error occurred while unpacking the object
437  *
438  */
439 CK_RV
440 soft_keystore_unpack_obj(soft_object_t *obj, ks_obj_t *ks_obj)
441 {
442 
443 	CK_RV rv;
444 	ks_obj_hdr_t *hdr;
445 	ks_attr_hdr_t *attr_hdr;
446 	CK_ATTRIBUTE template;
447 	int i;
448 	uchar_t *buf;
449 
450 	/*
451 	 * Unpack the common area.
452 	 */
453 	(void) strcpy((char *)obj->ks_handle.name,
454 	    (char *)ks_obj->ks_handle.name);
455 	obj->ks_handle.public = ks_obj->ks_handle.public;
456 	/* LINTED: pointer alignment */
457 	hdr = (ks_obj_hdr_t *)ks_obj->buf;
458 	obj->version = ks_obj->obj_version;
459 	obj->class = (CK_OBJECT_CLASS)(SWAP64(hdr->class));
460 	obj->key_type = (CK_KEY_TYPE)(SWAP64(hdr->key_type));
461 	obj->cert_type = (CK_CERTIFICATE_TYPE)(SWAP64(hdr->cert_type));
462 	obj->bool_attr_mask = SWAP64(hdr->bool_attr_mask);
463 	obj->mechanism = (CK_MECHANISM_TYPE)(SWAP64(hdr->mechanism));
464 	obj->object_type = hdr->object_type;
465 
466 	/*
467 	 * Initialize other stuffs which were not from keystore.
468 	 */
469 	(void) pthread_mutex_init(&obj->object_mutex, NULL);
470 	obj->magic_marker = SOFTTOKEN_OBJECT_MAGIC;
471 	obj->session_handle = (CK_SESSION_HANDLE)NULL;
472 
473 	buf = ks_obj->buf + sizeof (ks_obj_hdr_t);
474 
475 	/*
476 	 * Unpack extra attribute list.
477 	 */
478 	for (i = 0; i < SWAP32(hdr->num_attrs); i++) {
479 		/* LINTED: pointer alignment */
480 		attr_hdr = (ks_attr_hdr_t *)buf;
481 		(void) memset(&template, 0, sizeof (CK_ATTRIBUTE));
482 		template.type = (CK_ATTRIBUTE_TYPE)(SWAP64(attr_hdr->type));
483 		template.ulValueLen = (CK_ULONG)(SWAP64(attr_hdr->ulValueLen));
484 		buf = buf + sizeof (ks_attr_hdr_t);
485 		/* Allocate storage for the value of the attribute. */
486 		if (template.ulValueLen > 0) {
487 			template.pValue = malloc(template.ulValueLen);
488 			if (template.pValue == NULL) {
489 				return (CKR_HOST_MEMORY);
490 			}
491 			(void) memcpy(template.pValue, buf,
492 			    template.ulValueLen);
493 		}
494 
495 		rv = soft_add_extra_attr(&template, obj);
496 		if (template.pValue) {
497 			free(template.pValue);
498 		}
499 
500 		if (rv != CKR_OK) {
501 			return (rv);
502 		}
503 
504 		buf = buf + ROUNDUP(template.ulValueLen, 8);
505 	}
506 
507 	/*
508 	 * Unpack the key itself.
509 	 */
510 	rv = soft_unpack_object(obj, buf);
511 	return (rv);
512 
513 }
514 
515 
516 /*
517  * soft_unpack_obj_attribute()
518  *
519  * Arguments:
520  *
521  *	buf:	contains the packed data (attributes) from keystore
522  *	key_dest: the key attribute will be unpacked and save in key_dest
523  *	cert_dest: the certificate attribute will be unpacked an
524  *		   in cert_dest
525  *	offset: length of the current attribute occupies.
526  *		The caller should use this returned "offset" to
527  *		advance the buffer pointer to next attribute.
528  *	cert:	TRUE for certificate (use cert_dest)
529  *		FALSE for key (use key_dest)
530  *
531  * Description:
532  *
533  *	Unpack the attribute from keystore format to the big integer format.
534  *
535  * Returns:
536  *
537  *	CKR_OK: no error
538  *	Other: some error occurred while unpacking the object attribute
539  *
540  */
541 CK_RV
542 soft_unpack_obj_attribute(uchar_t *buf, biginteger_t *key_dest,
543     cert_attr_t **cert_dest, ulong_t *offset, boolean_t cert)
544 {
545 
546 	CK_RV rv;
547 	CK_ATTRIBUTE template;
548 
549 	/* LINTED: pointer alignment */
550 	template.ulValueLen = SWAP64(*(uint64_t *)buf);
551 	buf = buf + sizeof (uint64_t);
552 	template.pValue = malloc(template.ulValueLen);
553 	if (template.pValue == NULL) {
554 		return (CKR_HOST_MEMORY);
555 	}
556 
557 	(void) memcpy(template.pValue, buf, template.ulValueLen);
558 	if (cert) {
559 		rv = get_cert_attr_from_template(cert_dest, &template);
560 	} else {
561 		rv = get_bigint_attr_from_template(key_dest, &template);
562 	}
563 
564 	free(template.pValue);
565 	if (rv != CKR_OK) {
566 		return (rv);
567 	}
568 
569 	*offset = sizeof (uint64_t) + template.ulValueLen;
570 	return (CKR_OK);
571 }
572 
573 
574 /*
575  * Calculate the total buffer length required to store the
576  * object key (the third part) in a keystore format.
577  */
578 ulong_t
579 soft_pack_object_size(soft_object_t *objp)
580 {
581 
582 	CK_OBJECT_CLASS class = objp->class;
583 	CK_KEY_TYPE	keytype = objp->key_type;
584 	CK_CERTIFICATE_TYPE certtype = objp->cert_type;
585 
586 	switch (class) {
587 	case CKO_PUBLIC_KEY:
588 		switch (keytype) {
589 		case CKK_RSA:
590 			/*
591 			 * modulus_bits + modulus_len + modulus +
592 			 * pubexpo_len + pubexpo
593 			 */
594 			return (ROUNDUP(((biginteger_t *)
595 			    OBJ_PUB_RSA_MOD(objp))->big_value_len, 8) +
596 			    ROUNDUP(((biginteger_t *)
597 			    OBJ_PUB_RSA_PUBEXPO(objp))->big_value_len, 8) +
598 			    3 * sizeof (uint64_t));
599 
600 		case CKK_DSA:
601 			/*
602 			 * prime_len + prime + subprime_len + subprime +
603 			 * base_len + base + value_len + value
604 			 */
605 			return (ROUNDUP(((biginteger_t *)
606 			    OBJ_PUB_DSA_PRIME(objp))->big_value_len, 8) +
607 			    ROUNDUP(((biginteger_t *)
608 			    OBJ_PUB_DSA_SUBPRIME(objp))->big_value_len, 8) +
609 			    ROUNDUP(((biginteger_t *)
610 			    OBJ_PUB_DSA_BASE(objp))->big_value_len, 8) +
611 			    ROUNDUP(((biginteger_t *)
612 			    OBJ_PUB_DSA_VALUE(objp))->big_value_len, 8) +
613 			    4 * sizeof (uint64_t));
614 
615 		case CKK_DH:
616 			/*
617 			 * prime_len + prime + base_len + base +
618 			 * value_len + value
619 			 */
620 			return (ROUNDUP(((biginteger_t *)
621 			    OBJ_PUB_DH_PRIME(objp))->big_value_len, 8) +
622 			    ROUNDUP(((biginteger_t *)
623 			    OBJ_PUB_DH_BASE(objp))->big_value_len, 8) +
624 			    ROUNDUP(((biginteger_t *)
625 			    OBJ_PUB_DH_VALUE(objp))->big_value_len, 8) +
626 			    3 * sizeof (uint64_t));
627 
628 		case CKK_X9_42_DH:
629 			/*
630 			 * prime_len + prime + base_len + base +
631 			 * subprime_len + subprime + value_len + value
632 			 */
633 			return (ROUNDUP(((biginteger_t *)
634 			    OBJ_PUB_DH942_PRIME(objp))->big_value_len, 8) +
635 			    ROUNDUP(((biginteger_t *)
636 			    OBJ_PUB_DH942_BASE(objp))->big_value_len, 8) +
637 			    ROUNDUP(((biginteger_t *)
638 			    OBJ_PUB_DH942_SUBPRIME(objp))->big_value_len, 8) +
639 			    ROUNDUP(((biginteger_t *)
640 			    OBJ_PUB_DH942_VALUE(objp))->big_value_len, 8) +
641 			    4 * sizeof (uint64_t));
642 		} /* keytype */
643 
644 		break;
645 
646 	case CKO_PRIVATE_KEY:
647 		switch (keytype) {
648 		case CKK_RSA:
649 			/*
650 			 * modulus_len + modulus + pubexpo_len + pubexpo +
651 			 * priexpo_len + priexpo + prime1_len + prime1 +
652 			 * prime2_len + prime2 + expo1_len + expo1 +
653 			 * expo2_len + expo2 + coef_len + coef
654 			 */
655 			return (ROUNDUP(((biginteger_t *)
656 			    OBJ_PRI_RSA_MOD(objp))->big_value_len, 8) +
657 			    ROUNDUP(((biginteger_t *)
658 			    OBJ_PRI_RSA_PUBEXPO(objp))->big_value_len, 8) +
659 			    ROUNDUP(((biginteger_t *)
660 			    OBJ_PRI_RSA_PRIEXPO(objp))->big_value_len, 8) +
661 			    ROUNDUP(((biginteger_t *)
662 			    OBJ_PRI_RSA_PRIME1(objp))->big_value_len, 8) +
663 			    ROUNDUP(((biginteger_t *)
664 			    OBJ_PRI_RSA_PRIME2(objp))->big_value_len, 8) +
665 			    ROUNDUP(((biginteger_t *)
666 			    OBJ_PRI_RSA_EXPO1(objp))->big_value_len, 8) +
667 			    ROUNDUP(((biginteger_t *)
668 			    OBJ_PRI_RSA_EXPO2(objp))->big_value_len, 8) +
669 			    ROUNDUP(((biginteger_t *)
670 			    OBJ_PRI_RSA_COEF(objp))->big_value_len, 8) +
671 			    8 * sizeof (uint64_t));
672 
673 		case CKK_DSA:
674 			/*
675 			 * prime_len + prime + subprime_len + subprime +
676 			 * base_len + base + value_len + value
677 			 */
678 			return (ROUNDUP(((biginteger_t *)
679 			    OBJ_PRI_DSA_PRIME(objp))->big_value_len, 8) +
680 			    ROUNDUP(((biginteger_t *)
681 			    OBJ_PRI_DSA_SUBPRIME(objp))->big_value_len, 8) +
682 			    ROUNDUP(((biginteger_t *)
683 			    OBJ_PRI_DSA_BASE(objp))->big_value_len, 8) +
684 			    ROUNDUP(((biginteger_t *)
685 			    OBJ_PRI_DSA_VALUE(objp))->big_value_len, 8) +
686 			    4 * sizeof (uint64_t));
687 
688 		case CKK_DH:
689 			/*
690 			 * value_bits + prime_len + prime + base_len + base +
691 			 * value_len + value
692 			 */
693 			return (ROUNDUP(((biginteger_t *)
694 			    OBJ_PRI_DH_PRIME(objp))->big_value_len, 8) +
695 			    ROUNDUP(((biginteger_t *)
696 			    OBJ_PRI_DH_BASE(objp))->big_value_len, 8) +
697 			    ROUNDUP(((biginteger_t *)
698 			    OBJ_PRI_DH_VALUE(objp))->big_value_len, 8) +
699 			    4 * sizeof (uint64_t));
700 
701 		case CKK_X9_42_DH:
702 			/*
703 			 * prime_len + prime + base_len + base +
704 			 * subprime_len + subprime + value_len + value
705 			 */
706 			return (ROUNDUP(((biginteger_t *)
707 			    OBJ_PRI_DH942_PRIME(objp))->big_value_len, 8) +
708 			    ROUNDUP(((biginteger_t *)
709 			    OBJ_PRI_DH942_BASE(objp))->big_value_len, 8) +
710 			    ROUNDUP(((biginteger_t *)
711 			    OBJ_PRI_DH942_SUBPRIME(objp))->big_value_len, 8) +
712 			    ROUNDUP(((biginteger_t *)
713 			    OBJ_PRI_DH942_VALUE(objp))->big_value_len, 8) +
714 			    4 * sizeof (uint64_t));
715 
716 		} /* keytype */
717 
718 		break;
719 
720 	case CKO_SECRET_KEY:
721 		/*
722 		 * value_len + value
723 		 */
724 		return (ROUNDUP(OBJ_SEC_VALUE_LEN(objp), 8) +
725 			sizeof (uint64_t));
726 
727 	case CKO_CERTIFICATE:
728 		switch (certtype) {
729 		case CKC_X_509:
730 			/*
731 			 * subject_len + subject + value_len + value
732 			 */
733 			return (ROUNDUP(((cert_attr_t *)
734 				X509_CERT_SUBJECT(objp))->length, 8) +
735 				ROUNDUP(((cert_attr_t *)
736 				X509_CERT_VALUE(objp))->length, 8) +
737 				2 * sizeof (uint64_t));
738 
739 		case CKC_X_509_ATTR_CERT:
740 			/*
741 			 * owner_len + owner + value_len + value
742 			 */
743 			return (ROUNDUP(((cert_attr_t *)
744 				X509_ATTR_CERT_OWNER(objp))->length, 8) +
745 				ROUNDUP(((cert_attr_t *)
746 				X509_ATTR_CERT_VALUE(objp))->length, 8) +
747 				2 * sizeof (uint64_t));
748 		}
749 		return (0);
750 
751 	case CKO_DOMAIN_PARAMETERS:
752 
753 		return (0);
754 	}
755 	return (0);
756 }
757 
758 /*
759  * Pack the object key (the third part) from the soft_object_t
760  * into the keystore format.
761  */
762 CK_RV
763 soft_pack_object(soft_object_t *objp, uchar_t *buf)
764 {
765 
766 	CK_OBJECT_CLASS class = objp->class;
767 	CK_KEY_TYPE	keytype = objp->key_type;
768 	CK_CERTIFICATE_TYPE certtype = objp->cert_type;
769 	uint64_t tmp_val;
770 
771 	switch (class) {
772 	case CKO_PUBLIC_KEY:
773 		switch (keytype) {
774 		case CKK_RSA:
775 			/* modulus_bits */
776 			tmp_val = SWAP64((uint64_t)OBJ_PUB_RSA_MOD_BITS(objp));
777 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
778 			buf = buf + sizeof (uint64_t);
779 
780 			/* modulus_len + modulus */
781 			tmp_val = SWAP64((uint64_t)(((biginteger_t *)
782 			    OBJ_PUB_RSA_MOD(objp))->big_value_len));
783 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
784 			buf = buf + sizeof (uint64_t);
785 
786 			(void) memcpy(buf, (char *)(((biginteger_t *)
787 			    OBJ_PUB_RSA_MOD(objp))->big_value),
788 			    ((biginteger_t *)
789 			    OBJ_PUB_RSA_MOD(objp))->big_value_len);
790 			buf = buf + ROUNDUP(((biginteger_t *)
791 			    OBJ_PUB_RSA_MOD(objp))->big_value_len, 8);
792 
793 			/* pubexpo_len + pubexpo */
794 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
795 			    OBJ_PUB_RSA_PUBEXPO(objp))->big_value_len);
796 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
797 			buf = buf + sizeof (uint64_t);
798 
799 			(void) memcpy(buf, (char *)(((biginteger_t *)
800 			    OBJ_PUB_RSA_PUBEXPO(objp))->big_value),
801 			    ((biginteger_t *)
802 			    OBJ_PUB_RSA_PUBEXPO(objp))->big_value_len);
803 			break;
804 
805 		case CKK_DSA:
806 			/* prime_len + prime */
807 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
808 			    OBJ_PUB_DSA_PRIME(objp))->big_value_len);
809 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
810 			buf = buf + sizeof (uint64_t);
811 
812 			(void) memcpy(buf, (char *)((biginteger_t *)
813 			    OBJ_PUB_DSA_PRIME(objp))->big_value,
814 			    ((biginteger_t *)
815 			    OBJ_PUB_DSA_PRIME(objp))->big_value_len);
816 			buf = buf + ROUNDUP(((biginteger_t *)
817 			    OBJ_PUB_DSA_PRIME(objp))->big_value_len, 8);
818 
819 			/* subprime_len + subprime */
820 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
821 			    OBJ_PUB_DSA_SUBPRIME(objp))->big_value_len);
822 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
823 			buf = buf + sizeof (uint64_t);
824 
825 			(void) memcpy(buf, (char *)((biginteger_t *)
826 			    OBJ_PUB_DSA_SUBPRIME(objp))->big_value,
827 			    ((biginteger_t *)
828 			    OBJ_PUB_DSA_SUBPRIME(objp))->big_value_len);
829 			buf = buf + ROUNDUP(((biginteger_t *)
830 			    OBJ_PUB_DSA_SUBPRIME(objp))->big_value_len, 8);
831 
832 			/* base_len + base */
833 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
834 			    OBJ_PUB_DSA_BASE(objp))->big_value_len);
835 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
836 			buf = buf + sizeof (uint64_t);
837 
838 			(void) memcpy(buf, (char *)((biginteger_t *)
839 			    OBJ_PUB_DSA_BASE(objp))->big_value,
840 			    ((biginteger_t *)
841 			    OBJ_PUB_DSA_BASE(objp))->big_value_len);
842 			buf = buf + ROUNDUP(((biginteger_t *)
843 			    OBJ_PUB_DSA_BASE(objp))->big_value_len, 8);
844 
845 			/* value_len + value */
846 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
847 			    OBJ_PUB_DSA_VALUE(objp))->big_value_len);
848 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
849 			buf = buf + sizeof (uint64_t);
850 
851 			(void) memcpy(buf, (char *)((biginteger_t *)
852 			    OBJ_PUB_DSA_VALUE(objp))->big_value,
853 			    ((biginteger_t *)
854 			    OBJ_PUB_DSA_VALUE(objp))->big_value_len);
855 
856 			break;
857 
858 		case CKK_DH:
859 			/* prime_len + prime */
860 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
861 			    OBJ_PUB_DH_PRIME(objp))->big_value_len);
862 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
863 			buf = buf + sizeof (uint64_t);
864 
865 			(void) memcpy(buf, (char *)((biginteger_t *)
866 			    OBJ_PUB_DH_PRIME(objp))->big_value,
867 			    ((biginteger_t *)
868 			    OBJ_PUB_DH_PRIME(objp))->big_value_len);
869 			buf = buf + ROUNDUP(((biginteger_t *)
870 			    OBJ_PUB_DH_PRIME(objp))->big_value_len, 8);
871 
872 			/* base_len + base */
873 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
874 			    OBJ_PUB_DH_BASE(objp))->big_value_len);
875 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
876 			buf = buf + sizeof (uint64_t);
877 
878 			(void) memcpy(buf, (char *)((biginteger_t *)
879 			    OBJ_PUB_DH_BASE(objp))->big_value,
880 			    ((biginteger_t *)
881 			    OBJ_PUB_DH_BASE(objp))->big_value_len);
882 			buf = buf + ROUNDUP(((biginteger_t *)
883 			    OBJ_PUB_DH_BASE(objp))->big_value_len, 8);
884 
885 			/* value_len + value */
886 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
887 			    OBJ_PUB_DH_VALUE(objp))->big_value_len);
888 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
889 			buf = buf + sizeof (uint64_t);
890 
891 			(void) memcpy(buf, (char *)((biginteger_t *)
892 			    OBJ_PUB_DH_VALUE(objp))->big_value,
893 			    ((biginteger_t *)
894 			    OBJ_PUB_DH_VALUE(objp))->big_value_len);
895 
896 			break;
897 
898 		case CKK_X9_42_DH:
899 			/* prime_len +  prime */
900 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
901 			    OBJ_PUB_DH942_PRIME(objp))->big_value_len);
902 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
903 			buf = buf + sizeof (uint64_t);
904 
905 			(void) memcpy(buf, (char *)((biginteger_t *)
906 			    OBJ_PUB_DH942_PRIME(objp))->big_value,
907 			    ((biginteger_t *)
908 			    OBJ_PUB_DH942_PRIME(objp))->big_value_len);
909 			buf = buf + ROUNDUP(((biginteger_t *)
910 			    OBJ_PUB_DH942_PRIME(objp))->big_value_len, 8);
911 
912 			/* base_len + base */
913 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
914 			    OBJ_PUB_DH942_BASE(objp))->big_value_len);
915 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
916 			buf = buf + sizeof (uint64_t);
917 
918 			(void) memcpy(buf, (char *)((biginteger_t *)
919 			    OBJ_PUB_DH942_BASE(objp))->big_value,
920 			    ((biginteger_t *)
921 			    OBJ_PUB_DH942_BASE(objp))->big_value_len);
922 			buf = buf + ROUNDUP(((biginteger_t *)
923 			    OBJ_PUB_DH942_BASE(objp))->big_value_len, 8);
924 
925 			/* subprime_len + subprime */
926 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
927 			    OBJ_PUB_DH942_SUBPRIME(objp))->big_value_len);
928 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
929 			buf = buf + sizeof (uint64_t);
930 
931 			(void) memcpy(buf, (char *)((biginteger_t *)
932 			    OBJ_PUB_DH942_SUBPRIME(objp))->big_value,
933 			    ((biginteger_t *)
934 			    OBJ_PUB_DH942_SUBPRIME(objp))->big_value_len);
935 			buf = buf + ROUNDUP(((biginteger_t *)
936 			    OBJ_PUB_DH942_SUBPRIME(objp))->big_value_len, 8);
937 
938 			/* value_len + value */
939 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
940 			    OBJ_PUB_DH942_VALUE(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_PUB_DH942_VALUE(objp))->big_value,
946 			    ((biginteger_t *)
947 			    OBJ_PUB_DH942_VALUE(objp))->big_value_len);
948 
949 			break;
950 		} /* keytype */
951 
952 		break;
953 
954 	case CKO_PRIVATE_KEY:
955 		switch (keytype) {
956 		case CKK_RSA:
957 			/* modulus_len + modulus */
958 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
959 			    OBJ_PRI_RSA_MOD(objp))->big_value_len);
960 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
961 			buf = buf + sizeof (uint64_t);
962 
963 			(void) memcpy(buf, (char *)((biginteger_t *)
964 			    OBJ_PRI_RSA_MOD(objp))->big_value,
965 			    ((biginteger_t *)
966 			    OBJ_PRI_RSA_MOD(objp))->big_value_len);
967 			buf = buf + ROUNDUP(((biginteger_t *)
968 			    OBJ_PRI_RSA_MOD(objp))->big_value_len, 8);
969 
970 			/* pubexpo_len + pubexpo */
971 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
972 			    OBJ_PRI_RSA_PUBEXPO(objp))->big_value_len);
973 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
974 			buf = buf + sizeof (uint64_t);
975 
976 			(void) memcpy(buf, (char *)((biginteger_t *)
977 			    OBJ_PRI_RSA_PUBEXPO(objp))->big_value,
978 			    ((biginteger_t *)
979 			    OBJ_PRI_RSA_PUBEXPO(objp))->big_value_len);
980 			buf = buf + ROUNDUP(((biginteger_t *)
981 			    OBJ_PRI_RSA_PUBEXPO(objp))->big_value_len, 8);
982 
983 			/* priexpo_len + priexpo */
984 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
985 			    OBJ_PRI_RSA_PRIEXPO(objp))->big_value_len);
986 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
987 			buf = buf + sizeof (uint64_t);
988 
989 			(void) memcpy(buf, (char *)((biginteger_t *)
990 			    OBJ_PRI_RSA_PRIEXPO(objp))->big_value,
991 			    ((biginteger_t *)
992 			    OBJ_PRI_RSA_PRIEXPO(objp))->big_value_len);
993 			buf = buf + ROUNDUP(((biginteger_t *)
994 			    OBJ_PRI_RSA_PRIEXPO(objp))->big_value_len, 8);
995 
996 			/* prime1_len + prime1 */
997 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
998 			    OBJ_PRI_RSA_PRIME1(objp))->big_value_len);
999 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1000 			buf = buf + sizeof (uint64_t);
1001 
1002 			(void) memcpy(buf, (char *)((biginteger_t *)
1003 			    OBJ_PRI_RSA_PRIME1(objp))->big_value,
1004 			    ((biginteger_t *)
1005 			    OBJ_PRI_RSA_PRIME1(objp))->big_value_len);
1006 			buf = buf + ROUNDUP(((biginteger_t *)
1007 			    OBJ_PRI_RSA_PRIME1(objp))->big_value_len, 8);
1008 
1009 			/* prime2_len + prime2 */
1010 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1011 			    OBJ_PRI_RSA_PRIME2(objp))->big_value_len);
1012 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1013 			buf = buf + sizeof (uint64_t);
1014 
1015 			(void) memcpy(buf, (char *)((biginteger_t *)
1016 			    OBJ_PRI_RSA_PRIME2(objp))->big_value,
1017 			    ((biginteger_t *)
1018 			    OBJ_PRI_RSA_PRIME2(objp))->big_value_len);
1019 			buf = buf + ROUNDUP(((biginteger_t *)
1020 			    OBJ_PRI_RSA_PRIME2(objp))->big_value_len, 8);
1021 
1022 			/* expo1_len + expo1 */
1023 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1024 			    OBJ_PRI_RSA_EXPO1(objp))->big_value_len);
1025 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1026 			buf = buf + sizeof (uint64_t);
1027 
1028 			(void) memcpy(buf, (char *)((biginteger_t *)
1029 			    OBJ_PRI_RSA_EXPO1(objp))->big_value,
1030 			    ((biginteger_t *)
1031 			    OBJ_PRI_RSA_EXPO1(objp))->big_value_len);
1032 			buf = buf + ROUNDUP(((biginteger_t *)
1033 			    OBJ_PRI_RSA_EXPO1(objp))->big_value_len, 8);
1034 
1035 			/* expo2_len + expo2 */
1036 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1037 			    OBJ_PRI_RSA_EXPO2(objp))->big_value_len);
1038 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1039 			buf = buf + sizeof (uint64_t);
1040 
1041 			(void) memcpy(buf, (char *)((biginteger_t *)
1042 			    OBJ_PRI_RSA_EXPO2(objp))->big_value,
1043 			    ((biginteger_t *)
1044 			    OBJ_PRI_RSA_EXPO2(objp))->big_value_len);
1045 			buf = buf + ROUNDUP(((biginteger_t *)
1046 			    OBJ_PRI_RSA_EXPO2(objp))->big_value_len, 8);
1047 
1048 			/* coef_len + coef */
1049 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1050 			    OBJ_PRI_RSA_COEF(objp))->big_value_len);
1051 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1052 			buf = buf + sizeof (uint64_t);
1053 
1054 			(void) memcpy(buf, (char *)((biginteger_t *)
1055 			    OBJ_PRI_RSA_COEF(objp))->big_value,
1056 			    ((biginteger_t *)
1057 			    OBJ_PRI_RSA_COEF(objp))->big_value_len);
1058 			buf = buf + ROUNDUP(((biginteger_t *)
1059 			    OBJ_PRI_RSA_COEF(objp))->big_value_len, 8);
1060 
1061 			break;
1062 
1063 		case CKK_DSA:
1064 			/* prime_len + prime */
1065 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1066 			    OBJ_PRI_DSA_PRIME(objp))->big_value_len);
1067 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1068 			buf = buf + sizeof (uint64_t);
1069 
1070 			(void) memcpy(buf, (char *)((biginteger_t *)
1071 			    OBJ_PRI_DSA_PRIME(objp))->big_value,
1072 			    ((biginteger_t *)
1073 			    OBJ_PRI_DSA_PRIME(objp))->big_value_len);
1074 			buf = buf + ROUNDUP(((biginteger_t *)
1075 			    OBJ_PRI_DSA_PRIME(objp))->big_value_len, 8);
1076 
1077 			/* subprime_len + subprime */
1078 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1079 			    OBJ_PRI_DSA_SUBPRIME(objp))->big_value_len);
1080 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1081 			buf = buf + sizeof (uint64_t);
1082 
1083 			(void) memcpy(buf, (char *)((biginteger_t *)
1084 			    OBJ_PRI_DSA_SUBPRIME(objp))->big_value,
1085 			    ((biginteger_t *)
1086 			    OBJ_PRI_DSA_SUBPRIME(objp))->big_value_len);
1087 			buf = buf + ROUNDUP(((biginteger_t *)
1088 			    OBJ_PRI_DSA_SUBPRIME(objp))->big_value_len, 8);
1089 
1090 			/* base_len + base */
1091 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1092 			    OBJ_PRI_DSA_BASE(objp))->big_value_len);
1093 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1094 			buf = buf + sizeof (uint64_t);
1095 
1096 			(void) memcpy(buf, (char *)((biginteger_t *)
1097 			    OBJ_PRI_DSA_BASE(objp))->big_value,
1098 			    ((biginteger_t *)
1099 			    OBJ_PRI_DSA_BASE(objp))->big_value_len);
1100 			buf = buf + ROUNDUP(((biginteger_t *)
1101 			    OBJ_PRI_DSA_BASE(objp))->big_value_len, 8);
1102 
1103 			/* value_len + value */
1104 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1105 			    OBJ_PRI_DSA_VALUE(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_DSA_VALUE(objp))->big_value,
1111 			    ((biginteger_t *)
1112 			    OBJ_PRI_DSA_VALUE(objp))->big_value_len);
1113 
1114 			break;
1115 
1116 		case CKK_DH:
1117 			/* value_bits */
1118 			tmp_val = SWAP64((uint64_t)OBJ_PRI_DH_VAL_BITS(objp));
1119 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1120 			buf = buf + sizeof (uint64_t);
1121 
1122 			/* prime_len + prime */
1123 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1124 			    OBJ_PRI_DH_PRIME(objp))->big_value_len);
1125 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1126 			buf = buf + sizeof (uint64_t);
1127 
1128 			(void) memcpy(buf, (char *)((biginteger_t *)
1129 			    OBJ_PRI_DH_PRIME(objp))->big_value,
1130 			    ((biginteger_t *)
1131 			    OBJ_PRI_DH_PRIME(objp))->big_value_len);
1132 			buf = buf + ROUNDUP(((biginteger_t *)
1133 			    OBJ_PRI_DH_PRIME(objp))->big_value_len, 8);
1134 
1135 			/* base_len + base */
1136 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1137 			    OBJ_PRI_DH_BASE(objp))->big_value_len);
1138 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1139 			buf = buf + sizeof (uint64_t);
1140 
1141 			(void) memcpy(buf, (char *)((biginteger_t *)
1142 			    OBJ_PRI_DH_BASE(objp))->big_value,
1143 			    ((biginteger_t *)
1144 			    OBJ_PRI_DH_BASE(objp))->big_value_len);
1145 			buf = buf + ROUNDUP(((biginteger_t *)
1146 			    OBJ_PRI_DH_BASE(objp))->big_value_len, 8);
1147 
1148 			/* value_len + value */
1149 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1150 			    OBJ_PRI_DH_VALUE(objp))->big_value_len);
1151 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1152 			buf = buf + sizeof (uint64_t);
1153 
1154 			(void) memcpy(buf, (char *)((biginteger_t *)
1155 			    OBJ_PRI_DH_VALUE(objp))->big_value,
1156 			    ((biginteger_t *)
1157 			    OBJ_PRI_DH_VALUE(objp))->big_value_len);
1158 
1159 			break;
1160 
1161 		case CKK_X9_42_DH:
1162 			/* prime_len + prime */
1163 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1164 			    OBJ_PRI_DH942_PRIME(objp))->big_value_len);
1165 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1166 			buf = buf + sizeof (uint64_t);
1167 
1168 			(void) memcpy(buf, (char *)((biginteger_t *)
1169 			    OBJ_PRI_DH942_PRIME(objp))->big_value,
1170 			    ((biginteger_t *)
1171 			    OBJ_PRI_DH942_PRIME(objp))->big_value_len);
1172 			buf = buf + ROUNDUP(((biginteger_t *)
1173 			    OBJ_PRI_DH942_PRIME(objp))->big_value_len, 8);
1174 
1175 			/* base_len + base */
1176 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1177 			    OBJ_PRI_DH942_BASE(objp))->big_value_len);
1178 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1179 			buf = buf + sizeof (uint64_t);
1180 
1181 			(void) memcpy(buf, (char *)((biginteger_t *)
1182 			    OBJ_PRI_DH942_BASE(objp))->big_value,
1183 			    ((biginteger_t *)
1184 			    OBJ_PRI_DH942_BASE(objp))->big_value_len);
1185 			buf = buf + ROUNDUP(((biginteger_t *)
1186 			    OBJ_PRI_DH942_BASE(objp))->big_value_len, 8);
1187 
1188 			/* subprime_len + subprime */
1189 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1190 			    OBJ_PRI_DH942_SUBPRIME(objp))->big_value_len);
1191 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1192 			buf = buf + sizeof (uint64_t);
1193 
1194 			(void) memcpy(buf, (char *)((biginteger_t *)
1195 			    OBJ_PRI_DH942_SUBPRIME(objp))->big_value,
1196 			    ((biginteger_t *)
1197 			    OBJ_PRI_DH942_SUBPRIME(objp))->big_value_len);
1198 			buf = buf + ROUNDUP(((biginteger_t *)
1199 			    OBJ_PRI_DH942_SUBPRIME(objp))->big_value_len, 8);
1200 
1201 			/* value_len + value */
1202 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
1203 			    OBJ_PRI_DH942_VALUE(objp))->big_value_len);
1204 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1205 			buf = buf + sizeof (uint64_t);
1206 
1207 			(void) memcpy(buf, (char *)((biginteger_t *)
1208 			    OBJ_PRI_DH942_VALUE(objp))->big_value,
1209 			    ((biginteger_t *)
1210 			    OBJ_PRI_DH942_VALUE(objp))->big_value_len);
1211 
1212 			break;
1213 
1214 		} /* keytype */
1215 
1216 		break;
1217 
1218 	case CKO_SECRET_KEY:
1219 		/* value_len  + value */
1220 		tmp_val = SWAP64((uint64_t)OBJ_SEC_VALUE_LEN(objp));
1221 		(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1222 		buf = buf + sizeof (uint64_t);
1223 
1224 		if (OBJ_SEC_VALUE_LEN(objp) > 0) {
1225 			(void) memcpy(buf, (char *)OBJ_SEC_VALUE(objp),
1226 			    OBJ_SEC_VALUE_LEN(objp));
1227 			buf = buf + ROUNDUP(OBJ_SEC_VALUE_LEN(objp), 8);
1228 		}
1229 
1230 		break;
1231 
1232 	case CKO_CERTIFICATE:
1233 
1234 		switch (certtype) {
1235 		case CKC_X_509:
1236 			/* subject_len + subject */
1237 			tmp_val = SWAP64((uint64_t)(((cert_attr_t *)
1238 			    X509_CERT_SUBJECT(objp))->length));
1239 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1240 			buf = buf + sizeof (uint64_t);
1241 
1242 			(void) memcpy(buf, (char *)((cert_attr_t *)
1243 			    X509_CERT_SUBJECT(objp))->value,
1244 			    ((cert_attr_t *)
1245 			    X509_CERT_SUBJECT(objp))->length);
1246 			buf = buf + ROUNDUP(((cert_attr_t *)
1247 			    X509_CERT_SUBJECT(objp))->length, 8);
1248 
1249 			/* value_len + value */
1250 			tmp_val = SWAP64((uint64_t)(((cert_attr_t *)
1251 			    X509_CERT_VALUE(objp))->length));
1252 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1253 			buf = buf + sizeof (uint64_t);
1254 
1255 			(void) memcpy(buf, (char *)((cert_attr_t *)
1256 			    X509_CERT_VALUE(objp))->value,
1257 			    ((cert_attr_t *)
1258 			    X509_CERT_VALUE(objp))->length);
1259 			break;
1260 
1261 		case CKC_X_509_ATTR_CERT:
1262 			/* owner_len + owner */
1263 			tmp_val = SWAP64((uint64_t)(((cert_attr_t *)
1264 			    X509_ATTR_CERT_OWNER(objp))->length));
1265 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1266 			buf = buf + sizeof (uint64_t);
1267 
1268 			(void) memcpy(buf, (char *)((cert_attr_t *)
1269 			    X509_ATTR_CERT_OWNER(objp))->value,
1270 			    ((cert_attr_t *)
1271 			    X509_ATTR_CERT_OWNER(objp))->length);
1272 			buf = buf + ROUNDUP(((cert_attr_t *)
1273 			    X509_ATTR_CERT_OWNER(objp))->length, 8);
1274 
1275 			/* value_len + value */
1276 			tmp_val = SWAP64((uint64_t)(((cert_attr_t *)
1277 			    X509_ATTR_CERT_VALUE(objp))->length));
1278 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
1279 			buf = buf + sizeof (uint64_t);
1280 
1281 			(void) memcpy(buf, (char *)((cert_attr_t *)
1282 			    X509_ATTR_CERT_VALUE(objp))->value,
1283 			    ((cert_attr_t *)
1284 			    X509_ATTR_CERT_VALUE(objp))->length);
1285 			break;
1286 		}
1287 		break;
1288 
1289 	case CKO_DOMAIN_PARAMETERS:
1290 
1291 		return (0);
1292 	}
1293 	return (CKR_OK);
1294 }
1295 
1296 /*
1297  * Unpack the object key in keystore format (the third part)
1298  * into soft_object_t.
1299  */
1300 CK_RV
1301 soft_unpack_object(soft_object_t *objp, uchar_t *buf)
1302 {
1303 
1304 	public_key_obj_t  *pbk;
1305 	private_key_obj_t *pvk;
1306 	secret_key_obj_t  *sck;
1307 	certificate_obj_t *cert;
1308 	CK_OBJECT_CLASS class = objp->class;
1309 	CK_KEY_TYPE	keytype = objp->key_type;
1310 	CK_CERTIFICATE_TYPE certtype = objp->cert_type;
1311 
1312 	biginteger_t	modulus;
1313 	biginteger_t	pubexpo;
1314 	biginteger_t	prime;
1315 	biginteger_t	subprime;
1316 	biginteger_t	base;
1317 	biginteger_t	value;
1318 
1319 	biginteger_t	priexpo;
1320 	biginteger_t	prime1;
1321 	biginteger_t	prime2;
1322 	biginteger_t	expo1;
1323 	biginteger_t	expo2;
1324 	biginteger_t	coef;
1325 	CK_RV 		rv = CKR_OK;
1326 	ulong_t offset = 0;
1327 	uint64_t tmp_val;
1328 
1329 	/* prevent bigint_attr_cleanup from freeing invalid attr value */
1330 	(void) memset(&modulus, 0x0, sizeof (biginteger_t));
1331 	(void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1332 	(void) memset(&prime, 0x0, sizeof (biginteger_t));
1333 	(void) memset(&subprime, 0x0, sizeof (biginteger_t));
1334 	(void) memset(&base, 0x0, sizeof (biginteger_t));
1335 	(void) memset(&value, 0x0, sizeof (biginteger_t));
1336 
1337 	(void) memset(&priexpo, 0x0, sizeof (biginteger_t));
1338 	(void) memset(&prime1, 0x0, sizeof (biginteger_t));
1339 	(void) memset(&prime2, 0x0, sizeof (biginteger_t));
1340 	(void) memset(&expo1, 0x0, sizeof (biginteger_t));
1341 	(void) memset(&expo2, 0x0, sizeof (biginteger_t));
1342 	(void) memset(&coef, 0x0, sizeof (biginteger_t));
1343 
1344 	switch (class) {
1345 
1346 	case CKO_PUBLIC_KEY:
1347 		/* Allocate storage for Public Key Object. */
1348 		pbk = calloc(1, sizeof (public_key_obj_t));
1349 		if (pbk == NULL) {
1350 			rv =  CKR_HOST_MEMORY;
1351 			return (rv);
1352 		}
1353 
1354 		objp->object_class_u.public_key = pbk;
1355 
1356 		switch (keytype) {
1357 		case CKK_RSA:			/* modulus_bits */
1358 			(void) memcpy(&tmp_val, buf, sizeof (uint64_t));
1359 			KEY_PUB_RSA_MOD_BITS(pbk) = (CK_ULONG)(SWAP64(tmp_val));
1360 			buf = buf + sizeof (uint64_t);
1361 
1362 			/* modulus */
1363 			if ((rv = soft_unpack_obj_attribute(buf, &modulus,
1364 			    NULL, &offset, B_FALSE)) != CKR_OK)
1365 				goto pub_cleanup;
1366 
1367 			copy_bigint_attr(&modulus, KEY_PUB_RSA_MOD(pbk));
1368 
1369 			buf += ROUNDUP(offset, 8);
1370 
1371 			/* pubexpo */
1372 			if ((rv = soft_unpack_obj_attribute(buf, &pubexpo,
1373 			    NULL, &offset, B_FALSE)) != CKR_OK)
1374 				goto pub_cleanup;
1375 
1376 			copy_bigint_attr(&pubexpo, KEY_PUB_RSA_PUBEXPO(pbk));
1377 
1378 			break;
1379 
1380 		case CKK_DSA:
1381 			/* prime */
1382 			if ((rv = soft_unpack_obj_attribute(buf, &prime,
1383 			    NULL, &offset, B_FALSE)) != CKR_OK)
1384 				goto pub_cleanup;
1385 
1386 			copy_bigint_attr(&prime, KEY_PUB_DSA_PRIME(pbk));
1387 
1388 			buf += ROUNDUP(offset, 8);
1389 
1390 			/* subprime */
1391 			if ((rv = soft_unpack_obj_attribute(buf, &subprime,
1392 			    NULL, &offset, B_FALSE)) != CKR_OK)
1393 				goto pub_cleanup;
1394 
1395 			copy_bigint_attr(&subprime, KEY_PUB_DSA_SUBPRIME(pbk));
1396 
1397 			buf += ROUNDUP(offset, 8);
1398 
1399 			/* base */
1400 			if ((rv = soft_unpack_obj_attribute(buf, &base,
1401 			    NULL, &offset, B_FALSE)) != CKR_OK)
1402 				goto pub_cleanup;
1403 
1404 			copy_bigint_attr(&base, KEY_PUB_DSA_BASE(pbk));
1405 
1406 			buf += ROUNDUP(offset, 8);
1407 
1408 			/* value */
1409 			if ((rv = soft_unpack_obj_attribute(buf, &value,
1410 			    NULL, &offset, B_FALSE)) != CKR_OK)
1411 				goto pub_cleanup;
1412 
1413 			copy_bigint_attr(&value, KEY_PUB_DSA_VALUE(pbk));
1414 
1415 			break;
1416 
1417 		case CKK_DH:
1418 			/* prime */
1419 			if ((rv = soft_unpack_obj_attribute(buf, &prime,
1420 			    NULL, &offset, B_FALSE)) != CKR_OK)
1421 				goto pub_cleanup;
1422 
1423 			copy_bigint_attr(&prime, KEY_PUB_DH_PRIME(pbk));
1424 
1425 			buf += ROUNDUP(offset, 8);
1426 
1427 			/* base */
1428 			if ((rv = soft_unpack_obj_attribute(buf, &base,
1429 			    NULL, &offset, B_FALSE)) != CKR_OK)
1430 				goto pub_cleanup;
1431 
1432 			copy_bigint_attr(&base, KEY_PUB_DH_BASE(pbk));
1433 
1434 			buf += ROUNDUP(offset, 8);
1435 
1436 			/* value */
1437 			if ((rv = soft_unpack_obj_attribute(buf, &value,
1438 			    NULL, &offset, B_FALSE)) != CKR_OK)
1439 				goto pub_cleanup;
1440 
1441 			copy_bigint_attr(&value, KEY_PUB_DH_VALUE(pbk));
1442 
1443 			break;
1444 
1445 		case CKK_X9_42_DH:
1446 			/* prime */
1447 			if ((rv = soft_unpack_obj_attribute(buf, &prime,
1448 			    NULL, &offset, B_FALSE)) != CKR_OK)
1449 				goto pub_cleanup;
1450 
1451 			copy_bigint_attr(&prime, KEY_PUB_DH942_PRIME(pbk));
1452 
1453 			buf += ROUNDUP(offset, 8);
1454 
1455 			/* base */
1456 			if ((rv = soft_unpack_obj_attribute(buf, &base,
1457 			    NULL, &offset, B_FALSE)) != CKR_OK)
1458 				goto pub_cleanup;
1459 
1460 			copy_bigint_attr(&base, KEY_PUB_DH942_BASE(pbk));
1461 
1462 			buf += ROUNDUP(offset, 8);
1463 
1464 			/* subprime */
1465 			if ((rv = soft_unpack_obj_attribute(buf, &subprime,
1466 			    NULL, &offset, B_FALSE)) != CKR_OK)
1467 				goto pub_cleanup;
1468 
1469 			copy_bigint_attr(&subprime,
1470 			    KEY_PUB_DH942_SUBPRIME(pbk));
1471 
1472 			buf += ROUNDUP(offset, 8);
1473 
1474 			/* value */
1475 			if ((rv = soft_unpack_obj_attribute(buf, &value,
1476 			    NULL, &offset, B_FALSE)) != CKR_OK)
1477 				goto pub_cleanup;
1478 
1479 			copy_bigint_attr(&value, KEY_PUB_DH942_VALUE(pbk));
1480 
1481 			break;
1482 		} /* keytype */
1483 
1484 		break;
1485 
1486 	case CKO_PRIVATE_KEY:
1487 		/* Allocate storage for Private Key Object. */
1488 		pvk = calloc(1, sizeof (private_key_obj_t));
1489 		if (pvk == NULL) {
1490 			rv = CKR_HOST_MEMORY;
1491 			return (rv);
1492 		}
1493 
1494 		objp->object_class_u.private_key = pvk;
1495 
1496 		switch (keytype) {
1497 		case CKK_RSA:
1498 			/* modulus */
1499 			if ((rv = soft_unpack_obj_attribute(buf, &modulus,
1500 			    NULL, &offset, B_FALSE)) != CKR_OK)
1501 				goto pri_cleanup;
1502 
1503 			copy_bigint_attr(&modulus, KEY_PRI_RSA_MOD(pvk));
1504 
1505 			buf += ROUNDUP(offset, 8);
1506 
1507 			/* pubexpo */
1508 			if ((rv = soft_unpack_obj_attribute(buf, &pubexpo,
1509 			    NULL, &offset, B_FALSE)) != CKR_OK)
1510 				goto pri_cleanup;
1511 
1512 			copy_bigint_attr(&pubexpo, KEY_PRI_RSA_PUBEXPO(pvk));
1513 
1514 			buf += ROUNDUP(offset, 8);
1515 
1516 			/* priexpo */
1517 			if ((rv = soft_unpack_obj_attribute(buf, &priexpo,
1518 			    NULL, &offset, B_FALSE)) != CKR_OK)
1519 				goto pri_cleanup;
1520 
1521 			copy_bigint_attr(&priexpo, KEY_PRI_RSA_PRIEXPO(pvk));
1522 
1523 			buf += ROUNDUP(offset, 8);
1524 
1525 			/* prime1 */
1526 			if ((rv = soft_unpack_obj_attribute(buf, &prime1,
1527 			    NULL, &offset, B_FALSE)) != CKR_OK)
1528 				goto pri_cleanup;
1529 
1530 			copy_bigint_attr(&prime1, KEY_PRI_RSA_PRIME1(pvk));
1531 
1532 			buf += ROUNDUP(offset, 8);
1533 
1534 			/* prime2 */
1535 			if ((rv = soft_unpack_obj_attribute(buf, &prime2,
1536 			    NULL, &offset, B_FALSE)) != CKR_OK)
1537 				goto pri_cleanup;
1538 
1539 			copy_bigint_attr(&prime2, KEY_PRI_RSA_PRIME2(pvk));
1540 
1541 			buf += ROUNDUP(offset, 8);
1542 
1543 			/* expo1 */
1544 			if ((rv = soft_unpack_obj_attribute(buf, &expo1,
1545 			    NULL, &offset, B_FALSE)) != CKR_OK)
1546 				goto pri_cleanup;
1547 
1548 			copy_bigint_attr(&expo1, KEY_PRI_RSA_EXPO1(pvk));
1549 
1550 			buf += ROUNDUP(offset, 8);
1551 
1552 			/* expo2 */
1553 			if ((rv = soft_unpack_obj_attribute(buf, &expo2,
1554 			    NULL, &offset, B_FALSE)) != CKR_OK)
1555 				goto pri_cleanup;
1556 
1557 			copy_bigint_attr(&expo2, KEY_PRI_RSA_EXPO2(pvk));
1558 
1559 			buf += ROUNDUP(offset, 8);
1560 
1561 			/* coef */
1562 			if ((rv = soft_unpack_obj_attribute(buf, &coef,
1563 			    NULL, &offset, B_FALSE)) != CKR_OK)
1564 				goto pri_cleanup;
1565 
1566 			copy_bigint_attr(&coef, KEY_PRI_RSA_COEF(pvk));
1567 
1568 			break;
1569 
1570 		case CKK_DSA:
1571 			/* prime */
1572 			if ((rv = soft_unpack_obj_attribute(buf, &prime,
1573 			    NULL, &offset, B_FALSE)) != CKR_OK)
1574 				goto pri_cleanup;
1575 
1576 			copy_bigint_attr(&prime, KEY_PRI_DSA_PRIME(pvk));
1577 
1578 			buf += ROUNDUP(offset, 8);
1579 
1580 			/* subprime */
1581 			if ((rv = soft_unpack_obj_attribute(buf, &subprime,
1582 			    NULL, &offset, B_FALSE)) != CKR_OK)
1583 				goto pri_cleanup;
1584 
1585 			copy_bigint_attr(&subprime, KEY_PRI_DSA_SUBPRIME(pvk));
1586 
1587 			buf += ROUNDUP(offset, 8);
1588 
1589 			/* base */
1590 			if ((rv = soft_unpack_obj_attribute(buf, &base,
1591 			    NULL, &offset, B_FALSE)) != CKR_OK)
1592 				goto pri_cleanup;
1593 
1594 			copy_bigint_attr(&base, KEY_PRI_DSA_BASE(pvk));
1595 
1596 			buf += ROUNDUP(offset, 8);
1597 
1598 			/* value */
1599 			if ((rv = soft_unpack_obj_attribute(buf, &value,
1600 			    NULL, &offset, B_FALSE)) != CKR_OK)
1601 				goto pri_cleanup;
1602 
1603 			copy_bigint_attr(&value, KEY_PRI_DSA_VALUE(pvk));
1604 
1605 			break;
1606 
1607 		case CKK_DH:
1608 			/* value_bits */
1609 			(void) memcpy(&tmp_val, buf, sizeof (uint64_t));
1610 			KEY_PRI_DH_VAL_BITS(pvk) = (CK_ULONG)(SWAP64(tmp_val));
1611 			buf = buf + sizeof (uint64_t);
1612 
1613 			/* prime */
1614 			if ((rv = soft_unpack_obj_attribute(buf, &prime,
1615 			    NULL, &offset, B_FALSE)) != CKR_OK)
1616 				goto pri_cleanup;
1617 
1618 			copy_bigint_attr(&prime, KEY_PRI_DH_PRIME(pvk));
1619 
1620 			buf += ROUNDUP(offset, 8);
1621 
1622 			/* base */
1623 			if ((rv = soft_unpack_obj_attribute(buf, &base,
1624 			    NULL, &offset, B_FALSE)) != CKR_OK)
1625 				goto pri_cleanup;
1626 
1627 			copy_bigint_attr(&base, KEY_PRI_DH_BASE(pvk));
1628 
1629 			buf += ROUNDUP(offset, 8);
1630 
1631 			/* value */
1632 			if ((rv = soft_unpack_obj_attribute(buf, &value,
1633 			    NULL, &offset, B_FALSE)) != CKR_OK)
1634 				goto pri_cleanup;
1635 
1636 			copy_bigint_attr(&value, KEY_PRI_DH_VALUE(pvk));
1637 
1638 			break;
1639 
1640 		case CKK_X9_42_DH:
1641 			/* prime */
1642 			if ((rv = soft_unpack_obj_attribute(buf, &prime,
1643 			    NULL, &offset, B_FALSE)) != CKR_OK)
1644 				goto pri_cleanup;
1645 
1646 			copy_bigint_attr(&prime, KEY_PRI_DH942_PRIME(pvk));
1647 
1648 			buf += ROUNDUP(offset, 8);
1649 
1650 			/* base */
1651 			if ((rv = soft_unpack_obj_attribute(buf, &base,
1652 			    NULL, &offset, B_FALSE)) != CKR_OK)
1653 				goto pri_cleanup;
1654 
1655 			copy_bigint_attr(&base, KEY_PRI_DH942_BASE(pvk));
1656 
1657 			buf += ROUNDUP(offset, 8);
1658 
1659 			/* subprime */
1660 			if ((rv = soft_unpack_obj_attribute(buf, &subprime,
1661 			    NULL, &offset, B_FALSE)) != CKR_OK)
1662 				goto pri_cleanup;
1663 
1664 			copy_bigint_attr(&subprime, KEY_PRI_DH942_BASE(pvk));
1665 
1666 			buf += ROUNDUP(offset, 8);
1667 
1668 			/* value */
1669 			if ((rv = soft_unpack_obj_attribute(buf, &value,
1670 			    NULL, &offset, B_FALSE)) != CKR_OK)
1671 				goto pri_cleanup;
1672 
1673 			copy_bigint_attr(&value, KEY_PRI_DH942_VALUE(pvk));
1674 
1675 			break;
1676 		} /* keytype */
1677 
1678 		break;
1679 
1680 	case CKO_SECRET_KEY:
1681 		/* Allocate storage for Secret Key Object. */
1682 		sck = calloc(1, sizeof (secret_key_obj_t));
1683 		if (sck == NULL) {
1684 			return (CKR_HOST_MEMORY);
1685 		}
1686 
1687 		objp->object_class_u.secret_key = sck;
1688 
1689 		/* value */
1690 		(void) memcpy((void *)&tmp_val, buf, sizeof (uint64_t));
1691 		OBJ_SEC_VALUE_LEN(objp) = (CK_ULONG)(SWAP64(tmp_val));
1692 		buf = buf + sizeof (uint64_t);
1693 
1694 		if (OBJ_SEC_VALUE_LEN(objp) > 0) {
1695 			OBJ_SEC_VALUE(objp) = malloc(OBJ_SEC_VALUE_LEN(objp));
1696 			if (OBJ_SEC_VALUE(objp) == NULL) {
1697 				free(sck);
1698 				return (CKR_HOST_MEMORY);
1699 			}
1700 			(void) memcpy(OBJ_SEC_VALUE(objp), buf,
1701 			    OBJ_SEC_VALUE_LEN(objp));
1702 
1703 			buf = buf + ROUNDUP(OBJ_SEC_VALUE_LEN(objp), 8);
1704 		}
1705 
1706 		return (rv);
1707 
1708 	case CKO_CERTIFICATE:
1709 		/* Allocate storage for Certificate Object. */
1710 		cert = calloc(1, sizeof (certificate_obj_t));
1711 		if (cert == NULL) {
1712 			return (CKR_HOST_MEMORY);
1713 		}
1714 		(void) memset((void *)cert, 0, sizeof (certificate_obj_t));
1715 
1716 		cert->certificate_type = certtype;
1717 		objp->object_class_u.certificate = cert;
1718 
1719 		switch (certtype) {
1720 		case CKC_X_509:
1721 			/* subject */
1722 			if ((rv = soft_unpack_obj_attribute(buf, NULL,
1723 			    &cert->cert_type_u.x509.subject,
1724 				&offset, B_TRUE)) != CKR_OK) {
1725 				free(cert);
1726 				return (rv);
1727 			}
1728 
1729 			buf += ROUNDUP(offset, 8);
1730 
1731 			/* value */
1732 			if ((rv = soft_unpack_obj_attribute(buf, NULL,
1733 			    &cert->cert_type_u.x509.value,
1734 				&offset, B_TRUE)) != CKR_OK) {
1735 				free(cert);
1736 				return (rv);
1737 			}
1738 
1739 			break;
1740 
1741 		case CKC_X_509_ATTR_CERT:
1742 			/* owner */
1743 			if ((rv = soft_unpack_obj_attribute(buf, NULL,
1744 			    &cert->cert_type_u.x509_attr.owner,
1745 				&offset, B_TRUE)) != CKR_OK) {
1746 				free(cert);
1747 				return (rv);
1748 			}
1749 
1750 			buf += ROUNDUP(offset, 8);
1751 
1752 			/* value */
1753 			if ((rv = soft_unpack_obj_attribute(buf, NULL,
1754 			    &cert->cert_type_u.x509_attr.value,
1755 				&offset, B_TRUE)) != CKR_OK) {
1756 				free(cert);
1757 				return (rv);
1758 			}
1759 
1760 			break;
1761 		}
1762 
1763 		return (rv);
1764 
1765 	case CKO_DOMAIN_PARAMETERS:
1766 
1767 		break;
1768 	}
1769 
1770 pub_cleanup:
1771 	/*
1772 	 * cleanup the storage allocated to the local variables.
1773 	 */
1774 	if (rv != CKR_OK)
1775 		free(pbk);
1776 	bigint_attr_cleanup(&modulus);
1777 	bigint_attr_cleanup(&pubexpo);
1778 	bigint_attr_cleanup(&prime);
1779 	bigint_attr_cleanup(&subprime);
1780 	bigint_attr_cleanup(&base);
1781 	bigint_attr_cleanup(&value);
1782 	return (rv);
1783 
1784 pri_cleanup:
1785 	/*
1786 	 * cleanup the storage allocated to the local variables.
1787 	 */
1788 	if (rv != CKR_OK)
1789 		free(pvk);
1790 	bigint_attr_cleanup(&modulus);
1791 	bigint_attr_cleanup(&priexpo);
1792 	bigint_attr_cleanup(&prime);
1793 	bigint_attr_cleanup(&subprime);
1794 	bigint_attr_cleanup(&base);
1795 	bigint_attr_cleanup(&value);
1796 	bigint_attr_cleanup(&pubexpo);
1797 	bigint_attr_cleanup(&prime1);
1798 	bigint_attr_cleanup(&prime2);
1799 	bigint_attr_cleanup(&expo1);
1800 	bigint_attr_cleanup(&expo2);
1801 	bigint_attr_cleanup(&coef);
1802 	return (rv);
1803 }
1804 
1805 
1806 /*
1807  * Store the token object to a keystore file.
1808  */
1809 CK_RV
1810 soft_put_object_to_keystore(soft_object_t *objp)
1811 {
1812 
1813 	uchar_t *buf;
1814 	size_t len;
1815 	CK_RV rv;
1816 
1817 	rv = soft_keystore_pack_obj(objp, &buf, &len);
1818 	if (rv != CKR_OK)
1819 		return (rv);
1820 
1821 	if (objp->object_type == TOKEN_PUBLIC) {
1822 		if ((soft_keystore_put_new_obj(buf, len, B_TRUE,
1823 		    B_FALSE, &objp->ks_handle)) == -1) {
1824 			free(buf);
1825 			return (CKR_FUNCTION_FAILED);
1826 		}
1827 	} else {
1828 		if ((soft_keystore_put_new_obj(buf, len, B_FALSE,
1829 		    B_FALSE, &objp->ks_handle)) == -1) {
1830 			free(buf);
1831 			return (CKR_FUNCTION_FAILED);
1832 		}
1833 	}
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