17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
590e0e8c4Sizick  * Common Development and Distribution License (the "License").
690e0e8c4Sizick  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22c5866e1dSPeter Shoults  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
23*cfcec266SJason King  * Copyright 2020 Joyent, Inc.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include <crypt.h>
277c478bd9Sstevel@tonic-gate #include <cryptoutil.h>
287c478bd9Sstevel@tonic-gate #include <pwd.h>
297c478bd9Sstevel@tonic-gate #include <pthread.h>
307c478bd9Sstevel@tonic-gate #include <stdlib.h>
317c478bd9Sstevel@tonic-gate #include <string.h>
327c478bd9Sstevel@tonic-gate #include <strings.h>
337c478bd9Sstevel@tonic-gate #include <sys/types.h>
347c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
357c478bd9Sstevel@tonic-gate #include <security/cryptoki.h>
367c478bd9Sstevel@tonic-gate #include "softGlobal.h"
377c478bd9Sstevel@tonic-gate #include "softCrypt.h"
387c478bd9Sstevel@tonic-gate #include "softSession.h"
397c478bd9Sstevel@tonic-gate #include "softObject.h"
407c478bd9Sstevel@tonic-gate #include "softKeys.h"
417c478bd9Sstevel@tonic-gate #include "softKeystore.h"
427c478bd9Sstevel@tonic-gate #include "softKeystoreUtil.h"
437c478bd9Sstevel@tonic-gate #include "softMAC.h"
447c478bd9Sstevel@tonic-gate #include "softOps.h"
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate soft_session_t token_session;
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate /*
497c478bd9Sstevel@tonic-gate  * soft_gen_hashed_pin()
507c478bd9Sstevel@tonic-gate  *
517c478bd9Sstevel@tonic-gate  * Arguments:
527c478bd9Sstevel@tonic-gate  *
537c478bd9Sstevel@tonic-gate  *	pPin:	pointer to caller provided Pin
547c478bd9Sstevel@tonic-gate  *	result:	output argument which contains the address of the
557c478bd9Sstevel@tonic-gate  *		pointer to the hashed pin
567c478bd9Sstevel@tonic-gate  *	salt:	input argument (if non-NULL), or
577c478bd9Sstevel@tonic-gate  *		output argument (if NULL):
587c478bd9Sstevel@tonic-gate  *		address of pointer to the "salt" of the hashed pin
597c478bd9Sstevel@tonic-gate  *
607c478bd9Sstevel@tonic-gate  * Description:
617c478bd9Sstevel@tonic-gate  *
627c478bd9Sstevel@tonic-gate  *	Generate a hashed pin using system provided crypt(3C) function.
637c478bd9Sstevel@tonic-gate  *
647c478bd9Sstevel@tonic-gate  * Returns:
657c478bd9Sstevel@tonic-gate  *
667c478bd9Sstevel@tonic-gate  *	0: no error
677c478bd9Sstevel@tonic-gate  *	-1: some error occurred while generating the hashed pin
687c478bd9Sstevel@tonic-gate  *
697c478bd9Sstevel@tonic-gate  */
707c478bd9Sstevel@tonic-gate int
soft_gen_hashed_pin(CK_UTF8CHAR_PTR pPin,char ** result,char ** salt)717c478bd9Sstevel@tonic-gate soft_gen_hashed_pin(CK_UTF8CHAR_PTR pPin, char **result, char **salt)
727c478bd9Sstevel@tonic-gate {
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate 	uid_t uid;
757c478bd9Sstevel@tonic-gate 	struct passwd pwd, *pw;
767c478bd9Sstevel@tonic-gate 	char pwdbuf[PWD_BUFFER_SIZE];
777c478bd9Sstevel@tonic-gate 	boolean_t new_salt = B_FALSE;
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate 	/*
807c478bd9Sstevel@tonic-gate 	 * We need to get the passwd entry of the application, which is required
817c478bd9Sstevel@tonic-gate 	 * by the crypt_gensalt() below.
827c478bd9Sstevel@tonic-gate 	 */
837c478bd9Sstevel@tonic-gate 	uid = geteuid();
847c478bd9Sstevel@tonic-gate 	if (getpwuid_r(uid, &pwd, pwdbuf, PWD_BUFFER_SIZE, &pw) != 0) {
857c478bd9Sstevel@tonic-gate 		return (-1);
867c478bd9Sstevel@tonic-gate 	}
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate 	if (*salt == NULL) {
897c478bd9Sstevel@tonic-gate 		new_salt = B_TRUE;
907c478bd9Sstevel@tonic-gate 		/*
917c478bd9Sstevel@tonic-gate 		 * crypt_gensalt() will allocate memory to store the new salt.
92c5866e1dSPeter Shoults 		 * on return.  Pass "$5" here to default to crypt_sha256 since
93c5866e1dSPeter Shoults 		 * SHA256 is a FIPS 140-2 certified algorithm and we shouldn't
94c5866e1dSPeter Shoults 		 * assume the system default is that strong.
957c478bd9Sstevel@tonic-gate 		 */
96c5866e1dSPeter Shoults 		if ((*salt = crypt_gensalt("$5", pw)) == NULL) {
977c478bd9Sstevel@tonic-gate 			return (-1);
987c478bd9Sstevel@tonic-gate 		}
997c478bd9Sstevel@tonic-gate 	}
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 	if ((*result = crypt((char *)pPin, *salt)) == NULL) {
102a8793c76SJason King 		if (new_salt) {
103a8793c76SJason King 			size_t saltlen = strlen(*salt) + 1;
104a8793c76SJason King 
105a8793c76SJason King 			freezero(*salt, saltlen);
106a8793c76SJason King 		}
1077c478bd9Sstevel@tonic-gate 		return (-1);
1087c478bd9Sstevel@tonic-gate 	}
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate 	return (0);
1117c478bd9Sstevel@tonic-gate }
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate /*
1147c478bd9Sstevel@tonic-gate  * Authenticate user's PIN for C_Login.
1157c478bd9Sstevel@tonic-gate  */
1167c478bd9Sstevel@tonic-gate CK_RV
soft_verify_pin(CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen)1177c478bd9Sstevel@tonic-gate soft_verify_pin(CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
1187c478bd9Sstevel@tonic-gate {
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate 	char	*user_cryptpin = NULL;
1217c478bd9Sstevel@tonic-gate 	char	*ks_cryptpin = NULL;
1227c478bd9Sstevel@tonic-gate 	char	*salt = NULL;
1237c478bd9Sstevel@tonic-gate 	uchar_t	*tmp_pin = NULL;
1247c478bd9Sstevel@tonic-gate 	boolean_t pin_initialized = B_FALSE;
1257c478bd9Sstevel@tonic-gate 	CK_RV	rv = CKR_OK;
126a8793c76SJason King 	size_t	len = 0;
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate 	/*
1297c478bd9Sstevel@tonic-gate 	 * Check to see if keystore is initialized.
1307c478bd9Sstevel@tonic-gate 	 */
1317c478bd9Sstevel@tonic-gate 	rv = soft_keystore_pin_initialized(&pin_initialized, &ks_cryptpin,
1327c478bd9Sstevel@tonic-gate 	    B_FALSE);
1337c478bd9Sstevel@tonic-gate 	if (rv != CKR_OK)
1347c478bd9Sstevel@tonic-gate 		return (rv);
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate 	/*
1377c478bd9Sstevel@tonic-gate 	 * Authenticate user's PIN for C_Login.
1387c478bd9Sstevel@tonic-gate 	 */
1397c478bd9Sstevel@tonic-gate 	if (pin_initialized) {
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate 		if (soft_keystore_get_pin_salt(&salt) < 0) {
1427c478bd9Sstevel@tonic-gate 			rv = CKR_FUNCTION_FAILED;
1437c478bd9Sstevel@tonic-gate 			goto cleanup;
1447c478bd9Sstevel@tonic-gate 		}
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate 		/*
1477c478bd9Sstevel@tonic-gate 		 * Generate the hashed value based on the user's supplied pin.
1487c478bd9Sstevel@tonic-gate 		 */
1497c478bd9Sstevel@tonic-gate 		tmp_pin = malloc(ulPinLen + 1);
1507c478bd9Sstevel@tonic-gate 		if (tmp_pin == NULL) {
1517c478bd9Sstevel@tonic-gate 			rv = CKR_HOST_MEMORY;
1527c478bd9Sstevel@tonic-gate 			goto cleanup;
1537c478bd9Sstevel@tonic-gate 		}
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate 		(void) memcpy(tmp_pin, pPin, ulPinLen);
1567c478bd9Sstevel@tonic-gate 		tmp_pin[ulPinLen] = '\0';
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate 		if (soft_gen_hashed_pin(tmp_pin, &user_cryptpin, &salt) < 0) {
1597c478bd9Sstevel@tonic-gate 			rv = CKR_FUNCTION_FAILED;
1607c478bd9Sstevel@tonic-gate 			goto cleanup;
1617c478bd9Sstevel@tonic-gate 		}
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate 		/*
1647c478bd9Sstevel@tonic-gate 		 * Compare hash value of the user supplied PIN with
1657c478bd9Sstevel@tonic-gate 		 * hash value of the keystore PIN.
1667c478bd9Sstevel@tonic-gate 		 */
1677c478bd9Sstevel@tonic-gate 		if (strcmp(user_cryptpin, ks_cryptpin) != 0) {
1687c478bd9Sstevel@tonic-gate 			rv = CKR_PIN_INCORRECT;
1697c478bd9Sstevel@tonic-gate 			goto cleanup;
1707c478bd9Sstevel@tonic-gate 		}
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate 		/*
1737c478bd9Sstevel@tonic-gate 		 * Provide the user's PIN to low-level keystore so that
1747c478bd9Sstevel@tonic-gate 		 * it can use it to generate encryption key as needed for
1757c478bd9Sstevel@tonic-gate 		 * encryption/decryption of the private objects in
1767c478bd9Sstevel@tonic-gate 		 * keystore.
1777c478bd9Sstevel@tonic-gate 		 */
1787c478bd9Sstevel@tonic-gate 		if (soft_keystore_authpin(tmp_pin) != 0) {
1797c478bd9Sstevel@tonic-gate 			rv = CKR_FUNCTION_FAILED;
1807c478bd9Sstevel@tonic-gate 		} else {
1817c478bd9Sstevel@tonic-gate 			rv = CKR_OK;
1827c478bd9Sstevel@tonic-gate 		}
1837c478bd9Sstevel@tonic-gate 		goto cleanup;
1847c478bd9Sstevel@tonic-gate 	} else {
1857c478bd9Sstevel@tonic-gate 		/*
1867c478bd9Sstevel@tonic-gate 		 * The PIN is not initialized in the keystore
1877c478bd9Sstevel@tonic-gate 		 * We will let it pass the authentication anyway but set the
1887c478bd9Sstevel@tonic-gate 		 * "userpin_change_needed" flag so that the application
1897c478bd9Sstevel@tonic-gate 		 * will get CKR_PIN_EXPIRED by other C_functions such as
1907c478bd9Sstevel@tonic-gate 		 * C_CreateObject, C_FindObjectInit, C_GenerateKey etc.
1917c478bd9Sstevel@tonic-gate 		 */
1927c478bd9Sstevel@tonic-gate 		soft_slot.userpin_change_needed = 1;
1937c478bd9Sstevel@tonic-gate 		rv = CKR_OK;
1947c478bd9Sstevel@tonic-gate 	}
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate cleanup:
197a8793c76SJason King 	if (salt) {
198a8793c76SJason King 		len = strlen(salt) + 1;
199a8793c76SJason King 		freezero(salt, len);
200a8793c76SJason King 	}
201a8793c76SJason King 	if (tmp_pin) {
202a8793c76SJason King 		len = strlen((char *)tmp_pin) + 1;
203a8793c76SJason King 		freezero(tmp_pin, len);
204a8793c76SJason King 	}
205a8793c76SJason King 	if (ks_cryptpin) {
206a8793c76SJason King 		len = strlen(ks_cryptpin) + 1;
207a8793c76SJason King 		freezero(ks_cryptpin, len);
208a8793c76SJason King 	}
2097c478bd9Sstevel@tonic-gate 	return (rv);
2107c478bd9Sstevel@tonic-gate }
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate /*
2137c478bd9Sstevel@tonic-gate  * The second level C_SetPIN function.
2147c478bd9Sstevel@tonic-gate  */
2157c478bd9Sstevel@tonic-gate CK_RV
soft_setpin(CK_UTF8CHAR_PTR pOldPin,CK_ULONG ulOldPinLen,CK_UTF8CHAR_PTR pNewPin,CK_ULONG ulNewPinLen)2167c478bd9Sstevel@tonic-gate soft_setpin(CK_UTF8CHAR_PTR pOldPin, CK_ULONG ulOldPinLen,
2177c478bd9Sstevel@tonic-gate     CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewPinLen)
2187c478bd9Sstevel@tonic-gate {
2197c478bd9Sstevel@tonic-gate 
2207c478bd9Sstevel@tonic-gate 	char	*user_cryptpin = NULL;
2217c478bd9Sstevel@tonic-gate 	char	*ks_cryptpin = NULL;
2227c478bd9Sstevel@tonic-gate 	char	*salt = NULL;
2237c478bd9Sstevel@tonic-gate 	boolean_t pin_initialized = B_FALSE;
2247c478bd9Sstevel@tonic-gate 	uchar_t	*tmp_old_pin = NULL, *tmp_new_pin = NULL;
2257c478bd9Sstevel@tonic-gate 	CK_RV	rv = CKR_OK;
226a8793c76SJason King 	size_t	len = 0;
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate 	/*
2297c478bd9Sstevel@tonic-gate 	 * Check to see if keystore is initialized.
2307c478bd9Sstevel@tonic-gate 	 */
2317c478bd9Sstevel@tonic-gate 	rv = soft_keystore_pin_initialized(&pin_initialized, &ks_cryptpin,
2327c478bd9Sstevel@tonic-gate 	    B_FALSE);
2337c478bd9Sstevel@tonic-gate 	if (rv != CKR_OK)
2347c478bd9Sstevel@tonic-gate 		return (rv);
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate 	/*
2377c478bd9Sstevel@tonic-gate 	 * Authenticate user's PIN for C_SetPIN.
2387c478bd9Sstevel@tonic-gate 	 */
2397c478bd9Sstevel@tonic-gate 	if (pin_initialized) {
2407c478bd9Sstevel@tonic-gate 		/*
2417c478bd9Sstevel@tonic-gate 		 * Generate the hashed value based on the user supplied PIN.
2427c478bd9Sstevel@tonic-gate 		 */
2437c478bd9Sstevel@tonic-gate 		if (soft_keystore_get_pin_salt(&salt) < 0) {
2447c478bd9Sstevel@tonic-gate 			rv = CKR_FUNCTION_FAILED;
2457c478bd9Sstevel@tonic-gate 			goto cleanup;
2467c478bd9Sstevel@tonic-gate 		}
2477c478bd9Sstevel@tonic-gate 
2487c478bd9Sstevel@tonic-gate 		tmp_old_pin = malloc(ulOldPinLen + 1);
2497c478bd9Sstevel@tonic-gate 		if (tmp_old_pin == NULL) {
2507c478bd9Sstevel@tonic-gate 			rv = CKR_HOST_MEMORY;
2517c478bd9Sstevel@tonic-gate 			goto cleanup;
2527c478bd9Sstevel@tonic-gate 		}
2537c478bd9Sstevel@tonic-gate 		(void) memcpy(tmp_old_pin, pOldPin, ulOldPinLen);
2547c478bd9Sstevel@tonic-gate 		tmp_old_pin[ulOldPinLen] = '\0';
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate 		if (soft_gen_hashed_pin(tmp_old_pin, &user_cryptpin,
2577c478bd9Sstevel@tonic-gate 		    &salt) < 0) {
2587c478bd9Sstevel@tonic-gate 			rv = CKR_FUNCTION_FAILED;
2597c478bd9Sstevel@tonic-gate 			goto cleanup;
2607c478bd9Sstevel@tonic-gate 		}
2617c478bd9Sstevel@tonic-gate 
2627c478bd9Sstevel@tonic-gate 		/*
2637c478bd9Sstevel@tonic-gate 		 * Compare hashed value of the user supplied PIN with the
2647c478bd9Sstevel@tonic-gate 		 * hashed value of the keystore PIN.
2657c478bd9Sstevel@tonic-gate 		 */
2667c478bd9Sstevel@tonic-gate 		if (strcmp(user_cryptpin, ks_cryptpin) != 0) {
2677c478bd9Sstevel@tonic-gate 			rv = CKR_PIN_INCORRECT;
2687c478bd9Sstevel@tonic-gate 			goto cleanup;
2697c478bd9Sstevel@tonic-gate 		}
2707c478bd9Sstevel@tonic-gate 	} else {
2717c478bd9Sstevel@tonic-gate 		/*
2727c478bd9Sstevel@tonic-gate 		 * This is the first time to setpin, the oldpin must be
2737c478bd9Sstevel@tonic-gate 		 * "changeme".
2747c478bd9Sstevel@tonic-gate 		 */
2757c478bd9Sstevel@tonic-gate 		if (strncmp("changeme", (const char *)pOldPin,
2767c478bd9Sstevel@tonic-gate 		    ulOldPinLen) != 0) {
2777c478bd9Sstevel@tonic-gate 			rv = CKR_PIN_INCORRECT;
2787c478bd9Sstevel@tonic-gate 			goto cleanup;
2797c478bd9Sstevel@tonic-gate 		}
2807c478bd9Sstevel@tonic-gate 	}
2817c478bd9Sstevel@tonic-gate 
2827c478bd9Sstevel@tonic-gate 	tmp_new_pin = malloc(ulNewPinLen + 1);
2837c478bd9Sstevel@tonic-gate 	if (tmp_new_pin == NULL) {
2847c478bd9Sstevel@tonic-gate 		rv = CKR_HOST_MEMORY;
2857c478bd9Sstevel@tonic-gate 		goto cleanup;
2867c478bd9Sstevel@tonic-gate 	}
2877c478bd9Sstevel@tonic-gate 	(void) memcpy(tmp_new_pin, pNewPin, ulNewPinLen);
2887c478bd9Sstevel@tonic-gate 	tmp_new_pin[ulNewPinLen] = '\0';
2897c478bd9Sstevel@tonic-gate 
2907c478bd9Sstevel@tonic-gate 	/*
2917c478bd9Sstevel@tonic-gate 	 * Set the new pin after the old pin is authenticated.
2927c478bd9Sstevel@tonic-gate 	 */
2937c478bd9Sstevel@tonic-gate 	if (soft_keystore_setpin(tmp_old_pin, tmp_new_pin, B_FALSE)) {
2947c478bd9Sstevel@tonic-gate 		rv = CKR_FUNCTION_FAILED;
2957c478bd9Sstevel@tonic-gate 		goto cleanup;
2967c478bd9Sstevel@tonic-gate 	} else {
2977c478bd9Sstevel@tonic-gate 		(void) pthread_mutex_lock(&soft_giant_mutex);
2987c478bd9Sstevel@tonic-gate 		soft_slot.userpin_change_needed = 0;
2997c478bd9Sstevel@tonic-gate 		(void) pthread_mutex_unlock(&soft_giant_mutex);
3007c478bd9Sstevel@tonic-gate 		rv = CKR_OK;
3017c478bd9Sstevel@tonic-gate 	}
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate cleanup:
304a8793c76SJason King 	if (salt) {
305a8793c76SJason King 		len = strlen(salt) + 1;
306a8793c76SJason King 		freezero(salt, len);
307a8793c76SJason King 	}
308a8793c76SJason King 	if (ks_cryptpin) {
309a8793c76SJason King 		len = strlen(ks_cryptpin) + 1;
310a8793c76SJason King 		freezero(ks_cryptpin, len);
311a8793c76SJason King 	}
312a8793c76SJason King 	if (tmp_old_pin) {
313a8793c76SJason King 		len = strlen((char *)tmp_old_pin) + 1;
314a8793c76SJason King 		freezero(tmp_old_pin, len);
315a8793c76SJason King 	}
316a8793c76SJason King 	if (tmp_new_pin) {
317a8793c76SJason King 		len = strlen((char *)tmp_new_pin) + 1;
318a8793c76SJason King 		freezero(tmp_new_pin, len);
319a8793c76SJason King 	}
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate 	return (rv);
3227c478bd9Sstevel@tonic-gate }
3237c478bd9Sstevel@tonic-gate 
3247c478bd9Sstevel@tonic-gate /*
3257c478bd9Sstevel@tonic-gate  * soft_keystore_pack_obj()
3267c478bd9Sstevel@tonic-gate  *
3277c478bd9Sstevel@tonic-gate  * Arguments:
3287c478bd9Sstevel@tonic-gate  *
3297c478bd9Sstevel@tonic-gate  *	obj:	pointer to the soft_object_t of the token object to
3307c478bd9Sstevel@tonic-gate  *		be packed
3317c478bd9Sstevel@tonic-gate  *	ks_buf:	output argument which contains the address of the
3327c478bd9Sstevel@tonic-gate  *		pointer to the buf of the packed token object
3337c478bd9Sstevel@tonic-gate  *		soft_keystore_pack_obj() will allocate memory for the buf,
3347c478bd9Sstevel@tonic-gate  *		it is caller's responsibility to free it.
3357c478bd9Sstevel@tonic-gate  *	len:	output argument which contains the address of the
3367c478bd9Sstevel@tonic-gate  *		buffer length of the packed token object
3377c478bd9Sstevel@tonic-gate  *
3387c478bd9Sstevel@tonic-gate  * Description:
3397c478bd9Sstevel@tonic-gate  *
3407c478bd9Sstevel@tonic-gate  *	Pack the in-core token object into the keystore format.
3417c478bd9Sstevel@tonic-gate  *
3427c478bd9Sstevel@tonic-gate  * Returns:
3437c478bd9Sstevel@tonic-gate  *
3447c478bd9Sstevel@tonic-gate  *	CKR_OK: no error
3457c478bd9Sstevel@tonic-gate  *	Other: some error occurred while packing the object
3467c478bd9Sstevel@tonic-gate  *
3477c478bd9Sstevel@tonic-gate  */
3487c478bd9Sstevel@tonic-gate CK_RV
soft_keystore_pack_obj(soft_object_t * obj,uchar_t ** ks_buf,size_t * len)3497c478bd9Sstevel@tonic-gate soft_keystore_pack_obj(soft_object_t *obj, uchar_t **ks_buf, size_t *len)
3507c478bd9Sstevel@tonic-gate {
3517c478bd9Sstevel@tonic-gate 	ks_obj_hdr_t hdr;
3527c478bd9Sstevel@tonic-gate 	ks_attr_hdr_t attr_hdr;
3537c478bd9Sstevel@tonic-gate 	CK_ATTRIBUTE_INFO_PTR extra_attr;
3547c478bd9Sstevel@tonic-gate 	int num_attrs = 0;
3557c478bd9Sstevel@tonic-gate 	ulong_t len_attrs = 0;
3567c478bd9Sstevel@tonic-gate 	size_t ks_len;
3577c478bd9Sstevel@tonic-gate 	uchar_t *buf, *buf1;
3587c478bd9Sstevel@tonic-gate 	CK_RV rv;
3597c478bd9Sstevel@tonic-gate 	int i;
3607c478bd9Sstevel@tonic-gate 
3617c478bd9Sstevel@tonic-gate 	(void) memset(&hdr, 0, sizeof (ks_obj_hdr_t));
3627c478bd9Sstevel@tonic-gate 
3637c478bd9Sstevel@tonic-gate 	/*
3647c478bd9Sstevel@tonic-gate 	 * The first part of the packed format contains
3657c478bd9Sstevel@tonic-gate 	 * the ks_obj_hdr_t struct.
3667c478bd9Sstevel@tonic-gate 	 */
3677c478bd9Sstevel@tonic-gate 	hdr.class = SWAP64((uint64_t)obj->class);
3687c478bd9Sstevel@tonic-gate 	hdr.key_type = SWAP64((uint64_t)obj->key_type);
3697c478bd9Sstevel@tonic-gate 	hdr.cert_type = SWAP64((uint64_t)obj->cert_type);
3707c478bd9Sstevel@tonic-gate 	hdr.bool_attr_mask = SWAP64(obj->bool_attr_mask);
3717c478bd9Sstevel@tonic-gate 	hdr.mechanism = SWAP64((uint64_t)obj->mechanism);
3727c478bd9Sstevel@tonic-gate 	hdr.object_type = obj->object_type;
3737c478bd9Sstevel@tonic-gate 
3747c478bd9Sstevel@tonic-gate 	/*
3757c478bd9Sstevel@tonic-gate 	 * The second part of the packed format contains
3767c478bd9Sstevel@tonic-gate 	 * the attributes from the extra atrribute list.
3777c478bd9Sstevel@tonic-gate 	 */
3787c478bd9Sstevel@tonic-gate 	extra_attr = obj->extra_attrlistp;
3797c478bd9Sstevel@tonic-gate 
3807c478bd9Sstevel@tonic-gate 	while (extra_attr) {
3817c478bd9Sstevel@tonic-gate 		num_attrs++;
3827c478bd9Sstevel@tonic-gate 		len_attrs += ROUNDUP(extra_attr->attr.ulValueLen, 8);
3837c478bd9Sstevel@tonic-gate 		extra_attr = extra_attr->next;
3847c478bd9Sstevel@tonic-gate 	}
3857c478bd9Sstevel@tonic-gate 	hdr.num_attrs = SWAP32(num_attrs);
3867c478bd9Sstevel@tonic-gate 	ks_len = soft_pack_object_size(obj);
3877c478bd9Sstevel@tonic-gate 	ks_len += sizeof (ks_obj_hdr_t) + len_attrs +
3887c478bd9Sstevel@tonic-gate 	    2 * num_attrs * sizeof (uint64_t);
3897c478bd9Sstevel@tonic-gate 	buf = calloc(1, ks_len);
3907c478bd9Sstevel@tonic-gate 	if (buf == NULL) {
3917c478bd9Sstevel@tonic-gate 		return (CKR_HOST_MEMORY);
3927c478bd9Sstevel@tonic-gate 	}
3937c478bd9Sstevel@tonic-gate 	(void) memcpy(buf, &hdr, sizeof (ks_obj_hdr_t));
3947c478bd9Sstevel@tonic-gate 	buf1 = buf + sizeof (ks_obj_hdr_t);
3957c478bd9Sstevel@tonic-gate 	extra_attr = obj->extra_attrlistp;
3967c478bd9Sstevel@tonic-gate 	for (i = 0; i < num_attrs; i++) {
3977c478bd9Sstevel@tonic-gate 		attr_hdr.type = SWAP64((uint64_t)extra_attr->attr.type);
3987c478bd9Sstevel@tonic-gate 		attr_hdr.ulValueLen =
3997c478bd9Sstevel@tonic-gate 		    SWAP64((uint64_t)extra_attr->attr.ulValueLen);
4007c478bd9Sstevel@tonic-gate 		(void) memcpy(buf1, &attr_hdr, sizeof (ks_attr_hdr_t));
4017c478bd9Sstevel@tonic-gate 		buf1 = buf1 + sizeof (ks_attr_hdr_t);
4027c478bd9Sstevel@tonic-gate 		(void) memcpy(buf1, extra_attr->attr.pValue,
4037c478bd9Sstevel@tonic-gate 		    extra_attr->attr.ulValueLen);
4047c478bd9Sstevel@tonic-gate 		buf1 = buf1 + ROUNDUP(extra_attr->attr.ulValueLen, 8);
4057c478bd9Sstevel@tonic-gate 		extra_attr = extra_attr->next;
4067c478bd9Sstevel@tonic-gate 	}
4077c478bd9Sstevel@tonic-gate 
4087c478bd9Sstevel@tonic-gate 	/*
4097c478bd9Sstevel@tonic-gate 	 * The third part of the packed format contains
4107c478bd9Sstevel@tonic-gate 	 * the key itself.
4117c478bd9Sstevel@tonic-gate 	 */
4127c478bd9Sstevel@tonic-gate 	rv = soft_pack_object(obj, buf1);
4137c478bd9Sstevel@tonic-gate 	*len = ks_len;
4147c478bd9Sstevel@tonic-gate 	*ks_buf = buf;
4157c478bd9Sstevel@tonic-gate 
4167c478bd9Sstevel@tonic-gate 	return (rv);
4177c478bd9Sstevel@tonic-gate 
4187c478bd9Sstevel@tonic-gate }
4197c478bd9Sstevel@tonic-gate 
4207c478bd9Sstevel@tonic-gate /*
4217c478bd9Sstevel@tonic-gate  * soft_keystore_unpack_obj()
4227c478bd9Sstevel@tonic-gate  *
4237c478bd9Sstevel@tonic-gate  * Arguments:
4247c478bd9Sstevel@tonic-gate  *
4257c478bd9Sstevel@tonic-gate  *	obj:	pointer to the soft_object_t to store the unpacked
4267c478bd9Sstevel@tonic-gate  *		token object
4277c478bd9Sstevel@tonic-gate  *	ks_obj:	input argument which contains the pointer to the
4287c478bd9Sstevel@tonic-gate  *		ks_obj_t struct of packed token object to be unpacked
4297c478bd9Sstevel@tonic-gate  *
4307c478bd9Sstevel@tonic-gate  * Description:
4317c478bd9Sstevel@tonic-gate  *
4327c478bd9Sstevel@tonic-gate  *	Unpack the token object in keystore format to in-core soft_object_t.
4337c478bd9Sstevel@tonic-gate  *
4347c478bd9Sstevel@tonic-gate  * Returns:
4357c478bd9Sstevel@tonic-gate  *
4367c478bd9Sstevel@tonic-gate  *	CKR_OK: no error
4377c478bd9Sstevel@tonic-gate  *	Other: some error occurred while unpacking the object
4387c478bd9Sstevel@tonic-gate  *
4397c478bd9Sstevel@tonic-gate  */
4407c478bd9Sstevel@tonic-gate CK_RV
soft_keystore_unpack_obj(soft_object_t * obj,ks_obj_t * ks_obj)4417c478bd9Sstevel@tonic-gate soft_keystore_unpack_obj(soft_object_t *obj, ks_obj_t *ks_obj)
4427c478bd9Sstevel@tonic-gate {
4437c478bd9Sstevel@tonic-gate 
4447c478bd9Sstevel@tonic-gate 	CK_RV rv;
4457c478bd9Sstevel@tonic-gate 	ks_obj_hdr_t *hdr;
4467c478bd9Sstevel@tonic-gate 	ks_attr_hdr_t *attr_hdr;
4477c478bd9Sstevel@tonic-gate 	CK_ATTRIBUTE template;
4487c478bd9Sstevel@tonic-gate 	int i;
4497c478bd9Sstevel@tonic-gate 	uchar_t *buf;
4507c478bd9Sstevel@tonic-gate 
4517c478bd9Sstevel@tonic-gate 	/*
4527c478bd9Sstevel@tonic-gate 	 * Unpack the common area.
4537c478bd9Sstevel@tonic-gate 	 */
4547c478bd9Sstevel@tonic-gate 	(void) strcpy((char *)obj->ks_handle.name,
4557c478bd9Sstevel@tonic-gate 	    (char *)ks_obj->ks_handle.name);
4567c478bd9Sstevel@tonic-gate 	obj->ks_handle.public = ks_obj->ks_handle.public;
4577c478bd9Sstevel@tonic-gate 	/* LINTED: pointer alignment */
4587c478bd9Sstevel@tonic-gate 	hdr = (ks_obj_hdr_t *)ks_obj->buf;
4597c478bd9Sstevel@tonic-gate 	obj->version = ks_obj->obj_version;
4607c478bd9Sstevel@tonic-gate 	obj->class = (CK_OBJECT_CLASS)(SWAP64(hdr->class));
4617c478bd9Sstevel@tonic-gate 	obj->key_type = (CK_KEY_TYPE)(SWAP64(hdr->key_type));
4627c478bd9Sstevel@tonic-gate 	obj->cert_type = (CK_CERTIFICATE_TYPE)(SWAP64(hdr->cert_type));
4637c478bd9Sstevel@tonic-gate 	obj->bool_attr_mask = SWAP64(hdr->bool_attr_mask);
4647c478bd9Sstevel@tonic-gate 	obj->mechanism = (CK_MECHANISM_TYPE)(SWAP64(hdr->mechanism));
4657c478bd9Sstevel@tonic-gate 	obj->object_type = hdr->object_type;
4667c478bd9Sstevel@tonic-gate 
4677c478bd9Sstevel@tonic-gate 	/*
4687c478bd9Sstevel@tonic-gate 	 * Initialize other stuffs which were not from keystore.
4697c478bd9Sstevel@tonic-gate 	 */
4707c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_init(&obj->object_mutex, NULL);
4717c478bd9Sstevel@tonic-gate 	obj->magic_marker = SOFTTOKEN_OBJECT_MAGIC;
4727c478bd9Sstevel@tonic-gate 	obj->session_handle = (CK_SESSION_HANDLE)NULL;
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate 	buf = ks_obj->buf + sizeof (ks_obj_hdr_t);
4757c478bd9Sstevel@tonic-gate 
4767c478bd9Sstevel@tonic-gate 	/*
4777c478bd9Sstevel@tonic-gate 	 * Unpack extra attribute list.
4787c478bd9Sstevel@tonic-gate 	 */
4797c478bd9Sstevel@tonic-gate 	for (i = 0; i < SWAP32(hdr->num_attrs); i++) {
4807c478bd9Sstevel@tonic-gate 		/* LINTED: pointer alignment */
4817c478bd9Sstevel@tonic-gate 		attr_hdr = (ks_attr_hdr_t *)buf;
4827c478bd9Sstevel@tonic-gate 		(void) memset(&template, 0, sizeof (CK_ATTRIBUTE));
4837c478bd9Sstevel@tonic-gate 		template.type = (CK_ATTRIBUTE_TYPE)(SWAP64(attr_hdr->type));
4847c478bd9Sstevel@tonic-gate 		template.ulValueLen = (CK_ULONG)(SWAP64(attr_hdr->ulValueLen));
4857c478bd9Sstevel@tonic-gate 		buf = buf + sizeof (ks_attr_hdr_t);
4867c478bd9Sstevel@tonic-gate 		/* Allocate storage for the value of the attribute. */
4877c478bd9Sstevel@tonic-gate 		if (template.ulValueLen > 0) {
4887c478bd9Sstevel@tonic-gate 			template.pValue = malloc(template.ulValueLen);
4897c478bd9Sstevel@tonic-gate 			if (template.pValue == NULL) {
4907c478bd9Sstevel@tonic-gate 				return (CKR_HOST_MEMORY);
4917c478bd9Sstevel@tonic-gate 			}
4927c478bd9Sstevel@tonic-gate 			(void) memcpy(template.pValue, buf,
4937c478bd9Sstevel@tonic-gate 			    template.ulValueLen);
4947c478bd9Sstevel@tonic-gate 		}
4957c478bd9Sstevel@tonic-gate 
4967c478bd9Sstevel@tonic-gate 		rv = soft_add_extra_attr(&template, obj);
497a8793c76SJason King 		freezero(template.pValue, template.ulValueLen);
4987c478bd9Sstevel@tonic-gate 
4997c478bd9Sstevel@tonic-gate 		if (rv != CKR_OK) {
5007c478bd9Sstevel@tonic-gate 			return (rv);
5017c478bd9Sstevel@tonic-gate 		}
5027c478bd9Sstevel@tonic-gate 
5037c478bd9Sstevel@tonic-gate 		buf = buf + ROUNDUP(template.ulValueLen, 8);
5047c478bd9Sstevel@tonic-gate 	}
5057c478bd9Sstevel@tonic-gate 
5067c478bd9Sstevel@tonic-gate 	/*
5077c478bd9Sstevel@tonic-gate 	 * Unpack the key itself.
5087c478bd9Sstevel@tonic-gate 	 */
5097c478bd9Sstevel@tonic-gate 	rv = soft_unpack_object(obj, buf);
5107c478bd9Sstevel@tonic-gate 	return (rv);
5117c478bd9Sstevel@tonic-gate 
5127c478bd9Sstevel@tonic-gate }
5137c478bd9Sstevel@tonic-gate 
5147c478bd9Sstevel@tonic-gate 
5157c478bd9Sstevel@tonic-gate /*
5167c478bd9Sstevel@tonic-gate  * soft_unpack_obj_attribute()
5177c478bd9Sstevel@tonic-gate  *
5187c478bd9Sstevel@tonic-gate  * Arguments:
5197c478bd9Sstevel@tonic-gate  *
5207c478bd9Sstevel@tonic-gate  *	buf:	contains the packed data (attributes) from keystore
5217c478bd9Sstevel@tonic-gate  *	key_dest: the key attribute will be unpacked and save in key_dest
5227c478bd9Sstevel@tonic-gate  *	cert_dest: the certificate attribute will be unpacked an
5237c478bd9Sstevel@tonic-gate  *		   in cert_dest
5247c478bd9Sstevel@tonic-gate  *	offset: length of the current attribute occupies.
5257c478bd9Sstevel@tonic-gate  *		The caller should use this returned "offset" to
5267c478bd9Sstevel@tonic-gate  *		advance the buffer pointer to next attribute.
5277c478bd9Sstevel@tonic-gate  *	cert:	TRUE for certificate (use cert_dest)
5287c478bd9Sstevel@tonic-gate  *		FALSE for key (use key_dest)
5297c478bd9Sstevel@tonic-gate  *
5307c478bd9Sstevel@tonic-gate  * Description:
5317c478bd9Sstevel@tonic-gate  *
5327c478bd9Sstevel@tonic-gate  *	Unpack the attribute from keystore format to the big integer format.
5337c478bd9Sstevel@tonic-gate  *
5347c478bd9Sstevel@tonic-gate  * Returns:
5357c478bd9Sstevel@tonic-gate  *
5367c478bd9Sstevel@tonic-gate  *	CKR_OK: no error
5377c478bd9Sstevel@tonic-gate  *	Other: some error occurred while unpacking the object attribute
5387c478bd9Sstevel@tonic-gate  *
5397c478bd9Sstevel@tonic-gate  */
5407c478bd9Sstevel@tonic-gate CK_RV
soft_unpack_obj_attribute(uchar_t * buf,biginteger_t * key_dest,cert_attr_t ** cert_dest,ulong_t * offset,boolean_t cert)5417c478bd9Sstevel@tonic-gate soft_unpack_obj_attribute(uchar_t *buf, biginteger_t *key_dest,
5427c478bd9Sstevel@tonic-gate     cert_attr_t **cert_dest, ulong_t *offset, boolean_t cert)
5437c478bd9Sstevel@tonic-gate {
5447c478bd9Sstevel@tonic-gate 
5457c478bd9Sstevel@tonic-gate 	CK_RV rv;
5467c478bd9Sstevel@tonic-gate 	CK_ATTRIBUTE template;
5477c478bd9Sstevel@tonic-gate 
5487c478bd9Sstevel@tonic-gate 	/* LINTED: pointer alignment */
5497c478bd9Sstevel@tonic-gate 	template.ulValueLen = SWAP64(*(uint64_t *)buf);
5507c478bd9Sstevel@tonic-gate 	buf = buf + sizeof (uint64_t);
5517c478bd9Sstevel@tonic-gate 	template.pValue = malloc(template.ulValueLen);
5527c478bd9Sstevel@tonic-gate 	if (template.pValue == NULL) {
5537c478bd9Sstevel@tonic-gate 		return (CKR_HOST_MEMORY);
5547c478bd9Sstevel@tonic-gate 	}
5557c478bd9Sstevel@tonic-gate 
5567c478bd9Sstevel@tonic-gate 	(void) memcpy(template.pValue, buf, template.ulValueLen);
5577c478bd9Sstevel@tonic-gate 	if (cert) {
5587c478bd9Sstevel@tonic-gate 		rv = get_cert_attr_from_template(cert_dest, &template);
5597c478bd9Sstevel@tonic-gate 	} else {
5607c478bd9Sstevel@tonic-gate 		rv = get_bigint_attr_from_template(key_dest, &template);
5617c478bd9Sstevel@tonic-gate 	}
5627c478bd9Sstevel@tonic-gate 
563a8793c76SJason King 	freezero(template.pValue, template.ulValueLen);
5647c478bd9Sstevel@tonic-gate 	if (rv != CKR_OK) {
5657c478bd9Sstevel@tonic-gate 		return (rv);
5667c478bd9Sstevel@tonic-gate 	}
5677c478bd9Sstevel@tonic-gate 
5687c478bd9Sstevel@tonic-gate 	*offset = sizeof (uint64_t) + template.ulValueLen;
5697c478bd9Sstevel@tonic-gate 	return (CKR_OK);
5707c478bd9Sstevel@tonic-gate }
5717c478bd9Sstevel@tonic-gate 
5727c478bd9Sstevel@tonic-gate 
5737c478bd9Sstevel@tonic-gate /*
5747c478bd9Sstevel@tonic-gate  * Calculate the total buffer length required to store the
5757c478bd9Sstevel@tonic-gate  * object key (the third part) in a keystore format.
5767c478bd9Sstevel@tonic-gate  */
5777c478bd9Sstevel@tonic-gate ulong_t
soft_pack_object_size(soft_object_t * objp)5787c478bd9Sstevel@tonic-gate soft_pack_object_size(soft_object_t *objp)
5797c478bd9Sstevel@tonic-gate {
5807c478bd9Sstevel@tonic-gate 
5817c478bd9Sstevel@tonic-gate 	CK_OBJECT_CLASS class = objp->class;
5827c478bd9Sstevel@tonic-gate 	CK_KEY_TYPE	keytype = objp->key_type;
5837c478bd9Sstevel@tonic-gate 	CK_CERTIFICATE_TYPE certtype = objp->cert_type;
5847c478bd9Sstevel@tonic-gate 
5857c478bd9Sstevel@tonic-gate 	switch (class) {
5867c478bd9Sstevel@tonic-gate 	case CKO_PUBLIC_KEY:
5877c478bd9Sstevel@tonic-gate 		switch (keytype) {
5887c478bd9Sstevel@tonic-gate 		case CKK_RSA:
5897c478bd9Sstevel@tonic-gate 			/*
5907c478bd9Sstevel@tonic-gate 			 * modulus_bits + modulus_len + modulus +
5917c478bd9Sstevel@tonic-gate 			 * pubexpo_len + pubexpo
5927c478bd9Sstevel@tonic-gate 			 */
5937c478bd9Sstevel@tonic-gate 			return (ROUNDUP(((biginteger_t *)
5947c478bd9Sstevel@tonic-gate 			    OBJ_PUB_RSA_MOD(objp))->big_value_len, 8) +
5957c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
5967c478bd9Sstevel@tonic-gate 			    OBJ_PUB_RSA_PUBEXPO(objp))->big_value_len, 8) +
5977c478bd9Sstevel@tonic-gate 			    3 * sizeof (uint64_t));
5987c478bd9Sstevel@tonic-gate 
5997c478bd9Sstevel@tonic-gate 		case CKK_DSA:
6007c478bd9Sstevel@tonic-gate 			/*
6017c478bd9Sstevel@tonic-gate 			 * prime_len + prime + subprime_len + subprime +
6027c478bd9Sstevel@tonic-gate 			 * base_len + base + value_len + value
6037c478bd9Sstevel@tonic-gate 			 */
6047c478bd9Sstevel@tonic-gate 			return (ROUNDUP(((biginteger_t *)
6057c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DSA_PRIME(objp))->big_value_len, 8) +
6067c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
6077c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DSA_SUBPRIME(objp))->big_value_len, 8) +
6087c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
6097c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DSA_BASE(objp))->big_value_len, 8) +
6107c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
6117c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DSA_VALUE(objp))->big_value_len, 8) +
6127c478bd9Sstevel@tonic-gate 			    4 * sizeof (uint64_t));
61326b0c172SWyllys Ingersoll 		case CKK_EC:
61426b0c172SWyllys Ingersoll 			/*
61526b0c172SWyllys Ingersoll 			 * ec_point_len + ec_point
61626b0c172SWyllys Ingersoll 			 */
61726b0c172SWyllys Ingersoll 			return (ROUNDUP(((biginteger_t *)
61826b0c172SWyllys Ingersoll 			    OBJ_PUB_EC_POINT(objp))->big_value_len, 8) +
61926b0c172SWyllys Ingersoll 			    sizeof (uint64_t));
6207c478bd9Sstevel@tonic-gate 		case CKK_DH:
6217c478bd9Sstevel@tonic-gate 			/*
6227c478bd9Sstevel@tonic-gate 			 * prime_len + prime + base_len + base +
6237c478bd9Sstevel@tonic-gate 			 * value_len + value
6247c478bd9Sstevel@tonic-gate 			 */
6257c478bd9Sstevel@tonic-gate 			return (ROUNDUP(((biginteger_t *)
6267c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH_PRIME(objp))->big_value_len, 8) +
6277c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
6287c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH_BASE(objp))->big_value_len, 8) +
6297c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
6307c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH_VALUE(objp))->big_value_len, 8) +
6317c478bd9Sstevel@tonic-gate 			    3 * sizeof (uint64_t));
6327c478bd9Sstevel@tonic-gate 
6337c478bd9Sstevel@tonic-gate 		case CKK_X9_42_DH:
6347c478bd9Sstevel@tonic-gate 			/*
6357c478bd9Sstevel@tonic-gate 			 * prime_len + prime + base_len + base +
6367c478bd9Sstevel@tonic-gate 			 * subprime_len + subprime + value_len + value
6377c478bd9Sstevel@tonic-gate 			 */
6387c478bd9Sstevel@tonic-gate 			return (ROUNDUP(((biginteger_t *)
6397c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH942_PRIME(objp))->big_value_len, 8) +
6407c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
6417c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH942_BASE(objp))->big_value_len, 8) +
6427c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
6437c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH942_SUBPRIME(objp))->big_value_len, 8) +
6447c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
6457c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH942_VALUE(objp))->big_value_len, 8) +
6467c478bd9Sstevel@tonic-gate 			    4 * sizeof (uint64_t));
6477c478bd9Sstevel@tonic-gate 		} /* keytype */
6487c478bd9Sstevel@tonic-gate 
6497c478bd9Sstevel@tonic-gate 		break;
6507c478bd9Sstevel@tonic-gate 
6517c478bd9Sstevel@tonic-gate 	case CKO_PRIVATE_KEY:
6527c478bd9Sstevel@tonic-gate 		switch (keytype) {
6537c478bd9Sstevel@tonic-gate 		case CKK_RSA:
6547c478bd9Sstevel@tonic-gate 			/*
6557c478bd9Sstevel@tonic-gate 			 * modulus_len + modulus + pubexpo_len + pubexpo +
6567c478bd9Sstevel@tonic-gate 			 * priexpo_len + priexpo + prime1_len + prime1 +
6577c478bd9Sstevel@tonic-gate 			 * prime2_len + prime2 + expo1_len + expo1 +
6587c478bd9Sstevel@tonic-gate 			 * expo2_len + expo2 + coef_len + coef
6597c478bd9Sstevel@tonic-gate 			 */
6607c478bd9Sstevel@tonic-gate 			return (ROUNDUP(((biginteger_t *)
6617c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_MOD(objp))->big_value_len, 8) +
6627c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
6637c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_PUBEXPO(objp))->big_value_len, 8) +
6647c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
6657c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_PRIEXPO(objp))->big_value_len, 8) +
6667c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
6677c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_PRIME1(objp))->big_value_len, 8) +
6687c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
6697c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_PRIME2(objp))->big_value_len, 8) +
6707c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
6717c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_EXPO1(objp))->big_value_len, 8) +
6727c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
6737c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_EXPO2(objp))->big_value_len, 8) +
6747c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
6757c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_COEF(objp))->big_value_len, 8) +
6767c478bd9Sstevel@tonic-gate 			    8 * sizeof (uint64_t));
6777c478bd9Sstevel@tonic-gate 
6787c478bd9Sstevel@tonic-gate 		case CKK_DSA:
6797c478bd9Sstevel@tonic-gate 			/*
6807c478bd9Sstevel@tonic-gate 			 * prime_len + prime + subprime_len + subprime +
6817c478bd9Sstevel@tonic-gate 			 * base_len + base + value_len + value
6827c478bd9Sstevel@tonic-gate 			 */
6837c478bd9Sstevel@tonic-gate 			return (ROUNDUP(((biginteger_t *)
6847c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DSA_PRIME(objp))->big_value_len, 8) +
6857c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
6867c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DSA_SUBPRIME(objp))->big_value_len, 8) +
6877c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
6887c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DSA_BASE(objp))->big_value_len, 8) +
6897c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
6907c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DSA_VALUE(objp))->big_value_len, 8) +
6917c478bd9Sstevel@tonic-gate 			    4 * sizeof (uint64_t));
6927c478bd9Sstevel@tonic-gate 
6937c478bd9Sstevel@tonic-gate 		case CKK_DH:
6947c478bd9Sstevel@tonic-gate 			/*
6957c478bd9Sstevel@tonic-gate 			 * value_bits + prime_len + prime + base_len + base +
6967c478bd9Sstevel@tonic-gate 			 * value_len + value
6977c478bd9Sstevel@tonic-gate 			 */
6987c478bd9Sstevel@tonic-gate 			return (ROUNDUP(((biginteger_t *)
6997c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH_PRIME(objp))->big_value_len, 8) +
7007c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
7017c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH_BASE(objp))->big_value_len, 8) +
7027c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
7037c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH_VALUE(objp))->big_value_len, 8) +
7047c478bd9Sstevel@tonic-gate 			    4 * sizeof (uint64_t));
7057c478bd9Sstevel@tonic-gate 
70626b0c172SWyllys Ingersoll 		case CKK_EC:
70726b0c172SWyllys Ingersoll 			/*
70826b0c172SWyllys Ingersoll 			 * value_len + value
70926b0c172SWyllys Ingersoll 			 */
71026b0c172SWyllys Ingersoll 			return (ROUNDUP(((biginteger_t *)
71126b0c172SWyllys Ingersoll 			    OBJ_PRI_EC_VALUE(objp))->big_value_len, 8) +
71226b0c172SWyllys Ingersoll 			    sizeof (uint64_t));
71326b0c172SWyllys Ingersoll 
7147c478bd9Sstevel@tonic-gate 		case CKK_X9_42_DH:
7157c478bd9Sstevel@tonic-gate 			/*
7167c478bd9Sstevel@tonic-gate 			 * prime_len + prime + base_len + base +
7177c478bd9Sstevel@tonic-gate 			 * subprime_len + subprime + value_len + value
7187c478bd9Sstevel@tonic-gate 			 */
7197c478bd9Sstevel@tonic-gate 			return (ROUNDUP(((biginteger_t *)
7207c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH942_PRIME(objp))->big_value_len, 8) +
7217c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
7227c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH942_BASE(objp))->big_value_len, 8) +
7237c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
7247c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH942_SUBPRIME(objp))->big_value_len, 8) +
7257c478bd9Sstevel@tonic-gate 			    ROUNDUP(((biginteger_t *)
7267c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH942_VALUE(objp))->big_value_len, 8) +
7277c478bd9Sstevel@tonic-gate 			    4 * sizeof (uint64_t));
7287c478bd9Sstevel@tonic-gate 
7297c478bd9Sstevel@tonic-gate 		} /* keytype */
7307c478bd9Sstevel@tonic-gate 
7317c478bd9Sstevel@tonic-gate 		break;
7327c478bd9Sstevel@tonic-gate 
7337c478bd9Sstevel@tonic-gate 	case CKO_SECRET_KEY:
7347c478bd9Sstevel@tonic-gate 		/*
7357c478bd9Sstevel@tonic-gate 		 * value_len + value
7367c478bd9Sstevel@tonic-gate 		 */
7377c478bd9Sstevel@tonic-gate 		return (ROUNDUP(OBJ_SEC_VALUE_LEN(objp), 8) +
7387b79d846SDina K Nimeh 		    sizeof (uint64_t));
7397c478bd9Sstevel@tonic-gate 
7407c478bd9Sstevel@tonic-gate 	case CKO_CERTIFICATE:
7417c478bd9Sstevel@tonic-gate 		switch (certtype) {
7427c478bd9Sstevel@tonic-gate 		case CKC_X_509:
7437c478bd9Sstevel@tonic-gate 			/*
7447c478bd9Sstevel@tonic-gate 			 * subject_len + subject + value_len + value
7457c478bd9Sstevel@tonic-gate 			 */
7467c478bd9Sstevel@tonic-gate 			return (ROUNDUP(((cert_attr_t *)
7477b79d846SDina K Nimeh 			    X509_CERT_SUBJECT(objp))->length, 8) +
7487b79d846SDina K Nimeh 			    ROUNDUP(((cert_attr_t *)
7497b79d846SDina K Nimeh 			    X509_CERT_VALUE(objp))->length, 8) +
7507b79d846SDina K Nimeh 			    2 * sizeof (uint64_t));
7517c478bd9Sstevel@tonic-gate 
7527c478bd9Sstevel@tonic-gate 		case CKC_X_509_ATTR_CERT:
7537c478bd9Sstevel@tonic-gate 			/*
7547c478bd9Sstevel@tonic-gate 			 * owner_len + owner + value_len + value
7557c478bd9Sstevel@tonic-gate 			 */
7567c478bd9Sstevel@tonic-gate 			return (ROUNDUP(((cert_attr_t *)
7577b79d846SDina K Nimeh 			    X509_ATTR_CERT_OWNER(objp))->length, 8) +
7587b79d846SDina K Nimeh 			    ROUNDUP(((cert_attr_t *)
7597b79d846SDina K Nimeh 			    X509_ATTR_CERT_VALUE(objp))->length, 8) +
7607b79d846SDina K Nimeh 			    2 * sizeof (uint64_t));
7617c478bd9Sstevel@tonic-gate 		}
7627c478bd9Sstevel@tonic-gate 		return (0);
7637c478bd9Sstevel@tonic-gate 
7647c478bd9Sstevel@tonic-gate 	case CKO_DOMAIN_PARAMETERS:
7657c478bd9Sstevel@tonic-gate 
7667c478bd9Sstevel@tonic-gate 		return (0);
7677c478bd9Sstevel@tonic-gate 	}
7687c478bd9Sstevel@tonic-gate 	return (0);
7697c478bd9Sstevel@tonic-gate }
7707c478bd9Sstevel@tonic-gate 
7717c478bd9Sstevel@tonic-gate /*
7727c478bd9Sstevel@tonic-gate  * Pack the object key (the third part) from the soft_object_t
7737c478bd9Sstevel@tonic-gate  * into the keystore format.
7747c478bd9Sstevel@tonic-gate  */
7757c478bd9Sstevel@tonic-gate CK_RV
soft_pack_object(soft_object_t * objp,uchar_t * buf)7767c478bd9Sstevel@tonic-gate soft_pack_object(soft_object_t *objp, uchar_t *buf)
7777c478bd9Sstevel@tonic-gate {
7787c478bd9Sstevel@tonic-gate 
7797c478bd9Sstevel@tonic-gate 	CK_OBJECT_CLASS class = objp->class;
7807c478bd9Sstevel@tonic-gate 	CK_KEY_TYPE	keytype = objp->key_type;
7817c478bd9Sstevel@tonic-gate 	CK_CERTIFICATE_TYPE certtype = objp->cert_type;
7827c478bd9Sstevel@tonic-gate 	uint64_t tmp_val;
7837c478bd9Sstevel@tonic-gate 
7847c478bd9Sstevel@tonic-gate 	switch (class) {
7857c478bd9Sstevel@tonic-gate 	case CKO_PUBLIC_KEY:
7867c478bd9Sstevel@tonic-gate 		switch (keytype) {
7877c478bd9Sstevel@tonic-gate 		case CKK_RSA:
7887c478bd9Sstevel@tonic-gate 			/* modulus_bits */
7897c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)OBJ_PUB_RSA_MOD_BITS(objp));
7907c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
7917c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
7927c478bd9Sstevel@tonic-gate 
7937c478bd9Sstevel@tonic-gate 			/* modulus_len + modulus */
7947c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)(((biginteger_t *)
7957c478bd9Sstevel@tonic-gate 			    OBJ_PUB_RSA_MOD(objp))->big_value_len));
7967c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
7977c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
7987c478bd9Sstevel@tonic-gate 
7997c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)(((biginteger_t *)
8007c478bd9Sstevel@tonic-gate 			    OBJ_PUB_RSA_MOD(objp))->big_value),
8017c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
8027c478bd9Sstevel@tonic-gate 			    OBJ_PUB_RSA_MOD(objp))->big_value_len);
8037c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
8047c478bd9Sstevel@tonic-gate 			    OBJ_PUB_RSA_MOD(objp))->big_value_len, 8);
8057c478bd9Sstevel@tonic-gate 
8067c478bd9Sstevel@tonic-gate 			/* pubexpo_len + pubexpo */
8077c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
8087c478bd9Sstevel@tonic-gate 			    OBJ_PUB_RSA_PUBEXPO(objp))->big_value_len);
8097c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
8107c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
8117c478bd9Sstevel@tonic-gate 
8127c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)(((biginteger_t *)
8137c478bd9Sstevel@tonic-gate 			    OBJ_PUB_RSA_PUBEXPO(objp))->big_value),
8147c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
8157c478bd9Sstevel@tonic-gate 			    OBJ_PUB_RSA_PUBEXPO(objp))->big_value_len);
8167c478bd9Sstevel@tonic-gate 			break;
8177c478bd9Sstevel@tonic-gate 
8187c478bd9Sstevel@tonic-gate 		case CKK_DSA:
8197c478bd9Sstevel@tonic-gate 			/* prime_len + prime */
8207c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
8217c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DSA_PRIME(objp))->big_value_len);
8227c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
8237c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
8247c478bd9Sstevel@tonic-gate 
8257c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
8267c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DSA_PRIME(objp))->big_value,
8277c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
8287c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DSA_PRIME(objp))->big_value_len);
8297c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
8307c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DSA_PRIME(objp))->big_value_len, 8);
8317c478bd9Sstevel@tonic-gate 
8327c478bd9Sstevel@tonic-gate 			/* subprime_len + subprime */
8337c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
8347c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DSA_SUBPRIME(objp))->big_value_len);
8357c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
8367c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
8377c478bd9Sstevel@tonic-gate 
8387c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
8397c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DSA_SUBPRIME(objp))->big_value,
8407c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
8417c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DSA_SUBPRIME(objp))->big_value_len);
8427c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
8437c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DSA_SUBPRIME(objp))->big_value_len, 8);
8447c478bd9Sstevel@tonic-gate 
8457c478bd9Sstevel@tonic-gate 			/* base_len + base */
8467c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
8477c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DSA_BASE(objp))->big_value_len);
8487c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
8497c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
8507c478bd9Sstevel@tonic-gate 
8517c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
8527c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DSA_BASE(objp))->big_value,
8537c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
8547c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DSA_BASE(objp))->big_value_len);
8557c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
8567c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DSA_BASE(objp))->big_value_len, 8);
8577c478bd9Sstevel@tonic-gate 
8587c478bd9Sstevel@tonic-gate 			/* value_len + value */
8597c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
8607c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DSA_VALUE(objp))->big_value_len);
8617c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
8627c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
8637c478bd9Sstevel@tonic-gate 
8647c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
8657c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DSA_VALUE(objp))->big_value,
8667c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
8677c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DSA_VALUE(objp))->big_value_len);
8687c478bd9Sstevel@tonic-gate 
8697c478bd9Sstevel@tonic-gate 			break;
87026b0c172SWyllys Ingersoll 		case CKK_EC:
87126b0c172SWyllys Ingersoll 			/* point_len + point */
87226b0c172SWyllys Ingersoll 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
87326b0c172SWyllys Ingersoll 			    OBJ_PUB_EC_POINT(objp))->big_value_len);
87426b0c172SWyllys Ingersoll 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
87526b0c172SWyllys Ingersoll 			buf = buf + sizeof (uint64_t);
87626b0c172SWyllys Ingersoll 
87726b0c172SWyllys Ingersoll 			(void) memcpy(buf, (char *)((biginteger_t *)
87826b0c172SWyllys Ingersoll 			    OBJ_PUB_EC_POINT(objp))->big_value,
87926b0c172SWyllys Ingersoll 			    ((biginteger_t *)
88026b0c172SWyllys Ingersoll 			    OBJ_PUB_EC_POINT(objp))->big_value_len);
88126b0c172SWyllys Ingersoll 			break;
8827c478bd9Sstevel@tonic-gate 
8837c478bd9Sstevel@tonic-gate 		case CKK_DH:
8847c478bd9Sstevel@tonic-gate 			/* prime_len + prime */
8857c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
8867c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH_PRIME(objp))->big_value_len);
8877c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
8887c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
8897c478bd9Sstevel@tonic-gate 
8907c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
8917c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH_PRIME(objp))->big_value,
8927c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
8937c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH_PRIME(objp))->big_value_len);
8947c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
8957c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH_PRIME(objp))->big_value_len, 8);
8967c478bd9Sstevel@tonic-gate 
8977c478bd9Sstevel@tonic-gate 			/* base_len + base */
8987c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
8997c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH_BASE(objp))->big_value_len);
9007c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
9017c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
9027c478bd9Sstevel@tonic-gate 
9037c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
9047c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH_BASE(objp))->big_value,
9057c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
9067c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH_BASE(objp))->big_value_len);
9077c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
9087c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH_BASE(objp))->big_value_len, 8);
9097c478bd9Sstevel@tonic-gate 
9107c478bd9Sstevel@tonic-gate 			/* value_len + value */
9117c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
9127c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH_VALUE(objp))->big_value_len);
9137c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
9147c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
9157c478bd9Sstevel@tonic-gate 
9167c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
9177c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH_VALUE(objp))->big_value,
9187c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
9197c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH_VALUE(objp))->big_value_len);
9207c478bd9Sstevel@tonic-gate 
9217c478bd9Sstevel@tonic-gate 			break;
9227c478bd9Sstevel@tonic-gate 
9237c478bd9Sstevel@tonic-gate 		case CKK_X9_42_DH:
9247c478bd9Sstevel@tonic-gate 			/* prime_len +  prime */
9257c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
9267c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH942_PRIME(objp))->big_value_len);
9277c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
9287c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
9297c478bd9Sstevel@tonic-gate 
9307c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
9317c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH942_PRIME(objp))->big_value,
9327c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
9337c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH942_PRIME(objp))->big_value_len);
9347c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
9357c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH942_PRIME(objp))->big_value_len, 8);
9367c478bd9Sstevel@tonic-gate 
9377c478bd9Sstevel@tonic-gate 			/* base_len + base */
9387c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
9397c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH942_BASE(objp))->big_value_len);
9407c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
9417c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
9427c478bd9Sstevel@tonic-gate 
9437c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
9447c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH942_BASE(objp))->big_value,
9457c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
9467c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH942_BASE(objp))->big_value_len);
9477c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
9487c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH942_BASE(objp))->big_value_len, 8);
9497c478bd9Sstevel@tonic-gate 
9507c478bd9Sstevel@tonic-gate 			/* subprime_len + subprime */
9517c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
9527c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH942_SUBPRIME(objp))->big_value_len);
9537c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
9547c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
9557c478bd9Sstevel@tonic-gate 
9567c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
9577c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH942_SUBPRIME(objp))->big_value,
9587c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
9597c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH942_SUBPRIME(objp))->big_value_len);
9607c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
9617c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH942_SUBPRIME(objp))->big_value_len, 8);
9627c478bd9Sstevel@tonic-gate 
9637c478bd9Sstevel@tonic-gate 			/* value_len + value */
9647c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
9657c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH942_VALUE(objp))->big_value_len);
9667c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
9677c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
9687c478bd9Sstevel@tonic-gate 
9697c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
9707c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH942_VALUE(objp))->big_value,
9717c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
9727c478bd9Sstevel@tonic-gate 			    OBJ_PUB_DH942_VALUE(objp))->big_value_len);
9737c478bd9Sstevel@tonic-gate 
9747c478bd9Sstevel@tonic-gate 			break;
9757c478bd9Sstevel@tonic-gate 		} /* keytype */
9767c478bd9Sstevel@tonic-gate 
9777c478bd9Sstevel@tonic-gate 		break;
9787c478bd9Sstevel@tonic-gate 
9797c478bd9Sstevel@tonic-gate 	case CKO_PRIVATE_KEY:
9807c478bd9Sstevel@tonic-gate 		switch (keytype) {
9817c478bd9Sstevel@tonic-gate 		case CKK_RSA:
9827c478bd9Sstevel@tonic-gate 			/* modulus_len + modulus */
9837c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
9847c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_MOD(objp))->big_value_len);
9857c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
9867c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
9877c478bd9Sstevel@tonic-gate 
9887c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
9897c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_MOD(objp))->big_value,
9907c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
9917c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_MOD(objp))->big_value_len);
9927c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
9937c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_MOD(objp))->big_value_len, 8);
9947c478bd9Sstevel@tonic-gate 
9957c478bd9Sstevel@tonic-gate 			/* pubexpo_len + pubexpo */
9967c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
9977c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_PUBEXPO(objp))->big_value_len);
9987c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
9997c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
10007c478bd9Sstevel@tonic-gate 
10017c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
10027c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_PUBEXPO(objp))->big_value,
10037c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
10047c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_PUBEXPO(objp))->big_value_len);
10057c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
10067c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_PUBEXPO(objp))->big_value_len, 8);
10077c478bd9Sstevel@tonic-gate 
10087c478bd9Sstevel@tonic-gate 			/* priexpo_len + priexpo */
10097c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
10107c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_PRIEXPO(objp))->big_value_len);
10117c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
10127c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
10137c478bd9Sstevel@tonic-gate 
10147c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
10157c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_PRIEXPO(objp))->big_value,
10167c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
10177c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_PRIEXPO(objp))->big_value_len);
10187c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
10197c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_PRIEXPO(objp))->big_value_len, 8);
10207c478bd9Sstevel@tonic-gate 
10217c478bd9Sstevel@tonic-gate 			/* prime1_len + prime1 */
10227c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
10237c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_PRIME1(objp))->big_value_len);
10247c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
10257c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
10267c478bd9Sstevel@tonic-gate 
10277c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
10287c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_PRIME1(objp))->big_value,
10297c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
10307c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_PRIME1(objp))->big_value_len);
10317c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
10327c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_PRIME1(objp))->big_value_len, 8);
10337c478bd9Sstevel@tonic-gate 
10347c478bd9Sstevel@tonic-gate 			/* prime2_len + prime2 */
10357c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
10367c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_PRIME2(objp))->big_value_len);
10377c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
10387c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
10397c478bd9Sstevel@tonic-gate 
10407c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
10417c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_PRIME2(objp))->big_value,
10427c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
10437c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_PRIME2(objp))->big_value_len);
10447c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
10457c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_PRIME2(objp))->big_value_len, 8);
10467c478bd9Sstevel@tonic-gate 
10477c478bd9Sstevel@tonic-gate 			/* expo1_len + expo1 */
10487c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
10497c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_EXPO1(objp))->big_value_len);
10507c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
10517c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
10527c478bd9Sstevel@tonic-gate 
10537c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
10547c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_EXPO1(objp))->big_value,
10557c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
10567c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_EXPO1(objp))->big_value_len);
10577c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
10587c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_EXPO1(objp))->big_value_len, 8);
10597c478bd9Sstevel@tonic-gate 
10607c478bd9Sstevel@tonic-gate 			/* expo2_len + expo2 */
10617c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
10627c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_EXPO2(objp))->big_value_len);
10637c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
10647c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
10657c478bd9Sstevel@tonic-gate 
10667c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
10677c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_EXPO2(objp))->big_value,
10687c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
10697c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_EXPO2(objp))->big_value_len);
10707c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
10717c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_EXPO2(objp))->big_value_len, 8);
10727c478bd9Sstevel@tonic-gate 
10737c478bd9Sstevel@tonic-gate 			/* coef_len + coef */
10747c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
10757c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_COEF(objp))->big_value_len);
10767c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
10777c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
10787c478bd9Sstevel@tonic-gate 
10797c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
10807c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_COEF(objp))->big_value,
10817c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
10827c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_COEF(objp))->big_value_len);
10837c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
10847c478bd9Sstevel@tonic-gate 			    OBJ_PRI_RSA_COEF(objp))->big_value_len, 8);
10857c478bd9Sstevel@tonic-gate 
10867c478bd9Sstevel@tonic-gate 			break;
10877c478bd9Sstevel@tonic-gate 
10887c478bd9Sstevel@tonic-gate 		case CKK_DSA:
10897c478bd9Sstevel@tonic-gate 			/* prime_len + prime */
10907c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
10917c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DSA_PRIME(objp))->big_value_len);
10927c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
10937c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
10947c478bd9Sstevel@tonic-gate 
10957c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
10967c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DSA_PRIME(objp))->big_value,
10977c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
10987c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DSA_PRIME(objp))->big_value_len);
10997c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
11007c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DSA_PRIME(objp))->big_value_len, 8);
11017c478bd9Sstevel@tonic-gate 
11027c478bd9Sstevel@tonic-gate 			/* subprime_len + subprime */
11037c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
11047c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DSA_SUBPRIME(objp))->big_value_len);
11057c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
11067c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
11077c478bd9Sstevel@tonic-gate 
11087c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
11097c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DSA_SUBPRIME(objp))->big_value,
11107c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
11117c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DSA_SUBPRIME(objp))->big_value_len);
11127c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
11137c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DSA_SUBPRIME(objp))->big_value_len, 8);
11147c478bd9Sstevel@tonic-gate 
11157c478bd9Sstevel@tonic-gate 			/* base_len + base */
11167c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
11177c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DSA_BASE(objp))->big_value_len);
11187c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
11197c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
11207c478bd9Sstevel@tonic-gate 
11217c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
11227c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DSA_BASE(objp))->big_value,
11237c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
11247c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DSA_BASE(objp))->big_value_len);
11257c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
11267c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DSA_BASE(objp))->big_value_len, 8);
11277c478bd9Sstevel@tonic-gate 
11287c478bd9Sstevel@tonic-gate 			/* value_len + value */
11297c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
11307c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DSA_VALUE(objp))->big_value_len);
11317c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
11327c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
11337c478bd9Sstevel@tonic-gate 
11347c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
11357c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DSA_VALUE(objp))->big_value,
11367c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
11377c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DSA_VALUE(objp))->big_value_len);
11387c478bd9Sstevel@tonic-gate 
11397c478bd9Sstevel@tonic-gate 			break;
114026b0c172SWyllys Ingersoll 		case CKK_EC:
114126b0c172SWyllys Ingersoll 			/* value_len + value */
114226b0c172SWyllys Ingersoll 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
114326b0c172SWyllys Ingersoll 			    OBJ_PRI_EC_VALUE(objp))->big_value_len);
114426b0c172SWyllys Ingersoll 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
114526b0c172SWyllys Ingersoll 			buf = buf + sizeof (uint64_t);
114626b0c172SWyllys Ingersoll 
114726b0c172SWyllys Ingersoll 			(void) memcpy(buf, (char *)((biginteger_t *)
114826b0c172SWyllys Ingersoll 			    OBJ_PRI_EC_VALUE(objp))->big_value,
114926b0c172SWyllys Ingersoll 			    ((biginteger_t *)
115026b0c172SWyllys Ingersoll 			    OBJ_PRI_EC_VALUE(objp))->big_value_len);
115126b0c172SWyllys Ingersoll 			break;
11527c478bd9Sstevel@tonic-gate 
11537c478bd9Sstevel@tonic-gate 		case CKK_DH:
11547c478bd9Sstevel@tonic-gate 			/* value_bits */
11557c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)OBJ_PRI_DH_VAL_BITS(objp));
11567c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
11577c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
11587c478bd9Sstevel@tonic-gate 
11597c478bd9Sstevel@tonic-gate 			/* prime_len + prime */
11607c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
11617c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH_PRIME(objp))->big_value_len);
11627c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
11637c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
11647c478bd9Sstevel@tonic-gate 
11657c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
11667c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH_PRIME(objp))->big_value,
11677c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
11687c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH_PRIME(objp))->big_value_len);
11697c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
11707c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH_PRIME(objp))->big_value_len, 8);
11717c478bd9Sstevel@tonic-gate 
11727c478bd9Sstevel@tonic-gate 			/* base_len + base */
11737c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
11747c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH_BASE(objp))->big_value_len);
11757c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
11767c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
11777c478bd9Sstevel@tonic-gate 
11787c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
11797c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH_BASE(objp))->big_value,
11807c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
11817c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH_BASE(objp))->big_value_len);
11827c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
11837c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH_BASE(objp))->big_value_len, 8);
11847c478bd9Sstevel@tonic-gate 
11857c478bd9Sstevel@tonic-gate 			/* value_len + value */
11867c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
11877c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH_VALUE(objp))->big_value_len);
11887c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
11897c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
11907c478bd9Sstevel@tonic-gate 
11917c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
11927c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH_VALUE(objp))->big_value,
11937c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
11947c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH_VALUE(objp))->big_value_len);
11957c478bd9Sstevel@tonic-gate 
11967c478bd9Sstevel@tonic-gate 			break;
11977c478bd9Sstevel@tonic-gate 
11987c478bd9Sstevel@tonic-gate 		case CKK_X9_42_DH:
11997c478bd9Sstevel@tonic-gate 			/* prime_len + prime */
12007c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
12017c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH942_PRIME(objp))->big_value_len);
12027c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
12037c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
12047c478bd9Sstevel@tonic-gate 
12057c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
12067c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH942_PRIME(objp))->big_value,
12077c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
12087c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH942_PRIME(objp))->big_value_len);
12097c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
12107c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH942_PRIME(objp))->big_value_len, 8);
12117c478bd9Sstevel@tonic-gate 
12127c478bd9Sstevel@tonic-gate 			/* base_len + base */
12137c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
12147c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH942_BASE(objp))->big_value_len);
12157c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
12167c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
12177c478bd9Sstevel@tonic-gate 
12187c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
12197c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH942_BASE(objp))->big_value,
12207c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
12217c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH942_BASE(objp))->big_value_len);
12227c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
12237c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH942_BASE(objp))->big_value_len, 8);
12247c478bd9Sstevel@tonic-gate 
12257c478bd9Sstevel@tonic-gate 			/* subprime_len + subprime */
12267c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
12277c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH942_SUBPRIME(objp))->big_value_len);
12287c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
12297c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
12307c478bd9Sstevel@tonic-gate 
12317c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
12327c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH942_SUBPRIME(objp))->big_value,
12337c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
12347c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH942_SUBPRIME(objp))->big_value_len);
12357c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((biginteger_t *)
12367c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH942_SUBPRIME(objp))->big_value_len, 8);
12377c478bd9Sstevel@tonic-gate 
12387c478bd9Sstevel@tonic-gate 			/* value_len + value */
12397c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)((biginteger_t *)
12407c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH942_VALUE(objp))->big_value_len);
12417c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
12427c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
12437c478bd9Sstevel@tonic-gate 
12447c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((biginteger_t *)
12457c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH942_VALUE(objp))->big_value,
12467c478bd9Sstevel@tonic-gate 			    ((biginteger_t *)
12477c478bd9Sstevel@tonic-gate 			    OBJ_PRI_DH942_VALUE(objp))->big_value_len);
12487c478bd9Sstevel@tonic-gate 
12497c478bd9Sstevel@tonic-gate 			break;
12507c478bd9Sstevel@tonic-gate 
12517c478bd9Sstevel@tonic-gate 		} /* keytype */
12527c478bd9Sstevel@tonic-gate 
12537c478bd9Sstevel@tonic-gate 		break;
12547c478bd9Sstevel@tonic-gate 
12557c478bd9Sstevel@tonic-gate 	case CKO_SECRET_KEY:
12567c478bd9Sstevel@tonic-gate 		/* value_len  + value */
12577c478bd9Sstevel@tonic-gate 		tmp_val = SWAP64((uint64_t)OBJ_SEC_VALUE_LEN(objp));
12587c478bd9Sstevel@tonic-gate 		(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
12597c478bd9Sstevel@tonic-gate 		buf = buf + sizeof (uint64_t);
12607c478bd9Sstevel@tonic-gate 
12617c478bd9Sstevel@tonic-gate 		if (OBJ_SEC_VALUE_LEN(objp) > 0) {
12627c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)OBJ_SEC_VALUE(objp),
12637c478bd9Sstevel@tonic-gate 			    OBJ_SEC_VALUE_LEN(objp));
12647c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(OBJ_SEC_VALUE_LEN(objp), 8);
12657c478bd9Sstevel@tonic-gate 		}
12667c478bd9Sstevel@tonic-gate 
12677c478bd9Sstevel@tonic-gate 		break;
12687c478bd9Sstevel@tonic-gate 
12697c478bd9Sstevel@tonic-gate 	case CKO_CERTIFICATE:
12707c478bd9Sstevel@tonic-gate 
12717c478bd9Sstevel@tonic-gate 		switch (certtype) {
12727c478bd9Sstevel@tonic-gate 		case CKC_X_509:
12737c478bd9Sstevel@tonic-gate 			/* subject_len + subject */
12747c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)(((cert_attr_t *)
12757c478bd9Sstevel@tonic-gate 			    X509_CERT_SUBJECT(objp))->length));
12767c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
12777c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
12787c478bd9Sstevel@tonic-gate 
12797c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((cert_attr_t *)
12807c478bd9Sstevel@tonic-gate 			    X509_CERT_SUBJECT(objp))->value,
12817c478bd9Sstevel@tonic-gate 			    ((cert_attr_t *)
12827c478bd9Sstevel@tonic-gate 			    X509_CERT_SUBJECT(objp))->length);
12837c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((cert_attr_t *)
12847c478bd9Sstevel@tonic-gate 			    X509_CERT_SUBJECT(objp))->length, 8);
12857c478bd9Sstevel@tonic-gate 
12867c478bd9Sstevel@tonic-gate 			/* value_len + value */
12877c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)(((cert_attr_t *)
12887c478bd9Sstevel@tonic-gate 			    X509_CERT_VALUE(objp))->length));
12897c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
12907c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
12917c478bd9Sstevel@tonic-gate 
12927c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((cert_attr_t *)
12937c478bd9Sstevel@tonic-gate 			    X509_CERT_VALUE(objp))->value,
12947c478bd9Sstevel@tonic-gate 			    ((cert_attr_t *)
12957c478bd9Sstevel@tonic-gate 			    X509_CERT_VALUE(objp))->length);
12967c478bd9Sstevel@tonic-gate 			break;
12977c478bd9Sstevel@tonic-gate 
12987c478bd9Sstevel@tonic-gate 		case CKC_X_509_ATTR_CERT:
12997c478bd9Sstevel@tonic-gate 			/* owner_len + owner */
13007c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)(((cert_attr_t *)
13017c478bd9Sstevel@tonic-gate 			    X509_ATTR_CERT_OWNER(objp))->length));
13027c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
13037c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
13047c478bd9Sstevel@tonic-gate 
13057c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((cert_attr_t *)
13067c478bd9Sstevel@tonic-gate 			    X509_ATTR_CERT_OWNER(objp))->value,
13077c478bd9Sstevel@tonic-gate 			    ((cert_attr_t *)
13087c478bd9Sstevel@tonic-gate 			    X509_ATTR_CERT_OWNER(objp))->length);
13097c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(((cert_attr_t *)
13107c478bd9Sstevel@tonic-gate 			    X509_ATTR_CERT_OWNER(objp))->length, 8);
13117c478bd9Sstevel@tonic-gate 
13127c478bd9Sstevel@tonic-gate 			/* value_len + value */
13137c478bd9Sstevel@tonic-gate 			tmp_val = SWAP64((uint64_t)(((cert_attr_t *)
13147c478bd9Sstevel@tonic-gate 			    X509_ATTR_CERT_VALUE(objp))->length));
13157c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)&tmp_val, sizeof (uint64_t));
13167c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
13177c478bd9Sstevel@tonic-gate 
13187c478bd9Sstevel@tonic-gate 			(void) memcpy(buf, (char *)((cert_attr_t *)
13197c478bd9Sstevel@tonic-gate 			    X509_ATTR_CERT_VALUE(objp))->value,
13207c478bd9Sstevel@tonic-gate 			    ((cert_attr_t *)
13217c478bd9Sstevel@tonic-gate 			    X509_ATTR_CERT_VALUE(objp))->length);
13227c478bd9Sstevel@tonic-gate 			break;
13237c478bd9Sstevel@tonic-gate 		}
13247c478bd9Sstevel@tonic-gate 		break;
13257c478bd9Sstevel@tonic-gate 
13267c478bd9Sstevel@tonic-gate 	case CKO_DOMAIN_PARAMETERS:
13277c478bd9Sstevel@tonic-gate 
13287c478bd9Sstevel@tonic-gate 		return (0);
13297c478bd9Sstevel@tonic-gate 	}
13307c478bd9Sstevel@tonic-gate 	return (CKR_OK);
13317c478bd9Sstevel@tonic-gate }
13327c478bd9Sstevel@tonic-gate 
13337c478bd9Sstevel@tonic-gate /*
13347c478bd9Sstevel@tonic-gate  * Unpack the object key in keystore format (the third part)
13357c478bd9Sstevel@tonic-gate  * into soft_object_t.
13367c478bd9Sstevel@tonic-gate  */
13377c478bd9Sstevel@tonic-gate CK_RV
soft_unpack_object(soft_object_t * objp,uchar_t * buf)13387c478bd9Sstevel@tonic-gate soft_unpack_object(soft_object_t *objp, uchar_t *buf)
13397c478bd9Sstevel@tonic-gate {
13407c478bd9Sstevel@tonic-gate 
13417c478bd9Sstevel@tonic-gate 	public_key_obj_t  *pbk;
13427c478bd9Sstevel@tonic-gate 	private_key_obj_t *pvk;
13437c478bd9Sstevel@tonic-gate 	secret_key_obj_t  *sck;
13447c478bd9Sstevel@tonic-gate 	certificate_obj_t *cert;
13457c478bd9Sstevel@tonic-gate 	CK_OBJECT_CLASS class = objp->class;
13467c478bd9Sstevel@tonic-gate 	CK_KEY_TYPE	keytype = objp->key_type;
13477c478bd9Sstevel@tonic-gate 	CK_CERTIFICATE_TYPE certtype = objp->cert_type;
13487c478bd9Sstevel@tonic-gate 
13497c478bd9Sstevel@tonic-gate 	biginteger_t	modulus;
13507c478bd9Sstevel@tonic-gate 	biginteger_t	pubexpo;
13517c478bd9Sstevel@tonic-gate 	biginteger_t	prime;
13527c478bd9Sstevel@tonic-gate 	biginteger_t	subprime;
13537c478bd9Sstevel@tonic-gate 	biginteger_t	base;
13547c478bd9Sstevel@tonic-gate 	biginteger_t	value;
13557c478bd9Sstevel@tonic-gate 
13567c478bd9Sstevel@tonic-gate 	biginteger_t	priexpo;
13577c478bd9Sstevel@tonic-gate 	biginteger_t	prime1;
13587c478bd9Sstevel@tonic-gate 	biginteger_t	prime2;
13597c478bd9Sstevel@tonic-gate 	biginteger_t	expo1;
13607c478bd9Sstevel@tonic-gate 	biginteger_t	expo2;
13617c478bd9Sstevel@tonic-gate 	biginteger_t	coef;
1362a8793c76SJason King 	CK_RV		rv = CKR_OK;
13637c478bd9Sstevel@tonic-gate 	ulong_t offset = 0;
13647c478bd9Sstevel@tonic-gate 	uint64_t tmp_val;
13657c478bd9Sstevel@tonic-gate 
13667c478bd9Sstevel@tonic-gate 	/* prevent bigint_attr_cleanup from freeing invalid attr value */
13677c478bd9Sstevel@tonic-gate 	(void) memset(&modulus, 0x0, sizeof (biginteger_t));
13687c478bd9Sstevel@tonic-gate 	(void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
13697c478bd9Sstevel@tonic-gate 	(void) memset(&prime, 0x0, sizeof (biginteger_t));
13707c478bd9Sstevel@tonic-gate 	(void) memset(&subprime, 0x0, sizeof (biginteger_t));
13717c478bd9Sstevel@tonic-gate 	(void) memset(&base, 0x0, sizeof (biginteger_t));
13727c478bd9Sstevel@tonic-gate 	(void) memset(&value, 0x0, sizeof (biginteger_t));
13737c478bd9Sstevel@tonic-gate 
13747c478bd9Sstevel@tonic-gate 	(void) memset(&priexpo, 0x0, sizeof (biginteger_t));
13757c478bd9Sstevel@tonic-gate 	(void) memset(&prime1, 0x0, sizeof (biginteger_t));
13767c478bd9Sstevel@tonic-gate 	(void) memset(&prime2, 0x0, sizeof (biginteger_t));
13777c478bd9Sstevel@tonic-gate 	(void) memset(&expo1, 0x0, sizeof (biginteger_t));
13787c478bd9Sstevel@tonic-gate 	(void) memset(&expo2, 0x0, sizeof (biginteger_t));
13797c478bd9Sstevel@tonic-gate 	(void) memset(&coef, 0x0, sizeof (biginteger_t));
13807c478bd9Sstevel@tonic-gate 
13817c478bd9Sstevel@tonic-gate 	switch (class) {
13827c478bd9Sstevel@tonic-gate 
13837c478bd9Sstevel@tonic-gate 	case CKO_PUBLIC_KEY:
13847c478bd9Sstevel@tonic-gate 		/* Allocate storage for Public Key Object. */
13857c478bd9Sstevel@tonic-gate 		pbk = calloc(1, sizeof (public_key_obj_t));
13867c478bd9Sstevel@tonic-gate 		if (pbk == NULL) {
13877c478bd9Sstevel@tonic-gate 			rv =  CKR_HOST_MEMORY;
13887c478bd9Sstevel@tonic-gate 			return (rv);
13897c478bd9Sstevel@tonic-gate 		}
13907c478bd9Sstevel@tonic-gate 
13917c478bd9Sstevel@tonic-gate 		objp->object_class_u.public_key = pbk;
13927c478bd9Sstevel@tonic-gate 
13937c478bd9Sstevel@tonic-gate 		switch (keytype) {
13947c478bd9Sstevel@tonic-gate 		case CKK_RSA:			/* modulus_bits */
13957c478bd9Sstevel@tonic-gate 			(void) memcpy(&tmp_val, buf, sizeof (uint64_t));
13967c478bd9Sstevel@tonic-gate 			KEY_PUB_RSA_MOD_BITS(pbk) = (CK_ULONG)(SWAP64(tmp_val));
13977c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
13987c478bd9Sstevel@tonic-gate 
13997c478bd9Sstevel@tonic-gate 			/* modulus */
14007c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &modulus,
14017c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
14027c478bd9Sstevel@tonic-gate 				goto pub_cleanup;
14037c478bd9Sstevel@tonic-gate 
14047c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&modulus, KEY_PUB_RSA_MOD(pbk));
14057c478bd9Sstevel@tonic-gate 
14067c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
14077c478bd9Sstevel@tonic-gate 
14087c478bd9Sstevel@tonic-gate 			/* pubexpo */
14097c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &pubexpo,
14107c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
14117c478bd9Sstevel@tonic-gate 				goto pub_cleanup;
14127c478bd9Sstevel@tonic-gate 
14137c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&pubexpo, KEY_PUB_RSA_PUBEXPO(pbk));
14147c478bd9Sstevel@tonic-gate 
14157c478bd9Sstevel@tonic-gate 			break;
14167c478bd9Sstevel@tonic-gate 
14177c478bd9Sstevel@tonic-gate 		case CKK_DSA:
14187c478bd9Sstevel@tonic-gate 			/* prime */
14197c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &prime,
14207c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
14217c478bd9Sstevel@tonic-gate 				goto pub_cleanup;
14227c478bd9Sstevel@tonic-gate 
14237c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&prime, KEY_PUB_DSA_PRIME(pbk));
14247c478bd9Sstevel@tonic-gate 
14257c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
14267c478bd9Sstevel@tonic-gate 
14277c478bd9Sstevel@tonic-gate 			/* subprime */
14287c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &subprime,
14297c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
14307c478bd9Sstevel@tonic-gate 				goto pub_cleanup;
14317c478bd9Sstevel@tonic-gate 
14327c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&subprime, KEY_PUB_DSA_SUBPRIME(pbk));
14337c478bd9Sstevel@tonic-gate 
14347c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
14357c478bd9Sstevel@tonic-gate 
14367c478bd9Sstevel@tonic-gate 			/* base */
14377c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &base,
14387c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
14397c478bd9Sstevel@tonic-gate 				goto pub_cleanup;
14407c478bd9Sstevel@tonic-gate 
14417c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&base, KEY_PUB_DSA_BASE(pbk));
14427c478bd9Sstevel@tonic-gate 
14437c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
14447c478bd9Sstevel@tonic-gate 
14457c478bd9Sstevel@tonic-gate 			/* value */
14467c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &value,
14477c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
14487c478bd9Sstevel@tonic-gate 				goto pub_cleanup;
14497c478bd9Sstevel@tonic-gate 
14507c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&value, KEY_PUB_DSA_VALUE(pbk));
14517c478bd9Sstevel@tonic-gate 
14527c478bd9Sstevel@tonic-gate 			break;
14537c478bd9Sstevel@tonic-gate 
14547c478bd9Sstevel@tonic-gate 		case CKK_DH:
14557c478bd9Sstevel@tonic-gate 			/* prime */
14567c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &prime,
14577c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
14587c478bd9Sstevel@tonic-gate 				goto pub_cleanup;
14597c478bd9Sstevel@tonic-gate 
14607c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&prime, KEY_PUB_DH_PRIME(pbk));
14617c478bd9Sstevel@tonic-gate 
14627c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
14637c478bd9Sstevel@tonic-gate 
14647c478bd9Sstevel@tonic-gate 			/* base */
14657c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &base,
14667c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
14677c478bd9Sstevel@tonic-gate 				goto pub_cleanup;
14687c478bd9Sstevel@tonic-gate 
14697c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&base, KEY_PUB_DH_BASE(pbk));
14707c478bd9Sstevel@tonic-gate 
14717c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
14727c478bd9Sstevel@tonic-gate 
14737c478bd9Sstevel@tonic-gate 			/* value */
14747c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &value,
14757c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
14767c478bd9Sstevel@tonic-gate 				goto pub_cleanup;
14777c478bd9Sstevel@tonic-gate 
14787c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&value, KEY_PUB_DH_VALUE(pbk));
14797c478bd9Sstevel@tonic-gate 
14807c478bd9Sstevel@tonic-gate 			break;
14817c478bd9Sstevel@tonic-gate 
148226b0c172SWyllys Ingersoll 		case CKK_EC:
148326b0c172SWyllys Ingersoll 			/* ec_point */
148426b0c172SWyllys Ingersoll 			if ((rv = soft_unpack_obj_attribute(buf, &value,
148526b0c172SWyllys Ingersoll 			    NULL, &offset, B_FALSE)) != CKR_OK)
148626b0c172SWyllys Ingersoll 				goto pri_cleanup;
148726b0c172SWyllys Ingersoll 
148826b0c172SWyllys Ingersoll 			copy_bigint_attr(&value, KEY_PUB_EC_POINT(pbk));
148926b0c172SWyllys Ingersoll 			break;
149026b0c172SWyllys Ingersoll 
14917c478bd9Sstevel@tonic-gate 		case CKK_X9_42_DH:
14927c478bd9Sstevel@tonic-gate 			/* prime */
14937c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &prime,
14947c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
14957c478bd9Sstevel@tonic-gate 				goto pub_cleanup;
14967c478bd9Sstevel@tonic-gate 
14977c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&prime, KEY_PUB_DH942_PRIME(pbk));
14987c478bd9Sstevel@tonic-gate 
14997c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
15007c478bd9Sstevel@tonic-gate 
15017c478bd9Sstevel@tonic-gate 			/* base */
15027c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &base,
15037c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
15047c478bd9Sstevel@tonic-gate 				goto pub_cleanup;
15057c478bd9Sstevel@tonic-gate 
15067c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&base, KEY_PUB_DH942_BASE(pbk));
15077c478bd9Sstevel@tonic-gate 
15087c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
15097c478bd9Sstevel@tonic-gate 
15107c478bd9Sstevel@tonic-gate 			/* subprime */
15117c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &subprime,
15127c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
15137c478bd9Sstevel@tonic-gate 				goto pub_cleanup;
15147c478bd9Sstevel@tonic-gate 
15157c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&subprime,
15167c478bd9Sstevel@tonic-gate 			    KEY_PUB_DH942_SUBPRIME(pbk));
15177c478bd9Sstevel@tonic-gate 
15187c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
15197c478bd9Sstevel@tonic-gate 
15207c478bd9Sstevel@tonic-gate 			/* value */
15217c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &value,
15227c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
15237c478bd9Sstevel@tonic-gate 				goto pub_cleanup;
15247c478bd9Sstevel@tonic-gate 
15257c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&value, KEY_PUB_DH942_VALUE(pbk));
15267c478bd9Sstevel@tonic-gate 
15277c478bd9Sstevel@tonic-gate 			break;
15287c478bd9Sstevel@tonic-gate 		} /* keytype */
15297c478bd9Sstevel@tonic-gate 
15307c478bd9Sstevel@tonic-gate 		break;
15317c478bd9Sstevel@tonic-gate 
15327c478bd9Sstevel@tonic-gate 	case CKO_PRIVATE_KEY:
15337c478bd9Sstevel@tonic-gate 		/* Allocate storage for Private Key Object. */
15347c478bd9Sstevel@tonic-gate 		pvk = calloc(1, sizeof (private_key_obj_t));
15357c478bd9Sstevel@tonic-gate 		if (pvk == NULL) {
15367c478bd9Sstevel@tonic-gate 			rv = CKR_HOST_MEMORY;
15377c478bd9Sstevel@tonic-gate 			return (rv);
15387c478bd9Sstevel@tonic-gate 		}
15397c478bd9Sstevel@tonic-gate 
15407c478bd9Sstevel@tonic-gate 		objp->object_class_u.private_key = pvk;
15417c478bd9Sstevel@tonic-gate 
15427c478bd9Sstevel@tonic-gate 		switch (keytype) {
15437c478bd9Sstevel@tonic-gate 		case CKK_RSA:
15447c478bd9Sstevel@tonic-gate 			/* modulus */
15457c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &modulus,
15467c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
15477c478bd9Sstevel@tonic-gate 				goto pri_cleanup;
15487c478bd9Sstevel@tonic-gate 
15497c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&modulus, KEY_PRI_RSA_MOD(pvk));
15507c478bd9Sstevel@tonic-gate 
15517c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
15527c478bd9Sstevel@tonic-gate 
15537c478bd9Sstevel@tonic-gate 			/* pubexpo */
15547c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &pubexpo,
15557c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
15567c478bd9Sstevel@tonic-gate 				goto pri_cleanup;
15577c478bd9Sstevel@tonic-gate 
15587c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&pubexpo, KEY_PRI_RSA_PUBEXPO(pvk));
15597c478bd9Sstevel@tonic-gate 
15607c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
15617c478bd9Sstevel@tonic-gate 
15627c478bd9Sstevel@tonic-gate 			/* priexpo */
15637c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &priexpo,
15647c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
15657c478bd9Sstevel@tonic-gate 				goto pri_cleanup;
15667c478bd9Sstevel@tonic-gate 
15677c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&priexpo, KEY_PRI_RSA_PRIEXPO(pvk));
15687c478bd9Sstevel@tonic-gate 
15697c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
15707c478bd9Sstevel@tonic-gate 
15717c478bd9Sstevel@tonic-gate 			/* prime1 */
15727c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &prime1,
15737c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
15747c478bd9Sstevel@tonic-gate 				goto pri_cleanup;
15757c478bd9Sstevel@tonic-gate 
15767c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&prime1, KEY_PRI_RSA_PRIME1(pvk));
15777c478bd9Sstevel@tonic-gate 
15787c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
15797c478bd9Sstevel@tonic-gate 
15807c478bd9Sstevel@tonic-gate 			/* prime2 */
15817c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &prime2,
15827c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
15837c478bd9Sstevel@tonic-gate 				goto pri_cleanup;
15847c478bd9Sstevel@tonic-gate 
15857c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&prime2, KEY_PRI_RSA_PRIME2(pvk));
15867c478bd9Sstevel@tonic-gate 
15877c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
15887c478bd9Sstevel@tonic-gate 
15897c478bd9Sstevel@tonic-gate 			/* expo1 */
15907c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &expo1,
15917c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
15927c478bd9Sstevel@tonic-gate 				goto pri_cleanup;
15937c478bd9Sstevel@tonic-gate 
15947c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&expo1, KEY_PRI_RSA_EXPO1(pvk));
15957c478bd9Sstevel@tonic-gate 
15967c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
15977c478bd9Sstevel@tonic-gate 
15987c478bd9Sstevel@tonic-gate 			/* expo2 */
15997c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &expo2,
16007c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
16017c478bd9Sstevel@tonic-gate 				goto pri_cleanup;
16027c478bd9Sstevel@tonic-gate 
16037c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&expo2, KEY_PRI_RSA_EXPO2(pvk));
16047c478bd9Sstevel@tonic-gate 
16057c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
16067c478bd9Sstevel@tonic-gate 
16077c478bd9Sstevel@tonic-gate 			/* coef */
16087c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &coef,
16097c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
16107c478bd9Sstevel@tonic-gate 				goto pri_cleanup;
16117c478bd9Sstevel@tonic-gate 
16127c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&coef, KEY_PRI_RSA_COEF(pvk));
16137c478bd9Sstevel@tonic-gate 
16147c478bd9Sstevel@tonic-gate 			break;
16157c478bd9Sstevel@tonic-gate 
16167c478bd9Sstevel@tonic-gate 		case CKK_DSA:
16177c478bd9Sstevel@tonic-gate 			/* prime */
16187c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &prime,
16197c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
16207c478bd9Sstevel@tonic-gate 				goto pri_cleanup;
16217c478bd9Sstevel@tonic-gate 
16227c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&prime, KEY_PRI_DSA_PRIME(pvk));
16237c478bd9Sstevel@tonic-gate 
16247c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
16257c478bd9Sstevel@tonic-gate 
16267c478bd9Sstevel@tonic-gate 			/* subprime */
16277c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &subprime,
16287c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
16297c478bd9Sstevel@tonic-gate 				goto pri_cleanup;
16307c478bd9Sstevel@tonic-gate 
16317c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&subprime, KEY_PRI_DSA_SUBPRIME(pvk));
16327c478bd9Sstevel@tonic-gate 
16337c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
16347c478bd9Sstevel@tonic-gate 
16357c478bd9Sstevel@tonic-gate 			/* base */
16367c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &base,
16377c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
16387c478bd9Sstevel@tonic-gate 				goto pri_cleanup;
16397c478bd9Sstevel@tonic-gate 
16407c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&base, KEY_PRI_DSA_BASE(pvk));
16417c478bd9Sstevel@tonic-gate 
16427c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
16437c478bd9Sstevel@tonic-gate 
16447c478bd9Sstevel@tonic-gate 			/* value */
16457c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &value,
16467c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
16477c478bd9Sstevel@tonic-gate 				goto pri_cleanup;
16487c478bd9Sstevel@tonic-gate 
16497c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&value, KEY_PRI_DSA_VALUE(pvk));
16507c478bd9Sstevel@tonic-gate 
16517c478bd9Sstevel@tonic-gate 			break;
16527c478bd9Sstevel@tonic-gate 
16537c478bd9Sstevel@tonic-gate 		case CKK_DH:
16547c478bd9Sstevel@tonic-gate 			/* value_bits */
16557c478bd9Sstevel@tonic-gate 			(void) memcpy(&tmp_val, buf, sizeof (uint64_t));
16567c478bd9Sstevel@tonic-gate 			KEY_PRI_DH_VAL_BITS(pvk) = (CK_ULONG)(SWAP64(tmp_val));
16577c478bd9Sstevel@tonic-gate 			buf = buf + sizeof (uint64_t);
16587c478bd9Sstevel@tonic-gate 
16597c478bd9Sstevel@tonic-gate 			/* prime */
16607c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &prime,
16617c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
16627c478bd9Sstevel@tonic-gate 				goto pri_cleanup;
16637c478bd9Sstevel@tonic-gate 
16647c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&prime, KEY_PRI_DH_PRIME(pvk));
16657c478bd9Sstevel@tonic-gate 
16667c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
16677c478bd9Sstevel@tonic-gate 
16687c478bd9Sstevel@tonic-gate 			/* base */
16697c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &base,
16707c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
16717c478bd9Sstevel@tonic-gate 				goto pri_cleanup;
16727c478bd9Sstevel@tonic-gate 
16737c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&base, KEY_PRI_DH_BASE(pvk));
16747c478bd9Sstevel@tonic-gate 
16757c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
16767c478bd9Sstevel@tonic-gate 
16777c478bd9Sstevel@tonic-gate 			/* value */
16787c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &value,
16797c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
16807c478bd9Sstevel@tonic-gate 				goto pri_cleanup;
16817c478bd9Sstevel@tonic-gate 
16827c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&value, KEY_PRI_DH_VALUE(pvk));
16837c478bd9Sstevel@tonic-gate 
16847c478bd9Sstevel@tonic-gate 			break;
16857c478bd9Sstevel@tonic-gate 
168626b0c172SWyllys Ingersoll 		case CKK_EC:
168726b0c172SWyllys Ingersoll 			/* value */
168826b0c172SWyllys Ingersoll 			if ((rv = soft_unpack_obj_attribute(buf, &value,
168926b0c172SWyllys Ingersoll 			    NULL, &offset, B_FALSE)) != CKR_OK)
169026b0c172SWyllys Ingersoll 				goto pri_cleanup;
169126b0c172SWyllys Ingersoll 
169226b0c172SWyllys Ingersoll 			copy_bigint_attr(&value, KEY_PRI_EC_VALUE(pvk));
169326b0c172SWyllys Ingersoll 			break;
169426b0c172SWyllys Ingersoll 
16957c478bd9Sstevel@tonic-gate 		case CKK_X9_42_DH:
16967c478bd9Sstevel@tonic-gate 			/* prime */
16977c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &prime,
16987c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
16997c478bd9Sstevel@tonic-gate 				goto pri_cleanup;
17007c478bd9Sstevel@tonic-gate 
17017c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&prime, KEY_PRI_DH942_PRIME(pvk));
17027c478bd9Sstevel@tonic-gate 
17037c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
17047c478bd9Sstevel@tonic-gate 
17057c478bd9Sstevel@tonic-gate 			/* base */
17067c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &base,
17077c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
17087c478bd9Sstevel@tonic-gate 				goto pri_cleanup;
17097c478bd9Sstevel@tonic-gate 
17107c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&base, KEY_PRI_DH942_BASE(pvk));
17117c478bd9Sstevel@tonic-gate 
17127c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
17137c478bd9Sstevel@tonic-gate 
17147c478bd9Sstevel@tonic-gate 			/* subprime */
17157c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &subprime,
17167c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
17177c478bd9Sstevel@tonic-gate 				goto pri_cleanup;
17187c478bd9Sstevel@tonic-gate 
17197c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&subprime, KEY_PRI_DH942_BASE(pvk));
17207c478bd9Sstevel@tonic-gate 
17217c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
17227c478bd9Sstevel@tonic-gate 
17237c478bd9Sstevel@tonic-gate 			/* value */
17247c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, &value,
17257c478bd9Sstevel@tonic-gate 			    NULL, &offset, B_FALSE)) != CKR_OK)
17267c478bd9Sstevel@tonic-gate 				goto pri_cleanup;
17277c478bd9Sstevel@tonic-gate 
17287c478bd9Sstevel@tonic-gate 			copy_bigint_attr(&value, KEY_PRI_DH942_VALUE(pvk));
17297c478bd9Sstevel@tonic-gate 
17307c478bd9Sstevel@tonic-gate 			break;
17317c478bd9Sstevel@tonic-gate 		} /* keytype */
17327c478bd9Sstevel@tonic-gate 
17337c478bd9Sstevel@tonic-gate 		break;
17347c478bd9Sstevel@tonic-gate 
17357c478bd9Sstevel@tonic-gate 	case CKO_SECRET_KEY:
17367c478bd9Sstevel@tonic-gate 		/* Allocate storage for Secret Key Object. */
17377c478bd9Sstevel@tonic-gate 		sck = calloc(1, sizeof (secret_key_obj_t));
17387c478bd9Sstevel@tonic-gate 		if (sck == NULL) {
17397c478bd9Sstevel@tonic-gate 			return (CKR_HOST_MEMORY);
17407c478bd9Sstevel@tonic-gate 		}
17417c478bd9Sstevel@tonic-gate 
17427c478bd9Sstevel@tonic-gate 		objp->object_class_u.secret_key = sck;
17437c478bd9Sstevel@tonic-gate 
17447c478bd9Sstevel@tonic-gate 		/* value */
17457c478bd9Sstevel@tonic-gate 		(void) memcpy((void *)&tmp_val, buf, sizeof (uint64_t));
17467c478bd9Sstevel@tonic-gate 		OBJ_SEC_VALUE_LEN(objp) = (CK_ULONG)(SWAP64(tmp_val));
17477c478bd9Sstevel@tonic-gate 		buf = buf + sizeof (uint64_t);
17487c478bd9Sstevel@tonic-gate 
17497c478bd9Sstevel@tonic-gate 		if (OBJ_SEC_VALUE_LEN(objp) > 0) {
17507c478bd9Sstevel@tonic-gate 			OBJ_SEC_VALUE(objp) = malloc(OBJ_SEC_VALUE_LEN(objp));
17517c478bd9Sstevel@tonic-gate 			if (OBJ_SEC_VALUE(objp) == NULL) {
17527c478bd9Sstevel@tonic-gate 				free(sck);
17537c478bd9Sstevel@tonic-gate 				return (CKR_HOST_MEMORY);
17547c478bd9Sstevel@tonic-gate 			}
17557c478bd9Sstevel@tonic-gate 			(void) memcpy(OBJ_SEC_VALUE(objp), buf,
17567c478bd9Sstevel@tonic-gate 			    OBJ_SEC_VALUE_LEN(objp));
17577c478bd9Sstevel@tonic-gate 
17587c478bd9Sstevel@tonic-gate 			buf = buf + ROUNDUP(OBJ_SEC_VALUE_LEN(objp), 8);
17597c478bd9Sstevel@tonic-gate 		}
17607c478bd9Sstevel@tonic-gate 
17617c478bd9Sstevel@tonic-gate 		return (rv);
17627c478bd9Sstevel@tonic-gate 
17637c478bd9Sstevel@tonic-gate 	case CKO_CERTIFICATE:
17647c478bd9Sstevel@tonic-gate 		/* Allocate storage for Certificate Object. */
17657c478bd9Sstevel@tonic-gate 		cert = calloc(1, sizeof (certificate_obj_t));
17667c478bd9Sstevel@tonic-gate 		if (cert == NULL) {
17677c478bd9Sstevel@tonic-gate 			return (CKR_HOST_MEMORY);
17687c478bd9Sstevel@tonic-gate 		}
17697c478bd9Sstevel@tonic-gate 		(void) memset((void *)cert, 0, sizeof (certificate_obj_t));
17707c478bd9Sstevel@tonic-gate 
17717c478bd9Sstevel@tonic-gate 		cert->certificate_type = certtype;
17727c478bd9Sstevel@tonic-gate 		objp->object_class_u.certificate = cert;
17737c478bd9Sstevel@tonic-gate 
17747c478bd9Sstevel@tonic-gate 		switch (certtype) {
17757c478bd9Sstevel@tonic-gate 		case CKC_X_509:
17767c478bd9Sstevel@tonic-gate 			/* subject */
17777c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, NULL,
17787c478bd9Sstevel@tonic-gate 			    &cert->cert_type_u.x509.subject,
17797b79d846SDina K Nimeh 			    &offset, B_TRUE)) != CKR_OK) {
17807c478bd9Sstevel@tonic-gate 				free(cert);
17817c478bd9Sstevel@tonic-gate 				return (rv);
17827c478bd9Sstevel@tonic-gate 			}
17837c478bd9Sstevel@tonic-gate 
17847c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
17857c478bd9Sstevel@tonic-gate 
17867c478bd9Sstevel@tonic-gate 			/* value */
17877c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, NULL,
17887c478bd9Sstevel@tonic-gate 			    &cert->cert_type_u.x509.value,
17897b79d846SDina K Nimeh 			    &offset, B_TRUE)) != CKR_OK) {
17907c478bd9Sstevel@tonic-gate 				free(cert);
17917c478bd9Sstevel@tonic-gate 				return (rv);
17927c478bd9Sstevel@tonic-gate 			}
17937c478bd9Sstevel@tonic-gate 
17947c478bd9Sstevel@tonic-gate 			break;
17957c478bd9Sstevel@tonic-gate 
17967c478bd9Sstevel@tonic-gate 		case CKC_X_509_ATTR_CERT:
17977c478bd9Sstevel@tonic-gate 			/* owner */
17987c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, NULL,
17997c478bd9Sstevel@tonic-gate 			    &cert->cert_type_u.x509_attr.owner,
18007b79d846SDina K Nimeh 			    &offset, B_TRUE)) != CKR_OK) {
18017c478bd9Sstevel@tonic-gate 				free(cert);
18027c478bd9Sstevel@tonic-gate 				return (rv);
18037c478bd9Sstevel@tonic-gate 			}
18047c478bd9Sstevel@tonic-gate 
18057c478bd9Sstevel@tonic-gate 			buf += ROUNDUP(offset, 8);
18067c478bd9Sstevel@tonic-gate 
18077c478bd9Sstevel@tonic-gate 			/* value */
18087c478bd9Sstevel@tonic-gate 			if ((rv = soft_unpack_obj_attribute(buf, NULL,
18097c478bd9Sstevel@tonic-gate 			    &cert->cert_type_u.x509_attr.value,
18107b79d846SDina K Nimeh 			    &offset, B_TRUE)) != CKR_OK) {
18117c478bd9Sstevel@tonic-gate 				free(cert);
18127c478bd9Sstevel@tonic-gate 				return (rv);
18137c478bd9Sstevel@tonic-gate 			}
18147c478bd9Sstevel@tonic-gate 
18157c478bd9Sstevel@tonic-gate 			break;
18167c478bd9Sstevel@tonic-gate 		}
18177c478bd9Sstevel@tonic-gate 
18187c478bd9Sstevel@tonic-gate 		return (rv);
18197c478bd9Sstevel@tonic-gate 
18207c478bd9Sstevel@tonic-gate 	case CKO_DOMAIN_PARAMETERS:
18217c478bd9Sstevel@tonic-gate 
18227c478bd9Sstevel@tonic-gate 		break;
18237c478bd9Sstevel@tonic-gate 	}
18247c478bd9Sstevel@tonic-gate 
18257c478bd9Sstevel@tonic-gate pub_cleanup:
18267c478bd9Sstevel@tonic-gate 	/*
18277c478bd9Sstevel@tonic-gate 	 * cleanup the storage allocated to the local variables.
18287c478bd9Sstevel@tonic-gate 	 */
18297c478bd9Sstevel@tonic-gate 	if (rv != CKR_OK)
18307c478bd9Sstevel@tonic-gate 		free(pbk);
18317c478bd9Sstevel@tonic-gate 	bigint_attr_cleanup(&modulus);
18327c478bd9Sstevel@tonic-gate 	bigint_attr_cleanup(&pubexpo);
18337c478bd9Sstevel@tonic-gate 	bigint_attr_cleanup(&prime);
18347c478bd9Sstevel@tonic-gate 	bigint_attr_cleanup(&subprime);
18357c478bd9Sstevel@tonic-gate 	bigint_attr_cleanup(&base);
18367c478bd9Sstevel@tonic-gate 	bigint_attr_cleanup(&value);
18377c478bd9Sstevel@tonic-gate 	return (rv);
18387c478bd9Sstevel@tonic-gate 
18397c478bd9Sstevel@tonic-gate pri_cleanup:
18407c478bd9Sstevel@tonic-gate 	/*
18417c478bd9Sstevel@tonic-gate 	 * cleanup the storage allocated to the local variables.
18427c478bd9Sstevel@tonic-gate 	 */
18437c478bd9Sstevel@tonic-gate 	if (rv != CKR_OK)
18447c478bd9Sstevel@tonic-gate 		free(pvk);
18457c478bd9Sstevel@tonic-gate 	bigint_attr_cleanup(&modulus);
18467c478bd9Sstevel@tonic-gate 	bigint_attr_cleanup(&priexpo);
18477c478bd9Sstevel@tonic-gate 	bigint_attr_cleanup(&prime);
18487c478bd9Sstevel@tonic-gate 	bigint_attr_cleanup(&subprime);
18497c478bd9Sstevel@tonic-gate 	bigint_attr_cleanup(&base);
18507c478bd9Sstevel@tonic-gate 	bigint_attr_cleanup(&value);
18517c478bd9Sstevel@tonic-gate 	bigint_attr_cleanup(&pubexpo);
18527c478bd9Sstevel@tonic-gate 	bigint_attr_cleanup(&prime1);
18537c478bd9Sstevel@tonic-gate 	bigint_attr_cleanup(&prime2);
18547c478bd9Sstevel@tonic-gate 	bigint_attr_cleanup(&expo1);
18557c478bd9Sstevel@tonic-gate 	bigint_attr_cleanup(&expo2);
18567c478bd9Sstevel@tonic-gate 	bigint_attr_cleanup(&coef);
18577c478bd9Sstevel@tonic-gate 	return (rv);
18587c478bd9Sstevel@tonic-gate }
18597c478bd9Sstevel@tonic-gate 
18607c478bd9Sstevel@tonic-gate 
18617c478bd9Sstevel@tonic-gate /*
18627c478bd9Sstevel@tonic-gate  * Store the token object to a keystore file.
18637c478bd9Sstevel@tonic-gate  */
18647c478bd9Sstevel@tonic-gate CK_RV
soft_put_object_to_keystore(soft_object_t * objp)18657c478bd9Sstevel@tonic-gate soft_put_object_to_keystore(soft_object_t *objp)
18667c478bd9Sstevel@tonic-gate {
18677c478bd9Sstevel@tonic-gate 
18687c478bd9Sstevel@tonic-gate 	uchar_t *buf;
18697c478bd9Sstevel@tonic-gate 	size_t len;
18707c478bd9Sstevel@tonic-gate 	CK_RV rv;
18717c478bd9Sstevel@tonic-gate 
18727c478bd9Sstevel@tonic-gate 	rv = soft_keystore_pack_obj(objp, &buf, &len);
18737c478bd9Sstevel@tonic-gate 	if (rv != CKR_OK)
18747c478bd9Sstevel@tonic-gate 		return (rv);
18757c478bd9Sstevel@tonic-gate 
18764d25c1d6Smcpowers 	(void) pthread_mutex_lock(&soft_slot.slot_mutex);
1877a8793c76SJason King 	if (soft_keystore_put_new_obj(buf, len,
1878a8793c76SJason King 	    !!(objp->object_type == TOKEN_PUBLIC), B_FALSE,
1879a8793c76SJason King 	    &objp->ks_handle) == -1) {
1880a8793c76SJason King 		rv = CKR_FUNCTION_FAILED;
18817c478bd9Sstevel@tonic-gate 	}
18824d25c1d6Smcpowers 	(void) pthread_mutex_unlock(&soft_slot.slot_mutex);
18837c478bd9Sstevel@tonic-gate 
1884a8793c76SJason King 	freezero(buf, len);
1885a8793c76SJason King 	return (rv);
18867c478bd9Sstevel@tonic-gate }
18877c478bd9Sstevel@tonic-gate 
18887c478bd9Sstevel@tonic-gate /*
18897c478bd9Sstevel@tonic-gate  * Modify the in-core token object and then write it to
18907c478bd9Sstevel@tonic-gate  * a keystore file.
18917c478bd9Sstevel@tonic-gate  */
18927c478bd9Sstevel@tonic-gate CK_RV
soft_modify_object_to_keystore(soft_object_t * objp)18937c478bd9Sstevel@tonic-gate soft_modify_object_to_keystore(soft_object_t *objp)
18947c478bd9Sstevel@tonic-gate {
18957c478bd9Sstevel@tonic-gate 
18967c478bd9Sstevel@tonic-gate 	uchar_t *buf;
18977c478bd9Sstevel@tonic-gate 	size_t len;
18987c478bd9Sstevel@tonic-gate 	CK_RV rv;
18997c478bd9Sstevel@tonic-gate 
19007c478bd9Sstevel@tonic-gate 	rv = soft_keystore_pack_obj(objp, &buf, &len);
19017c478bd9Sstevel@tonic-gate 	if (rv != CKR_OK)
19027c478bd9Sstevel@tonic-gate 		return (rv);
19037c478bd9Sstevel@tonic-gate 
19047c478bd9Sstevel@tonic-gate 	/* B_TRUE: caller has held a writelock on the keystore */
19057c478bd9Sstevel@tonic-gate 	if (soft_keystore_modify_obj(&objp->ks_handle, buf, len,
19067c478bd9Sstevel@tonic-gate 	    B_TRUE) < 0) {
1907a8793c76SJason King 		rv = CKR_FUNCTION_FAILED;
19087c478bd9Sstevel@tonic-gate 	}
19097c478bd9Sstevel@tonic-gate 
1910a8793c76SJason King 	freezero(buf, len);
1911a8793c76SJason King 	return (rv);
19127c478bd9Sstevel@tonic-gate 
19137c478bd9Sstevel@tonic-gate }
19147c478bd9Sstevel@tonic-gate 
19157c478bd9Sstevel@tonic-gate /*
19167c478bd9Sstevel@tonic-gate  * Read the token object from the keystore file.
19177c478bd9Sstevel@tonic-gate  */
19187c478bd9Sstevel@tonic-gate CK_RV
soft_get_token_objects_from_keystore(ks_search_type_t type)19197c478bd9Sstevel@tonic-gate soft_get_token_objects_from_keystore(ks_search_type_t type)
19207c478bd9Sstevel@tonic-gate {
19217c478bd9Sstevel@tonic-gate 	CK_RV rv;
19227c478bd9Sstevel@tonic-gate 	ks_obj_t	*ks_obj = NULL, *ks_obj_next;
19237c478bd9Sstevel@tonic-gate 	soft_object_t *new_objp = NULL;
19247c478bd9Sstevel@tonic-gate 
19257c478bd9Sstevel@tonic-gate 	/* Load the token object from keystore based on the object type */
19267c478bd9Sstevel@tonic-gate 	rv = soft_keystore_get_objs(type, &ks_obj, B_FALSE);
19277c478bd9Sstevel@tonic-gate 	if (rv != CKR_OK) {
19287c478bd9Sstevel@tonic-gate 		return (rv);
19297c478bd9Sstevel@tonic-gate 	}
19307c478bd9Sstevel@tonic-gate 
19317c478bd9Sstevel@tonic-gate 	while (ks_obj) {
19327c478bd9Sstevel@tonic-gate 
19337c478bd9Sstevel@tonic-gate 		new_objp = calloc(1, sizeof (soft_object_t));
19347c478bd9Sstevel@tonic-gate 		if (new_objp == NULL) {
19357c478bd9Sstevel@tonic-gate 			rv = CKR_HOST_MEMORY;
19367c478bd9Sstevel@tonic-gate 			goto cleanup;
19377c478bd9Sstevel@tonic-gate 		}
19387c478bd9Sstevel@tonic-gate 		/* Convert the keystore format to memory format */
19397c478bd9Sstevel@tonic-gate 		rv = soft_keystore_unpack_obj(new_objp, ks_obj);
19407c478bd9Sstevel@tonic-gate 		if (rv != CKR_OK) {
19417c478bd9Sstevel@tonic-gate 			if (new_objp->class == CKO_CERTIFICATE)
19427c478bd9Sstevel@tonic-gate 				soft_cleanup_cert_object(new_objp);
19437c478bd9Sstevel@tonic-gate 			else
19447c478bd9Sstevel@tonic-gate 				soft_cleanup_object(new_objp);
19457c478bd9Sstevel@tonic-gate 			goto cleanup;
19467c478bd9Sstevel@tonic-gate 		}
19477c478bd9Sstevel@tonic-gate 
19487c478bd9Sstevel@tonic-gate 		soft_add_token_object_to_slot(new_objp);
19497c478bd9Sstevel@tonic-gate 
19507c478bd9Sstevel@tonic-gate 		/* Free the ks_obj list */
19517c478bd9Sstevel@tonic-gate 		ks_obj_next = ks_obj->next;
1952a8793c76SJason King 		freezero(ks_obj->buf, ks_obj->size);
19537c478bd9Sstevel@tonic-gate 		free(ks_obj);
19547c478bd9Sstevel@tonic-gate 		ks_obj = ks_obj_next;
19557c478bd9Sstevel@tonic-gate 	}
19567c478bd9Sstevel@tonic-gate 
19577c478bd9Sstevel@tonic-gate 	return (CKR_OK);
19587c478bd9Sstevel@tonic-gate 
19597c478bd9Sstevel@tonic-gate cleanup:
19607c478bd9Sstevel@tonic-gate 	while (ks_obj) {
19617c478bd9Sstevel@tonic-gate 		ks_obj_next = ks_obj->next;
1962a8793c76SJason King 		freezero(ks_obj->buf, ks_obj->size);
19637c478bd9Sstevel@tonic-gate 		free(ks_obj);
19647c478bd9Sstevel@tonic-gate 		ks_obj = ks_obj_next;
19657c478bd9Sstevel@tonic-gate 	}
19667c478bd9Sstevel@tonic-gate 	return (rv);
19677c478bd9Sstevel@tonic-gate }
19687c478bd9Sstevel@tonic-gate 
19697c478bd9Sstevel@tonic-gate /*
19707c478bd9Sstevel@tonic-gate  * soft_gen_crypt_key()
19717c478bd9Sstevel@tonic-gate  *
19727c478bd9Sstevel@tonic-gate  * Arguments:
19737c478bd9Sstevel@tonic-gate  *
19747c478bd9Sstevel@tonic-gate  *	pPIN:	pointer to caller provided Pin
19757c478bd9Sstevel@tonic-gate  *	key:	output argument which contains the address of the
19767c478bd9Sstevel@tonic-gate  *		pointer to encryption key in the soft_object_t.
19777c478bd9Sstevel@tonic-gate  *		It is caller's responsibility to call soft_delete_object()
19787c478bd9Sstevel@tonic-gate  *		if this key is no longer in use.
19797c478bd9Sstevel@tonic-gate  *	saltdata: input argument (if non-NULL), or
19807c478bd9Sstevel@tonic-gate  *		  output argument (if NULL):
19817c478bd9Sstevel@tonic-gate  *		  address of pointer to the "salt" of the encryption key
19827c478bd9Sstevel@tonic-gate  *
19837c478bd9Sstevel@tonic-gate  * Description:
19847c478bd9Sstevel@tonic-gate  *
19857c478bd9Sstevel@tonic-gate  *	Generate an encryption key of the input PIN.
19867c478bd9Sstevel@tonic-gate  *
19877c478bd9Sstevel@tonic-gate  * Returns:
19887c478bd9Sstevel@tonic-gate  *
19897c478bd9Sstevel@tonic-gate  *	CKR_OK: no error
19907c478bd9Sstevel@tonic-gate  *	Other: some error occurred while generating the encryption key
19917c478bd9Sstevel@tonic-gate  *
19927c478bd9Sstevel@tonic-gate  */
19937c478bd9Sstevel@tonic-gate CK_RV
soft_gen_crypt_key(uchar_t * pPIN,soft_object_t ** key,CK_BYTE ** saltdata)19947c478bd9Sstevel@tonic-gate soft_gen_crypt_key(uchar_t *pPIN, soft_object_t **key, CK_BYTE **saltdata)
19957c478bd9Sstevel@tonic-gate {
19967c478bd9Sstevel@tonic-gate 	CK_OBJECT_CLASS class = CKO_SECRET_KEY;
19977c478bd9Sstevel@tonic-gate 	CK_ATTRIBUTE tmpl[5];
19987c478bd9Sstevel@tonic-gate 	int attrs = 0;
19997c478bd9Sstevel@tonic-gate 	CK_RV rv;
20007c478bd9Sstevel@tonic-gate 	CK_MECHANISM Mechanism;
20017c478bd9Sstevel@tonic-gate 	CK_PKCS5_PBKD2_PARAMS params;
20027c478bd9Sstevel@tonic-gate 	CK_BYTE		salt[PBKD2_SALT_SIZE];
20037c478bd9Sstevel@tonic-gate 	CK_ULONG	keylen = AES_MIN_KEY_BYTES;
20047c478bd9Sstevel@tonic-gate 	CK_KEY_TYPE keytype = CKK_AES;
20057c478bd9Sstevel@tonic-gate 	static CK_BBOOL truevalue = TRUE;
20067c478bd9Sstevel@tonic-gate 	soft_object_t *secret_key;
20077c478bd9Sstevel@tonic-gate 	CK_ULONG	passwd_size;
20087c478bd9Sstevel@tonic-gate 
20097c478bd9Sstevel@tonic-gate 	if (pPIN == NULL)
20107c478bd9Sstevel@tonic-gate 		return (CKR_FUNCTION_FAILED);
20117c478bd9Sstevel@tonic-gate 
20127c478bd9Sstevel@tonic-gate 	tmpl[attrs].type = CKA_CLASS;
20137c478bd9Sstevel@tonic-gate 	tmpl[attrs].pValue = &class;
20147c478bd9Sstevel@tonic-gate 	tmpl[attrs].ulValueLen = sizeof (class);
20157c478bd9Sstevel@tonic-gate 	attrs++;
20167c478bd9Sstevel@tonic-gate 
20177c478bd9Sstevel@tonic-gate 	tmpl[attrs].type = CKA_KEY_TYPE;
20187c478bd9Sstevel@tonic-gate 	tmpl[attrs].pValue = &keytype;
20197c478bd9Sstevel@tonic-gate 	tmpl[attrs].ulValueLen = sizeof (keytype);
20207c478bd9Sstevel@tonic-gate 	attrs++;
20217c478bd9Sstevel@tonic-gate 
20227c478bd9Sstevel@tonic-gate 	tmpl[attrs].type = CKA_ENCRYPT;
20237c478bd9Sstevel@tonic-gate 	tmpl[attrs].pValue = &truevalue;
20247c478bd9Sstevel@tonic-gate 	tmpl[attrs].ulValueLen = sizeof (CK_BBOOL);
20257c478bd9Sstevel@tonic-gate 	attrs++;
20267c478bd9Sstevel@tonic-gate 
20277c478bd9Sstevel@tonic-gate 	tmpl[attrs].type = CKA_DECRYPT;
20287c478bd9Sstevel@tonic-gate 	tmpl[attrs].pValue = &truevalue;
20297c478bd9Sstevel@tonic-gate 	tmpl[attrs].ulValueLen = sizeof (CK_BBOOL);
20307c478bd9Sstevel@tonic-gate 	attrs++;
20317c478bd9Sstevel@tonic-gate 
20327c478bd9Sstevel@tonic-gate 	tmpl[attrs].type = CKA_VALUE_LEN;
20337c478bd9Sstevel@tonic-gate 	tmpl[attrs].pValue = &keylen;
20347c478bd9Sstevel@tonic-gate 	tmpl[attrs].ulValueLen = sizeof (keylen);
20357c478bd9Sstevel@tonic-gate 	attrs++;
20367c478bd9Sstevel@tonic-gate 
20377c478bd9Sstevel@tonic-gate 	if (*saltdata == NULL) {
20387c478bd9Sstevel@tonic-gate 		bzero(salt, sizeof (salt));
20397b79d846SDina K Nimeh 		(void) pkcs11_get_nzero_urandom(salt, sizeof (salt));
20407c478bd9Sstevel@tonic-gate 		*saltdata = malloc(PBKD2_SALT_SIZE);
20417c478bd9Sstevel@tonic-gate 		if (*saltdata == NULL)
20427c478bd9Sstevel@tonic-gate 			return (CKR_HOST_MEMORY);
20437c478bd9Sstevel@tonic-gate 		(void) memcpy(*saltdata, salt, PBKD2_SALT_SIZE);
20447c478bd9Sstevel@tonic-gate 	} else {
20457c478bd9Sstevel@tonic-gate 		bzero(salt, sizeof (salt));
20467c478bd9Sstevel@tonic-gate 		(void) memcpy(salt, *saltdata, PBKD2_SALT_SIZE);
20477c478bd9Sstevel@tonic-gate 	}
20487c478bd9Sstevel@tonic-gate 
20497c478bd9Sstevel@tonic-gate 	Mechanism.mechanism = CKM_PKCS5_PBKD2;
20507c478bd9Sstevel@tonic-gate 	Mechanism.pParameter = &params;
20517c478bd9Sstevel@tonic-gate 	Mechanism.ulParameterLen = sizeof (params);
20527c478bd9Sstevel@tonic-gate 	passwd_size = (CK_ULONG)strlen((const char *)pPIN);
20537c478bd9Sstevel@tonic-gate 
20547c478bd9Sstevel@tonic-gate 	params.saltSource = CKZ_SALT_SPECIFIED;
20557c478bd9Sstevel@tonic-gate 	params.pSaltSourceData = (void *)salt;
20567c478bd9Sstevel@tonic-gate 	params.ulSaltSourceDataLen = sizeof (salt);
20577c478bd9Sstevel@tonic-gate 	params.iterations = PBKD2_ITERATIONS;
20587c478bd9Sstevel@tonic-gate 	params.prf = CKP_PKCS5_PBKD2_HMAC_SHA1;
20597c478bd9Sstevel@tonic-gate 	params.pPrfData = NULL;
20607c478bd9Sstevel@tonic-gate 	params.ulPrfDataLen = 0;
20617c478bd9Sstevel@tonic-gate 	params.pPassword = (CK_UTF8CHAR_PTR)pPIN;
20627c478bd9Sstevel@tonic-gate 	params.ulPasswordLen = &passwd_size;
20637c478bd9Sstevel@tonic-gate 
2064*cfcec266SJason King 	rv = soft_gen_keyobject(tmpl, attrs, &secret_key, &token_session,
20657c478bd9Sstevel@tonic-gate 	    CKO_SECRET_KEY, CKK_AES, 0, SOFT_GEN_KEY, B_TRUE);
20667c478bd9Sstevel@tonic-gate 
20677c478bd9Sstevel@tonic-gate 	if (rv != CKR_OK) {
20687c478bd9Sstevel@tonic-gate 		return (rv);
20697c478bd9Sstevel@tonic-gate 	}
20707c478bd9Sstevel@tonic-gate 
20717c478bd9Sstevel@tonic-gate 	keylen = OBJ_SEC_VALUE_LEN(secret_key);
20727c478bd9Sstevel@tonic-gate 	if ((OBJ_SEC_VALUE(secret_key) = malloc(keylen)) == NULL) {
20731f49a79aSZdenek Kotala 		soft_delete_object(&token_session, secret_key,
20741f49a79aSZdenek Kotala 		    B_FALSE, B_FALSE);
20757c478bd9Sstevel@tonic-gate 		return (CKR_HOST_MEMORY);
20767c478bd9Sstevel@tonic-gate 	}
20777c478bd9Sstevel@tonic-gate 
20787c478bd9Sstevel@tonic-gate 	rv = soft_generate_pkcs5_pbkdf2_key(&token_session, &Mechanism,
20797c478bd9Sstevel@tonic-gate 	    secret_key);
20807c478bd9Sstevel@tonic-gate 
20817c478bd9Sstevel@tonic-gate 	if (rv != CKR_OK)
20821f49a79aSZdenek Kotala 		soft_delete_object(&token_session, secret_key,
20831f49a79aSZdenek Kotala 		    B_FALSE, B_FALSE);
20847c478bd9Sstevel@tonic-gate 	else
20857c478bd9Sstevel@tonic-gate 		*key = secret_key;
20867c478bd9Sstevel@tonic-gate 
20877c478bd9Sstevel@tonic-gate 	return (rv);
20887c478bd9Sstevel@tonic-gate 
20897c478bd9Sstevel@tonic-gate }
20907c478bd9Sstevel@tonic-gate 
20917c478bd9Sstevel@tonic-gate /*
20927c478bd9Sstevel@tonic-gate  * soft_gen_hmac_key()
20937c478bd9Sstevel@tonic-gate  *
20947c478bd9Sstevel@tonic-gate  * Arguments:
20957c478bd9Sstevel@tonic-gate  *
20967c478bd9Sstevel@tonic-gate  *	pPIN:	pointer to caller provided Pin
20977c478bd9Sstevel@tonic-gate  *	key:	output argument which contains the address of the
20987c478bd9Sstevel@tonic-gate  *		pointer to hmac key in the soft_object_t.
20997c478bd9Sstevel@tonic-gate  *		It is caller's responsibility to call soft_delete_object()
21007c478bd9Sstevel@tonic-gate  *		if this key is no longer in use.
21017c478bd9Sstevel@tonic-gate  *	saltdata: input argument (if non-NULL), or
21027c478bd9Sstevel@tonic-gate  *                output argument (if NULL):
21037c478bd9Sstevel@tonic-gate  *                address of pointer to the "salt" of the hmac key
21047c478bd9Sstevel@tonic-gate  *
21057c478bd9Sstevel@tonic-gate  * Description:
21067c478bd9Sstevel@tonic-gate  *
21077c478bd9Sstevel@tonic-gate  *	Generate a hmac key of the input PIN.
21087c478bd9Sstevel@tonic-gate  *
21097c478bd9Sstevel@tonic-gate  * Returns:
21107c478bd9Sstevel@tonic-gate  *
21117c478bd9Sstevel@tonic-gate  *	CKR_OK: no error
21127c478bd9Sstevel@tonic-gate  *	Other: some error occurred while generating the hmac key
21137c478bd9Sstevel@tonic-gate  *
21147c478bd9Sstevel@tonic-gate  */
21157c478bd9Sstevel@tonic-gate CK_RV
soft_gen_hmac_key(uchar_t * pPIN,soft_object_t ** key,CK_BYTE ** saltdata)21167c478bd9Sstevel@tonic-gate soft_gen_hmac_key(uchar_t *pPIN, soft_object_t **key, CK_BYTE **saltdata)
21177c478bd9Sstevel@tonic-gate {
21187c478bd9Sstevel@tonic-gate 	CK_OBJECT_CLASS class = CKO_SECRET_KEY;
21197c478bd9Sstevel@tonic-gate 	CK_ATTRIBUTE tmpl[5];
21207c478bd9Sstevel@tonic-gate 	int attrs = 0;
21217c478bd9Sstevel@tonic-gate 	CK_RV rv;
21227c478bd9Sstevel@tonic-gate 	CK_MECHANISM Mechanism;
21237c478bd9Sstevel@tonic-gate 	CK_PKCS5_PBKD2_PARAMS params;
21247c478bd9Sstevel@tonic-gate 	CK_BYTE		salt[PBKD2_SALT_SIZE];
21257c478bd9Sstevel@tonic-gate 	CK_ULONG	keylen = 16;
21267c478bd9Sstevel@tonic-gate 	CK_KEY_TYPE keytype = CKK_GENERIC_SECRET;
21277c478bd9Sstevel@tonic-gate 	static CK_BBOOL truevalue = TRUE;
21287c478bd9Sstevel@tonic-gate 	soft_object_t *secret_key;
21297c478bd9Sstevel@tonic-gate 	CK_ULONG	passwd_size;
21307c478bd9Sstevel@tonic-gate 
21317c478bd9Sstevel@tonic-gate 	if (pPIN == NULL)
21327c478bd9Sstevel@tonic-gate 		return (CKR_FUNCTION_FAILED);
21337c478bd9Sstevel@tonic-gate 
21347c478bd9Sstevel@tonic-gate 	tmpl[attrs].type = CKA_CLASS;
21357c478bd9Sstevel@tonic-gate 	tmpl[attrs].pValue = &class;
21367c478bd9Sstevel@tonic-gate 	tmpl[attrs].ulValueLen = sizeof (class);
21377c478bd9Sstevel@tonic-gate 	attrs++;
21387c478bd9Sstevel@tonic-gate 
21397c478bd9Sstevel@tonic-gate 	tmpl[attrs].type = CKA_KEY_TYPE;
21407c478bd9Sstevel@tonic-gate 	tmpl[attrs].pValue = &keytype;
21417c478bd9Sstevel@tonic-gate 	tmpl[attrs].ulValueLen = sizeof (keytype);
21427c478bd9Sstevel@tonic-gate 	attrs++;
21437c478bd9Sstevel@tonic-gate 
21447c478bd9Sstevel@tonic-gate 	tmpl[attrs].type = CKA_SIGN;
21457c478bd9Sstevel@tonic-gate 	tmpl[attrs].pValue = &truevalue;
21467c478bd9Sstevel@tonic-gate 	tmpl[attrs].ulValueLen = sizeof (CK_BBOOL);
21477c478bd9Sstevel@tonic-gate 	attrs++;
21487c478bd9Sstevel@tonic-gate 
21497c478bd9Sstevel@tonic-gate 	tmpl[attrs].type = CKA_VERIFY;
21507c478bd9Sstevel@tonic-gate 	tmpl[attrs].pValue = &truevalue;
21517c478bd9Sstevel@tonic-gate 	tmpl[attrs].ulValueLen = sizeof (CK_BBOOL);
21527c478bd9Sstevel@tonic-gate 	attrs++;
21537c478bd9Sstevel@tonic-gate 
21547c478bd9Sstevel@tonic-gate 	tmpl[attrs].type = CKA_VALUE_LEN;
21557c478bd9Sstevel@tonic-gate 	tmpl[attrs].pValue = &keylen;
21567c478bd9Sstevel@tonic-gate 	tmpl[attrs].ulValueLen = sizeof (keylen);
21577c478bd9Sstevel@tonic-gate 	attrs++;
21587c478bd9Sstevel@tonic-gate 
21597c478bd9Sstevel@tonic-gate 	if (*saltdata == NULL) {
21607c478bd9Sstevel@tonic-gate 		bzero(salt, sizeof (salt));
21617b79d846SDina K Nimeh 		(void) pkcs11_get_nzero_urandom(salt, sizeof (salt));
21627c478bd9Sstevel@tonic-gate 		*saltdata = malloc(PBKD2_SALT_SIZE);
21637c478bd9Sstevel@tonic-gate 		if (*saltdata == NULL)
21647c478bd9Sstevel@tonic-gate 			return (CKR_HOST_MEMORY);
21657c478bd9Sstevel@tonic-gate 		(void) memcpy(*saltdata, salt, PBKD2_SALT_SIZE);
21667c478bd9Sstevel@tonic-gate 	} else {
21677c478bd9Sstevel@tonic-gate 		bzero(salt, sizeof (salt));
21687c478bd9Sstevel@tonic-gate 		(void) memcpy(salt, *saltdata, PBKD2_SALT_SIZE);
21697c478bd9Sstevel@tonic-gate 	}
21707c478bd9Sstevel@tonic-gate 
21717c478bd9Sstevel@tonic-gate 	Mechanism.mechanism = CKM_PKCS5_PBKD2;
21727c478bd9Sstevel@tonic-gate 	Mechanism.pParameter = &params;
21737c478bd9Sstevel@tonic-gate 	Mechanism.ulParameterLen = sizeof (params);
21747c478bd9Sstevel@tonic-gate 	passwd_size = (CK_ULONG)strlen((const char *)pPIN);
21757c478bd9Sstevel@tonic-gate 
21767c478bd9Sstevel@tonic-gate 	params.saltSource = CKZ_SALT_SPECIFIED;
21777c478bd9Sstevel@tonic-gate 	params.pSaltSourceData = (void *)salt;
21787c478bd9Sstevel@tonic-gate 	params.ulSaltSourceDataLen = sizeof (salt);
21797c478bd9Sstevel@tonic-gate 	params.iterations = PBKD2_ITERATIONS;
21807c478bd9Sstevel@tonic-gate 	params.prf = CKP_PKCS5_PBKD2_HMAC_SHA1;
21817c478bd9Sstevel@tonic-gate 	params.pPrfData = NULL;
21827c478bd9Sstevel@tonic-gate 	params.ulPrfDataLen = 0;
21837c478bd9Sstevel@tonic-gate 	params.pPassword = (CK_UTF8CHAR_PTR)pPIN;
21847c478bd9Sstevel@tonic-gate 	params.ulPasswordLen = &passwd_size;
21857c478bd9Sstevel@tonic-gate 
2186*cfcec266SJason King 	rv = soft_gen_keyobject(tmpl, attrs, &secret_key, &token_session,
21877c478bd9Sstevel@tonic-gate 	    CKO_SECRET_KEY, CKK_GENERIC_SECRET, 0, SOFT_GEN_KEY, B_TRUE);
21887c478bd9Sstevel@tonic-gate 
21897c478bd9Sstevel@tonic-gate 	if (rv != CKR_OK) {
21907c478bd9Sstevel@tonic-gate 		return (rv);
21917c478bd9Sstevel@tonic-gate 	}
21927c478bd9Sstevel@tonic-gate 
21937c478bd9Sstevel@tonic-gate 	keylen = OBJ_SEC_VALUE_LEN(secret_key);
21947c478bd9Sstevel@tonic-gate 	if ((OBJ_SEC_VALUE(secret_key) = malloc(keylen)) == NULL) {
21951f49a79aSZdenek Kotala 		soft_delete_object(&token_session, secret_key,
21961f49a79aSZdenek Kotala 		    B_FALSE, B_FALSE);
21977c478bd9Sstevel@tonic-gate 		return (CKR_HOST_MEMORY);
21987c478bd9Sstevel@tonic-gate 	}
21997c478bd9Sstevel@tonic-gate 
22007c478bd9Sstevel@tonic-gate 	rv = soft_generate_pkcs5_pbkdf2_key(&token_session, &Mechanism,
22017c478bd9Sstevel@tonic-gate 	    secret_key);
22027c478bd9Sstevel@tonic-gate 
22037c478bd9Sstevel@tonic-gate 	if (rv != CKR_OK)
22041f49a79aSZdenek Kotala 		soft_delete_object(&token_session, secret_key,
22051f49a79aSZdenek Kotala 		    B_FALSE, B_FALSE);
22067c478bd9Sstevel@tonic-gate 	else
22077c478bd9Sstevel@tonic-gate 		*key = secret_key;
22087c478bd9Sstevel@tonic-gate 
22097c478bd9Sstevel@tonic-gate 	return (rv);
22107c478bd9Sstevel@tonic-gate 
22117c478bd9Sstevel@tonic-gate }
22127c478bd9Sstevel@tonic-gate 
22137c478bd9Sstevel@tonic-gate /*
22147c478bd9Sstevel@tonic-gate  * The token session is just a psuedo session (a place holder)
22157c478bd9Sstevel@tonic-gate  * to hold some information during encryption/decryption and
22167c478bd9Sstevel@tonic-gate  * sign/verify operations when writing/reading the keystore
22177c478bd9Sstevel@tonic-gate  * token object.
22187c478bd9Sstevel@tonic-gate  */
22197c478bd9Sstevel@tonic-gate CK_RV
soft_init_token_session(void)22207c478bd9Sstevel@tonic-gate soft_init_token_session(void)
22217c478bd9Sstevel@tonic-gate {
22227c478bd9Sstevel@tonic-gate 
22237c478bd9Sstevel@tonic-gate 
22247c478bd9Sstevel@tonic-gate 	token_session.magic_marker = SOFTTOKEN_SESSION_MAGIC;
22257c478bd9Sstevel@tonic-gate 	token_session.pApplication = NULL_PTR;
22267c478bd9Sstevel@tonic-gate 	token_session.Notify = NULL;
22277c478bd9Sstevel@tonic-gate 	token_session.flags = CKF_SERIAL_SESSION;
22287c478bd9Sstevel@tonic-gate 	token_session.state = CKS_RO_PUBLIC_SESSION;
22297c478bd9Sstevel@tonic-gate 	token_session.object_list = NULL;
22307c478bd9Sstevel@tonic-gate 	token_session.ses_refcnt = 0;
22317c478bd9Sstevel@tonic-gate 	token_session.ses_close_sync = 0;
223283140133SZdenek Kotala 	token_session.next = NULL;
223383140133SZdenek Kotala 	token_session.prev = NULL;
22347c478bd9Sstevel@tonic-gate 
22357c478bd9Sstevel@tonic-gate 	/* Initialize the lock for the token session */
22367c478bd9Sstevel@tonic-gate 	if (pthread_mutex_init(&token_session.session_mutex, NULL) != 0) {
22377c478bd9Sstevel@tonic-gate 		return (CKR_CANT_LOCK);
22387c478bd9Sstevel@tonic-gate 	}
22397c478bd9Sstevel@tonic-gate 
22407c478bd9Sstevel@tonic-gate 	(void) pthread_cond_init(&token_session.ses_free_cond, NULL);
22417c478bd9Sstevel@tonic-gate 
22427c478bd9Sstevel@tonic-gate 	return (CKR_OK);
22437c478bd9Sstevel@tonic-gate 
22447c478bd9Sstevel@tonic-gate }
22457c478bd9Sstevel@tonic-gate 
22467c478bd9Sstevel@tonic-gate void
soft_destroy_token_session(void)22477c478bd9Sstevel@tonic-gate soft_destroy_token_session(void)
22487c478bd9Sstevel@tonic-gate {
22497c478bd9Sstevel@tonic-gate 
22507c478bd9Sstevel@tonic-gate 	(void) pthread_cond_destroy(&token_session.ses_free_cond);
22517c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_destroy(&token_session.session_mutex);
22527c478bd9Sstevel@tonic-gate 
22537c478bd9Sstevel@tonic-gate }
22547c478bd9Sstevel@tonic-gate 
22557c478bd9Sstevel@tonic-gate /*
22567c478bd9Sstevel@tonic-gate  * Encrypt/Decrypt the private token object when dealing with the keystore.
22577c478bd9Sstevel@tonic-gate  * This function only applies to the private token object.
22587c478bd9Sstevel@tonic-gate  */
22597c478bd9Sstevel@tonic-gate CK_RV
soft_keystore_crypt(soft_object_t * key_p,uchar_t * ivec,boolean_t encrypt,CK_BYTE_PTR in,CK_ULONG in_len,CK_BYTE_PTR out,CK_ULONG_PTR out_len)22607c478bd9Sstevel@tonic-gate soft_keystore_crypt(soft_object_t *key_p, uchar_t *ivec, boolean_t encrypt,
2261a8793c76SJason King     CK_BYTE_PTR in, CK_ULONG in_len, CK_BYTE_PTR out, CK_ULONG_PTR out_len)
22627c478bd9Sstevel@tonic-gate {
22637c478bd9Sstevel@tonic-gate 	CK_MECHANISM	mech;
22647c478bd9Sstevel@tonic-gate 	CK_RV rv;
22657c478bd9Sstevel@tonic-gate 	CK_ULONG tmplen, tmplen1;
22667c478bd9Sstevel@tonic-gate 
22677c478bd9Sstevel@tonic-gate 	/*
22687c478bd9Sstevel@tonic-gate 	 * The caller will pass NULL for "out" (output buffer) to find out
22697c478bd9Sstevel@tonic-gate 	 * the output buffer size that it need to allocate for the encrption
22707c478bd9Sstevel@tonic-gate 	 * or decryption.
22717c478bd9Sstevel@tonic-gate 	 */
22727c478bd9Sstevel@tonic-gate 	if (out == NULL) {
22737c478bd9Sstevel@tonic-gate 		mech.mechanism = CKM_AES_CBC_PAD;
22747c478bd9Sstevel@tonic-gate 		mech.pParameter = (void *)ivec;
22757c478bd9Sstevel@tonic-gate 		mech.ulParameterLen = AES_BLOCK_LEN;
22767c478bd9Sstevel@tonic-gate 
22777c478bd9Sstevel@tonic-gate 		if (encrypt)
22787c478bd9Sstevel@tonic-gate 			rv = soft_aes_crypt_init_common(&token_session, &mech,
22797c478bd9Sstevel@tonic-gate 			    key_p, B_TRUE);
22807c478bd9Sstevel@tonic-gate 		else
22817c478bd9Sstevel@tonic-gate 			rv = soft_aes_crypt_init_common(&token_session, &mech,
22827c478bd9Sstevel@tonic-gate 			    key_p, B_FALSE);
22837c478bd9Sstevel@tonic-gate 
22847c478bd9Sstevel@tonic-gate 		if (rv != CKR_OK)
22857c478bd9Sstevel@tonic-gate 			return (rv);
22867c478bd9Sstevel@tonic-gate 
22877c478bd9Sstevel@tonic-gate 		/*
22887c478bd9Sstevel@tonic-gate 		 * Since out == NULL, the soft_aes_xxcrypt_common() will
22897c478bd9Sstevel@tonic-gate 		 * simply return the output buffer length to the caller.
22907c478bd9Sstevel@tonic-gate 		 */
22917c478bd9Sstevel@tonic-gate 		if (encrypt) {
2292fb261280SJason King 			rv = soft_aes_encrypt(&token_session, in, in_len,
2293fb261280SJason King 			    out, out_len);
22947c478bd9Sstevel@tonic-gate 		} else {
2295fb261280SJason King 			rv = soft_aes_decrypt(&token_session, in, in_len,
2296fb261280SJason King 			    out, out_len);
22977c478bd9Sstevel@tonic-gate 		}
22987c478bd9Sstevel@tonic-gate 
22997c478bd9Sstevel@tonic-gate 	} else {
23007c478bd9Sstevel@tonic-gate 		/*
23017c478bd9Sstevel@tonic-gate 		 * The caller has allocated the output buffer, so that we
23027c478bd9Sstevel@tonic-gate 		 * are doing the real encryption/decryption this time.
23037c478bd9Sstevel@tonic-gate 		 */
23047c478bd9Sstevel@tonic-gate 		tmplen = *out_len;
23057c478bd9Sstevel@tonic-gate 		if (encrypt) {
2306fb261280SJason King 			rv = soft_aes_encrypt_update(&token_session, in,
2307fb261280SJason King 			    in_len, out, &tmplen);
23087c478bd9Sstevel@tonic-gate 			if (rv == CKR_OK) {
23097c478bd9Sstevel@tonic-gate 				tmplen1 = *out_len - tmplen;
23107c478bd9Sstevel@tonic-gate 				rv = soft_encrypt_final(&token_session,
23117c478bd9Sstevel@tonic-gate 				    out+tmplen, &tmplen1);
23127c478bd9Sstevel@tonic-gate 				*out_len = tmplen + tmplen1;
23137c478bd9Sstevel@tonic-gate 			}
23147c478bd9Sstevel@tonic-gate 		} else {
2315fb261280SJason King 			rv = soft_aes_decrypt_update(&token_session, in,
2316fb261280SJason King 			    in_len, out, &tmplen);
23177c478bd9Sstevel@tonic-gate 			if (rv == CKR_OK) {
23187c478bd9Sstevel@tonic-gate 				tmplen1 = *out_len - tmplen;
23197c478bd9Sstevel@tonic-gate 				rv = soft_decrypt_final(&token_session,
23207c478bd9Sstevel@tonic-gate 				    out+tmplen, &tmplen1);
23217c478bd9Sstevel@tonic-gate 				*out_len = tmplen + tmplen1;
23227c478bd9Sstevel@tonic-gate 			}
23237c478bd9Sstevel@tonic-gate 		}
23247c478bd9Sstevel@tonic-gate 	}
23257c478bd9Sstevel@tonic-gate 
23267c478bd9Sstevel@tonic-gate 	return (rv);
23277c478bd9Sstevel@tonic-gate 
23287c478bd9Sstevel@tonic-gate }
23297c478bd9Sstevel@tonic-gate 
23307c478bd9Sstevel@tonic-gate /*
23317c478bd9Sstevel@tonic-gate  * Sign/Verify the private token object for checking its data integrity
23327c478bd9Sstevel@tonic-gate  * when dealing with the keystore.
23337c478bd9Sstevel@tonic-gate  * This function only applies to the private token object.
23347c478bd9Sstevel@tonic-gate  */
23357c478bd9Sstevel@tonic-gate CK_RV
soft_keystore_hmac(soft_object_t * key_p,boolean_t sign,CK_BYTE_PTR in,CK_ULONG in_len,CK_BYTE_PTR out,CK_ULONG_PTR out_len)23367c478bd9Sstevel@tonic-gate soft_keystore_hmac(soft_object_t *key_p, boolean_t sign,
2337a8793c76SJason King     CK_BYTE_PTR in, CK_ULONG in_len, CK_BYTE_PTR out, CK_ULONG_PTR out_len)
23387c478bd9Sstevel@tonic-gate {
23397c478bd9Sstevel@tonic-gate 	CK_MECHANISM mech;
23407c478bd9Sstevel@tonic-gate 	CK_RV rv;
23417c478bd9Sstevel@tonic-gate 
23427c478bd9Sstevel@tonic-gate 	mech.mechanism = CKM_MD5_HMAC;
23437c478bd9Sstevel@tonic-gate 	mech.pParameter = NULL_PTR;
23447c478bd9Sstevel@tonic-gate 	mech.ulParameterLen = 0;
23457c478bd9Sstevel@tonic-gate 
23467c478bd9Sstevel@tonic-gate 	rv = soft_hmac_sign_verify_init_common(&token_session, &mech,
23477c478bd9Sstevel@tonic-gate 	    key_p, sign);
23487c478bd9Sstevel@tonic-gate 
23497c478bd9Sstevel@tonic-gate 	if (rv != CKR_OK)
23507c478bd9Sstevel@tonic-gate 		return (rv);
23517c478bd9Sstevel@tonic-gate 
23527c478bd9Sstevel@tonic-gate 	if (sign) {
23537c478bd9Sstevel@tonic-gate 		rv = soft_sign(&token_session, in, in_len, out, out_len);
23547c478bd9Sstevel@tonic-gate 	} else {
23557c478bd9Sstevel@tonic-gate 		rv = soft_verify(&token_session, in, in_len, out, *out_len);
23567c478bd9Sstevel@tonic-gate 	}
23577c478bd9Sstevel@tonic-gate 
23587c478bd9Sstevel@tonic-gate 	return (rv);
23597c478bd9Sstevel@tonic-gate }
2360