xref: /titanic_51/usr/src/uts/common/crypto/io/dprov.c (revision 1a5e258f5471356ca102c7176637cdce45bac147)
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
58047c9fbSmcpowers  * Common Development and Distribution License (the "License").
68047c9fbSmcpowers  * 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 /*
2295014fbbSDan OpenSolaris Anderson  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*
287c478bd9Sstevel@tonic-gate  * Dummy Cryptographic Provider:
297c478bd9Sstevel@tonic-gate  *
307c478bd9Sstevel@tonic-gate  * This file implements a "dummy" cryptographic provider. It is implemented
317c478bd9Sstevel@tonic-gate  * as a pseudo device driver.
327c478bd9Sstevel@tonic-gate  *
337c478bd9Sstevel@tonic-gate  */
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate /*
367c478bd9Sstevel@tonic-gate  * This driver implements a KEF provider with the following capabilities:
377c478bd9Sstevel@tonic-gate  *
387c478bd9Sstevel@tonic-gate  * - registration/unregistration with KEF
397c478bd9Sstevel@tonic-gate  * - digest entry points
407c478bd9Sstevel@tonic-gate  * - mac entry points
417c478bd9Sstevel@tonic-gate  * - ctx management
427c478bd9Sstevel@tonic-gate  * - support for async requests
437c478bd9Sstevel@tonic-gate  * - cipher entry points
447c478bd9Sstevel@tonic-gate  * - dual entry points
457c478bd9Sstevel@tonic-gate  * - sign entry points
467c478bd9Sstevel@tonic-gate  * - verify entry points
477c478bd9Sstevel@tonic-gate  * - dual operations entry points
487c478bd9Sstevel@tonic-gate  * - dual cipher/mac operation entry points
497c478bd9Sstevel@tonic-gate  * - session management
507c478bd9Sstevel@tonic-gate  * - object management
517c478bd9Sstevel@tonic-gate  * - key management
527c478bd9Sstevel@tonic-gate  * - provider management
537c478bd9Sstevel@tonic-gate  *
547c478bd9Sstevel@tonic-gate  * In order to avoid duplicating the implementation of algorithms
557c478bd9Sstevel@tonic-gate  * provided by software providers, this pseudo driver acts as
567c478bd9Sstevel@tonic-gate  * a consumer of the framework. When invoking one of the framework's
577c478bd9Sstevel@tonic-gate  * entry points, the driver specifies the software provider to
587c478bd9Sstevel@tonic-gate  * be used for the operation.
597c478bd9Sstevel@tonic-gate  *
607c478bd9Sstevel@tonic-gate  * User management: we implement a PKCS#11 style provider which supports:
617c478bd9Sstevel@tonic-gate  * - one normal user with a PIN, and
627c478bd9Sstevel@tonic-gate  * - one SO user with a PIN.
637c478bd9Sstevel@tonic-gate  * These values are kept in the per-instance structure, and are initialized
647c478bd9Sstevel@tonic-gate  * with the provider management entry points.
657c478bd9Sstevel@tonic-gate  *
667c478bd9Sstevel@tonic-gate  */
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate #include <sys/types.h>
707c478bd9Sstevel@tonic-gate #include <sys/modctl.h>
717c478bd9Sstevel@tonic-gate #include <sys/conf.h>
727c478bd9Sstevel@tonic-gate #include <sys/stat.h>
737c478bd9Sstevel@tonic-gate #include <sys/ddi.h>
747c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
757c478bd9Sstevel@tonic-gate #include <sys/kmem.h>
767c478bd9Sstevel@tonic-gate #include <sys/errno.h>
777c478bd9Sstevel@tonic-gate #include <sys/ksynch.h>
787c478bd9Sstevel@tonic-gate #include <sys/file.h>
797c478bd9Sstevel@tonic-gate #include <sys/open.h>
807c478bd9Sstevel@tonic-gate #include <sys/cred.h>
817c478bd9Sstevel@tonic-gate #include <sys/model.h>
827c478bd9Sstevel@tonic-gate #include <sys/note.h>
837c478bd9Sstevel@tonic-gate #include <sys/random.h>
847c478bd9Sstevel@tonic-gate #include <sys/byteorder.h>
857c478bd9Sstevel@tonic-gate #include <sys/crypto/common.h>
867c478bd9Sstevel@tonic-gate #include <sys/crypto/spi.h>
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate #include <sys/taskq.h>
897c478bd9Sstevel@tonic-gate #include <sys/disp.h>
907c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
917c478bd9Sstevel@tonic-gate #include <sys/crypto/impl.h>
927c478bd9Sstevel@tonic-gate #include <sys/crypto/sched_impl.h>
93894b2776Smcpowers 
94f66d273dSizick #include <sys/sha2.h>
9523c57df7Smcpowers #include <modes/modes.h>
9623c57df7Smcpowers #include <aes/aes_impl.h>
97894b2776Smcpowers #include <des/des_impl.h>
98f9fbec18Smcpowers #include <ecc/ecc_impl.h>
99894b2776Smcpowers #include <blowfish/blowfish_impl.h>
100894b2776Smcpowers 
1017c478bd9Sstevel@tonic-gate /*
1027c478bd9Sstevel@tonic-gate  * Debugging macros.
1037c478bd9Sstevel@tonic-gate  */
1047c478bd9Sstevel@tonic-gate #ifdef DEBUG
1057c478bd9Sstevel@tonic-gate #define	D_INIT		0x00000001	/* _init/_fini/_info */
1067c478bd9Sstevel@tonic-gate #define	D_ATTACH	0x00000002	/* attach/detach */
1077c478bd9Sstevel@tonic-gate #define	D_DIGEST	0x00000010	/* digest entry points */
1087c478bd9Sstevel@tonic-gate #define	D_MAC		0x00000020	/* mac entry points */
1097c478bd9Sstevel@tonic-gate #define	D_CONTEXT	0x00000040	/* context entry points */
1107c478bd9Sstevel@tonic-gate #define	D_CIPHER	0x00000080	/* cipher entry points */
1117c478bd9Sstevel@tonic-gate #define	D_SIGN		0x00000100	/* sign entry points */
1127c478bd9Sstevel@tonic-gate #define	D_VERIFY	0x00000200	/* verify entry points */
1137c478bd9Sstevel@tonic-gate #define	D_SESSION	0x00000400	/* session management entry points */
1147c478bd9Sstevel@tonic-gate #define	D_MGMT		0x00000800	/* provider management entry points */
1157c478bd9Sstevel@tonic-gate #define	D_DUAL		0x00001000	/* dual ops */
1167c478bd9Sstevel@tonic-gate #define	D_CIPHER_MAC	0x00002000	/* cipher/mac dual ops */
1177c478bd9Sstevel@tonic-gate #define	D_OBJECT	0x00004000	/* object management */
1187c478bd9Sstevel@tonic-gate #define	D_RANDOM	0x00008000	/* random number generation */
1197c478bd9Sstevel@tonic-gate #define	D_KEY		0x00010000	/* key management */
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate static uint32_t dprov_debug = 0;
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate #define	DPROV_DEBUG(f, x)	if (dprov_debug & (f)) { (void) printf x; }
1247c478bd9Sstevel@tonic-gate #define	DPROV_CALL(f, r, x)	if (dprov_debug & (f)) { (void) r x; }
1257c478bd9Sstevel@tonic-gate #else /* DEBUG */
1267c478bd9Sstevel@tonic-gate #define	DPROV_DEBUG(f, x)
1277c478bd9Sstevel@tonic-gate #define	DPROV_CALL(f, r, x)
1287c478bd9Sstevel@tonic-gate #endif /* DEBUG */
1297c478bd9Sstevel@tonic-gate 
130034448feSmcpowers static int nostore_key_gen;
131ba5f469cSkrishna static boolean_t dprov_no_multipart = B_FALSE;
132ba5f469cSkrishna static int dprov_max_digestsz = INT_MAX;
133ba5f469cSkrishna 
1347c478bd9Sstevel@tonic-gate /*
1357c478bd9Sstevel@tonic-gate  * DDI entry points.
1367c478bd9Sstevel@tonic-gate  */
1377c478bd9Sstevel@tonic-gate static int dprov_attach(dev_info_t *, ddi_attach_cmd_t);
1387c478bd9Sstevel@tonic-gate static int dprov_detach(dev_info_t *, ddi_detach_cmd_t);
1397c478bd9Sstevel@tonic-gate static int dprov_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate /*
1427c478bd9Sstevel@tonic-gate  * Module linkage.
1437c478bd9Sstevel@tonic-gate  */
1447c478bd9Sstevel@tonic-gate static struct cb_ops cbops = {
1457c478bd9Sstevel@tonic-gate 	nodev,			/* cb_open */
1467c478bd9Sstevel@tonic-gate 	nodev,			/* cb_close */
1477c478bd9Sstevel@tonic-gate 	nodev,			/* cb_strategy */
1487c478bd9Sstevel@tonic-gate 	nodev,			/* cb_print */
1497c478bd9Sstevel@tonic-gate 	nodev,			/* cb_dump */
1507c478bd9Sstevel@tonic-gate 	nodev,			/* cb_read */
1517c478bd9Sstevel@tonic-gate 	nodev,			/* cb_write */
1527c478bd9Sstevel@tonic-gate 	nodev,			/* cb_ioctl */
1537c478bd9Sstevel@tonic-gate 	nodev,			/* cb_devmap */
1547c478bd9Sstevel@tonic-gate 	nodev,			/* cb_mmap */
1557c478bd9Sstevel@tonic-gate 	nodev,			/* cb_segmap */
1567c478bd9Sstevel@tonic-gate 	nochpoll,		/* cb_chpoll */
1577c478bd9Sstevel@tonic-gate 	ddi_prop_op,		/* cb_prop_op */
1587c478bd9Sstevel@tonic-gate 	NULL,			/* cb_streamtab */
1597c478bd9Sstevel@tonic-gate 	D_MP,			/* cb_flag */
1607c478bd9Sstevel@tonic-gate 	CB_REV,			/* cb_rev */
1617c478bd9Sstevel@tonic-gate 	nodev,			/* cb_aread */
1627c478bd9Sstevel@tonic-gate 	nodev,			/* cb_awrite */
1637c478bd9Sstevel@tonic-gate };
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate static struct dev_ops devops = {
1667c478bd9Sstevel@tonic-gate 	DEVO_REV,		/* devo_rev */
1677c478bd9Sstevel@tonic-gate 	0,			/* devo_refcnt */
1687c478bd9Sstevel@tonic-gate 	dprov_getinfo,		/* devo_getinfo */
1697c478bd9Sstevel@tonic-gate 	nulldev,		/* devo_identify */
1707c478bd9Sstevel@tonic-gate 	nulldev,		/* devo_probe */
1717c478bd9Sstevel@tonic-gate 	dprov_attach,		/* devo_attach */
1727c478bd9Sstevel@tonic-gate 	dprov_detach,		/* devo_detach */
1737c478bd9Sstevel@tonic-gate 	nodev,			/* devo_reset */
1747c478bd9Sstevel@tonic-gate 	&cbops,			/* devo_cb_ops */
1757c478bd9Sstevel@tonic-gate 	NULL,			/* devo_bus_ops */
1767c478bd9Sstevel@tonic-gate 	NULL,			/* devo_power */
17719397407SSherry Moore 	ddi_quiesce_not_needed,		/* devo_quiesce */
1787c478bd9Sstevel@tonic-gate };
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate static struct modldrv modldrv = {
1817c478bd9Sstevel@tonic-gate 	&mod_driverops,
182d2b32306Smcpowers 	"Pseudo KCF Prov (drv)",
1837c478bd9Sstevel@tonic-gate 	&devops
1847c478bd9Sstevel@tonic-gate };
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate static struct modlcrypto modlcrypto = {
1877c478bd9Sstevel@tonic-gate 	&mod_cryptoops,
188d2b32306Smcpowers 	"Pseudo KCF Prov (crypto)"
1897c478bd9Sstevel@tonic-gate };
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate static struct modlinkage modlinkage = {
1927c478bd9Sstevel@tonic-gate 	MODREV_1,
1937c478bd9Sstevel@tonic-gate 	&modldrv,
1947c478bd9Sstevel@tonic-gate 	&modlcrypto,
1957c478bd9Sstevel@tonic-gate 	NULL
1967c478bd9Sstevel@tonic-gate };
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate /*
1997c478bd9Sstevel@tonic-gate  * CSPI information (entry points, provider info, etc.)
2007c478bd9Sstevel@tonic-gate  */
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate typedef enum dprov_mech_type {
2035151fb12Sdarrenm 	MD4_MECH_INFO_TYPE,		/* SUN_CKM_MD4 */
2045151fb12Sdarrenm 
2057c478bd9Sstevel@tonic-gate 	MD5_MECH_INFO_TYPE,		/* SUN_CKM_MD5 */
2067c478bd9Sstevel@tonic-gate 	MD5_HMAC_MECH_INFO_TYPE,	/* SUN_CKM_MD5_HMAC */
2077c478bd9Sstevel@tonic-gate 	MD5_HMAC_GEN_MECH_INFO_TYPE,	/* SUN_CKM_MD5_HMAC_GENERAL */
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate 	SHA1_HMAC_MECH_INFO_TYPE,	/* SUN_CKM_SHA1_HMAC */
2107c478bd9Sstevel@tonic-gate 	SHA1_HMAC_GEN_MECH_INFO_TYPE,	/* SUN_CKM_SHA1_HMAC_GENERAL */
2117c478bd9Sstevel@tonic-gate 	SHA1_MECH_INFO_TYPE,		/* SUN_CKM_SHA1 */
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate 	SHA256_HMAC_MECH_INFO_TYPE,	/* SUN_CKM_SHA256_HMAC */
2147c478bd9Sstevel@tonic-gate 	SHA256_HMAC_GEN_MECH_INFO_TYPE,	/* SUN_CKM_SHA256_HMAC_GENERAL */
2157c478bd9Sstevel@tonic-gate 	SHA256_MECH_INFO_TYPE,		/* SUN_CKM_SHA256 */
2167c478bd9Sstevel@tonic-gate 	SHA384_HMAC_MECH_INFO_TYPE,	/* SUN_CKM_SHA384_HMAC */
2177c478bd9Sstevel@tonic-gate 	SHA384_HMAC_GEN_MECH_INFO_TYPE,	/* SUN_CKM_SHA384_HMAC_GENERAL */
2187c478bd9Sstevel@tonic-gate 	SHA384_MECH_INFO_TYPE,		/* SUN_CKM_SHA384 */
2197c478bd9Sstevel@tonic-gate 	SHA512_HMAC_MECH_INFO_TYPE,	/* SUN_CKM_SHA512_HMAC */
2207c478bd9Sstevel@tonic-gate 	SHA512_HMAC_GEN_MECH_INFO_TYPE,	/* SUN_CKM_SHA512_HMAC_GENERAL */
2217c478bd9Sstevel@tonic-gate 	SHA512_MECH_INFO_TYPE,		/* SUN_CKM_SHA512 */
2227c478bd9Sstevel@tonic-gate 
2237c478bd9Sstevel@tonic-gate 	DES_CBC_MECH_INFO_TYPE,		/* SUN_CKM_DES_CBC */
2247c478bd9Sstevel@tonic-gate 	DES3_CBC_MECH_INFO_TYPE,	/* SUN_CKM_DES3_CBC */
2257c478bd9Sstevel@tonic-gate 	DES_ECB_MECH_INFO_TYPE,		/* SUN_CKM_DES_ECB */
2267c478bd9Sstevel@tonic-gate 	DES3_ECB_MECH_INFO_TYPE,	/* SUN_CKM_DES3_ECB */
2277c478bd9Sstevel@tonic-gate 
228f66d273dSizick 	BLOWFISH_CBC_MECH_INFO_TYPE,	/* SUN_CKM_BLOWFISH_CBC */
229f66d273dSizick 	BLOWFISH_ECB_MECH_INFO_TYPE,	/* SUN_CKM_BLOWFISH_ECB */
2307c478bd9Sstevel@tonic-gate 	AES_CBC_MECH_INFO_TYPE,		/* SUN_CKM_AES_CBC */
2317c478bd9Sstevel@tonic-gate 	AES_ECB_MECH_INFO_TYPE,		/* SUN_CKM_AES_ECB */
232894b2776Smcpowers 	AES_CTR_MECH_INFO_TYPE,		/* SUN_CKM_AES_CTR */
2332d864512Sdinak 	AES_CCM_MECH_INFO_TYPE,		/* SUN_CKM_AES_CCM */
234983a1033SMark Powers 	AES_GCM_MECH_INFO_TYPE,		/* SUN_CKM_AES_GCM */
235983a1033SMark Powers 	AES_GMAC_MECH_INFO_TYPE,	/* SUN_CKM_AES_GMAC */
2367c478bd9Sstevel@tonic-gate 	RC4_MECH_INFO_TYPE,		/* SUN_CKM_RC4 */
2377c478bd9Sstevel@tonic-gate 	RSA_PKCS_MECH_INFO_TYPE,	/* SUN_CKM_RSA_PKCS */
2387c478bd9Sstevel@tonic-gate 	RSA_X_509_MECH_INFO_TYPE,	/* SUN_CKM_RSA_X_509 */
2397c478bd9Sstevel@tonic-gate 	MD5_RSA_PKCS_MECH_INFO_TYPE,	/* SUN_CKM_MD5_RSA_PKCS */
2407c478bd9Sstevel@tonic-gate 	SHA1_RSA_PKCS_MECH_INFO_TYPE,	/* SUN_CKM_SHA1_RSA_PKCS */
241f66d273dSizick 	SHA256_RSA_PKCS_MECH_INFO_TYPE,	/* SUN_CKM_SHA256_RSA_PKCS */
242f66d273dSizick 	SHA384_RSA_PKCS_MECH_INFO_TYPE,	/* SUN_CKM_SHA384_RSA_PKCS */
243f66d273dSizick 	SHA512_RSA_PKCS_MECH_INFO_TYPE,	/* SUN_CKM_SHA512_RSA_PKCS */
2447c478bd9Sstevel@tonic-gate 	MD5_KEY_DERIVATION_MECH_INFO_TYPE, /* SUN_CKM_MD5_KEY_DERIVATION */
2457c478bd9Sstevel@tonic-gate 	SHA1_KEY_DERIVATION_MECH_INFO_TYPE, /* SUN_CKM_SHA1_KEY_DERIVATION */
246f66d273dSizick 	/* SUN_CKM_SHA256_KEY_DERIVATION */
247f66d273dSizick 	SHA256_KEY_DERIVATION_MECH_INFO_TYPE,
248f66d273dSizick 	/* SUN_CKM_SHA384_KEY_DERIVATION */
249f66d273dSizick 	SHA384_KEY_DERIVATION_MECH_INFO_TYPE,
250f66d273dSizick 	/* SUN_CKM_SHA512_KEY_DERIVATION */
251f66d273dSizick 	SHA512_KEY_DERIVATION_MECH_INFO_TYPE,
2527c478bd9Sstevel@tonic-gate 	DES_KEY_GEN_MECH_INFO_TYPE,	/* SUN_CKM_DES_KEY_GEN */
2537c478bd9Sstevel@tonic-gate 	DES3_KEY_GEN_MECH_INFO_TYPE,	/* SUN_CKM_DES3_KEY_GEN */
2547c478bd9Sstevel@tonic-gate 	AES_KEY_GEN_MECH_INFO_TYPE,	/* SUN_CKM_AES_KEY_GEN */
255f66d273dSizick 	BLOWFISH_KEY_GEN_MECH_INFO_TYPE,	/* SUN_CKM_BLOWFISH_KEY_GEN */
2567c478bd9Sstevel@tonic-gate 	RC4_KEY_GEN_MECH_INFO_TYPE,	/* SUN_CKM_RC4_KEY_GEN */
257f9fbec18Smcpowers 	EC_KEY_PAIR_GEN_MECH_INFO_TYPE,	/* SUN_CKM_EC_KEY_PAIR_GEN */
258f9fbec18Smcpowers 	ECDSA_MECH_INFO_TYPE,		/* SUN_CKM_ECDSA */
259f9fbec18Smcpowers 	ECDSA_SHA1_MECH_INFO_TYPE,	/* SUN_CKM_ECDSA_SHA1 */
260f9fbec18Smcpowers 	ECDH1_DERIVE_MECH_INFO_TYPE,	/* SUN_CKM_ECDH1_DERIVE */
2615b0c7657Sizick 	DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE, /* SUN_CKM_DH_PKCS_KEY_PAIR_GEN */
2625b0c7657Sizick 	DH_PKCS_DERIVE_MECH_INFO_TYPE,	/* SUN_CKM_DH_PKCS_DERIVE */
2637c478bd9Sstevel@tonic-gate 	RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE /* SUN_CKM_RSA_PKCS_KEY_PAIR_GEN */
2647c478bd9Sstevel@tonic-gate } dprov_mech_type_t;
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate /*
2677c478bd9Sstevel@tonic-gate  * Mechanism info structure passed to KCF during registration.
2687c478bd9Sstevel@tonic-gate  */
2697c478bd9Sstevel@tonic-gate #define	MD5_DIGEST_LEN		16	/* MD5 digest size */
2707c478bd9Sstevel@tonic-gate #define	MD5_HMAC_BLOCK_SIZE	64	/* MD5-HMAC block size */
2715b675b31SVladimir Kotal #define	MD5_HMAC_MIN_KEY_LEN	1	/* MD5-HMAC min key length in bytes */
2725b675b31SVladimir Kotal #define	MD5_HMAC_MAX_KEY_LEN	INT_MAX	/* MD5-HMAC max key length in bytes */
2737c478bd9Sstevel@tonic-gate 
2747c478bd9Sstevel@tonic-gate #define	SHA1_DIGEST_LEN		20	/* SHA1 digest size */
2757c478bd9Sstevel@tonic-gate #define	SHA1_HMAC_BLOCK_SIZE	64	/* SHA1-HMAC block size */
2765b675b31SVladimir Kotal #define	SHA1_HMAC_MIN_KEY_LEN	1	/* SHA1-HMAC min key length in bytes */
2775b675b31SVladimir Kotal #define	SHA1_HMAC_MAX_KEY_LEN	INT_MAX	/* SHA1-HMAC max key length in bytes */
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate #define	DES_KEY_LEN		8	/* DES key length in bytes */
2807c478bd9Sstevel@tonic-gate #define	DES3_KEY_LEN		24	/* DES3 key length in bytes */
2817c478bd9Sstevel@tonic-gate 
282f66d273dSizick #define	BLOWFISH_MIN_KEY_LEN	32	/* Blowfish min key length in bits */
283f66d273dSizick #define	BLOWFISH_MAX_KEY_LEN	448	/* Blowfish max key length in bits */
2847c478bd9Sstevel@tonic-gate 
2857c478bd9Sstevel@tonic-gate #define	AES_MIN_KEY_LEN		16	/* AES min key length in bytes */
2867c478bd9Sstevel@tonic-gate #define	AES_MAX_KEY_LEN		32	/* AES max key length in bytes */
2877c478bd9Sstevel@tonic-gate 
2887c478bd9Sstevel@tonic-gate #define	ARCFOUR_MIN_KEY_BITS	40	/* RC4 min supported key size */
2897c478bd9Sstevel@tonic-gate #define	ARCFOUR_MAX_KEY_BITS	2048	/* RC4 max supported key size */
2907c478bd9Sstevel@tonic-gate 
2917c478bd9Sstevel@tonic-gate #define	RSA_MIN_KEY_LEN		256	/* RSA min key length in bits */
2927c478bd9Sstevel@tonic-gate #define	RSA_MAX_KEY_LEN		4096	/* RSA max key length in bits */
2937c478bd9Sstevel@tonic-gate 
2945b0c7657Sizick #define	DH_MIN_KEY_LEN		64	/* DH min key length in bits */
2955b0c7657Sizick #define	DH_MAX_KEY_LEN		4096	/* DH max key length in bits */
2965b0c7657Sizick 
2977c478bd9Sstevel@tonic-gate #define	DPROV_CKM_MD5_KEY_DERIVATION	"CKM_MD5_KEY_DERIVATION"
2987c478bd9Sstevel@tonic-gate #define	DPROV_CKM_SHA1_KEY_DERIVATION	"CKM_SHA1_KEY_DERIVATION"
299f66d273dSizick #define	DPROV_CKM_SHA256_KEY_DERIVATION	"CKM_SHA256_KEY_DERIVATION"
300f66d273dSizick #define	DPROV_CKM_SHA384_KEY_DERIVATION	"CKM_SHA384_KEY_DERIVATION"
301f66d273dSizick #define	DPROV_CKM_SHA512_KEY_DERIVATION	"CKM_SHA512_KEY_DERIVATION"
3027c478bd9Sstevel@tonic-gate #define	DPROV_CKM_DES_KEY_GEN		"CKM_DES_KEY_GEN"
3037c478bd9Sstevel@tonic-gate #define	DPROV_CKM_DES3_KEY_GEN		"CKM_DES3_KEY_GEN"
3047c478bd9Sstevel@tonic-gate #define	DPROV_CKM_AES_KEY_GEN		"CKM_AES_KEY_GEN"
305f66d273dSizick #define	DPROV_CKM_BLOWFISH_KEY_GEN	"CKM_BLOWFISH_KEY_GEN"
3067c478bd9Sstevel@tonic-gate #define	DPROV_CKM_RC4_KEY_GEN		"CKM_RC4_KEY_GEN"
3077c478bd9Sstevel@tonic-gate #define	DPROV_CKM_RSA_PKCS_KEY_PAIR_GEN	"CKM_RSA_PKCS_KEY_PAIR_GEN"
308f9fbec18Smcpowers #define	DPROV_CKM_EC_KEY_PAIR_GEN	"CKM_EC_KEY_PAIR_GEN"
309f9fbec18Smcpowers #define	DPROV_CKM_ECDSA			"CKM_ECDSA"
310f9fbec18Smcpowers #define	DPROV_CKM_ECDSA_SHA1		"CKM_ECDSA_SHA1"
311f9fbec18Smcpowers #define	DPROV_CKM_ECDH1_DERIVE		"CKM_ECDH1_DERIVE"
3125b0c7657Sizick #define	DPROV_CKM_DH_PKCS_KEY_PAIR_GEN	"CKM_DH_PKCS_KEY_PAIR_GEN"
3135b0c7657Sizick #define	DPROV_CKM_DH_PKCS_DERIVE	"CKM_DH_PKCS_DERIVE"
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate static crypto_mech_info_t dprov_mech_info_tab[] = {
3165151fb12Sdarrenm 	/* MD4 */
3175151fb12Sdarrenm 	{SUN_CKM_MD4, MD4_MECH_INFO_TYPE,
3185151fb12Sdarrenm 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
3195151fb12Sdarrenm 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
3207c478bd9Sstevel@tonic-gate 	/* MD5 */
3217c478bd9Sstevel@tonic-gate 	{SUN_CKM_MD5, MD5_MECH_INFO_TYPE,
3227c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
3237c478bd9Sstevel@tonic-gate 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
3247c478bd9Sstevel@tonic-gate 	/* MD5-HMAC */
3257c478bd9Sstevel@tonic-gate 	{SUN_CKM_MD5_HMAC, MD5_HMAC_MECH_INFO_TYPE,
3267c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
3277c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
3287c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
3297c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
3307c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
3317c478bd9Sstevel@tonic-gate 	    MD5_HMAC_MIN_KEY_LEN, MD5_HMAC_MAX_KEY_LEN,
3325b675b31SVladimir Kotal 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
3337c478bd9Sstevel@tonic-gate 	/* MD5-HMAC GENERAL */
3347c478bd9Sstevel@tonic-gate 	{SUN_CKM_MD5_HMAC_GENERAL, MD5_HMAC_GEN_MECH_INFO_TYPE,
3357c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
3367c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
3377c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
3387c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
3397c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
3407c478bd9Sstevel@tonic-gate 	    MD5_HMAC_MIN_KEY_LEN, MD5_HMAC_MAX_KEY_LEN,
3415b675b31SVladimir Kotal 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
3427c478bd9Sstevel@tonic-gate 	/* SHA1 */
3437c478bd9Sstevel@tonic-gate 	{SUN_CKM_SHA1, SHA1_MECH_INFO_TYPE,
3447c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
3457c478bd9Sstevel@tonic-gate 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
3467c478bd9Sstevel@tonic-gate 	/* SHA1-HMAC */
3477c478bd9Sstevel@tonic-gate 	{SUN_CKM_SHA1_HMAC, SHA1_HMAC_MECH_INFO_TYPE,
3487c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
3497c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
3507c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
3517c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
3527c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
3537c478bd9Sstevel@tonic-gate 	    SHA1_HMAC_MIN_KEY_LEN, SHA1_HMAC_MAX_KEY_LEN,
3545b675b31SVladimir Kotal 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
3557c478bd9Sstevel@tonic-gate 	/* SHA1-HMAC GENERAL */
3567c478bd9Sstevel@tonic-gate 	{SUN_CKM_SHA1_HMAC_GENERAL, SHA1_HMAC_GEN_MECH_INFO_TYPE,
3577c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
3587c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
3597c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
3607c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
3617c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
3627c478bd9Sstevel@tonic-gate 	    SHA1_HMAC_MIN_KEY_LEN, SHA1_HMAC_MAX_KEY_LEN,
3635b675b31SVladimir Kotal 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
3647c478bd9Sstevel@tonic-gate 	/* SHA256 */
3657c478bd9Sstevel@tonic-gate 	{SUN_CKM_SHA256, SHA256_MECH_INFO_TYPE,
3667c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
3677c478bd9Sstevel@tonic-gate 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
3687c478bd9Sstevel@tonic-gate 	/* SHA256-HMAC */
3697c478bd9Sstevel@tonic-gate 	{SUN_CKM_SHA256_HMAC, SHA256_HMAC_MECH_INFO_TYPE,
3707c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
3717c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
3727c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
3737c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
3747c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
3757c478bd9Sstevel@tonic-gate 	    SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
3765b675b31SVladimir Kotal 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
3777c478bd9Sstevel@tonic-gate 	/* SHA256-HMAC GENERAL */
3787c478bd9Sstevel@tonic-gate 	{SUN_CKM_SHA256_HMAC_GENERAL, SHA256_HMAC_GEN_MECH_INFO_TYPE,
3797c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
3807c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
3817c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
3827c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
3837c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
3847c478bd9Sstevel@tonic-gate 	    SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
3855b675b31SVladimir Kotal 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
3867c478bd9Sstevel@tonic-gate 	/* SHA384 */
3877c478bd9Sstevel@tonic-gate 	{SUN_CKM_SHA384, SHA384_MECH_INFO_TYPE,
3887c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
3897c478bd9Sstevel@tonic-gate 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
3907c478bd9Sstevel@tonic-gate 	/* SHA384-HMAC */
3917c478bd9Sstevel@tonic-gate 	{SUN_CKM_SHA384_HMAC, SHA384_HMAC_MECH_INFO_TYPE,
3927c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
3937c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
3947c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
3957c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
3967c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
3977c478bd9Sstevel@tonic-gate 	    SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
3985b675b31SVladimir Kotal 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
3997c478bd9Sstevel@tonic-gate 	/* SHA384-HMAC GENERAL */
4007c478bd9Sstevel@tonic-gate 	{SUN_CKM_SHA384_HMAC_GENERAL, SHA384_HMAC_GEN_MECH_INFO_TYPE,
4017c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
4027c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
4037c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
4047c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
4057c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4067c478bd9Sstevel@tonic-gate 	    SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
4075b675b31SVladimir Kotal 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4087c478bd9Sstevel@tonic-gate 	/* SHA512 */
4097c478bd9Sstevel@tonic-gate 	{SUN_CKM_SHA512, SHA512_MECH_INFO_TYPE,
4107c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
4117c478bd9Sstevel@tonic-gate 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
4127c478bd9Sstevel@tonic-gate 	/* SHA512-HMAC */
4137c478bd9Sstevel@tonic-gate 	{SUN_CKM_SHA512_HMAC, SHA512_HMAC_MECH_INFO_TYPE,
4147c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
4157c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
4167c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
4177c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
4187c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4197c478bd9Sstevel@tonic-gate 	    SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
4205b675b31SVladimir Kotal 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4217c478bd9Sstevel@tonic-gate 	/* SHA512-HMAC GENERAL */
4227c478bd9Sstevel@tonic-gate 	{SUN_CKM_SHA512_HMAC_GENERAL, SHA512_HMAC_GEN_MECH_INFO_TYPE,
4237c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
4247c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
4257c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
4267c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
4277c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4287c478bd9Sstevel@tonic-gate 	    SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
4295b675b31SVladimir Kotal 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4307c478bd9Sstevel@tonic-gate 	/* DES-CBC */
4317c478bd9Sstevel@tonic-gate 	{SUN_CKM_DES_CBC, DES_CBC_MECH_INFO_TYPE,
4327c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4337c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4347c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
4357c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4367c478bd9Sstevel@tonic-gate 	    DES_KEY_LEN, DES_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4377c478bd9Sstevel@tonic-gate 	/* DES3-CBC */
4387c478bd9Sstevel@tonic-gate 	{SUN_CKM_DES3_CBC, DES3_CBC_MECH_INFO_TYPE,
4397c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4407c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4417c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
4427c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4437c478bd9Sstevel@tonic-gate 	    DES3_KEY_LEN, DES3_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4447c478bd9Sstevel@tonic-gate 	/* DES-ECB */
4457c478bd9Sstevel@tonic-gate 	{SUN_CKM_DES_ECB, DES_ECB_MECH_INFO_TYPE,
4467c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4477c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4487c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
4497c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4507c478bd9Sstevel@tonic-gate 	    DES_KEY_LEN, DES_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4517c478bd9Sstevel@tonic-gate 	/* DES3-ECB */
4527c478bd9Sstevel@tonic-gate 	{SUN_CKM_DES3_ECB, DES3_ECB_MECH_INFO_TYPE,
4537c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4547c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4557c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
4567c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4577c478bd9Sstevel@tonic-gate 	    DES3_KEY_LEN, DES3_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
458f66d273dSizick 	/* BLOWFISH-CBC */
459f66d273dSizick 	{SUN_CKM_BLOWFISH_CBC, BLOWFISH_CBC_MECH_INFO_TYPE,
4607c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4617c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4627c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
463f66d273dSizick 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC, BLOWFISH_MIN_KEY_LEN,
464f66d273dSizick 	    BLOWFISH_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
465f66d273dSizick 	/* BLOWFISH-ECB */
466f66d273dSizick 	{SUN_CKM_BLOWFISH_ECB, BLOWFISH_ECB_MECH_INFO_TYPE,
4677c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4687c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4697c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
470f66d273dSizick 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC, BLOWFISH_MIN_KEY_LEN,
471f66d273dSizick 	    BLOWFISH_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
4727c478bd9Sstevel@tonic-gate 	/* AES-CBC */
4737c478bd9Sstevel@tonic-gate 	{SUN_CKM_AES_CBC, AES_CBC_MECH_INFO_TYPE,
4747c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4757c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4767c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
4777c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4787c478bd9Sstevel@tonic-gate 	    AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4797c478bd9Sstevel@tonic-gate 	/* AES-ECB */
4807c478bd9Sstevel@tonic-gate 	{SUN_CKM_AES_ECB, AES_ECB_MECH_INFO_TYPE,
4817c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4827c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4837c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
4847c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4857c478bd9Sstevel@tonic-gate 	    AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
486894b2776Smcpowers 	/* AES-CTR */
487894b2776Smcpowers 	{SUN_CKM_AES_CTR, AES_CTR_MECH_INFO_TYPE,
488894b2776Smcpowers 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
489894b2776Smcpowers 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
490894b2776Smcpowers 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
491894b2776Smcpowers 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
492894b2776Smcpowers 	    AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4932d864512Sdinak 	/* AES-CCM */
4942d864512Sdinak 	{SUN_CKM_AES_CCM, AES_CCM_MECH_INFO_TYPE,
4952d864512Sdinak 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4962d864512Sdinak 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4972d864512Sdinak 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
4982d864512Sdinak 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4992d864512Sdinak 	    AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
5004d703b5cSMark Powers 	/* AES-GCM */
5014d703b5cSMark Powers 	{SUN_CKM_AES_GCM, AES_GCM_MECH_INFO_TYPE,
5024d703b5cSMark Powers 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
5034d703b5cSMark Powers 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
5044d703b5cSMark Powers 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
5054d703b5cSMark Powers 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
5064d703b5cSMark Powers 	    AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
507983a1033SMark Powers 	/* AES-GMAC */
508983a1033SMark Powers 	{SUN_CKM_AES_GMAC, AES_GMAC_MECH_INFO_TYPE,
509983a1033SMark Powers 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
510983a1033SMark Powers 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
511983a1033SMark Powers 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
512983a1033SMark Powers 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC |
513983a1033SMark Powers 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
514983a1033SMark Powers 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
515983a1033SMark Powers 	    AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
5167c478bd9Sstevel@tonic-gate 	/* RC4 */
5177c478bd9Sstevel@tonic-gate 	{SUN_CKM_RC4, RC4_MECH_INFO_TYPE,
5187c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
5197c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
5207c478bd9Sstevel@tonic-gate 	    ARCFOUR_MIN_KEY_BITS, ARCFOUR_MAX_KEY_BITS,
5216a1073f8Skrishna 	    CRYPTO_KEYSIZE_UNIT_IN_BITS | CRYPTO_CAN_SHARE_OPSTATE},
5227c478bd9Sstevel@tonic-gate 	/* RSA_PKCS */
5237c478bd9Sstevel@tonic-gate 	{SUN_CKM_RSA_PKCS, RSA_PKCS_MECH_INFO_TYPE,
5247c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
5257c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC |
5267c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
5277c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
5287c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC |
5297c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC,
5307c478bd9Sstevel@tonic-gate 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
5317c478bd9Sstevel@tonic-gate 	/* RSA_X_509 */
5327c478bd9Sstevel@tonic-gate 	{SUN_CKM_RSA_X_509, RSA_X_509_MECH_INFO_TYPE,
5337c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
5347c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC |
5357c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
5367c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
5377c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC |
5387c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC,
5397c478bd9Sstevel@tonic-gate 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
5407c478bd9Sstevel@tonic-gate 	/* MD5_RSA_PKCS */
5417c478bd9Sstevel@tonic-gate 	{SUN_CKM_MD5_RSA_PKCS, MD5_RSA_PKCS_MECH_INFO_TYPE,
5427c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
5437c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
5447c478bd9Sstevel@tonic-gate 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
5457c478bd9Sstevel@tonic-gate 	/* SHA1_RSA_PKCS */
5467c478bd9Sstevel@tonic-gate 	{SUN_CKM_SHA1_RSA_PKCS, SHA1_RSA_PKCS_MECH_INFO_TYPE,
5477c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
5487c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
5497c478bd9Sstevel@tonic-gate 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
550f66d273dSizick 	/* SHA256_RSA_PKCS */
551f66d273dSizick 	{SUN_CKM_SHA256_RSA_PKCS, SHA256_RSA_PKCS_MECH_INFO_TYPE,
552f66d273dSizick 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
553f66d273dSizick 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
554f66d273dSizick 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
555f66d273dSizick 	/* SHA384_RSA_PKCS */
556f66d273dSizick 	{SUN_CKM_SHA384_RSA_PKCS, SHA384_RSA_PKCS_MECH_INFO_TYPE,
557f66d273dSizick 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
558f66d273dSizick 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
559f66d273dSizick 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
560f66d273dSizick 	/* SHA512_RSA_PKCS */
561f66d273dSizick 	{SUN_CKM_SHA512_RSA_PKCS, SHA512_RSA_PKCS_MECH_INFO_TYPE,
562f66d273dSizick 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
563f66d273dSizick 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
564f66d273dSizick 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
5657c478bd9Sstevel@tonic-gate 	/* MD5_KEY_DERIVATION */
5667c478bd9Sstevel@tonic-gate 	{DPROV_CKM_MD5_KEY_DERIVATION, MD5_KEY_DERIVATION_MECH_INFO_TYPE,
5677c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
5687c478bd9Sstevel@tonic-gate 	/* SHA1_KEY_DERIVATION */
5697c478bd9Sstevel@tonic-gate 	{DPROV_CKM_SHA1_KEY_DERIVATION, SHA1_KEY_DERIVATION_MECH_INFO_TYPE,
5707c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
571f66d273dSizick 	/* SHA256_KEY_DERIVATION */
572f66d273dSizick 	{DPROV_CKM_SHA256_KEY_DERIVATION, SHA256_KEY_DERIVATION_MECH_INFO_TYPE,
573f66d273dSizick 	    CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
574f66d273dSizick 	/* SHA384_KEY_DERIVATION */
575f66d273dSizick 	{DPROV_CKM_SHA384_KEY_DERIVATION, SHA384_KEY_DERIVATION_MECH_INFO_TYPE,
576f66d273dSizick 	    CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
577f66d273dSizick 	/* SHA512_KEY_DERIVATION */
578f66d273dSizick 	{DPROV_CKM_SHA512_KEY_DERIVATION, SHA512_KEY_DERIVATION_MECH_INFO_TYPE,
579f66d273dSizick 	    CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
5807c478bd9Sstevel@tonic-gate 	/* DES_KEY_GENERATION */
5817c478bd9Sstevel@tonic-gate 	{DPROV_CKM_DES_KEY_GEN, DES_KEY_GEN_MECH_INFO_TYPE,
5827c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_GENERATE, DES_KEY_LEN, DES_KEY_LEN,
5837c478bd9Sstevel@tonic-gate 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
5847c478bd9Sstevel@tonic-gate 	/* DES3_KEY_GENERATION */
5857c478bd9Sstevel@tonic-gate 	{DPROV_CKM_DES3_KEY_GEN, DES3_KEY_GEN_MECH_INFO_TYPE,
5867c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_GENERATE, DES3_KEY_LEN, DES3_KEY_LEN,
5877c478bd9Sstevel@tonic-gate 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
5887c478bd9Sstevel@tonic-gate 	/* AES_KEY_GENERATION */
5897c478bd9Sstevel@tonic-gate 	{DPROV_CKM_AES_KEY_GEN, AES_KEY_GEN_MECH_INFO_TYPE,
5907c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_GENERATE, AES_MIN_KEY_LEN, AES_MAX_KEY_LEN,
5917c478bd9Sstevel@tonic-gate 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
592f66d273dSizick 	/* BLOWFISH_KEY_GENERATION */
593f66d273dSizick 	{DPROV_CKM_BLOWFISH_KEY_GEN, BLOWFISH_KEY_GEN_MECH_INFO_TYPE,
594f66d273dSizick 	    CRYPTO_FG_GENERATE, BLOWFISH_MIN_KEY_LEN, BLOWFISH_MAX_KEY_LEN,
595f66d273dSizick 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
5967c478bd9Sstevel@tonic-gate 	/* RC4_KEY_GENERATION */
5977c478bd9Sstevel@tonic-gate 	{DPROV_CKM_RC4_KEY_GEN, RC4_KEY_GEN_MECH_INFO_TYPE,
5987c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_GENERATE, ARCFOUR_MIN_KEY_BITS, ARCFOUR_MAX_KEY_BITS,
5997c478bd9Sstevel@tonic-gate 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
6005b0c7657Sizick 	/* DH_PKCS_KEY_PAIR_GEN */
6015b0c7657Sizick 	{DPROV_CKM_DH_PKCS_KEY_PAIR_GEN, DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE,
6025b0c7657Sizick 	    CRYPTO_FG_GENERATE_KEY_PAIR, DH_MIN_KEY_LEN, DH_MAX_KEY_LEN,
6035b0c7657Sizick 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
6045b0c7657Sizick 	/* DH_PKCS_DERIVE */
6055b0c7657Sizick 	{DPROV_CKM_DH_PKCS_DERIVE, DH_PKCS_DERIVE_MECH_INFO_TYPE,
6065b0c7657Sizick 	    CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
6077c478bd9Sstevel@tonic-gate 	/* RSA_PKCS_KEY_PAIR_GEN */
6087c478bd9Sstevel@tonic-gate 	{DPROV_CKM_RSA_PKCS_KEY_PAIR_GEN, RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE,
6097c478bd9Sstevel@tonic-gate 	    CRYPTO_FG_GENERATE_KEY_PAIR, RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN,
610f9fbec18Smcpowers 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
611f9fbec18Smcpowers 	/* EC_KEY_PAIR_GEN */
612f9fbec18Smcpowers 	{DPROV_CKM_EC_KEY_PAIR_GEN, EC_KEY_PAIR_GEN_MECH_INFO_TYPE,
613f9fbec18Smcpowers 	    CRYPTO_FG_GENERATE_KEY_PAIR, EC_MIN_KEY_LEN, EC_MAX_KEY_LEN,
614f9fbec18Smcpowers 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
615f9fbec18Smcpowers 	/* ECDSA */
616f9fbec18Smcpowers 	{DPROV_CKM_ECDSA, ECDSA_MECH_INFO_TYPE,
617f9fbec18Smcpowers 	    CRYPTO_FG_SIGN | CRYPTO_FG_VERIFY |
618f9fbec18Smcpowers 	    CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC |
619f9fbec18Smcpowers 	    EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
620f9fbec18Smcpowers 	/* ECDSA_SHA1 */
621f9fbec18Smcpowers 	{DPROV_CKM_ECDSA_SHA1, ECDSA_SHA1_MECH_INFO_TYPE,
622f9fbec18Smcpowers 	    CRYPTO_FG_SIGN | CRYPTO_FG_VERIFY |
623f9fbec18Smcpowers 	    CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC |
624f9fbec18Smcpowers 	    EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
625f9fbec18Smcpowers 	/* ECDH1_DERIVE */
626f9fbec18Smcpowers 	{DPROV_CKM_ECDH1_DERIVE, ECDH1_DERIVE_MECH_INFO_TYPE,
627f9fbec18Smcpowers 	    CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}
6287c478bd9Sstevel@tonic-gate };
6297c478bd9Sstevel@tonic-gate 
6305b0c7657Sizick /*
6315b0c7657Sizick  * Crypto Values
6325b0c7657Sizick  *
6335b0c7657Sizick  * These values are the used in the STC ef test suite.  If they are changed
6345b0c7657Sizick  * the test suite needs to be changed.
6355b0c7657Sizick  */
6365b0c7657Sizick static uchar_t dh_value[8] = { 'd', 'h', 'd', 'h', 'd', 'h', 'd', '\0' };
6375b0c7657Sizick char public_exponent[3] = { 0x01, 0x00, 0x01 };
6385b0c7657Sizick static uchar_t private_exponent[128] = {
6395b0c7657Sizick 	0x8e, 0xc9, 0x70, 0x57, 0x6b, 0xcd, 0xfb, 0xa9,
6405b0c7657Sizick 	0x19, 0xad, 0xcd, 0x91, 0x69, 0xd5, 0x52, 0xec,
6415b0c7657Sizick 	0x72, 0x1e, 0x45, 0x15, 0x06, 0xdc, 0x65, 0x2d,
6425b0c7657Sizick 	0x98, 0xc4, 0xce, 0x33, 0x54, 0x15, 0x70, 0x8d,
6435b0c7657Sizick 	0xfa, 0x65, 0xea, 0x53, 0x44, 0xf3, 0x3e, 0x3f,
6445b0c7657Sizick 	0xb4, 0x4c, 0x60, 0xd5, 0x01, 0x2d, 0xa4, 0x12,
6455b0c7657Sizick 	0x99, 0xbf, 0x3f, 0x0b, 0xcd, 0xbb, 0x24, 0x10,
6465b0c7657Sizick 	0x60, 0x30, 0x5e, 0x58, 0xf8, 0x59, 0xaa, 0xd1,
6475b0c7657Sizick 	0x63, 0x3b, 0xbc, 0xcb, 0x94, 0x58, 0x38, 0x24,
6485b0c7657Sizick 	0xfc, 0x65, 0x25, 0xc5, 0xa6, 0x51, 0xa2, 0x2e,
6495b0c7657Sizick 	0xf1, 0x5e, 0xf5, 0xc1, 0xf5, 0x46, 0xf7, 0xbd,
6505b0c7657Sizick 	0xc7, 0x62, 0xa8, 0xe2, 0x27, 0xd6, 0x94, 0x5b,
6515b0c7657Sizick 	0xd3, 0xa2, 0xb5, 0x76, 0x42, 0x67, 0x6b, 0x86,
6525b0c7657Sizick 	0x91, 0x97, 0x4d, 0x07, 0x92, 0x00, 0x4a, 0xdf,
6535b0c7657Sizick 	0x0b, 0x65, 0x64, 0x05, 0x03, 0x48, 0x27, 0xeb,
6545b0c7657Sizick 	0xce, 0x9a, 0x49, 0x7f, 0x3e, 0x10, 0xe0, 0x01
6555b0c7657Sizick };
6565b0c7657Sizick 
6575b0c7657Sizick static uchar_t modulus[128] = {
6585b0c7657Sizick 	0x94, 0x32, 0xb9, 0x12, 0x1d, 0x68, 0x2c, 0xda,
6595b0c7657Sizick 	0x2b, 0xe0, 0xe4, 0x97, 0x1b, 0x4d, 0xdc, 0x43,
6605b0c7657Sizick 	0xdf, 0x38, 0x6e, 0x7b, 0x9f, 0x07, 0x58, 0xae,
6615b0c7657Sizick 	0x9d, 0x82, 0x1e, 0xc7, 0xbc, 0x92, 0xbf, 0xd3,
6625b0c7657Sizick 	0xce, 0x00, 0xbb, 0x91, 0xc9, 0x79, 0x06, 0x03,
6635b0c7657Sizick 	0x1f, 0xbc, 0x9f, 0x94, 0x75, 0x29, 0x5f, 0xd7,
6645b0c7657Sizick 	0xc5, 0xf3, 0x73, 0x8a, 0xa4, 0x35, 0x43, 0x7a,
6655b0c7657Sizick 	0x00, 0x32, 0x97, 0x3e, 0x86, 0xef, 0x70, 0x6f,
6665b0c7657Sizick 	0x18, 0x56, 0x15, 0xaa, 0x6a, 0x87, 0xe7, 0x8d,
6675b0c7657Sizick 	0x7d, 0xdd, 0x1f, 0xa4, 0xe4, 0x31, 0xd4, 0x7a,
6685b0c7657Sizick 	0x8c, 0x0e, 0x20, 0xd2, 0x23, 0xf5, 0x57, 0x3c,
6695b0c7657Sizick 	0x1b, 0xa8, 0x44, 0xa4, 0x57, 0x8f, 0x33, 0x52,
6705b0c7657Sizick 	0xad, 0x83, 0xae, 0x4a, 0x97, 0xa6, 0x1e, 0xa6,
6715b0c7657Sizick 	0x2b, 0xfa, 0xea, 0xeb, 0x6e, 0x71, 0xb8, 0xb6,
6725b0c7657Sizick 	0x0a, 0x36, 0xed, 0x83, 0xce, 0xb0, 0xdf, 0xc1,
6735b0c7657Sizick 	0xd4, 0x3a, 0xe9, 0x99, 0x6f, 0xf3, 0x96, 0xb7
6745b0c7657Sizick };
6755b0c7657Sizick 
6765b0c7657Sizick 
6777c478bd9Sstevel@tonic-gate static void dprov_provider_status(crypto_provider_handle_t, uint_t *);
6787c478bd9Sstevel@tonic-gate 
6797c478bd9Sstevel@tonic-gate static crypto_control_ops_t dprov_control_ops = {
6807c478bd9Sstevel@tonic-gate 	dprov_provider_status
6817c478bd9Sstevel@tonic-gate };
6827c478bd9Sstevel@tonic-gate 
6837c478bd9Sstevel@tonic-gate #define	DPROV_MANUFACTURER	"SUNW                            "
6847c478bd9Sstevel@tonic-gate #define	DPROV_MODEL		"dprov           "
6857c478bd9Sstevel@tonic-gate #define	DPROV_ALLSPACES		"                "
6867c478bd9Sstevel@tonic-gate 
6877c478bd9Sstevel@tonic-gate static int dprov_digest_init(crypto_ctx_t *, crypto_mechanism_t *,
6887c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
6897c478bd9Sstevel@tonic-gate static int dprov_digest(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
6907c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
6917c478bd9Sstevel@tonic-gate static int dprov_digest_update(crypto_ctx_t *, crypto_data_t *,
6927c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
6937c478bd9Sstevel@tonic-gate static int dprov_digest_key(crypto_ctx_t *, crypto_key_t *,
6947c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
6957c478bd9Sstevel@tonic-gate static int dprov_digest_final(crypto_ctx_t *, crypto_data_t *,
6967c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
6977c478bd9Sstevel@tonic-gate static int dprov_digest_atomic(crypto_provider_handle_t, crypto_session_id_t,
6987c478bd9Sstevel@tonic-gate     crypto_mechanism_t *, crypto_data_t *, crypto_data_t *,
6997c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
7007c478bd9Sstevel@tonic-gate 
7017c478bd9Sstevel@tonic-gate static crypto_digest_ops_t dprov_digest_ops = {
7027c478bd9Sstevel@tonic-gate 	dprov_digest_init,
7037c478bd9Sstevel@tonic-gate 	dprov_digest,
7047c478bd9Sstevel@tonic-gate 	dprov_digest_update,
7057c478bd9Sstevel@tonic-gate 	dprov_digest_key,
7067c478bd9Sstevel@tonic-gate 	dprov_digest_final,
7077c478bd9Sstevel@tonic-gate 	dprov_digest_atomic
7087c478bd9Sstevel@tonic-gate };
7097c478bd9Sstevel@tonic-gate 
7107c478bd9Sstevel@tonic-gate static int dprov_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
7117c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t, crypto_req_handle_t);
7127c478bd9Sstevel@tonic-gate static int dprov_mac(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
7137c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
7147c478bd9Sstevel@tonic-gate static int dprov_mac_update(crypto_ctx_t *, crypto_data_t *,
7157c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
7167c478bd9Sstevel@tonic-gate static int dprov_mac_final(crypto_ctx_t *, crypto_data_t *,
7177c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
7187c478bd9Sstevel@tonic-gate static int dprov_mac_atomic(crypto_provider_handle_t, crypto_session_id_t,
7197c478bd9Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
7207c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
7217c478bd9Sstevel@tonic-gate static int dprov_mac_verify_atomic(crypto_provider_handle_t,
7227c478bd9Sstevel@tonic-gate     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
7237c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
7247c478bd9Sstevel@tonic-gate 
7257c478bd9Sstevel@tonic-gate static crypto_mac_ops_t dprov_mac_ops = {
7267c478bd9Sstevel@tonic-gate 	dprov_mac_init,
7277c478bd9Sstevel@tonic-gate 	dprov_mac,
7287c478bd9Sstevel@tonic-gate 	dprov_mac_update,
7297c478bd9Sstevel@tonic-gate 	dprov_mac_final,
7307c478bd9Sstevel@tonic-gate 	dprov_mac_atomic,
7317c478bd9Sstevel@tonic-gate 	dprov_mac_verify_atomic
7327c478bd9Sstevel@tonic-gate };
7337c478bd9Sstevel@tonic-gate 
7347c478bd9Sstevel@tonic-gate static int dprov_encrypt_init(crypto_ctx_t *, crypto_mechanism_t *,
7357c478bd9Sstevel@tonic-gate     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
7367c478bd9Sstevel@tonic-gate static int dprov_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
7377c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
7387c478bd9Sstevel@tonic-gate static int dprov_encrypt_update(crypto_ctx_t *, crypto_data_t *,
7397c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_req_handle_t);
7407c478bd9Sstevel@tonic-gate static int dprov_encrypt_final(crypto_ctx_t *, crypto_data_t *,
7417c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
7427c478bd9Sstevel@tonic-gate static int dprov_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
7437c478bd9Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
7447c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
7457c478bd9Sstevel@tonic-gate 
7467c478bd9Sstevel@tonic-gate static int dprov_decrypt_init(crypto_ctx_t *, crypto_mechanism_t *,
7477c478bd9Sstevel@tonic-gate     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
7487c478bd9Sstevel@tonic-gate static int dprov_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
7497c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
7507c478bd9Sstevel@tonic-gate static int dprov_decrypt_update(crypto_ctx_t *, crypto_data_t *,
7517c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_req_handle_t);
7527c478bd9Sstevel@tonic-gate static int dprov_decrypt_final(crypto_ctx_t *, crypto_data_t *,
7537c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
7547c478bd9Sstevel@tonic-gate static int dprov_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
7557c478bd9Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
7567c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
7577c478bd9Sstevel@tonic-gate 
7587c478bd9Sstevel@tonic-gate static crypto_cipher_ops_t dprov_cipher_ops = {
7597c478bd9Sstevel@tonic-gate 	dprov_encrypt_init,
7607c478bd9Sstevel@tonic-gate 	dprov_encrypt,
7617c478bd9Sstevel@tonic-gate 	dprov_encrypt_update,
7627c478bd9Sstevel@tonic-gate 	dprov_encrypt_final,
7637c478bd9Sstevel@tonic-gate 	dprov_encrypt_atomic,
7647c478bd9Sstevel@tonic-gate 	dprov_decrypt_init,
7657c478bd9Sstevel@tonic-gate 	dprov_decrypt,
7667c478bd9Sstevel@tonic-gate 	dprov_decrypt_update,
7677c478bd9Sstevel@tonic-gate 	dprov_decrypt_final,
7687c478bd9Sstevel@tonic-gate 	dprov_decrypt_atomic
7697c478bd9Sstevel@tonic-gate };
7707c478bd9Sstevel@tonic-gate 
7717c478bd9Sstevel@tonic-gate static int dprov_sign_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
7727c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t, crypto_req_handle_t);
7737c478bd9Sstevel@tonic-gate static int dprov_sign(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
7747c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
7757c478bd9Sstevel@tonic-gate static int dprov_sign_update(crypto_ctx_t *, crypto_data_t *,
7767c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
7777c478bd9Sstevel@tonic-gate static int dprov_sign_final(crypto_ctx_t *, crypto_data_t *,
7787c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
7797c478bd9Sstevel@tonic-gate static int dprov_sign_atomic(crypto_provider_handle_t, crypto_session_id_t,
7807c478bd9Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
7817c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t, crypto_req_handle_t);
7827c478bd9Sstevel@tonic-gate static int dprov_sign_recover_init(crypto_ctx_t *, crypto_mechanism_t *,
7837c478bd9Sstevel@tonic-gate     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
7847c478bd9Sstevel@tonic-gate static int dprov_sign_recover(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
7857c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
7867c478bd9Sstevel@tonic-gate static int dprov_sign_recover_atomic(crypto_provider_handle_t,
7877c478bd9Sstevel@tonic-gate     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
7887c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
7897c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
7907c478bd9Sstevel@tonic-gate 
7917c478bd9Sstevel@tonic-gate static crypto_sign_ops_t dprov_sign_ops = {
7927c478bd9Sstevel@tonic-gate 	dprov_sign_init,
7937c478bd9Sstevel@tonic-gate 	dprov_sign,
7947c478bd9Sstevel@tonic-gate 	dprov_sign_update,
7957c478bd9Sstevel@tonic-gate 	dprov_sign_final,
7967c478bd9Sstevel@tonic-gate 	dprov_sign_atomic,
7977c478bd9Sstevel@tonic-gate 	dprov_sign_recover_init,
7987c478bd9Sstevel@tonic-gate 	dprov_sign_recover,
7997c478bd9Sstevel@tonic-gate 	dprov_sign_recover_atomic
8007c478bd9Sstevel@tonic-gate };
8017c478bd9Sstevel@tonic-gate 
8027c478bd9Sstevel@tonic-gate static int dprov_verify_init(crypto_ctx_t *, crypto_mechanism_t *,
8037c478bd9Sstevel@tonic-gate     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
8047c478bd9Sstevel@tonic-gate static int dprov_verify(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
8057c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
8067c478bd9Sstevel@tonic-gate static int dprov_verify_update(crypto_ctx_t *, crypto_data_t *,
8077c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
8087c478bd9Sstevel@tonic-gate static int dprov_verify_final(crypto_ctx_t *, crypto_data_t *,
8097c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
8107c478bd9Sstevel@tonic-gate static int dprov_verify_atomic(crypto_provider_handle_t, crypto_session_id_t,
8117c478bd9Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
8127c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
8137c478bd9Sstevel@tonic-gate static int dprov_verify_recover_init(crypto_ctx_t *, crypto_mechanism_t *,
8147c478bd9Sstevel@tonic-gate     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
8157c478bd9Sstevel@tonic-gate static int dprov_verify_recover(crypto_ctx_t *, crypto_data_t *,
8167c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_req_handle_t);
8177c478bd9Sstevel@tonic-gate static int dprov_verify_recover_atomic(crypto_provider_handle_t,
8187c478bd9Sstevel@tonic-gate     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
8197c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
8207c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
8217c478bd9Sstevel@tonic-gate 
8227c478bd9Sstevel@tonic-gate static crypto_verify_ops_t dprov_verify_ops = {
8237c478bd9Sstevel@tonic-gate 	dprov_verify_init,
8247c478bd9Sstevel@tonic-gate 	dprov_verify,
8257c478bd9Sstevel@tonic-gate 	dprov_verify_update,
8267c478bd9Sstevel@tonic-gate 	dprov_verify_final,
8277c478bd9Sstevel@tonic-gate 	dprov_verify_atomic,
8287c478bd9Sstevel@tonic-gate 	dprov_verify_recover_init,
8297c478bd9Sstevel@tonic-gate 	dprov_verify_recover,
8307c478bd9Sstevel@tonic-gate 	dprov_verify_recover_atomic
8317c478bd9Sstevel@tonic-gate };
8327c478bd9Sstevel@tonic-gate 
8337c478bd9Sstevel@tonic-gate static int dprov_digest_encrypt_update(crypto_ctx_t *, crypto_ctx_t *,
8347c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
8357c478bd9Sstevel@tonic-gate static int dprov_decrypt_digest_update(crypto_ctx_t *, crypto_ctx_t *,
8367c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
8377c478bd9Sstevel@tonic-gate static int dprov_sign_encrypt_update(crypto_ctx_t *, crypto_ctx_t *,
8387c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
8397c478bd9Sstevel@tonic-gate static int dprov_decrypt_verify_update(crypto_ctx_t *, crypto_ctx_t *,
8407c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
8417c478bd9Sstevel@tonic-gate 
8427c478bd9Sstevel@tonic-gate static crypto_dual_ops_t dprov_dual_ops = {
8437c478bd9Sstevel@tonic-gate 	dprov_digest_encrypt_update,
8447c478bd9Sstevel@tonic-gate 	dprov_decrypt_digest_update,
8457c478bd9Sstevel@tonic-gate 	dprov_sign_encrypt_update,
8467c478bd9Sstevel@tonic-gate 	dprov_decrypt_verify_update
8477c478bd9Sstevel@tonic-gate };
8487c478bd9Sstevel@tonic-gate 
8497c478bd9Sstevel@tonic-gate static int dprov_encrypt_mac_init(crypto_ctx_t *,
8507c478bd9Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *,
8517c478bd9Sstevel@tonic-gate     crypto_key_t *, crypto_spi_ctx_template_t,
8527c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t, crypto_req_handle_t);
8537c478bd9Sstevel@tonic-gate static int dprov_encrypt_mac(crypto_ctx_t *,
8547c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_dual_data_t *, crypto_data_t *,
8557c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
8567c478bd9Sstevel@tonic-gate static int dprov_encrypt_mac_update(crypto_ctx_t *,
8577c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_dual_data_t *, crypto_req_handle_t);
8587c478bd9Sstevel@tonic-gate static int dprov_encrypt_mac_final(crypto_ctx_t *,
8597c478bd9Sstevel@tonic-gate     crypto_dual_data_t *, crypto_data_t *, crypto_req_handle_t);
8607c478bd9Sstevel@tonic-gate static int dprov_encrypt_mac_atomic(crypto_provider_handle_t,
8617c478bd9Sstevel@tonic-gate     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
8627c478bd9Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
8637c478bd9Sstevel@tonic-gate     crypto_dual_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
8647c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t, crypto_req_handle_t);
8657c478bd9Sstevel@tonic-gate 
8667c478bd9Sstevel@tonic-gate static int dprov_mac_decrypt_init(crypto_ctx_t *,
8677c478bd9Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *,
8687c478bd9Sstevel@tonic-gate     crypto_key_t *, crypto_spi_ctx_template_t,
8697c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t, crypto_req_handle_t);
8707c478bd9Sstevel@tonic-gate static int dprov_mac_decrypt(crypto_ctx_t *,
8717c478bd9Sstevel@tonic-gate     crypto_dual_data_t *, crypto_data_t *, crypto_data_t *,
8727c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
8737c478bd9Sstevel@tonic-gate static int dprov_mac_decrypt_update(crypto_ctx_t *,
8747c478bd9Sstevel@tonic-gate     crypto_dual_data_t *, crypto_data_t *, crypto_req_handle_t);
8757c478bd9Sstevel@tonic-gate static int dprov_mac_decrypt_final(crypto_ctx_t *,
8767c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
8777c478bd9Sstevel@tonic-gate static int dprov_mac_decrypt_atomic(crypto_provider_handle_t,
8787c478bd9Sstevel@tonic-gate     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
8797c478bd9Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_dual_data_t *,
8807c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
8817c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t, crypto_req_handle_t);
8827c478bd9Sstevel@tonic-gate static int dprov_mac_verify_decrypt_atomic(crypto_provider_handle_t,
8837c478bd9Sstevel@tonic-gate     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
8847c478bd9Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_dual_data_t *,
8857c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
8867c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t, crypto_req_handle_t);
8877c478bd9Sstevel@tonic-gate 
8887c478bd9Sstevel@tonic-gate static crypto_dual_cipher_mac_ops_t dprov_cipher_mac_ops = {
8897c478bd9Sstevel@tonic-gate 	dprov_encrypt_mac_init,
8907c478bd9Sstevel@tonic-gate 	dprov_encrypt_mac,
8917c478bd9Sstevel@tonic-gate 	dprov_encrypt_mac_update,
8927c478bd9Sstevel@tonic-gate 	dprov_encrypt_mac_final,
8937c478bd9Sstevel@tonic-gate 	dprov_encrypt_mac_atomic,
8947c478bd9Sstevel@tonic-gate 	dprov_mac_decrypt_init,
8957c478bd9Sstevel@tonic-gate 	dprov_mac_decrypt,
8967c478bd9Sstevel@tonic-gate 	dprov_mac_decrypt_update,
8977c478bd9Sstevel@tonic-gate 	dprov_mac_decrypt_final,
8987c478bd9Sstevel@tonic-gate 	dprov_mac_decrypt_atomic,
8997c478bd9Sstevel@tonic-gate 	dprov_mac_verify_decrypt_atomic
9007c478bd9Sstevel@tonic-gate };
9017c478bd9Sstevel@tonic-gate 
9027c478bd9Sstevel@tonic-gate static int dprov_seed_random(crypto_provider_handle_t, crypto_session_id_t,
9038047c9fbSmcpowers     uchar_t *, size_t, uint_t, uint32_t, crypto_req_handle_t);
9047c478bd9Sstevel@tonic-gate static int dprov_generate_random(crypto_provider_handle_t, crypto_session_id_t,
9057c478bd9Sstevel@tonic-gate     uchar_t *, size_t, crypto_req_handle_t);
9067c478bd9Sstevel@tonic-gate 
9077c478bd9Sstevel@tonic-gate static crypto_random_number_ops_t dprov_random_number_ops = {
9087c478bd9Sstevel@tonic-gate 	dprov_seed_random,
9097c478bd9Sstevel@tonic-gate 	dprov_generate_random
9107c478bd9Sstevel@tonic-gate };
9117c478bd9Sstevel@tonic-gate 
9127c478bd9Sstevel@tonic-gate static int dprov_session_open(crypto_provider_handle_t, crypto_session_id_t *,
9137c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
9147c478bd9Sstevel@tonic-gate static int dprov_session_close(crypto_provider_handle_t, crypto_session_id_t,
9157c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
9167c478bd9Sstevel@tonic-gate static int dprov_session_login(crypto_provider_handle_t, crypto_session_id_t,
9177c478bd9Sstevel@tonic-gate     crypto_user_type_t, char *, size_t, crypto_req_handle_t);
9187c478bd9Sstevel@tonic-gate static int dprov_session_logout(crypto_provider_handle_t, crypto_session_id_t,
9197c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
9207c478bd9Sstevel@tonic-gate 
9217c478bd9Sstevel@tonic-gate static crypto_session_ops_t dprov_session_ops = {
9227c478bd9Sstevel@tonic-gate 	dprov_session_open,
9237c478bd9Sstevel@tonic-gate 	dprov_session_close,
9247c478bd9Sstevel@tonic-gate 	dprov_session_login,
9257c478bd9Sstevel@tonic-gate 	dprov_session_logout
9267c478bd9Sstevel@tonic-gate };
9277c478bd9Sstevel@tonic-gate 
9287c478bd9Sstevel@tonic-gate static int dprov_object_create(crypto_provider_handle_t, crypto_session_id_t,
9297c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
9307c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
9317c478bd9Sstevel@tonic-gate static int dprov_object_copy(crypto_provider_handle_t, crypto_session_id_t,
9327c478bd9Sstevel@tonic-gate     crypto_object_id_t, crypto_object_attribute_t *, uint_t,
9337c478bd9Sstevel@tonic-gate     crypto_object_id_t *, crypto_req_handle_t);
9347c478bd9Sstevel@tonic-gate static int dprov_object_destroy(crypto_provider_handle_t, crypto_session_id_t,
9357c478bd9Sstevel@tonic-gate     crypto_object_id_t, crypto_req_handle_t);
9367c478bd9Sstevel@tonic-gate static int dprov_object_get_size(crypto_provider_handle_t, crypto_session_id_t,
9377c478bd9Sstevel@tonic-gate     crypto_object_id_t, size_t *, crypto_req_handle_t);
9387c478bd9Sstevel@tonic-gate static int dprov_object_get_attribute_value(crypto_provider_handle_t,
9397c478bd9Sstevel@tonic-gate     crypto_session_id_t, crypto_object_id_t,
9407c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
9417c478bd9Sstevel@tonic-gate static int dprov_object_set_attribute_value(crypto_provider_handle_t,
9427c478bd9Sstevel@tonic-gate     crypto_session_id_t, crypto_object_id_t,
9437c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *,  uint_t, crypto_req_handle_t);
9447c478bd9Sstevel@tonic-gate static int dprov_object_find_init(crypto_provider_handle_t, crypto_session_id_t,
9457c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *, uint_t, void **,
9467c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
9477c478bd9Sstevel@tonic-gate static int dprov_object_find(crypto_provider_handle_t, void *,
9487c478bd9Sstevel@tonic-gate     crypto_object_id_t *, uint_t, uint_t *, crypto_req_handle_t);
9497c478bd9Sstevel@tonic-gate static int dprov_object_find_final(crypto_provider_handle_t, void *,
9507c478bd9Sstevel@tonic-gate     crypto_req_handle_t);
9517c478bd9Sstevel@tonic-gate 
9527c478bd9Sstevel@tonic-gate static crypto_object_ops_t dprov_object_ops = {
9537c478bd9Sstevel@tonic-gate 	dprov_object_create,
9547c478bd9Sstevel@tonic-gate 	dprov_object_copy,
9557c478bd9Sstevel@tonic-gate 	dprov_object_destroy,
9567c478bd9Sstevel@tonic-gate 	dprov_object_get_size,
9577c478bd9Sstevel@tonic-gate 	dprov_object_get_attribute_value,
9587c478bd9Sstevel@tonic-gate 	dprov_object_set_attribute_value,
9597c478bd9Sstevel@tonic-gate 	dprov_object_find_init,
9607c478bd9Sstevel@tonic-gate 	dprov_object_find,
9617c478bd9Sstevel@tonic-gate 	dprov_object_find_final
9627c478bd9Sstevel@tonic-gate };
9637c478bd9Sstevel@tonic-gate 
9647c478bd9Sstevel@tonic-gate static int dprov_key_generate(crypto_provider_handle_t, crypto_session_id_t,
9657c478bd9Sstevel@tonic-gate     crypto_mechanism_t *, crypto_object_attribute_t *, uint_t,
9667c478bd9Sstevel@tonic-gate     crypto_object_id_t *, crypto_req_handle_t);
9677c478bd9Sstevel@tonic-gate static int dprov_key_generate_pair(crypto_provider_handle_t,
9687c478bd9Sstevel@tonic-gate     crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *,
9697c478bd9Sstevel@tonic-gate     uint_t, crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
9707c478bd9Sstevel@tonic-gate     crypto_object_id_t *, crypto_req_handle_t);
9717c478bd9Sstevel@tonic-gate static int dprov_key_wrap(crypto_provider_handle_t, crypto_session_id_t,
9727c478bd9Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_object_id_t *,
9737c478bd9Sstevel@tonic-gate     uchar_t *, size_t *, crypto_req_handle_t);
9747c478bd9Sstevel@tonic-gate static int dprov_key_unwrap(crypto_provider_handle_t, crypto_session_id_t,
9757c478bd9Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, uchar_t *, size_t *,
9767c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *, uint_t,
9777c478bd9Sstevel@tonic-gate     crypto_object_id_t *, crypto_req_handle_t);
9787c478bd9Sstevel@tonic-gate static int dprov_key_derive(crypto_provider_handle_t, crypto_session_id_t,
9797c478bd9Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_object_attribute_t *,
9807c478bd9Sstevel@tonic-gate     uint_t, crypto_object_id_t *, crypto_req_handle_t);
9817c478bd9Sstevel@tonic-gate 
9827c478bd9Sstevel@tonic-gate static crypto_key_ops_t dprov_key_ops = {
9837c478bd9Sstevel@tonic-gate 	dprov_key_generate,
9847c478bd9Sstevel@tonic-gate 	dprov_key_generate_pair,
9857c478bd9Sstevel@tonic-gate 	dprov_key_wrap,
9867c478bd9Sstevel@tonic-gate 	dprov_key_unwrap,
9877c478bd9Sstevel@tonic-gate 	dprov_key_derive
9887c478bd9Sstevel@tonic-gate };
9897c478bd9Sstevel@tonic-gate 
9907c478bd9Sstevel@tonic-gate static int dprov_ext_info(crypto_provider_handle_t,
9917c478bd9Sstevel@tonic-gate     crypto_provider_ext_info_t *, crypto_req_handle_t);
9927c478bd9Sstevel@tonic-gate static int dprov_init_token(crypto_provider_handle_t, char *, size_t,
9937c478bd9Sstevel@tonic-gate     char *, crypto_req_handle_t);
9947c478bd9Sstevel@tonic-gate static int dprov_init_pin(crypto_provider_handle_t, crypto_session_id_t,
9957c478bd9Sstevel@tonic-gate     char *, size_t, crypto_req_handle_t);
9967c478bd9Sstevel@tonic-gate static int dprov_set_pin(crypto_provider_handle_t, crypto_session_id_t,
9977c478bd9Sstevel@tonic-gate     char *, size_t, char *, size_t, crypto_req_handle_t);
9987c478bd9Sstevel@tonic-gate 
9997c478bd9Sstevel@tonic-gate static crypto_provider_management_ops_t dprov_management_ops = {
10007c478bd9Sstevel@tonic-gate 	dprov_ext_info,
10017c478bd9Sstevel@tonic-gate 	dprov_init_token,
10027c478bd9Sstevel@tonic-gate 	dprov_init_pin,
10037c478bd9Sstevel@tonic-gate 	dprov_set_pin
10047c478bd9Sstevel@tonic-gate };
10057c478bd9Sstevel@tonic-gate 
10067c478bd9Sstevel@tonic-gate static int dprov_free_context(crypto_ctx_t *);
1007894b2776Smcpowers static int dprov_copyin_mechanism(crypto_provider_handle_t,
1008894b2776Smcpowers     crypto_mechanism_t *, crypto_mechanism_t *, int *error, int);
1009894b2776Smcpowers static int dprov_copyout_mechanism(crypto_provider_handle_t,
1010894b2776Smcpowers     crypto_mechanism_t *, crypto_mechanism_t *, int *error, int);
1011894b2776Smcpowers static int dprov_free_mechanism(crypto_provider_handle_t,
1012894b2776Smcpowers     crypto_mechanism_t *);
10137c478bd9Sstevel@tonic-gate 
10147c478bd9Sstevel@tonic-gate static crypto_ctx_ops_t dprov_ctx_ops = {
10157c478bd9Sstevel@tonic-gate 	NULL,
10167c478bd9Sstevel@tonic-gate 	dprov_free_context
10177c478bd9Sstevel@tonic-gate };
10187c478bd9Sstevel@tonic-gate 
1019894b2776Smcpowers static crypto_mech_ops_t dprov_mech_ops = {
1020894b2776Smcpowers 	dprov_copyin_mechanism,
1021894b2776Smcpowers 	dprov_copyout_mechanism,
1022894b2776Smcpowers 	dprov_free_mechanism
1023894b2776Smcpowers };
1024894b2776Smcpowers 
1025034448feSmcpowers static int dprov_nostore_key_generate(crypto_provider_handle_t,
1026034448feSmcpowers     crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *,
1027034448feSmcpowers     uint_t, crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
10285b0c7657Sizick static int dprov_nostore_key_generate_pair(crypto_provider_handle_t,
10295b0c7657Sizick     crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *,
10305b0c7657Sizick     uint_t, crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *,
10315b0c7657Sizick     uint_t, crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
10325b0c7657Sizick static int dprov_nostore_key_derive(crypto_provider_handle_t,
10335b0c7657Sizick     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
10345b0c7657Sizick     crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *,
10355b0c7657Sizick     uint_t, crypto_req_handle_t);
1036034448feSmcpowers 
1037034448feSmcpowers static crypto_nostore_key_ops_t dprov_nostore_key_ops = {
1038034448feSmcpowers 	dprov_nostore_key_generate,
10395b0c7657Sizick 	dprov_nostore_key_generate_pair,
10405b0c7657Sizick 	dprov_nostore_key_derive
1041034448feSmcpowers };
1042034448feSmcpowers 
10437c478bd9Sstevel@tonic-gate static crypto_ops_t dprov_crypto_ops = {
10447c478bd9Sstevel@tonic-gate 	&dprov_control_ops,
10457c478bd9Sstevel@tonic-gate 	&dprov_digest_ops,
10467c478bd9Sstevel@tonic-gate 	&dprov_cipher_ops,
10477c478bd9Sstevel@tonic-gate 	&dprov_mac_ops,
10487c478bd9Sstevel@tonic-gate 	&dprov_sign_ops,
10497c478bd9Sstevel@tonic-gate 	&dprov_verify_ops,
10507c478bd9Sstevel@tonic-gate 	&dprov_dual_ops,
10517c478bd9Sstevel@tonic-gate 	&dprov_cipher_mac_ops,
10527c478bd9Sstevel@tonic-gate 	&dprov_random_number_ops,
10537c478bd9Sstevel@tonic-gate 	&dprov_session_ops,
10547c478bd9Sstevel@tonic-gate 	&dprov_object_ops,
10557c478bd9Sstevel@tonic-gate 	&dprov_key_ops,
10567c478bd9Sstevel@tonic-gate 	&dprov_management_ops,
1057894b2776Smcpowers 	&dprov_ctx_ops,
1058894b2776Smcpowers 	&dprov_mech_ops
10597c478bd9Sstevel@tonic-gate };
10607c478bd9Sstevel@tonic-gate 
10617c478bd9Sstevel@tonic-gate 
10627c478bd9Sstevel@tonic-gate /* maximum SO and user PIN lengths */
10637c478bd9Sstevel@tonic-gate #define	DPROV_MAX_PIN_LEN	128
10647c478bd9Sstevel@tonic-gate 
10657c478bd9Sstevel@tonic-gate /*
10667c478bd9Sstevel@tonic-gate  * Objects: each session is associated with an array of objects.
10677c478bd9Sstevel@tonic-gate  * Unlike PKCS#11, the objects cannot be shared between sessions.
10687c478bd9Sstevel@tonic-gate  * The ioctl driver multiplexes PKCS#11 sessions to providers
10697c478bd9Sstevel@tonic-gate  * sessions in order to support this semantic. This simplifies
10707c478bd9Sstevel@tonic-gate  * the CSPI greatly since the provider does not have to associate
10717c478bd9Sstevel@tonic-gate  * sessions with a user space process.
10727c478bd9Sstevel@tonic-gate  * There is also a per-instance array of objects, which correspond
10737c478bd9Sstevel@tonic-gate  * to PKCS#11 token objects. These objects can be shared by multiple
10747c478bd9Sstevel@tonic-gate  * sesions.
10757c478bd9Sstevel@tonic-gate  *
10767c478bd9Sstevel@tonic-gate  * Token objects are identified by having a CKA_TOKEN attribute B_TRUE.
10777c478bd9Sstevel@tonic-gate  * Private objects are identified by having a CKA_PRIVATE attribute
10787c478bd9Sstevel@tonic-gate  * set to B_TRUE.
10797c478bd9Sstevel@tonic-gate  */
10807c478bd9Sstevel@tonic-gate 
10817c478bd9Sstevel@tonic-gate #define	DPROV_MAX_OBJECTS	128	/* max # of objects */
10827c478bd9Sstevel@tonic-gate #define	DPROV_MAX_ATTR		64	/* max # of attributes per object */
10837c478bd9Sstevel@tonic-gate 
10847c478bd9Sstevel@tonic-gate /* object description */
10857c478bd9Sstevel@tonic-gate typedef struct dprov_object {
10867c478bd9Sstevel@tonic-gate 	crypto_object_attribute_t do_attr[DPROV_MAX_ATTR]; /* attributes */
10877c478bd9Sstevel@tonic-gate 	uint_t do_token_idx;		/* index in per-instance table */
10887c478bd9Sstevel@tonic-gate 					/* for token objects. */
10897c478bd9Sstevel@tonic-gate 	boolean_t do_destroyed;		/* object has been destroyed. */
10907c478bd9Sstevel@tonic-gate 					/* keep object around until all */
10917c478bd9Sstevel@tonic-gate 					/* sessions that refer to it */
10927c478bd9Sstevel@tonic-gate 					/* are closed, but mark it */
10937c478bd9Sstevel@tonic-gate 					/* destroyed so that references */
10947c478bd9Sstevel@tonic-gate 					/* to the object fail. */
10957c478bd9Sstevel@tonic-gate 					/* used for token objects only */
10967c478bd9Sstevel@tonic-gate 	uint_t do_refcnt;
10977c478bd9Sstevel@tonic-gate } dprov_object_t;
10987c478bd9Sstevel@tonic-gate 
10997c478bd9Sstevel@tonic-gate /*
11007c478bd9Sstevel@tonic-gate  * If a session has a reference to a dprov_object_t,
11017c478bd9Sstevel@tonic-gate  * it REFHOLD()s.
11027c478bd9Sstevel@tonic-gate  */
11037c478bd9Sstevel@tonic-gate #define	DPROV_OBJECT_REFHOLD(object) {		\
1104*1a5e258fSJosef 'Jeff' Sipek 	atomic_inc_32(&(object)->do_refcnt);	\
11057c478bd9Sstevel@tonic-gate 	ASSERT((object)->do_refcnt != 0);		\
11067c478bd9Sstevel@tonic-gate }
11077c478bd9Sstevel@tonic-gate 
11087c478bd9Sstevel@tonic-gate /*
11097c478bd9Sstevel@tonic-gate  * Releases a reference to an object. When the last
11107c478bd9Sstevel@tonic-gate  * reference is released, the object is freed.
11117c478bd9Sstevel@tonic-gate  */
11127c478bd9Sstevel@tonic-gate #define	DPROV_OBJECT_REFRELE(object) {				\
11137c478bd9Sstevel@tonic-gate 	ASSERT((object)->do_refcnt != 0);			\
11147c478bd9Sstevel@tonic-gate 	membar_exit();						\
1115*1a5e258fSJosef 'Jeff' Sipek 	if (atomic_dec_32_nv(&(object)->do_refcnt) == 0)	\
11167c478bd9Sstevel@tonic-gate 		dprov_free_object(object);			\
11177c478bd9Sstevel@tonic-gate }
11187c478bd9Sstevel@tonic-gate 
11197c478bd9Sstevel@tonic-gate /*
11207c478bd9Sstevel@tonic-gate  * Object attributes are passed to the provider using crypto_object_attribute
11217c478bd9Sstevel@tonic-gate  * structures, which contain the type of the attribute, a pointer to
11227c478bd9Sstevel@tonic-gate  * it's value, and the length of its value. The attribute types values
11237c478bd9Sstevel@tonic-gate  * are defined by the PKCS#11 specification. This provider only cares
11247c478bd9Sstevel@tonic-gate  * about a subset of these attributes. In order to avoid having to
11257c478bd9Sstevel@tonic-gate  * include the PKCS#11 header files, we define here the attributes values
11267c478bd9Sstevel@tonic-gate  * which are used by the provider.
11277c478bd9Sstevel@tonic-gate  */
11287c478bd9Sstevel@tonic-gate 
11297c478bd9Sstevel@tonic-gate #define	DPROV_CKA_CLASS			0x00000000
11307c478bd9Sstevel@tonic-gate #define	DPROV_CKA_TOKEN			0x00000001
11317c478bd9Sstevel@tonic-gate #define	DPROV_CKA_PRIVATE		0x00000002
11327c478bd9Sstevel@tonic-gate #define	DPROV_CKA_VALUE			0x00000011
1133894b2776Smcpowers #define	DPROV_CKA_CERTIFICATE_TYPE	0x00000080
11347c478bd9Sstevel@tonic-gate #define	DPROV_CKA_KEY_TYPE		0x00000100
1135034448feSmcpowers #define	DPROV_CKA_SENSITIVE		0x00000103
11367c478bd9Sstevel@tonic-gate #define	DPROV_CKA_ENCRYPT		0x00000104
11377c478bd9Sstevel@tonic-gate #define	DPROV_CKA_DECRYPT		0x00000105
11387c478bd9Sstevel@tonic-gate #define	DPROV_CKA_WRAP			0x00000106
11397c478bd9Sstevel@tonic-gate #define	DPROV_CKA_UNWRAP		0x00000107
11407c478bd9Sstevel@tonic-gate #define	DPROV_CKA_SIGN			0x00000108
11417c478bd9Sstevel@tonic-gate #define	DPROV_CKA_SIGN_RECOVER		0x00000109
11427c478bd9Sstevel@tonic-gate #define	DPROV_CKA_VERIFY		0x0000010A
11437c478bd9Sstevel@tonic-gate #define	DPROV_CKA_VERIFY_RECOVER	0x0000010B
11447c478bd9Sstevel@tonic-gate #define	DPROV_CKA_DERIVE		0x0000010C
11457c478bd9Sstevel@tonic-gate #define	DPROV_CKA_MODULUS		0x00000120
11467c478bd9Sstevel@tonic-gate #define	DPROV_CKA_MODULUS_BITS		0x00000121
11477c478bd9Sstevel@tonic-gate #define	DPROV_CKA_PUBLIC_EXPONENT	0x00000122
11487c478bd9Sstevel@tonic-gate #define	DPROV_CKA_PRIVATE_EXPONENT	0x00000123
11495b0c7657Sizick #define	DPROV_CKA_PRIME			0x00000130
11505b0c7657Sizick #define	DPROV_CKA_BASE			0x00000132
11517c478bd9Sstevel@tonic-gate #define	DPROV_CKA_VALUE_BITS		0x00000160
11527c478bd9Sstevel@tonic-gate #define	DPROV_CKA_VALUE_LEN		0x00000161
11537c478bd9Sstevel@tonic-gate #define	DPROV_CKA_EXTRACTABLE		0x00000162
1154f9fbec18Smcpowers #define	DPROV_CKA_EC_PARAMS		0x00000180
1155f9fbec18Smcpowers #define	DPROV_CKA_EC_POINT		0x00000181
1156894b2776Smcpowers #define	DPROV_HW_FEATURE_TYPE		0x00000300
11577c478bd9Sstevel@tonic-gate 
11587c478bd9Sstevel@tonic-gate /*
11597c478bd9Sstevel@tonic-gate  * Object classes from PKCS#11
11607c478bd9Sstevel@tonic-gate  */
11617c478bd9Sstevel@tonic-gate #define	DPROV_CKO_DATA			0x00000000
11627c478bd9Sstevel@tonic-gate #define	DPROV_CKO_CERTIFICATE		0x00000001
11637c478bd9Sstevel@tonic-gate #define	DPROV_CKO_PUBLIC_KEY		0x00000002
11647c478bd9Sstevel@tonic-gate #define	DPROV_CKO_PRIVATE_KEY		0x00000003
11657c478bd9Sstevel@tonic-gate #define	DPROV_CKO_SECRET_KEY		0x00000004
11667c478bd9Sstevel@tonic-gate #define	DPROV_CKO_HW_FEATURE		0x00000005
11677c478bd9Sstevel@tonic-gate #define	DPROV_CKO_DOMAIN_PARAMETERS	0x00000006
11687c478bd9Sstevel@tonic-gate #define	DPROV_CKO_VENDOR_DEFINED	0x80000000
11697c478bd9Sstevel@tonic-gate 
11707c478bd9Sstevel@tonic-gate /*
11717c478bd9Sstevel@tonic-gate  * A few key types from PKCS#11
11727c478bd9Sstevel@tonic-gate  */
11737c478bd9Sstevel@tonic-gate #define	DPROV_CKK_RSA			0x00000000
11747c478bd9Sstevel@tonic-gate #define	DPROV_CKK_GENERIC_SECRET	0x00000010
11757c478bd9Sstevel@tonic-gate #define	DPROV_CKK_RC4			0x00000012
11767c478bd9Sstevel@tonic-gate #define	DPROV_CKK_DES			0x00000013
11777c478bd9Sstevel@tonic-gate #define	DPROV_CKK_DES3			0x00000015
11787c478bd9Sstevel@tonic-gate #define	DPROV_CKK_AES			0x0000001F
1179f66d273dSizick #define	DPROV_CKK_BLOWFISH		0x00000020
11807c478bd9Sstevel@tonic-gate 
11817c478bd9Sstevel@tonic-gate /*
11827c478bd9Sstevel@tonic-gate  * Find object context. Allows the find object init/find/final
11837c478bd9Sstevel@tonic-gate  * to store data persistent across calls.
11847c478bd9Sstevel@tonic-gate  */
11857c478bd9Sstevel@tonic-gate typedef struct dprov_find_ctx {
11867c478bd9Sstevel@tonic-gate 	crypto_object_id_t fc_ids[DPROV_MAX_OBJECTS];	/* object ids */
11877c478bd9Sstevel@tonic-gate 	uint_t fc_nids;			/* number of ids in fc_ids */
11887c478bd9Sstevel@tonic-gate 	uint_t fc_next;			/* next id to return */
11897c478bd9Sstevel@tonic-gate } dprov_find_ctx_t;
11907c478bd9Sstevel@tonic-gate 
11917c478bd9Sstevel@tonic-gate /*
11927c478bd9Sstevel@tonic-gate  * Session management: each instance is associated with an array
11937c478bd9Sstevel@tonic-gate  * of sessions. KEF providers sessions are always R/W the library and
11947c478bd9Sstevel@tonic-gate  * the ioctl maintain the PKCS#11 R/W attributes for the session.
11957c478bd9Sstevel@tonic-gate  */
11967c478bd9Sstevel@tonic-gate 
11977c478bd9Sstevel@tonic-gate #define	DPROV_MIN_SESSIONS	32	/* # of sessions to start with */
11987c478bd9Sstevel@tonic-gate 
11997c478bd9Sstevel@tonic-gate typedef enum dprov_session_state {
12007c478bd9Sstevel@tonic-gate 	DPROV_SESSION_STATE_PUBLIC,	/* public (default) */
12017c478bd9Sstevel@tonic-gate 	DPROV_SESSION_STATE_SO,		/* SO logged in */
12027c478bd9Sstevel@tonic-gate 	DPROV_SESSION_STATE_USER	/* user logged in */
12037c478bd9Sstevel@tonic-gate } dprov_session_state_t;
12047c478bd9Sstevel@tonic-gate 
12057c478bd9Sstevel@tonic-gate /* session description */
12067c478bd9Sstevel@tonic-gate typedef struct dprov_session {
12077c478bd9Sstevel@tonic-gate 	dprov_session_state_t ds_state;	/* session state */
12087c478bd9Sstevel@tonic-gate 	dprov_object_t *ds_objects[DPROV_MAX_OBJECTS];	/* session objects */
12097c478bd9Sstevel@tonic-gate } dprov_session_t;
12107c478bd9Sstevel@tonic-gate 
12117c478bd9Sstevel@tonic-gate 
12127c478bd9Sstevel@tonic-gate static crypto_provider_info_t dprov_prov_info = {
1213894b2776Smcpowers 	CRYPTO_SPI_VERSION_2,
12147c478bd9Sstevel@tonic-gate 	"Dummy Pseudo HW Provider",
12157c478bd9Sstevel@tonic-gate 	CRYPTO_HW_PROVIDER,
12167c478bd9Sstevel@tonic-gate 	NULL,				/* pi_provider_dev */
12177c478bd9Sstevel@tonic-gate 	NULL,				/* pi_provider_handle */
12187c478bd9Sstevel@tonic-gate 	&dprov_crypto_ops,
12197c478bd9Sstevel@tonic-gate 	sizeof (dprov_mech_info_tab)/sizeof (crypto_mech_info_t),
12207c478bd9Sstevel@tonic-gate 	dprov_mech_info_tab,
12217c478bd9Sstevel@tonic-gate 	0,				/* pi_logical_provider_count */
1222ba5f469cSkrishna 	NULL,				/* pi_logical_providers */
1223ba5f469cSkrishna 	0				/* pi_flags */
12247c478bd9Sstevel@tonic-gate };
12257c478bd9Sstevel@tonic-gate 
12267c478bd9Sstevel@tonic-gate /*
12277c478bd9Sstevel@tonic-gate  * Per-instance info.
12287c478bd9Sstevel@tonic-gate  */
12297c478bd9Sstevel@tonic-gate typedef struct dprov_state {
12307c478bd9Sstevel@tonic-gate 	kmutex_t ds_lock;		/* per-instance lock */
12317c478bd9Sstevel@tonic-gate 	dev_info_t *ds_dip;		/* device info */
12327c478bd9Sstevel@tonic-gate 	crypto_kcf_provider_handle_t ds_prov_handle;	/* framework handle */
12337c478bd9Sstevel@tonic-gate 	taskq_t *ds_taskq;		/* taskq for async behavior */
12347c478bd9Sstevel@tonic-gate 	char ds_user_pin[DPROV_MAX_PIN_LEN];	/* normal user PIN */
12357c478bd9Sstevel@tonic-gate 	uint_t ds_user_pin_len;
12367c478bd9Sstevel@tonic-gate 	char ds_so_pin[DPROV_MAX_PIN_LEN];	/* SO PIN */
12377c478bd9Sstevel@tonic-gate 	uint_t ds_so_pin_len;
12387c478bd9Sstevel@tonic-gate 	dprov_session_t **ds_sessions;	/* sessions for this instance */
12397c478bd9Sstevel@tonic-gate 	uint_t ds_sessions_slots;	/* number of session slots */
12407c478bd9Sstevel@tonic-gate 	uint_t ds_sessions_count;	/* number of open sessions */
12417c478bd9Sstevel@tonic-gate 	boolean_t ds_token_initialized;	/* provider initialized? */
12427c478bd9Sstevel@tonic-gate 	boolean_t ds_user_pin_set;	/* user pin set? */
12437c478bd9Sstevel@tonic-gate 	char ds_label[CRYPTO_EXT_SIZE_LABEL];		/* "token" label */
12447c478bd9Sstevel@tonic-gate 	dprov_object_t *ds_objects[DPROV_MAX_OBJECTS];	/* "token" objects */
12457c478bd9Sstevel@tonic-gate } dprov_state_t;
12467c478bd9Sstevel@tonic-gate 
12477c478bd9Sstevel@tonic-gate 
12487c478bd9Sstevel@tonic-gate /*
12497c478bd9Sstevel@tonic-gate  * A taskq is associated with each instance of the pseudo driver in order
12507c478bd9Sstevel@tonic-gate  * to simulate the asynchronous execution of requests.
12517c478bd9Sstevel@tonic-gate  * The following defines the taskq request structures.
12527c478bd9Sstevel@tonic-gate  */
12537c478bd9Sstevel@tonic-gate 
12547c478bd9Sstevel@tonic-gate /* request types */
12557c478bd9Sstevel@tonic-gate typedef enum dprov_req_type {
12567c478bd9Sstevel@tonic-gate 	/* digest requests */
12577c478bd9Sstevel@tonic-gate 	DPROV_REQ_DIGEST_INIT = 1,
12587c478bd9Sstevel@tonic-gate 	DPROV_REQ_DIGEST,
12597c478bd9Sstevel@tonic-gate 	DPROV_REQ_DIGEST_UPDATE,
12607c478bd9Sstevel@tonic-gate 	DPROV_REQ_DIGEST_KEY,
12617c478bd9Sstevel@tonic-gate 	DPROV_REQ_DIGEST_FINAL,
12627c478bd9Sstevel@tonic-gate 	DPROV_REQ_DIGEST_ATOMIC,
12637c478bd9Sstevel@tonic-gate 	/* cipher requests */
12647c478bd9Sstevel@tonic-gate 	DPROV_REQ_ENCRYPT_INIT,
12657c478bd9Sstevel@tonic-gate 	DPROV_REQ_ENCRYPT,
12667c478bd9Sstevel@tonic-gate 	DPROV_REQ_ENCRYPT_UPDATE,
12677c478bd9Sstevel@tonic-gate 	DPROV_REQ_ENCRYPT_FINAL,
12687c478bd9Sstevel@tonic-gate 	DPROV_REQ_ENCRYPT_ATOMIC,
12697c478bd9Sstevel@tonic-gate 	DPROV_REQ_DECRYPT_INIT,
12707c478bd9Sstevel@tonic-gate 	DPROV_REQ_DECRYPT,
12717c478bd9Sstevel@tonic-gate 	DPROV_REQ_DECRYPT_UPDATE,
12727c478bd9Sstevel@tonic-gate 	DPROV_REQ_DECRYPT_FINAL,
12737c478bd9Sstevel@tonic-gate 	DPROV_REQ_DECRYPT_ATOMIC,
12747c478bd9Sstevel@tonic-gate 	/* mac requests */
12757c478bd9Sstevel@tonic-gate 	DPROV_REQ_MAC_INIT,
12767c478bd9Sstevel@tonic-gate 	DPROV_REQ_MAC,
12777c478bd9Sstevel@tonic-gate 	DPROV_REQ_MAC_UPDATE,
12787c478bd9Sstevel@tonic-gate 	DPROV_REQ_MAC_FINAL,
12797c478bd9Sstevel@tonic-gate 	DPROV_REQ_MAC_ATOMIC,
12807c478bd9Sstevel@tonic-gate 	DPROV_REQ_MAC_VERIFY_ATOMIC,
12817c478bd9Sstevel@tonic-gate 	/* sign requests */
12827c478bd9Sstevel@tonic-gate 	DPROV_REQ_SIGN_INIT,
12837c478bd9Sstevel@tonic-gate 	DPROV_REQ_SIGN,
12847c478bd9Sstevel@tonic-gate 	DPROV_REQ_SIGN_UPDATE,
12857c478bd9Sstevel@tonic-gate 	DPROV_REQ_SIGN_FINAL,
12867c478bd9Sstevel@tonic-gate 	DPROV_REQ_SIGN_ATOMIC,
12877c478bd9Sstevel@tonic-gate 	DPROV_REQ_SIGN_RECOVER_INIT,
12887c478bd9Sstevel@tonic-gate 	DPROV_REQ_SIGN_RECOVER,
12897c478bd9Sstevel@tonic-gate 	DPROV_REQ_SIGN_RECOVER_ATOMIC,
12907c478bd9Sstevel@tonic-gate 	/* verify requests */
12917c478bd9Sstevel@tonic-gate 	DPROV_REQ_VERIFY_INIT,
12927c478bd9Sstevel@tonic-gate 	DPROV_REQ_VERIFY,
12937c478bd9Sstevel@tonic-gate 	DPROV_REQ_VERIFY_UPDATE,
12947c478bd9Sstevel@tonic-gate 	DPROV_REQ_VERIFY_FINAL,
12957c478bd9Sstevel@tonic-gate 	DPROV_REQ_VERIFY_ATOMIC,
12967c478bd9Sstevel@tonic-gate 	DPROV_REQ_VERIFY_RECOVER_INIT,
12977c478bd9Sstevel@tonic-gate 	DPROV_REQ_VERIFY_RECOVER,
12987c478bd9Sstevel@tonic-gate 	DPROV_REQ_VERIFY_RECOVER_ATOMIC,
12997c478bd9Sstevel@tonic-gate 	/* dual ops requests */
13007c478bd9Sstevel@tonic-gate 	DPROV_REQ_DIGEST_ENCRYPT_UPDATE,
13017c478bd9Sstevel@tonic-gate 	DPROV_REQ_DECRYPT_DIGEST_UPDATE,
13027c478bd9Sstevel@tonic-gate 	DPROV_REQ_SIGN_ENCRYPT_UPDATE,
13037c478bd9Sstevel@tonic-gate 	DPROV_REQ_DECRYPT_VERIFY_UPDATE,
13047c478bd9Sstevel@tonic-gate 	/* dual cipher/mac requests */
13057c478bd9Sstevel@tonic-gate 	DPROV_REQ_ENCRYPT_MAC_INIT,
13067c478bd9Sstevel@tonic-gate 	DPROV_REQ_ENCRYPT_MAC,
13077c478bd9Sstevel@tonic-gate 	DPROV_REQ_ENCRYPT_MAC_UPDATE,
13087c478bd9Sstevel@tonic-gate 	DPROV_REQ_ENCRYPT_MAC_FINAL,
13097c478bd9Sstevel@tonic-gate 	DPROV_REQ_ENCRYPT_MAC_ATOMIC,
13107c478bd9Sstevel@tonic-gate 	DPROV_REQ_MAC_DECRYPT_INIT,
13117c478bd9Sstevel@tonic-gate 	DPROV_REQ_MAC_DECRYPT,
13127c478bd9Sstevel@tonic-gate 	DPROV_REQ_MAC_DECRYPT_UPDATE,
13137c478bd9Sstevel@tonic-gate 	DPROV_REQ_MAC_DECRYPT_FINAL,
13147c478bd9Sstevel@tonic-gate 	DPROV_REQ_MAC_DECRYPT_ATOMIC,
13157c478bd9Sstevel@tonic-gate 	DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC,
13167c478bd9Sstevel@tonic-gate 	/* random number ops */
13177c478bd9Sstevel@tonic-gate 	DPROV_REQ_RANDOM_SEED,
13187c478bd9Sstevel@tonic-gate 	DPROV_REQ_RANDOM_GENERATE,
13197c478bd9Sstevel@tonic-gate 	/* session management requests */
13207c478bd9Sstevel@tonic-gate 	DPROV_REQ_SESSION_OPEN,
13217c478bd9Sstevel@tonic-gate 	DPROV_REQ_SESSION_CLOSE,
13227c478bd9Sstevel@tonic-gate 	DPROV_REQ_SESSION_LOGIN,
13237c478bd9Sstevel@tonic-gate 	DPROV_REQ_SESSION_LOGOUT,
13247c478bd9Sstevel@tonic-gate 	/* object management requests */
13257c478bd9Sstevel@tonic-gate 	DPROV_REQ_OBJECT_CREATE,
13267c478bd9Sstevel@tonic-gate 	DPROV_REQ_OBJECT_COPY,
13277c478bd9Sstevel@tonic-gate 	DPROV_REQ_OBJECT_DESTROY,
13287c478bd9Sstevel@tonic-gate 	DPROV_REQ_OBJECT_GET_SIZE,
13297c478bd9Sstevel@tonic-gate 	DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE,
13307c478bd9Sstevel@tonic-gate 	DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE,
13317c478bd9Sstevel@tonic-gate 	DPROV_REQ_OBJECT_FIND_INIT,
13327c478bd9Sstevel@tonic-gate 	DPROV_REQ_OBJECT_FIND,
13337c478bd9Sstevel@tonic-gate 	DPROV_REQ_OBJECT_FIND_FINAL,
13347c478bd9Sstevel@tonic-gate 	/* key management requests */
13357c478bd9Sstevel@tonic-gate 	DPROV_REQ_KEY_GENERATE,
13367c478bd9Sstevel@tonic-gate 	DPROV_REQ_KEY_GENERATE_PAIR,
13377c478bd9Sstevel@tonic-gate 	DPROV_REQ_KEY_WRAP,
13387c478bd9Sstevel@tonic-gate 	DPROV_REQ_KEY_UNWRAP,
13397c478bd9Sstevel@tonic-gate 	DPROV_REQ_KEY_DERIVE,
13407c478bd9Sstevel@tonic-gate 	/* provider management requests */
13417c478bd9Sstevel@tonic-gate 	DPROV_REQ_MGMT_EXTINFO,
13427c478bd9Sstevel@tonic-gate 	DPROV_REQ_MGMT_INITTOKEN,
13437c478bd9Sstevel@tonic-gate 	DPROV_REQ_MGMT_INITPIN,
1344034448feSmcpowers 	DPROV_REQ_MGMT_SETPIN,
1345034448feSmcpowers 	/* no (key)store key management requests */
13465b0c7657Sizick 	DPROV_REQ_NOSTORE_KEY_GENERATE,
13475b0c7657Sizick 	DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR,
13485b0c7657Sizick 	DPROV_REQ_NOSTORE_KEY_DERIVE
13497c478bd9Sstevel@tonic-gate } dprov_req_type_t;
13507c478bd9Sstevel@tonic-gate 
13517c478bd9Sstevel@tonic-gate /* for DPROV_REQ_DIGEST requests */
13527c478bd9Sstevel@tonic-gate typedef struct dprov_digest_req {
13537c478bd9Sstevel@tonic-gate 	crypto_mechanism_t *dr_mechanism;
13547c478bd9Sstevel@tonic-gate 	crypto_ctx_t *dr_ctx;
13557c478bd9Sstevel@tonic-gate 	crypto_data_t *dr_data;
13567c478bd9Sstevel@tonic-gate 	crypto_key_t *dr_key;
13577c478bd9Sstevel@tonic-gate 	crypto_data_t *dr_digest;
13587c478bd9Sstevel@tonic-gate } dprov_digest_req_t;
13597c478bd9Sstevel@tonic-gate 
13607c478bd9Sstevel@tonic-gate /* for DPROV_REQ_MAC requests */
13617c478bd9Sstevel@tonic-gate typedef struct dprov_mac_req {
13627c478bd9Sstevel@tonic-gate 	crypto_mechanism_t *dr_mechanism;
13637c478bd9Sstevel@tonic-gate 	crypto_ctx_t *dr_ctx;
13647c478bd9Sstevel@tonic-gate 	crypto_key_t *dr_key;
1365ba5f469cSkrishna 	crypto_data_t *dr_data;
13667c478bd9Sstevel@tonic-gate 	crypto_data_t *dr_mac;
13677c478bd9Sstevel@tonic-gate 	crypto_session_id_t dr_session_id;
13687c478bd9Sstevel@tonic-gate } dprov_mac_req_t;
13697c478bd9Sstevel@tonic-gate 
13707c478bd9Sstevel@tonic-gate /* for DPROV_REQ_ENCRYPT and DPROV_REQ_DECRYPT requests */
13717c478bd9Sstevel@tonic-gate typedef struct dprov_cipher_req {
13727c478bd9Sstevel@tonic-gate 	crypto_mechanism_t *dr_mechanism;
13737c478bd9Sstevel@tonic-gate 	crypto_ctx_t *dr_ctx;
13747c478bd9Sstevel@tonic-gate 	crypto_key_t *dr_key;
13757c478bd9Sstevel@tonic-gate 	crypto_data_t *dr_plaintext;
13767c478bd9Sstevel@tonic-gate 	crypto_data_t *dr_ciphertext;
13777c478bd9Sstevel@tonic-gate 	crypto_session_id_t dr_session_id;
13787c478bd9Sstevel@tonic-gate } dprov_cipher_req_t;
13797c478bd9Sstevel@tonic-gate 
13807c478bd9Sstevel@tonic-gate /* for DPROV_REQ_SIGN requests */
13817c478bd9Sstevel@tonic-gate typedef struct dprov_sign_req {
13827c478bd9Sstevel@tonic-gate 	crypto_mechanism_t *sr_mechanism;
13837c478bd9Sstevel@tonic-gate 	crypto_ctx_t *sr_ctx;
13847c478bd9Sstevel@tonic-gate 	crypto_key_t *sr_key;
13857c478bd9Sstevel@tonic-gate 	crypto_data_t *sr_data;
13867c478bd9Sstevel@tonic-gate 	crypto_data_t *sr_signature;
13877c478bd9Sstevel@tonic-gate 	crypto_session_id_t sr_session_id;
13887c478bd9Sstevel@tonic-gate } dprov_sign_req_t;
13897c478bd9Sstevel@tonic-gate 
13907c478bd9Sstevel@tonic-gate /* for DPROV_REQ_VERIFY requests */
13917c478bd9Sstevel@tonic-gate typedef struct dprov_verify_req {
13927c478bd9Sstevel@tonic-gate 	crypto_mechanism_t *vr_mechanism;
13937c478bd9Sstevel@tonic-gate 	crypto_ctx_t *vr_ctx;
13947c478bd9Sstevel@tonic-gate 	crypto_key_t *vr_key;
13957c478bd9Sstevel@tonic-gate 	crypto_data_t *vr_data;
13967c478bd9Sstevel@tonic-gate 	crypto_data_t *vr_signature;
13977c478bd9Sstevel@tonic-gate 	crypto_session_id_t vr_session_id;
13987c478bd9Sstevel@tonic-gate } dprov_verify_req_t;
13997c478bd9Sstevel@tonic-gate 
14007c478bd9Sstevel@tonic-gate /* for dual ops requests */
14017c478bd9Sstevel@tonic-gate typedef struct dprov_dual_req {
14027c478bd9Sstevel@tonic-gate 	crypto_ctx_t *dr_signverify_ctx;
14037c478bd9Sstevel@tonic-gate 	crypto_ctx_t *dr_cipher_ctx;
14047c478bd9Sstevel@tonic-gate 	crypto_data_t *dr_plaintext;
14057c478bd9Sstevel@tonic-gate 	crypto_data_t *dr_ciphertext;
14067c478bd9Sstevel@tonic-gate } dprov_dual_req_t;
14077c478bd9Sstevel@tonic-gate 
14087c478bd9Sstevel@tonic-gate /* for cipher/mac dual ops requests */
14097c478bd9Sstevel@tonic-gate typedef struct dprov_cipher_mac_req {
14107c478bd9Sstevel@tonic-gate 	crypto_session_id_t mr_session_id;
14117c478bd9Sstevel@tonic-gate 	crypto_ctx_t *mr_ctx;
14127c478bd9Sstevel@tonic-gate 	crypto_mechanism_t *mr_cipher_mech;
14137c478bd9Sstevel@tonic-gate 	crypto_key_t *mr_cipher_key;
14147c478bd9Sstevel@tonic-gate 	crypto_mechanism_t *mr_mac_mech;
14157c478bd9Sstevel@tonic-gate 	crypto_key_t *mr_mac_key;
14167c478bd9Sstevel@tonic-gate 	crypto_dual_data_t *mr_dual_data;
14177c478bd9Sstevel@tonic-gate 	crypto_data_t *mr_data;
14187c478bd9Sstevel@tonic-gate 	crypto_data_t *mr_mac;
14197c478bd9Sstevel@tonic-gate } dprov_cipher_mac_req_t;
14207c478bd9Sstevel@tonic-gate 
14217c478bd9Sstevel@tonic-gate /* for DPROV_REQ_RANDOM requests */
14227c478bd9Sstevel@tonic-gate typedef struct dprov_random_req {
14237c478bd9Sstevel@tonic-gate 	uchar_t *rr_buf;
14247c478bd9Sstevel@tonic-gate 	size_t rr_len;
14257c478bd9Sstevel@tonic-gate 	crypto_session_id_t rr_session_id;
14268047c9fbSmcpowers 	uint_t rr_entropy_est;
14278047c9fbSmcpowers 	uint32_t rr_flags;
14287c478bd9Sstevel@tonic-gate } dprov_random_req_t;
14297c478bd9Sstevel@tonic-gate 
14307c478bd9Sstevel@tonic-gate /* for DPROV_REQ_SESSION requests */
14317c478bd9Sstevel@tonic-gate typedef struct dprov_session_req {
14327c478bd9Sstevel@tonic-gate 	crypto_session_id_t *sr_session_id_ptr;
14337c478bd9Sstevel@tonic-gate 	crypto_session_id_t sr_session_id;
14347c478bd9Sstevel@tonic-gate 	crypto_user_type_t sr_user_type;
14357c478bd9Sstevel@tonic-gate 	char *sr_pin;
14367c478bd9Sstevel@tonic-gate 	size_t sr_pin_len;
14377c478bd9Sstevel@tonic-gate } dprov_session_req_t;
14387c478bd9Sstevel@tonic-gate 
14397c478bd9Sstevel@tonic-gate /* for DPROV_REQ_OBJECT requests */
14407c478bd9Sstevel@tonic-gate typedef struct dprov_object_req {
14417c478bd9Sstevel@tonic-gate 	crypto_session_id_t or_session_id;
14427c478bd9Sstevel@tonic-gate 	crypto_object_id_t or_object_id;
14437c478bd9Sstevel@tonic-gate 	crypto_object_attribute_t *or_template;
14447c478bd9Sstevel@tonic-gate 	uint_t or_attribute_count;
14457c478bd9Sstevel@tonic-gate 	crypto_object_id_t *or_object_id_ptr;
14467c478bd9Sstevel@tonic-gate 	size_t *or_object_size;
14477c478bd9Sstevel@tonic-gate 	void **or_find_pp;
14487c478bd9Sstevel@tonic-gate 	void *or_find_p;
14497c478bd9Sstevel@tonic-gate 	uint_t or_max_object_count;
14507c478bd9Sstevel@tonic-gate 	uint_t *or_object_count_ptr;
14517c478bd9Sstevel@tonic-gate } dprov_object_req_t;
14527c478bd9Sstevel@tonic-gate 
14537c478bd9Sstevel@tonic-gate /* for DPROV_REQ_KEY requests */
14547c478bd9Sstevel@tonic-gate typedef struct dprov_key_req {
14557c478bd9Sstevel@tonic-gate 	crypto_session_id_t kr_session_id;
14567c478bd9Sstevel@tonic-gate 	crypto_mechanism_t *kr_mechanism;
14577c478bd9Sstevel@tonic-gate 	crypto_object_attribute_t *kr_template;
14587c478bd9Sstevel@tonic-gate 	uint_t kr_attribute_count;
14597c478bd9Sstevel@tonic-gate 	crypto_object_id_t *kr_object_id_ptr;
14607c478bd9Sstevel@tonic-gate 	crypto_object_attribute_t *kr_private_key_template;
14617c478bd9Sstevel@tonic-gate 	uint_t kr_private_key_attribute_count;
14627c478bd9Sstevel@tonic-gate 	crypto_object_id_t *kr_private_key_object_id_ptr;
14637c478bd9Sstevel@tonic-gate 	crypto_key_t *kr_key;
14647c478bd9Sstevel@tonic-gate 	uchar_t *kr_wrapped_key;
14657c478bd9Sstevel@tonic-gate 	size_t *kr_wrapped_key_len_ptr;
1466034448feSmcpowers 	crypto_object_attribute_t *kr_out_template1;
1467034448feSmcpowers 	crypto_object_attribute_t *kr_out_template2;
1468034448feSmcpowers 	uint_t kr_out_attribute_count1;
1469034448feSmcpowers 	uint_t kr_out_attribute_count2;
14707c478bd9Sstevel@tonic-gate } dprov_key_req_t;
14717c478bd9Sstevel@tonic-gate 
14727c478bd9Sstevel@tonic-gate /* for DPROV_REQ_MGMT requests */
14737c478bd9Sstevel@tonic-gate typedef struct dprov_mgmt_req {
14747c478bd9Sstevel@tonic-gate 	crypto_session_id_t mr_session_id;
14757c478bd9Sstevel@tonic-gate 	char *mr_pin;
14767c478bd9Sstevel@tonic-gate 	size_t mr_pin_len;
14777c478bd9Sstevel@tonic-gate 	char *mr_old_pin;
14787c478bd9Sstevel@tonic-gate 	size_t mr_old_pin_len;
14797c478bd9Sstevel@tonic-gate 	char *mr_label;
14807c478bd9Sstevel@tonic-gate 	crypto_provider_ext_info_t *mr_ext_info;
14817c478bd9Sstevel@tonic-gate } dprov_mgmt_req_t;
14827c478bd9Sstevel@tonic-gate 
14837c478bd9Sstevel@tonic-gate /* request, as queued on taskq */
14847c478bd9Sstevel@tonic-gate typedef struct dprov_req {
14857c478bd9Sstevel@tonic-gate 	dprov_req_type_t dr_type;
14867c478bd9Sstevel@tonic-gate 	dprov_state_t *dr_softc;
14877c478bd9Sstevel@tonic-gate 	crypto_req_handle_t dr_kcf_req;
14887c478bd9Sstevel@tonic-gate 	union {
14897c478bd9Sstevel@tonic-gate 		dprov_digest_req_t dru_digest_req;
14907c478bd9Sstevel@tonic-gate 		dprov_mac_req_t dru_mac_req;
14917c478bd9Sstevel@tonic-gate 		dprov_cipher_req_t dru_cipher_req;
14927c478bd9Sstevel@tonic-gate 		dprov_sign_req_t dru_sign_req;
14937c478bd9Sstevel@tonic-gate 		dprov_verify_req_t dru_verify_req;
14947c478bd9Sstevel@tonic-gate 		dprov_dual_req_t dru_dual_req;
14957c478bd9Sstevel@tonic-gate 		dprov_cipher_mac_req_t dru_cipher_mac_req;
14967c478bd9Sstevel@tonic-gate 		dprov_random_req_t dru_random_req;
14977c478bd9Sstevel@tonic-gate 		dprov_session_req_t dru_session_req;
14987c478bd9Sstevel@tonic-gate 		dprov_object_req_t dru_object_req;
14997c478bd9Sstevel@tonic-gate 		dprov_key_req_t dru_key_req;
15007c478bd9Sstevel@tonic-gate 		dprov_mgmt_req_t dru_mgmt_req;
15017c478bd9Sstevel@tonic-gate 	} dr_req;
15027c478bd9Sstevel@tonic-gate } dprov_req_t;
15037c478bd9Sstevel@tonic-gate 
15047c478bd9Sstevel@tonic-gate /* shortcuts for union fields */
15057c478bd9Sstevel@tonic-gate #define	dr_digest_req		dr_req.dru_digest_req
15067c478bd9Sstevel@tonic-gate #define	dr_mac_req		dr_req.dru_mac_req
15077c478bd9Sstevel@tonic-gate #define	dr_cipher_req		dr_req.dru_cipher_req
15087c478bd9Sstevel@tonic-gate #define	dr_sign_req		dr_req.dru_sign_req
15097c478bd9Sstevel@tonic-gate #define	dr_verify_req		dr_req.dru_verify_req
15107c478bd9Sstevel@tonic-gate #define	dr_dual_req		dr_req.dru_dual_req
15117c478bd9Sstevel@tonic-gate #define	dr_cipher_mac_req	dr_req.dru_cipher_mac_req
15127c478bd9Sstevel@tonic-gate #define	dr_random_req		dr_req.dru_random_req
15137c478bd9Sstevel@tonic-gate #define	dr_session_req		dr_req.dru_session_req
15147c478bd9Sstevel@tonic-gate #define	dr_object_req		dr_req.dru_object_req
15157c478bd9Sstevel@tonic-gate #define	dr_key_req		dr_req.dru_key_req
15167c478bd9Sstevel@tonic-gate #define	dr_mgmt_req		dr_req.dru_mgmt_req
15177c478bd9Sstevel@tonic-gate 
15187c478bd9Sstevel@tonic-gate /* prototypes for the tasq dispatcher functions */
15197c478bd9Sstevel@tonic-gate static void dprov_digest_task(dprov_req_t *);
15207c478bd9Sstevel@tonic-gate static void dprov_mac_task(dprov_req_t *);
15217c478bd9Sstevel@tonic-gate static void dprov_sign_task(dprov_req_t *);
15227c478bd9Sstevel@tonic-gate static void dprov_verify_task(dprov_req_t *);
15237c478bd9Sstevel@tonic-gate static void dprov_dual_task(dprov_req_t *);
15247c478bd9Sstevel@tonic-gate static void dprov_cipher_task(dprov_req_t *);
15257c478bd9Sstevel@tonic-gate static void dprov_cipher_mac_task(dprov_req_t *);
15267c478bd9Sstevel@tonic-gate static void dprov_random_task(dprov_req_t *);
15277c478bd9Sstevel@tonic-gate static void dprov_session_task(dprov_req_t *);
15287c478bd9Sstevel@tonic-gate static void dprov_object_task(dprov_req_t *);
15297c478bd9Sstevel@tonic-gate static void dprov_key_task(dprov_req_t *);
15307c478bd9Sstevel@tonic-gate static void dprov_mgmt_task(dprov_req_t *);
15317c478bd9Sstevel@tonic-gate 
15327c478bd9Sstevel@tonic-gate /* helper functions */
15337c478bd9Sstevel@tonic-gate static int dprov_digest_submit_req(dprov_req_type_t, dprov_state_t *,
15347c478bd9Sstevel@tonic-gate     crypto_req_handle_t, crypto_mechanism_t *, crypto_data_t *, crypto_key_t *,
15357c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_ctx_t *, int);
15367c478bd9Sstevel@tonic-gate static int dprov_cipher_submit_req(dprov_req_type_t, dprov_state_t *,
15377c478bd9Sstevel@tonic-gate     crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
15387c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
15397c478bd9Sstevel@tonic-gate static int dprov_mac_submit_req(dprov_req_type_t, dprov_state_t *,
15407c478bd9Sstevel@tonic-gate     crypto_req_handle_t, crypto_mechanism_t *, crypto_data_t *,
15417c478bd9Sstevel@tonic-gate     crypto_key_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
15427c478bd9Sstevel@tonic-gate static int dprov_sign_submit_req(dprov_req_type_t, dprov_state_t *,
15437c478bd9Sstevel@tonic-gate     crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *,
15447c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
15457c478bd9Sstevel@tonic-gate static int dprov_verify_submit_req(dprov_req_type_t, dprov_state_t *,
15467c478bd9Sstevel@tonic-gate     crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *,
15477c478bd9Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
15487c478bd9Sstevel@tonic-gate static int dprov_dual_submit_req(dprov_req_type_t, dprov_state_t *,
15497c478bd9Sstevel@tonic-gate     crypto_req_handle_t, crypto_ctx_t *, crypto_ctx_t *, crypto_data_t *,
15507c478bd9Sstevel@tonic-gate     crypto_data_t *);
15517c478bd9Sstevel@tonic-gate static int dprov_cipher_mac_submit_req(dprov_req_type_t, dprov_state_t *,
15527c478bd9Sstevel@tonic-gate     crypto_req_handle_t, crypto_ctx_t *, crypto_session_id_t,
15537c478bd9Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *, crypto_key_t *,
15547c478bd9Sstevel@tonic-gate     crypto_dual_data_t *, crypto_data_t *, crypto_data_t *, int);
15557c478bd9Sstevel@tonic-gate static int dprov_random_submit_req(dprov_req_type_t, dprov_state_t *,
15568047c9fbSmcpowers     crypto_req_handle_t, uchar_t *, size_t, crypto_session_id_t, uint_t,
15578047c9fbSmcpowers     uint32_t);
15587c478bd9Sstevel@tonic-gate static int dprov_session_submit_req(dprov_req_type_t, dprov_state_t *,
15597c478bd9Sstevel@tonic-gate     crypto_req_handle_t, crypto_session_id_t *, crypto_session_id_t,
15607c478bd9Sstevel@tonic-gate     crypto_user_type_t, char *, size_t);
15617c478bd9Sstevel@tonic-gate static int dprov_object_submit_req(dprov_req_type_t, dprov_state_t *,
15627c478bd9Sstevel@tonic-gate     crypto_req_handle_t, crypto_session_id_t, crypto_object_id_t,
15637c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *, uint_t, crypto_object_id_t *, size_t *,
15647c478bd9Sstevel@tonic-gate     void **, void *, uint_t, uint_t *, int);
15657c478bd9Sstevel@tonic-gate static int dprov_key_submit_req(dprov_req_type_t, dprov_state_t *,
15667c478bd9Sstevel@tonic-gate     crypto_req_handle_t, crypto_session_id_t, crypto_mechanism_t *,
15677c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
15687c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
1569034448feSmcpowers     crypto_key_t *, uchar_t *, size_t *, crypto_object_attribute_t *,
1570034448feSmcpowers     uint_t, crypto_object_attribute_t *, uint_t);
15717c478bd9Sstevel@tonic-gate static int dprov_mgmt_submit_req(dprov_req_type_t, dprov_state_t *,
15727c478bd9Sstevel@tonic-gate     crypto_req_handle_t, crypto_session_id_t, char *, size_t, char *, size_t,
15737c478bd9Sstevel@tonic-gate     char *, crypto_provider_ext_info_t *);
15747c478bd9Sstevel@tonic-gate static int dprov_get_sw_prov(crypto_mechanism_t *, kcf_provider_desc_t **,
15757c478bd9Sstevel@tonic-gate     crypto_mech_type_t *);
15767c478bd9Sstevel@tonic-gate 
15777c478bd9Sstevel@tonic-gate /* object management helper functions */
15787c478bd9Sstevel@tonic-gate static void dprov_free_object(dprov_object_t *);
15797c478bd9Sstevel@tonic-gate static void dprov_release_session_objects(dprov_session_t *);
1580f9fbec18Smcpowers static void dprov_adjust_attrs(crypto_object_attribute_t *, int);
15817c478bd9Sstevel@tonic-gate static boolean_t dprov_object_is_private(dprov_object_t *);
15827c478bd9Sstevel@tonic-gate static boolean_t dprov_object_is_token(dprov_object_t *);
15837c478bd9Sstevel@tonic-gate static int dprov_key_value_secret(dprov_state_t *, crypto_session_id_t,
15847c478bd9Sstevel@tonic-gate     dprov_req_type_t, crypto_key_t *, crypto_key_t *);
15857c478bd9Sstevel@tonic-gate static int dprov_key_attr_asymmetric(dprov_state_t *, crypto_session_id_t,
15867c478bd9Sstevel@tonic-gate     dprov_req_type_t, crypto_key_t *, crypto_key_t *);
15877c478bd9Sstevel@tonic-gate static int dprov_get_object_attr_boolean(dprov_object_t *, uint64_t,
15887c478bd9Sstevel@tonic-gate 	boolean_t *);
15897c478bd9Sstevel@tonic-gate static int dprov_get_object_attr_ulong(dprov_object_t *, uint64_t, ulong_t *);
15907c478bd9Sstevel@tonic-gate static int dprov_get_object_attr_array(dprov_object_t *, uint64_t, void **,
15917c478bd9Sstevel@tonic-gate     size_t *);
15927c478bd9Sstevel@tonic-gate static int dprov_get_key_attr_ulong(crypto_key_t *, uint64_t, ulong_t *);
15937c478bd9Sstevel@tonic-gate static int dprov_get_key_attr_array(crypto_key_t *, uint64_t, void **,
15947c478bd9Sstevel@tonic-gate     size_t *);
15957c478bd9Sstevel@tonic-gate static int dprov_create_object_from_template(dprov_state_t *, dprov_session_t *,
15967c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *, uint_t, crypto_object_id_t *, boolean_t,
15977c478bd9Sstevel@tonic-gate     boolean_t);
15987c478bd9Sstevel@tonic-gate static int dprov_get_template_attr_scalar_common(crypto_object_attribute_t *,
15997c478bd9Sstevel@tonic-gate     uint_t, uint64_t, void *, size_t);
16007c478bd9Sstevel@tonic-gate static int dprov_get_template_attr_boolean(crypto_object_attribute_t *,
16017c478bd9Sstevel@tonic-gate     uint_t, uint64_t, boolean_t *);
16027c478bd9Sstevel@tonic-gate static int dprov_get_template_attr_ulong(crypto_object_attribute_t *, uint_t,
16037c478bd9Sstevel@tonic-gate     uint64_t, ulong_t *);
16047c478bd9Sstevel@tonic-gate static int dprov_template_attr_present(crypto_object_attribute_t *, uint_t,
16057c478bd9Sstevel@tonic-gate     uint64_t);
16067c478bd9Sstevel@tonic-gate static int dprov_get_template_attr_array(crypto_object_attribute_t *, uint_t,
16077c478bd9Sstevel@tonic-gate     uint64_t, void **, size_t *);
16087c478bd9Sstevel@tonic-gate static int dprov_destroy_object(dprov_state_t *, dprov_session_t *,
16097c478bd9Sstevel@tonic-gate     crypto_object_id_t);
16107c478bd9Sstevel@tonic-gate static int dprov_object_set_attr(dprov_session_t *, crypto_object_id_t,
16117c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *, uint_t, boolean_t);
16127c478bd9Sstevel@tonic-gate static int dprov_find_attr(crypto_object_attribute_t *, uint_t, uint64_t);
16137c478bd9Sstevel@tonic-gate static boolean_t dprov_attributes_match(dprov_object_t *,
16147c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *, uint_t);
16157c478bd9Sstevel@tonic-gate 
16167c478bd9Sstevel@tonic-gate /* retrieve the softc and instance number from a SPI crypto context */
16177c478bd9Sstevel@tonic-gate #define	DPROV_SOFTC_FROM_CTX(ctx, softc, instance) {	\
16187c478bd9Sstevel@tonic-gate 	(softc) = (dprov_state_t *)(ctx)->cc_provider;	\
16197c478bd9Sstevel@tonic-gate 	(instance) = ddi_get_instance((softc)->ds_dip);	\
16207c478bd9Sstevel@tonic-gate }
16217c478bd9Sstevel@tonic-gate 
16227c478bd9Sstevel@tonic-gate /* retrieve the softc and instance number from a taskq request */
16237c478bd9Sstevel@tonic-gate #define	DPROV_SOFTC_FROM_REQ(req, softc, instance) {	\
16247c478bd9Sstevel@tonic-gate 	(softc) = (req)->dr_softc;			\
16257c478bd9Sstevel@tonic-gate 	(instance) = ddi_get_instance((softc)->ds_dip);	\
16267c478bd9Sstevel@tonic-gate }
16277c478bd9Sstevel@tonic-gate 
16287c478bd9Sstevel@tonic-gate /*
16297c478bd9Sstevel@tonic-gate  * The dprov private context most of the time contains a pointer to the
16307c478bd9Sstevel@tonic-gate  * crypto_context_t that was allocated when calling a KCF function.
16317c478bd9Sstevel@tonic-gate  * Dual cipher/mac operations however require the dprov driver
16327c478bd9Sstevel@tonic-gate  * to maintain the contexts associated with the separate cipher
16337c478bd9Sstevel@tonic-gate  * and mac operations. These two types of dprov contexts are
16347c478bd9Sstevel@tonic-gate  * defined below.
16357c478bd9Sstevel@tonic-gate  */
16367c478bd9Sstevel@tonic-gate typedef enum dprov_ctx_type {
16377c478bd9Sstevel@tonic-gate 	DPROV_CTX_SINGLE,
16387c478bd9Sstevel@tonic-gate 	DPROV_CTX_DUAL
16397c478bd9Sstevel@tonic-gate } dprov_ctx_type_t;
16407c478bd9Sstevel@tonic-gate 
16417c478bd9Sstevel@tonic-gate /*
16427c478bd9Sstevel@tonic-gate  * When the context refers to a single KCF context, the
16437c478bd9Sstevel@tonic-gate  * cc_provider field of a crypto_ctx_t points to a structure of
16447c478bd9Sstevel@tonic-gate  * type dprov_ctx_single.
16457c478bd9Sstevel@tonic-gate  */
16467c478bd9Sstevel@tonic-gate typedef struct dprov_ctx_single {
16477c478bd9Sstevel@tonic-gate 	dprov_ctx_type_t dc_type;
16487c478bd9Sstevel@tonic-gate 	crypto_context_t dc_ctx;
1649ba5f469cSkrishna 	boolean_t dc_svrfy_to_mac;
16507c478bd9Sstevel@tonic-gate } dprov_ctx_single_t;
16517c478bd9Sstevel@tonic-gate 
16527c478bd9Sstevel@tonic-gate /*
16537c478bd9Sstevel@tonic-gate  * When the context is used for cipher/mac operations, it contains
16547c478bd9Sstevel@tonic-gate  * pointers to to KCF contexts, one for the cipher operation, the
16557c478bd9Sstevel@tonic-gate  * other for the mac operation.
16567c478bd9Sstevel@tonic-gate  */
16577c478bd9Sstevel@tonic-gate typedef struct dprov_ctx_dual {
16587c478bd9Sstevel@tonic-gate 	dprov_ctx_type_t cd_type;
16597c478bd9Sstevel@tonic-gate 	crypto_context_t cd_cipher_ctx;
16607c478bd9Sstevel@tonic-gate 	crypto_context_t cd_mac_ctx;
16617c478bd9Sstevel@tonic-gate } dprov_ctx_dual_t;
16627c478bd9Sstevel@tonic-gate 
16637c478bd9Sstevel@tonic-gate /*
16647c478bd9Sstevel@tonic-gate  * Helper macros for context accessors. These macros return the
16657c478bd9Sstevel@tonic-gate  * k-API context corresponding to the given SPI context for
16667c478bd9Sstevel@tonic-gate  * single and dual cipher/mac operations.
16677c478bd9Sstevel@tonic-gate  */
16687c478bd9Sstevel@tonic-gate 
1669ba5f469cSkrishna #define	DPROV_CTX_P(_ctx) \
1670ba5f469cSkrishna 	((dprov_ctx_single_t *)(_ctx)->cc_provider_private)
1671ba5f469cSkrishna 
1672ba5f469cSkrishna #define	DPROV_CTX_SINGLE(_ctx)	((DPROV_CTX_P(_ctx))->dc_ctx)
16737c478bd9Sstevel@tonic-gate 
16747c478bd9Sstevel@tonic-gate #define	DPROV_CTX_DUAL_CIPHER(_ctx) \
16757c478bd9Sstevel@tonic-gate 	(((dprov_ctx_dual_t *)(_ctx)->cc_provider_private)->cd_cipher_ctx)
16767c478bd9Sstevel@tonic-gate 
16777c478bd9Sstevel@tonic-gate #define	DPROV_CTX_DUAL_MAC(_ctx) \
16787c478bd9Sstevel@tonic-gate 	(((dprov_ctx_dual_t *)(_ctx)->cc_provider_private)->cd_mac_ctx)
16797c478bd9Sstevel@tonic-gate 
16807c478bd9Sstevel@tonic-gate static int dprov_alloc_context(dprov_req_type_t, crypto_ctx_t *);
16817c478bd9Sstevel@tonic-gate 
16827c478bd9Sstevel@tonic-gate 
16837c478bd9Sstevel@tonic-gate 
16847c478bd9Sstevel@tonic-gate static void *statep;	/* state pointer */
16857c478bd9Sstevel@tonic-gate 
16867c478bd9Sstevel@tonic-gate /*
16877c478bd9Sstevel@tonic-gate  * DDI entry points.
16887c478bd9Sstevel@tonic-gate  */
16897c478bd9Sstevel@tonic-gate int
16907c478bd9Sstevel@tonic-gate _init(void)
16917c478bd9Sstevel@tonic-gate {
16927c478bd9Sstevel@tonic-gate 	int error;
16937c478bd9Sstevel@tonic-gate 
16947c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_INIT, ("dprov: in _init\n"));
16957c478bd9Sstevel@tonic-gate 
16967c478bd9Sstevel@tonic-gate 	if ((error = ddi_soft_state_init(&statep, sizeof (dprov_state_t),
16977c478bd9Sstevel@tonic-gate 	    0)) != 0)
16987c478bd9Sstevel@tonic-gate 		return (error);
16997c478bd9Sstevel@tonic-gate 
17007c478bd9Sstevel@tonic-gate 	return (mod_install(&modlinkage));
17017c478bd9Sstevel@tonic-gate }
17027c478bd9Sstevel@tonic-gate 
17037c478bd9Sstevel@tonic-gate int
17047c478bd9Sstevel@tonic-gate _fini(void)
17057c478bd9Sstevel@tonic-gate {
17067c478bd9Sstevel@tonic-gate 	int error;
17077c478bd9Sstevel@tonic-gate 
17087c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_INIT, ("dprov: in _fini\n"));
17097c478bd9Sstevel@tonic-gate 
17107c478bd9Sstevel@tonic-gate 	if ((error = mod_remove(&modlinkage)) != 0)
17117c478bd9Sstevel@tonic-gate 		return (error);
17127c478bd9Sstevel@tonic-gate 
17137c478bd9Sstevel@tonic-gate 	ddi_soft_state_fini(&statep);
17147c478bd9Sstevel@tonic-gate 
17157c478bd9Sstevel@tonic-gate 	return (0);
17167c478bd9Sstevel@tonic-gate }
17177c478bd9Sstevel@tonic-gate 
17187c478bd9Sstevel@tonic-gate int
17197c478bd9Sstevel@tonic-gate _info(struct modinfo *modinfop)
17207c478bd9Sstevel@tonic-gate {
17217c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_INIT, ("dprov: in _info\n"));
17227c478bd9Sstevel@tonic-gate 
17237c478bd9Sstevel@tonic-gate 	return (mod_info(&modlinkage, modinfop));
17247c478bd9Sstevel@tonic-gate }
17257c478bd9Sstevel@tonic-gate 
17267c478bd9Sstevel@tonic-gate /* ARGSUSED */
17277c478bd9Sstevel@tonic-gate static int
17287c478bd9Sstevel@tonic-gate dprov_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
17297c478bd9Sstevel@tonic-gate {
17307c478bd9Sstevel@tonic-gate 	int instance = getminor((dev_t)arg);
17317c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
17327c478bd9Sstevel@tonic-gate 
17337c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_getinfo() for %d\n",
17347c478bd9Sstevel@tonic-gate 	    instance));
17357c478bd9Sstevel@tonic-gate 
17367c478bd9Sstevel@tonic-gate 	switch (cmd) {
17377c478bd9Sstevel@tonic-gate 	case DDI_INFO_DEVT2DEVINFO:
17387c478bd9Sstevel@tonic-gate 		softc = ddi_get_soft_state(statep, instance);
17397c478bd9Sstevel@tonic-gate 		*result = softc->ds_dip;
17407c478bd9Sstevel@tonic-gate 		return (DDI_SUCCESS);
17417c478bd9Sstevel@tonic-gate 
17427c478bd9Sstevel@tonic-gate 	case DDI_INFO_DEVT2INSTANCE:
17437c478bd9Sstevel@tonic-gate 		*result = (void *)(uintptr_t)instance;
17447c478bd9Sstevel@tonic-gate 		return (DDI_SUCCESS);
17457c478bd9Sstevel@tonic-gate 	}
17467c478bd9Sstevel@tonic-gate 	return (DDI_FAILURE);
17477c478bd9Sstevel@tonic-gate }
17487c478bd9Sstevel@tonic-gate 
17497c478bd9Sstevel@tonic-gate static int
17507c478bd9Sstevel@tonic-gate dprov_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
17517c478bd9Sstevel@tonic-gate {
17527c478bd9Sstevel@tonic-gate 	int instance = ddi_get_instance(dip);
17537c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
17547c478bd9Sstevel@tonic-gate 	char devname[256];
17557c478bd9Sstevel@tonic-gate 	int ret;
17567c478bd9Sstevel@tonic-gate 
17577c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_attach() for %d\n",
17587c478bd9Sstevel@tonic-gate 	    instance));
17597c478bd9Sstevel@tonic-gate 
17607c478bd9Sstevel@tonic-gate 	if (cmd != DDI_ATTACH) {
17617c478bd9Sstevel@tonic-gate 		return (DDI_FAILURE);
17627c478bd9Sstevel@tonic-gate 	}
17637c478bd9Sstevel@tonic-gate 
17647c478bd9Sstevel@tonic-gate 	/* get new softc and initialize it */
17657c478bd9Sstevel@tonic-gate 	if (ddi_soft_state_zalloc(statep, instance) != DDI_SUCCESS)
17667c478bd9Sstevel@tonic-gate 		return (DDI_FAILURE);
17677c478bd9Sstevel@tonic-gate 
17687c478bd9Sstevel@tonic-gate 	softc = ddi_get_soft_state(statep, instance);
17697c478bd9Sstevel@tonic-gate 	mutex_init(&softc->ds_lock, NULL, MUTEX_DRIVER, NULL);
17707c478bd9Sstevel@tonic-gate 	softc->ds_dip = dip;
17717c478bd9Sstevel@tonic-gate 	softc->ds_prov_handle = NULL;
17727c478bd9Sstevel@tonic-gate 
17737c478bd9Sstevel@tonic-gate 	/* create minor node */
1774973f6396Sizick 	(void) sprintf(devname, "dprov%d", instance);
17757c478bd9Sstevel@tonic-gate 	if (ddi_create_minor_node(dip, devname, S_IFCHR, instance,
17767c478bd9Sstevel@tonic-gate 	    DDI_PSEUDO, 0) != DDI_SUCCESS) {
17777c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "attach: failed creating minor node");
17787c478bd9Sstevel@tonic-gate 		mutex_destroy(&softc->ds_lock);
17797c478bd9Sstevel@tonic-gate 		ddi_soft_state_free(statep, instance);
17807c478bd9Sstevel@tonic-gate 		return (DDI_FAILURE);
17817c478bd9Sstevel@tonic-gate 	}
17827c478bd9Sstevel@tonic-gate 
1783034448feSmcpowers 	nostore_key_gen = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1784034448feSmcpowers 	    DDI_PROP_DONTPASS, "nostore_key_gen", 0);
1785034448feSmcpowers 	if (nostore_key_gen != 0) {
1786034448feSmcpowers 		dprov_prov_info.pi_interface_version = CRYPTO_SPI_VERSION_3;
1787034448feSmcpowers 		dprov_crypto_ops.co_object_ops = NULL;
1788034448feSmcpowers 		dprov_crypto_ops.co_nostore_key_ops = &dprov_nostore_key_ops;
1789034448feSmcpowers 	}
1790034448feSmcpowers 
1791ba5f469cSkrishna 	dprov_max_digestsz = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1792ba5f469cSkrishna 	    DDI_PROP_DONTPASS, "max_digest_sz", INT_MAX);
1793ba5f469cSkrishna 	if (dprov_max_digestsz != INT_MAX && dprov_max_digestsz != 0 &&
1794ba5f469cSkrishna 	    dprov_max_digestsz != DDI_PROP_NOT_FOUND) {
1795ba5f469cSkrishna 		dprov_no_multipart = B_TRUE;
17964df55fdeSJanie Lu 		dprov_prov_info.pi_flags |=
17974df55fdeSJanie Lu 		    (CRYPTO_HASH_NO_UPDATE | CRYPTO_HMAC_NO_UPDATE);
1798ba5f469cSkrishna 	}
1799ba5f469cSkrishna 
18007c478bd9Sstevel@tonic-gate 	/* create taskq */
18017c478bd9Sstevel@tonic-gate 	softc->ds_taskq = taskq_create(devname, 1, minclsyspri,
18027c478bd9Sstevel@tonic-gate 	    crypto_taskq_minalloc, crypto_taskq_maxalloc, TASKQ_PREPOPULATE);
18037c478bd9Sstevel@tonic-gate 
18047c478bd9Sstevel@tonic-gate 	/* initialize table of sessions */
18057c478bd9Sstevel@tonic-gate 	softc->ds_sessions = kmem_zalloc(DPROV_MIN_SESSIONS *
18067c478bd9Sstevel@tonic-gate 	    sizeof (dprov_session_t *), KM_SLEEP);
18077c478bd9Sstevel@tonic-gate 	softc->ds_sessions_slots = DPROV_MIN_SESSIONS;
18087c478bd9Sstevel@tonic-gate 	softc->ds_sessions_count = 0;
18097c478bd9Sstevel@tonic-gate 
18107c478bd9Sstevel@tonic-gate 	/* initialized done by init_token entry point */
18117c478bd9Sstevel@tonic-gate 	softc->ds_token_initialized = B_TRUE;
18127c478bd9Sstevel@tonic-gate 
1813894b2776Smcpowers 	(void) memset(softc->ds_label, ' ', CRYPTO_EXT_SIZE_LABEL);
1814894b2776Smcpowers 	bcopy("Dummy Pseudo HW Provider", softc->ds_label, 24);
1815894b2776Smcpowers 
18167c478bd9Sstevel@tonic-gate 	bcopy("changeme", softc->ds_user_pin, 8);
18177c478bd9Sstevel@tonic-gate 	softc->ds_user_pin_len = 8;
18187c478bd9Sstevel@tonic-gate 	softc->ds_user_pin_set = B_TRUE;
18197c478bd9Sstevel@tonic-gate 
18207c478bd9Sstevel@tonic-gate 	/* register with the crypto framework */
18217c478bd9Sstevel@tonic-gate 	dprov_prov_info.pi_provider_dev.pd_hw = dip;
18227c478bd9Sstevel@tonic-gate 	dprov_prov_info.pi_provider_handle = softc;
1823ba5f469cSkrishna 
1824ba5f469cSkrishna 	if (dprov_no_multipart) { /* Export only single part */
1825ba5f469cSkrishna 		dprov_digest_ops.digest_update = NULL;
1826ba5f469cSkrishna 		dprov_digest_ops.digest_key = NULL;
1827ba5f469cSkrishna 		dprov_digest_ops.digest_final = NULL;
1828ba5f469cSkrishna 		dprov_object_ops.object_create = NULL;
1829ba5f469cSkrishna 	}
1830ba5f469cSkrishna 
18317c478bd9Sstevel@tonic-gate 	if ((ret = crypto_register_provider(&dprov_prov_info,
18327c478bd9Sstevel@tonic-gate 	    &softc->ds_prov_handle)) != CRYPTO_SUCCESS) {
18337c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN,
18347c478bd9Sstevel@tonic-gate 		    "dprov crypto_register_provider() failed (0x%x)", ret);
18357c478bd9Sstevel@tonic-gate 		taskq_destroy(softc->ds_taskq);
18367c478bd9Sstevel@tonic-gate 		kmem_free(softc->ds_sessions, softc->ds_sessions_slots *
18377c478bd9Sstevel@tonic-gate 		    sizeof (dprov_session_t *));
18387c478bd9Sstevel@tonic-gate 		mutex_destroy(&softc->ds_lock);
18397c478bd9Sstevel@tonic-gate 		ddi_soft_state_free(statep, instance);
18407c478bd9Sstevel@tonic-gate 		ddi_remove_minor_node(dip, NULL);
18417c478bd9Sstevel@tonic-gate 		return (DDI_FAILURE);
18427c478bd9Sstevel@tonic-gate 	}
18437c478bd9Sstevel@tonic-gate 
18447c478bd9Sstevel@tonic-gate 	/*
18457c478bd9Sstevel@tonic-gate 	 * This call is for testing only; it is not required by the SPI.
18467c478bd9Sstevel@tonic-gate 	 */
18477c478bd9Sstevel@tonic-gate 	crypto_provider_notification(softc->ds_prov_handle,
18487c478bd9Sstevel@tonic-gate 	    CRYPTO_PROVIDER_READY);
18497c478bd9Sstevel@tonic-gate 
18507c478bd9Sstevel@tonic-gate 	return (DDI_SUCCESS);
18517c478bd9Sstevel@tonic-gate }
18527c478bd9Sstevel@tonic-gate 
18537c478bd9Sstevel@tonic-gate static int
18547c478bd9Sstevel@tonic-gate dprov_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
18557c478bd9Sstevel@tonic-gate {
18567c478bd9Sstevel@tonic-gate 	int instance = ddi_get_instance(dip);
18577c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = ddi_get_soft_state(statep, instance);
18587c478bd9Sstevel@tonic-gate 	dprov_session_t *session;
18597c478bd9Sstevel@tonic-gate 	int i, ret;
18607c478bd9Sstevel@tonic-gate 
18617c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_detach() for %d\n",
18627c478bd9Sstevel@tonic-gate 	    instance));
18637c478bd9Sstevel@tonic-gate 
18647c478bd9Sstevel@tonic-gate 	if (cmd != DDI_DETACH)
18657c478bd9Sstevel@tonic-gate 		return (DDI_FAILURE);
18667c478bd9Sstevel@tonic-gate 
18677c478bd9Sstevel@tonic-gate 	/* unregister from the crypto framework */
18687c478bd9Sstevel@tonic-gate 	if (softc->ds_prov_handle != NULL)
18697c478bd9Sstevel@tonic-gate 		if ((ret = crypto_unregister_provider(
18707c478bd9Sstevel@tonic-gate 		    softc->ds_prov_handle)) != CRYPTO_SUCCESS) {
18717c478bd9Sstevel@tonic-gate 			cmn_err(CE_WARN, "dprov_detach: "
18727c478bd9Sstevel@tonic-gate 			    "crypto_unregister_provider() "
18737c478bd9Sstevel@tonic-gate 			    "failed (0x%x)", ret);
18747c478bd9Sstevel@tonic-gate 			return (DDI_FAILURE);
18757c478bd9Sstevel@tonic-gate 		}
18767c478bd9Sstevel@tonic-gate 
18777c478bd9Sstevel@tonic-gate 
18787c478bd9Sstevel@tonic-gate 	taskq_destroy(softc->ds_taskq);
18797c478bd9Sstevel@tonic-gate 
18807c478bd9Sstevel@tonic-gate 	for (i = 0; i < softc->ds_sessions_slots; i++) {
18817c478bd9Sstevel@tonic-gate 		if ((session = softc->ds_sessions[i]) == NULL)
18827c478bd9Sstevel@tonic-gate 			continue;
18837c478bd9Sstevel@tonic-gate 
18847c478bd9Sstevel@tonic-gate 		dprov_release_session_objects(session);
18857c478bd9Sstevel@tonic-gate 
18867c478bd9Sstevel@tonic-gate 		kmem_free(session, sizeof (dprov_session_t));
18877c478bd9Sstevel@tonic-gate 		softc->ds_sessions_count--;
18887c478bd9Sstevel@tonic-gate 
18897c478bd9Sstevel@tonic-gate 	}
18907c478bd9Sstevel@tonic-gate 
18917c478bd9Sstevel@tonic-gate 	kmem_free(softc->ds_sessions, softc->ds_sessions_slots *
18927c478bd9Sstevel@tonic-gate 	    sizeof (dprov_session_t *));
18937c478bd9Sstevel@tonic-gate 	/* free token objects */
18947c478bd9Sstevel@tonic-gate 	for (i = 0; i < DPROV_MAX_OBJECTS; i++)
18957c478bd9Sstevel@tonic-gate 		if (softc->ds_objects[i] != NULL)
18967c478bd9Sstevel@tonic-gate 			dprov_free_object(softc->ds_objects[i]);
18977c478bd9Sstevel@tonic-gate 
18987c478bd9Sstevel@tonic-gate 	mutex_destroy(&softc->ds_lock);
18997c478bd9Sstevel@tonic-gate 	ddi_soft_state_free(statep, instance);
19007c478bd9Sstevel@tonic-gate 
19017c478bd9Sstevel@tonic-gate 	ddi_remove_minor_node(dip, NULL);
19027c478bd9Sstevel@tonic-gate 
19037c478bd9Sstevel@tonic-gate 	return (DDI_SUCCESS);
19047c478bd9Sstevel@tonic-gate }
19057c478bd9Sstevel@tonic-gate 
19067c478bd9Sstevel@tonic-gate /*
19077c478bd9Sstevel@tonic-gate  * Control entry points.
19087c478bd9Sstevel@tonic-gate  */
19097c478bd9Sstevel@tonic-gate static void
19107c478bd9Sstevel@tonic-gate dprov_provider_status(crypto_provider_handle_t provider, uint_t *status)
19117c478bd9Sstevel@tonic-gate {
19127c478bd9Sstevel@tonic-gate 	_NOTE(ARGUNUSED(provider))
19137c478bd9Sstevel@tonic-gate 
19147c478bd9Sstevel@tonic-gate 	*status = CRYPTO_PROVIDER_READY;
19157c478bd9Sstevel@tonic-gate }
19167c478bd9Sstevel@tonic-gate 
19177c478bd9Sstevel@tonic-gate /*
19187c478bd9Sstevel@tonic-gate  * Digest entry points.
19197c478bd9Sstevel@tonic-gate  */
19207c478bd9Sstevel@tonic-gate 
19217c478bd9Sstevel@tonic-gate static int
19227c478bd9Sstevel@tonic-gate dprov_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
19237c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
19247c478bd9Sstevel@tonic-gate {
19257c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
19267c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
19277c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
19287c478bd9Sstevel@tonic-gate 	int instance;
19297c478bd9Sstevel@tonic-gate 
19307c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
19317c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
19327c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_init: started\n", instance));
19337c478bd9Sstevel@tonic-gate 
19347c478bd9Sstevel@tonic-gate 	/* check mechanism */
19355151fb12Sdarrenm 	if (mechanism->cm_type != MD4_MECH_INFO_TYPE &&
19365151fb12Sdarrenm 	    mechanism->cm_type != MD5_MECH_INFO_TYPE &&
19377c478bd9Sstevel@tonic-gate 	    mechanism->cm_type != SHA1_MECH_INFO_TYPE &&
19387c478bd9Sstevel@tonic-gate 	    mechanism->cm_type != SHA256_MECH_INFO_TYPE &&
19397c478bd9Sstevel@tonic-gate 	    mechanism->cm_type != SHA384_MECH_INFO_TYPE &&
19407c478bd9Sstevel@tonic-gate 	    mechanism->cm_type != SHA512_MECH_INFO_TYPE) {
19417c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_digest_init: unexpected mech type "
19427c478bd9Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
19437c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
19447c478bd9Sstevel@tonic-gate 	}
19457c478bd9Sstevel@tonic-gate 
19467c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
19477c478bd9Sstevel@tonic-gate 	error = dprov_digest_submit_req(DPROV_REQ_DIGEST_INIT, softc, req,
19487c478bd9Sstevel@tonic-gate 	    mechanism, NULL, NULL, NULL, ctx, KM_SLEEP);
19497c478bd9Sstevel@tonic-gate 
19507c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_init: done err = 0x%x\n",
19517c478bd9Sstevel@tonic-gate 	    instance, error));
19527c478bd9Sstevel@tonic-gate 
19537c478bd9Sstevel@tonic-gate 	return (error);
19547c478bd9Sstevel@tonic-gate }
19557c478bd9Sstevel@tonic-gate 
19567c478bd9Sstevel@tonic-gate static int
19577c478bd9Sstevel@tonic-gate dprov_digest(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *digest,
19587c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
19597c478bd9Sstevel@tonic-gate {
19607c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
19617c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
19627c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
19637c478bd9Sstevel@tonic-gate 	int instance;
19647c478bd9Sstevel@tonic-gate 
1965ba5f469cSkrishna 	if (dprov_no_multipart && data->cd_length > dprov_max_digestsz)
1966ba5f469cSkrishna 		return (CRYPTO_BUFFER_TOO_BIG);
1967ba5f469cSkrishna 
19687c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
19697c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
19707c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest: started\n", instance));
19717c478bd9Sstevel@tonic-gate 
19727c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
19737c478bd9Sstevel@tonic-gate 	error = dprov_digest_submit_req(DPROV_REQ_DIGEST, softc, req,
19747c478bd9Sstevel@tonic-gate 	    NULL, data, NULL, digest, ctx, KM_NOSLEEP);
19757c478bd9Sstevel@tonic-gate 
19767c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest: done, err = 0x%x\n",
19777c478bd9Sstevel@tonic-gate 	    instance, error));
19787c478bd9Sstevel@tonic-gate 
19797c478bd9Sstevel@tonic-gate 	return (error);
19807c478bd9Sstevel@tonic-gate }
19817c478bd9Sstevel@tonic-gate 
19827c478bd9Sstevel@tonic-gate static int
19837c478bd9Sstevel@tonic-gate dprov_digest_update(crypto_ctx_t *ctx, crypto_data_t *data,
19847c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
19857c478bd9Sstevel@tonic-gate {
19867c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
19877c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
19887c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
19897c478bd9Sstevel@tonic-gate 	int instance;
19907c478bd9Sstevel@tonic-gate 
19917c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
19927c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
19937c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_update: started\n",
19947c478bd9Sstevel@tonic-gate 	    instance));
19957c478bd9Sstevel@tonic-gate 
19967c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
19977c478bd9Sstevel@tonic-gate 	error = dprov_digest_submit_req(DPROV_REQ_DIGEST_UPDATE, softc,
19987c478bd9Sstevel@tonic-gate 	    req, NULL, data, NULL, NULL, ctx, KM_NOSLEEP);
19997c478bd9Sstevel@tonic-gate 
20007c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_update: done err = 0x0%x\n",
20017c478bd9Sstevel@tonic-gate 	    instance, error));
20027c478bd9Sstevel@tonic-gate 
20037c478bd9Sstevel@tonic-gate 	return (error);
20047c478bd9Sstevel@tonic-gate }
20057c478bd9Sstevel@tonic-gate 
20067c478bd9Sstevel@tonic-gate static int
20077c478bd9Sstevel@tonic-gate dprov_digest_key(crypto_ctx_t *ctx, crypto_key_t *key, crypto_req_handle_t req)
20087c478bd9Sstevel@tonic-gate {
20097c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
20107c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
20117c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
20127c478bd9Sstevel@tonic-gate 	int instance;
20137c478bd9Sstevel@tonic-gate 
20147c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
20157c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
20167c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_key: started\n", instance));
20177c478bd9Sstevel@tonic-gate 
20187c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
20197c478bd9Sstevel@tonic-gate 	error = dprov_digest_submit_req(DPROV_REQ_DIGEST_KEY, softc, req, NULL,
20207c478bd9Sstevel@tonic-gate 	    NULL, key, NULL, ctx, KM_NOSLEEP);
20217c478bd9Sstevel@tonic-gate 
20227c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_key: done err = 0x0%x\n",
20237c478bd9Sstevel@tonic-gate 	    instance, error));
20247c478bd9Sstevel@tonic-gate 
20257c478bd9Sstevel@tonic-gate 	return (error);
20267c478bd9Sstevel@tonic-gate }
20277c478bd9Sstevel@tonic-gate 
20287c478bd9Sstevel@tonic-gate static int
20297c478bd9Sstevel@tonic-gate dprov_digest_final(crypto_ctx_t *ctx, crypto_data_t *digest,
20307c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
20317c478bd9Sstevel@tonic-gate {
20327c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
20337c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
20347c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
20357c478bd9Sstevel@tonic-gate 	int instance;
20367c478bd9Sstevel@tonic-gate 
20377c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
20387c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
20397c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_final: started\n", instance));
20407c478bd9Sstevel@tonic-gate 
20417c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
20427c478bd9Sstevel@tonic-gate 	error = dprov_digest_submit_req(DPROV_REQ_DIGEST_FINAL, softc, req,
20437c478bd9Sstevel@tonic-gate 	    NULL, NULL, NULL, digest, ctx, KM_NOSLEEP);
20447c478bd9Sstevel@tonic-gate 
20457c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_final: done err = 0x0%x\n",
20467c478bd9Sstevel@tonic-gate 	    instance, error));
20477c478bd9Sstevel@tonic-gate 
20487c478bd9Sstevel@tonic-gate 	return (error);
20497c478bd9Sstevel@tonic-gate }
20507c478bd9Sstevel@tonic-gate 
20517c478bd9Sstevel@tonic-gate /* ARGSUSED */
20527c478bd9Sstevel@tonic-gate static int
20537c478bd9Sstevel@tonic-gate dprov_digest_atomic(crypto_provider_handle_t provider,
20547c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
20557c478bd9Sstevel@tonic-gate     crypto_data_t *data, crypto_data_t *digest,
20567c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
20577c478bd9Sstevel@tonic-gate {
20587c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
20597c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
20607c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
20617c478bd9Sstevel@tonic-gate 	int instance;
20627c478bd9Sstevel@tonic-gate 
2063ba5f469cSkrishna 	if (dprov_no_multipart && data->cd_length > dprov_max_digestsz)
2064ba5f469cSkrishna 		return (CRYPTO_BUFFER_TOO_BIG);
2065ba5f469cSkrishna 
20667c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
20677c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_atomic: started\n",
20687c478bd9Sstevel@tonic-gate 	    instance));
20697c478bd9Sstevel@tonic-gate 
20707c478bd9Sstevel@tonic-gate 	/* check mechanism */
20715151fb12Sdarrenm 	if (mechanism->cm_type != MD4_MECH_INFO_TYPE &&
20725151fb12Sdarrenm 	    mechanism->cm_type != MD5_MECH_INFO_TYPE &&
20737c478bd9Sstevel@tonic-gate 	    mechanism->cm_type != SHA1_MECH_INFO_TYPE &&
20747c478bd9Sstevel@tonic-gate 	    mechanism->cm_type != SHA256_MECH_INFO_TYPE &&
20757c478bd9Sstevel@tonic-gate 	    mechanism->cm_type != SHA384_MECH_INFO_TYPE &&
20767c478bd9Sstevel@tonic-gate 	    mechanism->cm_type != SHA512_MECH_INFO_TYPE) {
20777c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_digest_atomic: unexpected mech type "
20787c478bd9Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
20797c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
20807c478bd9Sstevel@tonic-gate 	}
20817c478bd9Sstevel@tonic-gate 
20827c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
20837c478bd9Sstevel@tonic-gate 	error = dprov_digest_submit_req(DPROV_REQ_DIGEST_ATOMIC, softc, req,
20847c478bd9Sstevel@tonic-gate 	    mechanism, data, NULL, digest, NULL, KM_SLEEP);
20857c478bd9Sstevel@tonic-gate 
20867c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_atomic: done err = 0x0%x\n",
20877c478bd9Sstevel@tonic-gate 	    instance, error));
20887c478bd9Sstevel@tonic-gate 
20897c478bd9Sstevel@tonic-gate 	return (error);
20907c478bd9Sstevel@tonic-gate }
20917c478bd9Sstevel@tonic-gate 
20927c478bd9Sstevel@tonic-gate /*
20937c478bd9Sstevel@tonic-gate  * MAC entry points.
20947c478bd9Sstevel@tonic-gate  */
20957c478bd9Sstevel@tonic-gate 
20967c478bd9Sstevel@tonic-gate /*
20977c478bd9Sstevel@tonic-gate  * Checks whether the specified mech_type is supported by mac
20987c478bd9Sstevel@tonic-gate  * entry points.
20997c478bd9Sstevel@tonic-gate  */
21007c478bd9Sstevel@tonic-gate static boolean_t
21017c478bd9Sstevel@tonic-gate dprov_valid_mac_mech(crypto_mech_type_t mech_type)
21027c478bd9Sstevel@tonic-gate {
21037c478bd9Sstevel@tonic-gate 	return (mech_type == MD5_HMAC_MECH_INFO_TYPE ||
21047c478bd9Sstevel@tonic-gate 	    mech_type == MD5_HMAC_GEN_MECH_INFO_TYPE ||
21057c478bd9Sstevel@tonic-gate 	    mech_type == SHA1_HMAC_MECH_INFO_TYPE ||
21067c478bd9Sstevel@tonic-gate 	    mech_type == SHA1_HMAC_GEN_MECH_INFO_TYPE ||
21077c478bd9Sstevel@tonic-gate 	    mech_type == SHA256_HMAC_MECH_INFO_TYPE ||
21087c478bd9Sstevel@tonic-gate 	    mech_type == SHA256_HMAC_GEN_MECH_INFO_TYPE ||
21097c478bd9Sstevel@tonic-gate 	    mech_type == SHA384_HMAC_MECH_INFO_TYPE ||
21107c478bd9Sstevel@tonic-gate 	    mech_type == SHA384_HMAC_GEN_MECH_INFO_TYPE ||
21117c478bd9Sstevel@tonic-gate 	    mech_type == SHA512_HMAC_MECH_INFO_TYPE ||
2112983a1033SMark Powers 	    mech_type == SHA512_HMAC_GEN_MECH_INFO_TYPE ||
2113983a1033SMark Powers 	    mech_type == AES_GMAC_MECH_INFO_TYPE);
21147c478bd9Sstevel@tonic-gate }
21157c478bd9Sstevel@tonic-gate 
21167c478bd9Sstevel@tonic-gate static int
21177c478bd9Sstevel@tonic-gate dprov_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
21187c478bd9Sstevel@tonic-gate     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
21197c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
21207c478bd9Sstevel@tonic-gate {
21217c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
21227c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
21237c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
21247c478bd9Sstevel@tonic-gate 	int instance;
21257c478bd9Sstevel@tonic-gate 
21267c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
21277c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
21287c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_init: started\n", instance));
21297c478bd9Sstevel@tonic-gate 
21307c478bd9Sstevel@tonic-gate 	/* check mechanism */
21317c478bd9Sstevel@tonic-gate 	if (!dprov_valid_mac_mech(mechanism->cm_type)) {
21327c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_mac_init: unexpected mech type "
21337c478bd9Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
21347c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
21357c478bd9Sstevel@tonic-gate 	}
21367c478bd9Sstevel@tonic-gate 
21377c478bd9Sstevel@tonic-gate 	if (ctx_template != NULL)
21387c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
21397c478bd9Sstevel@tonic-gate 
21407c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
21417c478bd9Sstevel@tonic-gate 	error = dprov_mac_submit_req(DPROV_REQ_MAC_INIT, softc, req,
21427c478bd9Sstevel@tonic-gate 	    mechanism, NULL, key, NULL, ctx, 0, KM_SLEEP);
21437c478bd9Sstevel@tonic-gate 
21447c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_init: done err = 0x%x\n",
21457c478bd9Sstevel@tonic-gate 	    instance, error));
21467c478bd9Sstevel@tonic-gate 
21477c478bd9Sstevel@tonic-gate 	return (error);
21487c478bd9Sstevel@tonic-gate }
21497c478bd9Sstevel@tonic-gate 
21507c478bd9Sstevel@tonic-gate static int
21517c478bd9Sstevel@tonic-gate dprov_mac(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *mac,
21527c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
21537c478bd9Sstevel@tonic-gate {
21547c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
21557c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
21567c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
21577c478bd9Sstevel@tonic-gate 	int instance;
21587c478bd9Sstevel@tonic-gate 
21597c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
21607c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
21617c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac: started\n", instance));
21627c478bd9Sstevel@tonic-gate 
21637c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
21647c478bd9Sstevel@tonic-gate 	error = dprov_mac_submit_req(DPROV_REQ_MAC, softc, req,
21657c478bd9Sstevel@tonic-gate 	    NULL, data, NULL, mac, ctx, 0, KM_NOSLEEP);
21667c478bd9Sstevel@tonic-gate 
21677c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac: done, err = 0x%x\n", instance,
21687c478bd9Sstevel@tonic-gate 	    error));
21697c478bd9Sstevel@tonic-gate 
21707c478bd9Sstevel@tonic-gate 	return (error);
21717c478bd9Sstevel@tonic-gate }
21727c478bd9Sstevel@tonic-gate 
21737c478bd9Sstevel@tonic-gate static int
21747c478bd9Sstevel@tonic-gate dprov_mac_update(crypto_ctx_t *ctx, crypto_data_t *data,
21757c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
21767c478bd9Sstevel@tonic-gate {
21777c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
21787c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
21797c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
21807c478bd9Sstevel@tonic-gate 	int instance;
21817c478bd9Sstevel@tonic-gate 
21827c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
21837c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
21847c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_update: started\n", instance));
21857c478bd9Sstevel@tonic-gate 
21867c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
21877c478bd9Sstevel@tonic-gate 	error = dprov_mac_submit_req(DPROV_REQ_MAC_UPDATE, softc,
21887c478bd9Sstevel@tonic-gate 	    req, NULL, data, NULL, NULL, ctx, 0, KM_NOSLEEP);
21897c478bd9Sstevel@tonic-gate 
21907c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_update: done err = 0x0%x\n",
21917c478bd9Sstevel@tonic-gate 	    instance, error));
21927c478bd9Sstevel@tonic-gate 
21937c478bd9Sstevel@tonic-gate 	return (error);
21947c478bd9Sstevel@tonic-gate }
21957c478bd9Sstevel@tonic-gate 
21967c478bd9Sstevel@tonic-gate static int
21977c478bd9Sstevel@tonic-gate dprov_mac_final(crypto_ctx_t *ctx, crypto_data_t *mac, crypto_req_handle_t req)
21987c478bd9Sstevel@tonic-gate {
21997c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
22007c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
22017c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
22027c478bd9Sstevel@tonic-gate 	int instance;
22037c478bd9Sstevel@tonic-gate 
22047c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
22057c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
22067c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_final: started\n", instance));
22077c478bd9Sstevel@tonic-gate 
22087c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
22097c478bd9Sstevel@tonic-gate 	error = dprov_mac_submit_req(DPROV_REQ_MAC_FINAL, softc, req,
22107c478bd9Sstevel@tonic-gate 	    NULL, NULL, NULL, mac, ctx, 0, KM_NOSLEEP);
22117c478bd9Sstevel@tonic-gate 
22127c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_final: done err = 0x0%x\n",
22137c478bd9Sstevel@tonic-gate 	    instance, error));
22147c478bd9Sstevel@tonic-gate 
22157c478bd9Sstevel@tonic-gate 	return (error);
22167c478bd9Sstevel@tonic-gate }
22177c478bd9Sstevel@tonic-gate 
22187c478bd9Sstevel@tonic-gate static int
22197c478bd9Sstevel@tonic-gate dprov_mac_atomic(crypto_provider_handle_t provider,
22207c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
22217c478bd9Sstevel@tonic-gate     crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
22227c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
22237c478bd9Sstevel@tonic-gate {
22247c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
22257c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
22267c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
22277c478bd9Sstevel@tonic-gate 	int instance;
22287c478bd9Sstevel@tonic-gate 
22297c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
22307c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_atomic: started\n", instance));
22317c478bd9Sstevel@tonic-gate 
22327c478bd9Sstevel@tonic-gate 	if (ctx_template != NULL)
22337c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
22347c478bd9Sstevel@tonic-gate 
22357c478bd9Sstevel@tonic-gate 	/* check mechanism */
22367c478bd9Sstevel@tonic-gate 	if (!dprov_valid_mac_mech(mechanism->cm_type)) {
22377c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_mac_atomic: unexpected mech type "
22387c478bd9Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
22397c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
22407c478bd9Sstevel@tonic-gate 	}
22417c478bd9Sstevel@tonic-gate 
22427c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
22437c478bd9Sstevel@tonic-gate 	error = dprov_mac_submit_req(DPROV_REQ_MAC_ATOMIC, softc, req,
22447c478bd9Sstevel@tonic-gate 	    mechanism, data, key, mac, NULL, session_id, KM_SLEEP);
22457c478bd9Sstevel@tonic-gate 
22467c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_atomic: done err = 0x0%x\n",
22477c478bd9Sstevel@tonic-gate 	    instance, error));
22487c478bd9Sstevel@tonic-gate 
22497c478bd9Sstevel@tonic-gate 	return (error);
22507c478bd9Sstevel@tonic-gate }
22517c478bd9Sstevel@tonic-gate 
22527c478bd9Sstevel@tonic-gate static int
22537c478bd9Sstevel@tonic-gate dprov_mac_verify_atomic(crypto_provider_handle_t provider,
22547c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
22557c478bd9Sstevel@tonic-gate     crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
22567c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
22577c478bd9Sstevel@tonic-gate {
22587c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
22597c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
22607c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
22617c478bd9Sstevel@tonic-gate 	int instance;
22627c478bd9Sstevel@tonic-gate 
22637c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
22647c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_verify_atomic: started\n",
22657c478bd9Sstevel@tonic-gate 	    instance));
22667c478bd9Sstevel@tonic-gate 
22677c478bd9Sstevel@tonic-gate 	if (ctx_template != NULL)
22687c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
22697c478bd9Sstevel@tonic-gate 
22707c478bd9Sstevel@tonic-gate 	/* check mechanism */
22717c478bd9Sstevel@tonic-gate 	if (!dprov_valid_mac_mech(mechanism->cm_type)) {
22727c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_mac_verify_atomic: unexpected mech "
22737c478bd9Sstevel@tonic-gate 		    "type 0x%llx\n", (unsigned long long)mechanism->cm_type);
22747c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
22757c478bd9Sstevel@tonic-gate 	}
22767c478bd9Sstevel@tonic-gate 
22777c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
22787c478bd9Sstevel@tonic-gate 	error = dprov_mac_submit_req(DPROV_REQ_MAC_VERIFY_ATOMIC, softc, req,
22797c478bd9Sstevel@tonic-gate 	    mechanism, data, key, mac, NULL, session_id, KM_SLEEP);
22807c478bd9Sstevel@tonic-gate 
22817c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_verify_atomic: done err = 0x0%x\n",
22827c478bd9Sstevel@tonic-gate 	    instance, error));
22837c478bd9Sstevel@tonic-gate 
22847c478bd9Sstevel@tonic-gate 	return (error);
22857c478bd9Sstevel@tonic-gate }
22867c478bd9Sstevel@tonic-gate 
22877c478bd9Sstevel@tonic-gate /*
22887c478bd9Sstevel@tonic-gate  * Cipher (encrypt/decrypt) entry points.
22897c478bd9Sstevel@tonic-gate  */
22907c478bd9Sstevel@tonic-gate 
22917c478bd9Sstevel@tonic-gate /*
22927c478bd9Sstevel@tonic-gate  * Checks whether the specified mech_type is supported by cipher entry
22937c478bd9Sstevel@tonic-gate  * points.
22947c478bd9Sstevel@tonic-gate  */
22957c478bd9Sstevel@tonic-gate static boolean_t
22967c478bd9Sstevel@tonic-gate dprov_valid_cipher_mech(crypto_mech_type_t mech_type)
22977c478bd9Sstevel@tonic-gate {
22987c478bd9Sstevel@tonic-gate 	return (mech_type == DES_CBC_MECH_INFO_TYPE ||
22997c478bd9Sstevel@tonic-gate 	    mech_type == DES3_CBC_MECH_INFO_TYPE ||
23007c478bd9Sstevel@tonic-gate 	    mech_type == DES_ECB_MECH_INFO_TYPE ||
23017c478bd9Sstevel@tonic-gate 	    mech_type == DES3_ECB_MECH_INFO_TYPE ||
2302f66d273dSizick 	    mech_type == BLOWFISH_CBC_MECH_INFO_TYPE ||
2303f66d273dSizick 	    mech_type == BLOWFISH_ECB_MECH_INFO_TYPE ||
23047c478bd9Sstevel@tonic-gate 	    mech_type == AES_CBC_MECH_INFO_TYPE ||
23057c478bd9Sstevel@tonic-gate 	    mech_type == AES_ECB_MECH_INFO_TYPE ||
2306894b2776Smcpowers 	    mech_type == AES_CTR_MECH_INFO_TYPE ||
23072d864512Sdinak 	    mech_type == AES_CCM_MECH_INFO_TYPE ||
23084d703b5cSMark Powers 	    mech_type == AES_GCM_MECH_INFO_TYPE ||
2309983a1033SMark Powers 	    mech_type == AES_GMAC_MECH_INFO_TYPE ||
23107c478bd9Sstevel@tonic-gate 	    mech_type == RC4_MECH_INFO_TYPE ||
23117c478bd9Sstevel@tonic-gate 	    mech_type == RSA_PKCS_MECH_INFO_TYPE ||
23127c478bd9Sstevel@tonic-gate 	    mech_type == RSA_X_509_MECH_INFO_TYPE ||
23137c478bd9Sstevel@tonic-gate 	    mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE ||
2314f66d273dSizick 	    mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE ||
2315f66d273dSizick 	    mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE ||
2316f66d273dSizick 	    mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE ||
2317f66d273dSizick 	    mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE);
23187c478bd9Sstevel@tonic-gate }
23197c478bd9Sstevel@tonic-gate 
23207c478bd9Sstevel@tonic-gate static boolean_t
23217c478bd9Sstevel@tonic-gate is_publickey_mech(crypto_mech_type_t mech_type)
23227c478bd9Sstevel@tonic-gate {
23237c478bd9Sstevel@tonic-gate 	return (mech_type == RSA_PKCS_MECH_INFO_TYPE ||
23247c478bd9Sstevel@tonic-gate 	    mech_type == RSA_X_509_MECH_INFO_TYPE ||
23257c478bd9Sstevel@tonic-gate 	    mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE ||
2326f66d273dSizick 	    mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE ||
2327f66d273dSizick 	    mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE ||
2328f66d273dSizick 	    mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE ||
2329f9fbec18Smcpowers 	    mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE ||
2330f9fbec18Smcpowers 	    mech_type == ECDSA_SHA1_MECH_INFO_TYPE ||
2331f9fbec18Smcpowers 	    mech_type == ECDSA_MECH_INFO_TYPE);
23327c478bd9Sstevel@tonic-gate }
23337c478bd9Sstevel@tonic-gate 
23347c478bd9Sstevel@tonic-gate 
23357c478bd9Sstevel@tonic-gate /* ARGSUSED */
23367c478bd9Sstevel@tonic-gate static int
23377c478bd9Sstevel@tonic-gate dprov_encrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
23387c478bd9Sstevel@tonic-gate     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
23397c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
23407c478bd9Sstevel@tonic-gate {
23417c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
23427c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
23437c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
23447c478bd9Sstevel@tonic-gate 	int instance;
23457c478bd9Sstevel@tonic-gate 
23467c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
23477c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
23487c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_init: started\n",
23497c478bd9Sstevel@tonic-gate 	    instance));
23507c478bd9Sstevel@tonic-gate 
23517c478bd9Sstevel@tonic-gate 	/* check mechanism */
23527c478bd9Sstevel@tonic-gate 	if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
23537c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_encrypt_init: unexpected mech type "
23547c478bd9Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
23557c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
23567c478bd9Sstevel@tonic-gate 	}
23577c478bd9Sstevel@tonic-gate 
23587c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
23597c478bd9Sstevel@tonic-gate 	error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_INIT, softc,
23607c478bd9Sstevel@tonic-gate 	    req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
23617c478bd9Sstevel@tonic-gate 
23627c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_init: done err = 0x0%x\n",
23637c478bd9Sstevel@tonic-gate 	    instance, error));
23647c478bd9Sstevel@tonic-gate 
23657c478bd9Sstevel@tonic-gate 	return (error);
23667c478bd9Sstevel@tonic-gate }
23677c478bd9Sstevel@tonic-gate 
23687c478bd9Sstevel@tonic-gate /* ARGSUSED */
23697c478bd9Sstevel@tonic-gate static int
23707c478bd9Sstevel@tonic-gate dprov_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
23717c478bd9Sstevel@tonic-gate     crypto_data_t *ciphertext, crypto_req_handle_t req)
23727c478bd9Sstevel@tonic-gate {
23737c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
23747c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
23757c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
23767c478bd9Sstevel@tonic-gate 	int instance;
23777c478bd9Sstevel@tonic-gate 
23787c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
23797c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
23807c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt: started\n", instance));
23817c478bd9Sstevel@tonic-gate 
23827c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
23837c478bd9Sstevel@tonic-gate 	error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT, softc,
23847c478bd9Sstevel@tonic-gate 	    req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
23857c478bd9Sstevel@tonic-gate 
23867c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt: done err = 0x0%x\n",
23877c478bd9Sstevel@tonic-gate 	    instance, error));
23887c478bd9Sstevel@tonic-gate 
23897c478bd9Sstevel@tonic-gate 	return (error);
23907c478bd9Sstevel@tonic-gate }
23917c478bd9Sstevel@tonic-gate 
23927c478bd9Sstevel@tonic-gate /* ARGSUSED */
23937c478bd9Sstevel@tonic-gate static int
23947c478bd9Sstevel@tonic-gate dprov_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
23957c478bd9Sstevel@tonic-gate     crypto_data_t *ciphertext, crypto_req_handle_t req)
23967c478bd9Sstevel@tonic-gate {
23977c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
23987c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
23997c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
24007c478bd9Sstevel@tonic-gate 	int instance;
24017c478bd9Sstevel@tonic-gate 
24027c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
24037c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
24047c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_update: started\n",
24057c478bd9Sstevel@tonic-gate 	    instance));
24067c478bd9Sstevel@tonic-gate 
24077c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
24087c478bd9Sstevel@tonic-gate 	error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_UPDATE, softc,
24097c478bd9Sstevel@tonic-gate 	    req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
24107c478bd9Sstevel@tonic-gate 
24117c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_update: done err = 0x0%x\n",
24127c478bd9Sstevel@tonic-gate 	    instance, error));
24137c478bd9Sstevel@tonic-gate 
24147c478bd9Sstevel@tonic-gate 	return (error);
24157c478bd9Sstevel@tonic-gate }
24167c478bd9Sstevel@tonic-gate 
24177c478bd9Sstevel@tonic-gate /* ARGSUSED */
24187c478bd9Sstevel@tonic-gate static int
24197c478bd9Sstevel@tonic-gate dprov_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
24207c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
24217c478bd9Sstevel@tonic-gate {
24227c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
24237c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
24247c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
24257c478bd9Sstevel@tonic-gate 	int instance;
24267c478bd9Sstevel@tonic-gate 
24277c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
24287c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
24297c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_final: started\n",
24307c478bd9Sstevel@tonic-gate 	    instance));
24317c478bd9Sstevel@tonic-gate 
24327c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
24337c478bd9Sstevel@tonic-gate 	error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_FINAL, softc,
24347c478bd9Sstevel@tonic-gate 	    req, NULL, NULL, NULL, ciphertext, ctx, 0, KM_NOSLEEP);
24357c478bd9Sstevel@tonic-gate 
24367c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_final: done err = 0x0%x\n",
24377c478bd9Sstevel@tonic-gate 	    instance, error));
24387c478bd9Sstevel@tonic-gate 
24397c478bd9Sstevel@tonic-gate 	return (error);
24407c478bd9Sstevel@tonic-gate }
24417c478bd9Sstevel@tonic-gate 
24427c478bd9Sstevel@tonic-gate static int
24437c478bd9Sstevel@tonic-gate dprov_encrypt_atomic(crypto_provider_handle_t provider,
24447c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
24457c478bd9Sstevel@tonic-gate     crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext,
24467c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
24477c478bd9Sstevel@tonic-gate {
24487c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
24497c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
24507c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
24517c478bd9Sstevel@tonic-gate 	int instance;
24527c478bd9Sstevel@tonic-gate 
24537c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
24547c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_encrypt_atomic: started\n", instance));
24557c478bd9Sstevel@tonic-gate 
24567c478bd9Sstevel@tonic-gate 	if (ctx_template != NULL)
24577c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
24587c478bd9Sstevel@tonic-gate 
24597c478bd9Sstevel@tonic-gate 	/* check mechanism */
24607c478bd9Sstevel@tonic-gate 	if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
24617c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_encrypt_atomic: unexpected mech type "
24627c478bd9Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
24637c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
24647c478bd9Sstevel@tonic-gate 	}
24657c478bd9Sstevel@tonic-gate 
24667c478bd9Sstevel@tonic-gate 	error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_ATOMIC, softc,
24677c478bd9Sstevel@tonic-gate 	    req, mechanism, key, plaintext, ciphertext, NULL, session_id,
24687c478bd9Sstevel@tonic-gate 	    KM_SLEEP);
24697c478bd9Sstevel@tonic-gate 
24707c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_encrypt_atomic: done err = 0x0%x\n",
24717c478bd9Sstevel@tonic-gate 	    instance, error));
24727c478bd9Sstevel@tonic-gate 
24737c478bd9Sstevel@tonic-gate 	return (error);
24747c478bd9Sstevel@tonic-gate }
24757c478bd9Sstevel@tonic-gate 
24767c478bd9Sstevel@tonic-gate /* ARGSUSED */
24777c478bd9Sstevel@tonic-gate static int
24787c478bd9Sstevel@tonic-gate dprov_decrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
24797c478bd9Sstevel@tonic-gate     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
24807c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
24817c478bd9Sstevel@tonic-gate {
24827c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
24837c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
24847c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
24857c478bd9Sstevel@tonic-gate 	int instance;
24867c478bd9Sstevel@tonic-gate 
24877c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
24887c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
24897c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_init: started\n",
24907c478bd9Sstevel@tonic-gate 	    instance));
24917c478bd9Sstevel@tonic-gate 
24927c478bd9Sstevel@tonic-gate 	/* check mechanism */
24937c478bd9Sstevel@tonic-gate 	if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
24947c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_decrypt_init: unexpected mech type "
24957c478bd9Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
24967c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
24977c478bd9Sstevel@tonic-gate 	}
24987c478bd9Sstevel@tonic-gate 
24997c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
25007c478bd9Sstevel@tonic-gate 	error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_INIT, softc,
25017c478bd9Sstevel@tonic-gate 	    req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
25027c478bd9Sstevel@tonic-gate 
25037c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_init: done err = 0x0%x\n",
25047c478bd9Sstevel@tonic-gate 	    instance, error));
25057c478bd9Sstevel@tonic-gate 
25067c478bd9Sstevel@tonic-gate 	return (error);
25077c478bd9Sstevel@tonic-gate }
25087c478bd9Sstevel@tonic-gate 
25097c478bd9Sstevel@tonic-gate /* ARGSUSED */
25107c478bd9Sstevel@tonic-gate static int
25117c478bd9Sstevel@tonic-gate dprov_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
25127c478bd9Sstevel@tonic-gate     crypto_data_t *plaintext, crypto_req_handle_t req)
25137c478bd9Sstevel@tonic-gate {
25147c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
25157c478bd9Sstevel@tonic-gate 
25167c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
25177c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
25187c478bd9Sstevel@tonic-gate 	int instance;
25197c478bd9Sstevel@tonic-gate 
25207c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
25217c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
25227c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt: started\n", instance));
25237c478bd9Sstevel@tonic-gate 
25247c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
25257c478bd9Sstevel@tonic-gate 	error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT, softc,
25267c478bd9Sstevel@tonic-gate 	    req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
25277c478bd9Sstevel@tonic-gate 
25287c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt: done err = 0x0%x\n",
25297c478bd9Sstevel@tonic-gate 	    instance, error));
25307c478bd9Sstevel@tonic-gate 
25317c478bd9Sstevel@tonic-gate 	return (error);
25327c478bd9Sstevel@tonic-gate }
25337c478bd9Sstevel@tonic-gate 
25347c478bd9Sstevel@tonic-gate /* ARGSUSED */
25357c478bd9Sstevel@tonic-gate static int
25367c478bd9Sstevel@tonic-gate dprov_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
25377c478bd9Sstevel@tonic-gate     crypto_data_t *plaintext, crypto_req_handle_t req)
25387c478bd9Sstevel@tonic-gate {
25397c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
25407c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
25417c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
25427c478bd9Sstevel@tonic-gate 	int instance;
25437c478bd9Sstevel@tonic-gate 
25447c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
25457c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
25467c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_update: started\n",
25477c478bd9Sstevel@tonic-gate 	    instance));
25487c478bd9Sstevel@tonic-gate 
25497c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
25507c478bd9Sstevel@tonic-gate 	error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_UPDATE, softc,
25517c478bd9Sstevel@tonic-gate 	    req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
25527c478bd9Sstevel@tonic-gate 
25537c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_update: done err = 0x0%x\n",
25547c478bd9Sstevel@tonic-gate 	    instance, error));
25557c478bd9Sstevel@tonic-gate 
25567c478bd9Sstevel@tonic-gate 	return (error);
25577c478bd9Sstevel@tonic-gate }
25587c478bd9Sstevel@tonic-gate 
25597c478bd9Sstevel@tonic-gate /* ARGSUSED */
25607c478bd9Sstevel@tonic-gate static int
25617c478bd9Sstevel@tonic-gate dprov_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *plaintext,
25627c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
25637c478bd9Sstevel@tonic-gate {
25647c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
25657c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
25667c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
25677c478bd9Sstevel@tonic-gate 	int instance;
25687c478bd9Sstevel@tonic-gate 
25697c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
25707c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
25717c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_final: started\n",
25727c478bd9Sstevel@tonic-gate 	    instance));
25737c478bd9Sstevel@tonic-gate 
25747c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
25757c478bd9Sstevel@tonic-gate 	error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_FINAL, softc,
25767c478bd9Sstevel@tonic-gate 	    req, NULL, NULL, plaintext, NULL, ctx, 0, KM_NOSLEEP);
25777c478bd9Sstevel@tonic-gate 
25787c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_final: done err = 0x0%x\n",
25797c478bd9Sstevel@tonic-gate 	    instance, error));
25807c478bd9Sstevel@tonic-gate 
25817c478bd9Sstevel@tonic-gate 	return (error);
25827c478bd9Sstevel@tonic-gate }
25837c478bd9Sstevel@tonic-gate 
25847c478bd9Sstevel@tonic-gate static int
25857c478bd9Sstevel@tonic-gate dprov_decrypt_atomic(crypto_provider_handle_t provider,
25867c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
25877c478bd9Sstevel@tonic-gate     crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext,
25887c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
25897c478bd9Sstevel@tonic-gate {
25907c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
25917c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
25927c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
25937c478bd9Sstevel@tonic-gate 	int instance;
25947c478bd9Sstevel@tonic-gate 
25957c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
25967c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_decrypt_atomic: started\n", instance));
25977c478bd9Sstevel@tonic-gate 
25987c478bd9Sstevel@tonic-gate 	if (ctx_template != NULL)
25997c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
26007c478bd9Sstevel@tonic-gate 
26017c478bd9Sstevel@tonic-gate 	/* check mechanism */
26027c478bd9Sstevel@tonic-gate 	if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
26037c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_atomic_init: unexpected mech type "
26047c478bd9Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
26057c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
26067c478bd9Sstevel@tonic-gate 	}
26077c478bd9Sstevel@tonic-gate 
26087c478bd9Sstevel@tonic-gate 	error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_ATOMIC, softc,
26097c478bd9Sstevel@tonic-gate 	    req, mechanism, key, plaintext, ciphertext, NULL, session_id,
26107c478bd9Sstevel@tonic-gate 	    KM_SLEEP);
26117c478bd9Sstevel@tonic-gate 
26127c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_decrypt_atomic: done err = 0x0%x\n",
26137c478bd9Sstevel@tonic-gate 	    instance, error));
26147c478bd9Sstevel@tonic-gate 
26157c478bd9Sstevel@tonic-gate 	return (error);
26167c478bd9Sstevel@tonic-gate }
26177c478bd9Sstevel@tonic-gate 
26187c478bd9Sstevel@tonic-gate /*
26197c478bd9Sstevel@tonic-gate  * Sign entry points.
26207c478bd9Sstevel@tonic-gate  */
26217c478bd9Sstevel@tonic-gate 
26227c478bd9Sstevel@tonic-gate /*
26237c478bd9Sstevel@tonic-gate  * Checks whether the specified mech_type is supported by sign/verify
26247c478bd9Sstevel@tonic-gate  * entry points.
26257c478bd9Sstevel@tonic-gate  */
26267c478bd9Sstevel@tonic-gate static boolean_t
26277c478bd9Sstevel@tonic-gate dprov_valid_sign_verif_mech(crypto_mech_type_t mech_type)
26287c478bd9Sstevel@tonic-gate {
26297c478bd9Sstevel@tonic-gate 	return (mech_type == MD5_HMAC_MECH_INFO_TYPE ||
26307c478bd9Sstevel@tonic-gate 	    mech_type == MD5_HMAC_GEN_MECH_INFO_TYPE ||
2631ba5f469cSkrishna 	    mech_type == SHA1_HMAC_MECH_INFO_TYPE ||
2632ba5f469cSkrishna 	    mech_type == SHA1_HMAC_GEN_MECH_INFO_TYPE ||
2633ba5f469cSkrishna 	    mech_type == SHA256_HMAC_MECH_INFO_TYPE ||
2634ba5f469cSkrishna 	    mech_type == SHA256_HMAC_GEN_MECH_INFO_TYPE ||
2635ba5f469cSkrishna 	    mech_type == SHA384_HMAC_MECH_INFO_TYPE ||
2636ba5f469cSkrishna 	    mech_type == SHA384_HMAC_GEN_MECH_INFO_TYPE ||
2637ba5f469cSkrishna 	    mech_type == SHA512_HMAC_MECH_INFO_TYPE ||
2638ba5f469cSkrishna 	    mech_type == SHA512_HMAC_GEN_MECH_INFO_TYPE ||
26397c478bd9Sstevel@tonic-gate 	    mech_type == RSA_PKCS_MECH_INFO_TYPE ||
26407c478bd9Sstevel@tonic-gate 	    mech_type == RSA_X_509_MECH_INFO_TYPE ||
26417c478bd9Sstevel@tonic-gate 	    mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE ||
2642f66d273dSizick 	    mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE ||
2643f66d273dSizick 	    mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE ||
2644f66d273dSizick 	    mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE ||
2645f9fbec18Smcpowers 	    mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE ||
2646f9fbec18Smcpowers 	    mech_type == ECDSA_SHA1_MECH_INFO_TYPE ||
2647f9fbec18Smcpowers 	    mech_type == ECDSA_MECH_INFO_TYPE);
26487c478bd9Sstevel@tonic-gate }
26497c478bd9Sstevel@tonic-gate 
26507c478bd9Sstevel@tonic-gate static int
26517c478bd9Sstevel@tonic-gate dprov_sign_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
26527c478bd9Sstevel@tonic-gate     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
26537c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
26547c478bd9Sstevel@tonic-gate {
26557c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
26567c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
26577c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
26587c478bd9Sstevel@tonic-gate 	int instance;
26597c478bd9Sstevel@tonic-gate 
26607c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
26617c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
26627c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_init: started\n", instance));
26637c478bd9Sstevel@tonic-gate 
26647c478bd9Sstevel@tonic-gate 	/* check mechanism */
26657c478bd9Sstevel@tonic-gate 	if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
26667c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_sign_init: unexpected mech type "
26677c478bd9Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
26687c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
26697c478bd9Sstevel@tonic-gate 	}
26707c478bd9Sstevel@tonic-gate 
26717c478bd9Sstevel@tonic-gate 	if (ctx_template != NULL)
26727c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
26737c478bd9Sstevel@tonic-gate 
26747c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
26757c478bd9Sstevel@tonic-gate 	error = dprov_sign_submit_req(DPROV_REQ_SIGN_INIT, softc, req,
26767c478bd9Sstevel@tonic-gate 	    mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
26777c478bd9Sstevel@tonic-gate 
26787c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_init: done err = 0x%x\n",
26797c478bd9Sstevel@tonic-gate 	    instance, error));
26807c478bd9Sstevel@tonic-gate 
26817c478bd9Sstevel@tonic-gate 	return (error);
26827c478bd9Sstevel@tonic-gate }
26837c478bd9Sstevel@tonic-gate 
26847c478bd9Sstevel@tonic-gate static int
26857c478bd9Sstevel@tonic-gate dprov_sign(crypto_ctx_t *ctx, crypto_data_t *data,
26867c478bd9Sstevel@tonic-gate     crypto_data_t *signature, crypto_req_handle_t req)
26877c478bd9Sstevel@tonic-gate {
26887c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
26897c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
26907c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
26917c478bd9Sstevel@tonic-gate 	int instance;
26927c478bd9Sstevel@tonic-gate 
26937c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
26947c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
26957c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign: started\n", instance));
26967c478bd9Sstevel@tonic-gate 
26977c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
26987c478bd9Sstevel@tonic-gate 	error = dprov_sign_submit_req(DPROV_REQ_SIGN, softc, req,
26997c478bd9Sstevel@tonic-gate 	    NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
27007c478bd9Sstevel@tonic-gate 
27017c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign: done err = 0x%x\n",
27027c478bd9Sstevel@tonic-gate 	    instance, error));
27037c478bd9Sstevel@tonic-gate 
27047c478bd9Sstevel@tonic-gate 	return (error);
27057c478bd9Sstevel@tonic-gate }
27067c478bd9Sstevel@tonic-gate 
27077c478bd9Sstevel@tonic-gate static int
27087c478bd9Sstevel@tonic-gate dprov_sign_update(crypto_ctx_t *ctx, crypto_data_t *data,
27097c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
27107c478bd9Sstevel@tonic-gate {
27117c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
27127c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
27137c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
27147c478bd9Sstevel@tonic-gate 	int instance;
27157c478bd9Sstevel@tonic-gate 
27167c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
27177c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
27187c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_update: started\n", instance));
27197c478bd9Sstevel@tonic-gate 
27207c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
27217c478bd9Sstevel@tonic-gate 	error = dprov_sign_submit_req(DPROV_REQ_SIGN_UPDATE, softc, req,
27227c478bd9Sstevel@tonic-gate 	    NULL, NULL, data, NULL, ctx, 0, KM_NOSLEEP);
27237c478bd9Sstevel@tonic-gate 
27247c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_update: done err = 0x%x\n",
27257c478bd9Sstevel@tonic-gate 	    instance, error));
27267c478bd9Sstevel@tonic-gate 
27277c478bd9Sstevel@tonic-gate 	return (error);
27287c478bd9Sstevel@tonic-gate }
27297c478bd9Sstevel@tonic-gate 
27307c478bd9Sstevel@tonic-gate static int
27317c478bd9Sstevel@tonic-gate dprov_sign_final(crypto_ctx_t *ctx, crypto_data_t *signature,
27327c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
27337c478bd9Sstevel@tonic-gate {
27347c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
27357c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
27367c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
27377c478bd9Sstevel@tonic-gate 	int instance;
27387c478bd9Sstevel@tonic-gate 
27397c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
27407c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
27417c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_final: started\n", instance));
27427c478bd9Sstevel@tonic-gate 
27437c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
27447c478bd9Sstevel@tonic-gate 	error = dprov_sign_submit_req(DPROV_REQ_SIGN_FINAL, softc, req,
27457c478bd9Sstevel@tonic-gate 	    NULL, NULL, NULL, signature, ctx, 0, KM_NOSLEEP);
27467c478bd9Sstevel@tonic-gate 
27477c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_final: done err = 0x%x\n",
27487c478bd9Sstevel@tonic-gate 	    instance, error));
27497c478bd9Sstevel@tonic-gate 
27507c478bd9Sstevel@tonic-gate 	return (error);
27517c478bd9Sstevel@tonic-gate }
27527c478bd9Sstevel@tonic-gate 
27537c478bd9Sstevel@tonic-gate static int
27547c478bd9Sstevel@tonic-gate dprov_sign_atomic(crypto_provider_handle_t provider,
27557c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
27567c478bd9Sstevel@tonic-gate     crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature,
27577c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
27587c478bd9Sstevel@tonic-gate {
27597c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
27607c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
27617c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
27627c478bd9Sstevel@tonic-gate 	int instance;
27637c478bd9Sstevel@tonic-gate 
27647c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
27657c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_atomic: started\n", instance));
27667c478bd9Sstevel@tonic-gate 
27677c478bd9Sstevel@tonic-gate 	/* check mechanism */
27687c478bd9Sstevel@tonic-gate 	if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
27697c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_sign_atomic: unexpected mech type "
27707c478bd9Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
27717c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
27727c478bd9Sstevel@tonic-gate 	}
27737c478bd9Sstevel@tonic-gate 
27747c478bd9Sstevel@tonic-gate 	if (ctx_template != NULL)
27757c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
27767c478bd9Sstevel@tonic-gate 
27777c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
27787c478bd9Sstevel@tonic-gate 	error = dprov_sign_submit_req(DPROV_REQ_SIGN_ATOMIC, softc, req,
27797c478bd9Sstevel@tonic-gate 	    mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
27807c478bd9Sstevel@tonic-gate 
27817c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_atomic: done err = 0x%x\n",
27827c478bd9Sstevel@tonic-gate 	    instance, error));
27837c478bd9Sstevel@tonic-gate 
27847c478bd9Sstevel@tonic-gate 	return (error);
27857c478bd9Sstevel@tonic-gate }
27867c478bd9Sstevel@tonic-gate 
27877c478bd9Sstevel@tonic-gate static int
27887c478bd9Sstevel@tonic-gate dprov_sign_recover_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
27897c478bd9Sstevel@tonic-gate     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
27907c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
27917c478bd9Sstevel@tonic-gate {
27927c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
27937c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
27947c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
27957c478bd9Sstevel@tonic-gate 	int instance;
27967c478bd9Sstevel@tonic-gate 
27977c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
27987c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
27997c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_init: started\n",
28007c478bd9Sstevel@tonic-gate 	    instance));
28017c478bd9Sstevel@tonic-gate 
28027c478bd9Sstevel@tonic-gate 	if (ctx_template != NULL)
28037c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
28047c478bd9Sstevel@tonic-gate 
28057c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
28067c478bd9Sstevel@tonic-gate 	error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER_INIT, softc, req,
28077c478bd9Sstevel@tonic-gate 	    mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
28087c478bd9Sstevel@tonic-gate 
28097c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_init: done err = 0x%x\n",
28107c478bd9Sstevel@tonic-gate 	    instance, error));
28117c478bd9Sstevel@tonic-gate 
28127c478bd9Sstevel@tonic-gate 	return (error);
28137c478bd9Sstevel@tonic-gate }
28147c478bd9Sstevel@tonic-gate 
28157c478bd9Sstevel@tonic-gate static int
28167c478bd9Sstevel@tonic-gate dprov_sign_recover(crypto_ctx_t *ctx, crypto_data_t *data,
28177c478bd9Sstevel@tonic-gate     crypto_data_t *signature, crypto_req_handle_t req)
28187c478bd9Sstevel@tonic-gate {
28197c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
28207c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
28217c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
28227c478bd9Sstevel@tonic-gate 	int instance;
28237c478bd9Sstevel@tonic-gate 
28247c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
28257c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
28267c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover: started\n", instance));
28277c478bd9Sstevel@tonic-gate 
28287c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
28297c478bd9Sstevel@tonic-gate 	error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER, softc, req,
28307c478bd9Sstevel@tonic-gate 	    NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
28317c478bd9Sstevel@tonic-gate 
28327c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover: done err = 0x%x\n",
28337c478bd9Sstevel@tonic-gate 	    instance, error));
28347c478bd9Sstevel@tonic-gate 
28357c478bd9Sstevel@tonic-gate 	return (error);
28367c478bd9Sstevel@tonic-gate }
28377c478bd9Sstevel@tonic-gate 
28387c478bd9Sstevel@tonic-gate static int
28397c478bd9Sstevel@tonic-gate dprov_sign_recover_atomic(crypto_provider_handle_t provider,
28407c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
28417c478bd9Sstevel@tonic-gate     crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature,
28427c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
28437c478bd9Sstevel@tonic-gate {
28447c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
28457c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
28467c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
28477c478bd9Sstevel@tonic-gate 	int instance;
28487c478bd9Sstevel@tonic-gate 
28497c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
28507c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_atomic: started\n",
28517c478bd9Sstevel@tonic-gate 	    instance));
28527c478bd9Sstevel@tonic-gate 
28537c478bd9Sstevel@tonic-gate 	if (ctx_template != NULL)
28547c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
28557c478bd9Sstevel@tonic-gate 
28567c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
28577c478bd9Sstevel@tonic-gate 	error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER_ATOMIC, softc, req,
28587c478bd9Sstevel@tonic-gate 	    mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
28597c478bd9Sstevel@tonic-gate 
28607c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_atomic: done "
28617c478bd9Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
28627c478bd9Sstevel@tonic-gate 
28637c478bd9Sstevel@tonic-gate 	return (error);
28647c478bd9Sstevel@tonic-gate }
28657c478bd9Sstevel@tonic-gate 
28667c478bd9Sstevel@tonic-gate /*
28677c478bd9Sstevel@tonic-gate  * Verify entry points.
28687c478bd9Sstevel@tonic-gate  */
28697c478bd9Sstevel@tonic-gate 
28707c478bd9Sstevel@tonic-gate static int
28717c478bd9Sstevel@tonic-gate dprov_verify_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
28727c478bd9Sstevel@tonic-gate     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
28737c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
28747c478bd9Sstevel@tonic-gate {
28757c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
28767c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
28777c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
28787c478bd9Sstevel@tonic-gate 	int instance;
28797c478bd9Sstevel@tonic-gate 
28807c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
28817c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
28827c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_init: started\n", instance));
28837c478bd9Sstevel@tonic-gate 
28847c478bd9Sstevel@tonic-gate 	/* check mechanism */
28857c478bd9Sstevel@tonic-gate 	if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
28867c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_verify_init: unexpected mech type "
28877c478bd9Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
28887c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
28897c478bd9Sstevel@tonic-gate 	}
28907c478bd9Sstevel@tonic-gate 
28917c478bd9Sstevel@tonic-gate 	if (ctx_template != NULL)
28927c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
28937c478bd9Sstevel@tonic-gate 
28947c478bd9Sstevel@tonic-gate 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY_INIT, softc, req,
28957c478bd9Sstevel@tonic-gate 	    mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
28967c478bd9Sstevel@tonic-gate 
28977c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_init: done err = 0x%x\n",
28987c478bd9Sstevel@tonic-gate 	    instance, error));
28997c478bd9Sstevel@tonic-gate 
29007c478bd9Sstevel@tonic-gate 	return (error);
29017c478bd9Sstevel@tonic-gate }
29027c478bd9Sstevel@tonic-gate 
29037c478bd9Sstevel@tonic-gate static int
29047c478bd9Sstevel@tonic-gate dprov_verify(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature,
29057c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
29067c478bd9Sstevel@tonic-gate {
29077c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
29087c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
29097c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
29107c478bd9Sstevel@tonic-gate 	int instance;
29117c478bd9Sstevel@tonic-gate 
29127c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
29137c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
29147c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify: started\n", instance));
29157c478bd9Sstevel@tonic-gate 
29167c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
29177c478bd9Sstevel@tonic-gate 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY, softc, req,
29187c478bd9Sstevel@tonic-gate 	    NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
29197c478bd9Sstevel@tonic-gate 
29207c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify: done err = 0x%x\n",
29217c478bd9Sstevel@tonic-gate 	    instance, error));
29227c478bd9Sstevel@tonic-gate 
29237c478bd9Sstevel@tonic-gate 	return (error);
29247c478bd9Sstevel@tonic-gate }
29257c478bd9Sstevel@tonic-gate 
29267c478bd9Sstevel@tonic-gate static int
29277c478bd9Sstevel@tonic-gate dprov_verify_update(crypto_ctx_t *ctx, crypto_data_t *data,
29287c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
29297c478bd9Sstevel@tonic-gate {
29307c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
29317c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
29327c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
29337c478bd9Sstevel@tonic-gate 	int instance;
29347c478bd9Sstevel@tonic-gate 
29357c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
29367c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
29377c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_update: started\n",
29387c478bd9Sstevel@tonic-gate 	    instance));
29397c478bd9Sstevel@tonic-gate 
29407c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
29417c478bd9Sstevel@tonic-gate 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY_UPDATE, softc, req,
29427c478bd9Sstevel@tonic-gate 	    NULL, NULL, data, NULL, ctx, 0, KM_NOSLEEP);
29437c478bd9Sstevel@tonic-gate 
29447c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_update: done err = 0x%x\n",
29457c478bd9Sstevel@tonic-gate 	    instance, error));
29467c478bd9Sstevel@tonic-gate 
29477c478bd9Sstevel@tonic-gate 	return (error);
29487c478bd9Sstevel@tonic-gate }
29497c478bd9Sstevel@tonic-gate 
29507c478bd9Sstevel@tonic-gate static int
29517c478bd9Sstevel@tonic-gate dprov_verify_final(crypto_ctx_t *ctx, crypto_data_t *signature,
29527c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
29537c478bd9Sstevel@tonic-gate {
29547c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
29557c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
29567c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
29577c478bd9Sstevel@tonic-gate 	int instance;
29587c478bd9Sstevel@tonic-gate 
29597c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
29607c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
29617c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_final: started\n", instance));
29627c478bd9Sstevel@tonic-gate 
29637c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
29647c478bd9Sstevel@tonic-gate 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY_FINAL, softc, req,
29657c478bd9Sstevel@tonic-gate 	    NULL, NULL, NULL, signature, ctx, 0, KM_NOSLEEP);
29667c478bd9Sstevel@tonic-gate 
29677c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_final: done err = 0x%x\n",
29687c478bd9Sstevel@tonic-gate 	    instance, error));
29697c478bd9Sstevel@tonic-gate 
29707c478bd9Sstevel@tonic-gate 	return (error);
29717c478bd9Sstevel@tonic-gate }
29727c478bd9Sstevel@tonic-gate 
29737c478bd9Sstevel@tonic-gate static int
29747c478bd9Sstevel@tonic-gate dprov_verify_atomic(crypto_provider_handle_t provider,
29757c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
29767c478bd9Sstevel@tonic-gate     crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature,
29777c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
29787c478bd9Sstevel@tonic-gate {
29797c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
29807c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
29817c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
29827c478bd9Sstevel@tonic-gate 	int instance;
29837c478bd9Sstevel@tonic-gate 
29847c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
29857c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_atomic: started\n",
29867c478bd9Sstevel@tonic-gate 	    instance));
29877c478bd9Sstevel@tonic-gate 
29887c478bd9Sstevel@tonic-gate 	/* check mechanism */
29897c478bd9Sstevel@tonic-gate 	if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
29907c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_verify_atomic: unexpected mech type "
29917c478bd9Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
29927c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
29937c478bd9Sstevel@tonic-gate 	}
29947c478bd9Sstevel@tonic-gate 
29957c478bd9Sstevel@tonic-gate 	if (ctx_template != NULL)
29967c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
29977c478bd9Sstevel@tonic-gate 
29987c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
29997c478bd9Sstevel@tonic-gate 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY_ATOMIC, softc, req,
30007c478bd9Sstevel@tonic-gate 	    mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
30017c478bd9Sstevel@tonic-gate 
30027c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_atomic: done err = 0x%x\n",
30037c478bd9Sstevel@tonic-gate 	    instance, error));
30047c478bd9Sstevel@tonic-gate 
30057c478bd9Sstevel@tonic-gate 	return (error);
30067c478bd9Sstevel@tonic-gate }
30077c478bd9Sstevel@tonic-gate 
30087c478bd9Sstevel@tonic-gate static int
30097c478bd9Sstevel@tonic-gate dprov_verify_recover_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
30107c478bd9Sstevel@tonic-gate     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
30117c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
30127c478bd9Sstevel@tonic-gate {
30137c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
30147c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
30157c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
30167c478bd9Sstevel@tonic-gate 	int instance;
30177c478bd9Sstevel@tonic-gate 
30187c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
30197c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
30207c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_init: started\n",
30217c478bd9Sstevel@tonic-gate 	    instance));
30227c478bd9Sstevel@tonic-gate 
30237c478bd9Sstevel@tonic-gate 	if (ctx_template != NULL)
30247c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
30257c478bd9Sstevel@tonic-gate 
30267c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
30277c478bd9Sstevel@tonic-gate 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER_INIT, softc,
30287c478bd9Sstevel@tonic-gate 	    req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
30297c478bd9Sstevel@tonic-gate 
30307c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_init: done "
30317c478bd9Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
30327c478bd9Sstevel@tonic-gate 
30337c478bd9Sstevel@tonic-gate 	return (error);
30347c478bd9Sstevel@tonic-gate }
30357c478bd9Sstevel@tonic-gate 
30367c478bd9Sstevel@tonic-gate static int
30377c478bd9Sstevel@tonic-gate dprov_verify_recover(crypto_ctx_t *ctx, crypto_data_t *signature,
30387c478bd9Sstevel@tonic-gate     crypto_data_t *data, crypto_req_handle_t req)
30397c478bd9Sstevel@tonic-gate {
30407c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
30417c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
30427c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
30437c478bd9Sstevel@tonic-gate 	int instance;
30447c478bd9Sstevel@tonic-gate 
30457c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
30467c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
30477c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover: started\n",
30487c478bd9Sstevel@tonic-gate 	    instance));
30497c478bd9Sstevel@tonic-gate 
30507c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
30517c478bd9Sstevel@tonic-gate 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER, softc, req,
30527c478bd9Sstevel@tonic-gate 	    NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
30537c478bd9Sstevel@tonic-gate 
30547c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover: done err = 0x%x\n",
30557c478bd9Sstevel@tonic-gate 	    instance, error));
30567c478bd9Sstevel@tonic-gate 
30577c478bd9Sstevel@tonic-gate 	return (error);
30587c478bd9Sstevel@tonic-gate }
30597c478bd9Sstevel@tonic-gate 
30607c478bd9Sstevel@tonic-gate static int
30617c478bd9Sstevel@tonic-gate dprov_verify_recover_atomic(crypto_provider_handle_t provider,
30627c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
30637c478bd9Sstevel@tonic-gate     crypto_key_t *key, crypto_data_t *signature, crypto_data_t *data,
30647c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
30657c478bd9Sstevel@tonic-gate {
30667c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
30677c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
30687c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
30697c478bd9Sstevel@tonic-gate 	int instance;
30707c478bd9Sstevel@tonic-gate 
30717c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
30727c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_atomic: started\n",
30737c478bd9Sstevel@tonic-gate 	    instance));
30747c478bd9Sstevel@tonic-gate 
30757c478bd9Sstevel@tonic-gate 	if (ctx_template != NULL)
30767c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
30777c478bd9Sstevel@tonic-gate 
30787c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
30797c478bd9Sstevel@tonic-gate 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER_ATOMIC, softc,
30807c478bd9Sstevel@tonic-gate 	    req, mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
30817c478bd9Sstevel@tonic-gate 
30827c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_atomic: done "
30837c478bd9Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
30847c478bd9Sstevel@tonic-gate 
30857c478bd9Sstevel@tonic-gate 	return (error);
30867c478bd9Sstevel@tonic-gate }
30877c478bd9Sstevel@tonic-gate 
30887c478bd9Sstevel@tonic-gate /*
30897c478bd9Sstevel@tonic-gate  * Dual operations entry points.
30907c478bd9Sstevel@tonic-gate  */
30917c478bd9Sstevel@tonic-gate 
30927c478bd9Sstevel@tonic-gate static int
30937c478bd9Sstevel@tonic-gate dprov_digest_encrypt_update(crypto_ctx_t *digest_ctx,
30947c478bd9Sstevel@tonic-gate     crypto_ctx_t *encrypt_ctx, crypto_data_t *plaintext,
30957c478bd9Sstevel@tonic-gate     crypto_data_t *ciphertext, crypto_req_handle_t req)
30967c478bd9Sstevel@tonic-gate {
30977c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
30987c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
30997c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
31007c478bd9Sstevel@tonic-gate 	int instance;
31017c478bd9Sstevel@tonic-gate 
31027c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
31037c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(digest_ctx, softc, instance);
31047c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_digest_encrypt_update: started\n",
31057c478bd9Sstevel@tonic-gate 	    instance));
31067c478bd9Sstevel@tonic-gate 
31077c478bd9Sstevel@tonic-gate 	if (digest_ctx->cc_provider != encrypt_ctx->cc_provider)
31087c478bd9Sstevel@tonic-gate 		return (CRYPTO_INVALID_CONTEXT);
31097c478bd9Sstevel@tonic-gate 
31107c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
31117c478bd9Sstevel@tonic-gate 	error = dprov_dual_submit_req(DPROV_REQ_DIGEST_ENCRYPT_UPDATE,
31127c478bd9Sstevel@tonic-gate 	    softc, req, digest_ctx, encrypt_ctx, plaintext, ciphertext);
31137c478bd9Sstevel@tonic-gate 
31147c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_digest_encrypt_update: done "
31157c478bd9Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
31167c478bd9Sstevel@tonic-gate 
31177c478bd9Sstevel@tonic-gate 	return (error);
31187c478bd9Sstevel@tonic-gate }
31197c478bd9Sstevel@tonic-gate 
31207c478bd9Sstevel@tonic-gate static int
31217c478bd9Sstevel@tonic-gate dprov_decrypt_digest_update(crypto_ctx_t *decrypt_ctx, crypto_ctx_t *digest_ctx,
31227c478bd9Sstevel@tonic-gate     crypto_data_t *ciphertext, crypto_data_t *plaintext,
31237c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
31247c478bd9Sstevel@tonic-gate {
31257c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
31267c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
31277c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
31287c478bd9Sstevel@tonic-gate 	int instance;
31297c478bd9Sstevel@tonic-gate 
31307c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
31317c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(decrypt_ctx, softc, instance);
31327c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_digest_update: started\n",
31337c478bd9Sstevel@tonic-gate 	    instance));
31347c478bd9Sstevel@tonic-gate 
31357c478bd9Sstevel@tonic-gate 	if (decrypt_ctx->cc_provider != digest_ctx->cc_provider)
31367c478bd9Sstevel@tonic-gate 		return (CRYPTO_INVALID_CONTEXT);
31377c478bd9Sstevel@tonic-gate 
31387c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
31397c478bd9Sstevel@tonic-gate 	error = dprov_dual_submit_req(DPROV_REQ_DECRYPT_DIGEST_UPDATE,
31407c478bd9Sstevel@tonic-gate 	    softc, req, digest_ctx, decrypt_ctx, plaintext, ciphertext);
31417c478bd9Sstevel@tonic-gate 
31427c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_digest_update: done "
31437c478bd9Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
31447c478bd9Sstevel@tonic-gate 
31457c478bd9Sstevel@tonic-gate 	return (error);
31467c478bd9Sstevel@tonic-gate }
31477c478bd9Sstevel@tonic-gate 
31487c478bd9Sstevel@tonic-gate static int
31497c478bd9Sstevel@tonic-gate dprov_sign_encrypt_update(crypto_ctx_t *sign_ctx, crypto_ctx_t *encrypt_ctx,
31507c478bd9Sstevel@tonic-gate     crypto_data_t *plaintext, crypto_data_t *ciphertext,
31517c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
31527c478bd9Sstevel@tonic-gate {
31537c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
31547c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
31557c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
31567c478bd9Sstevel@tonic-gate 	int instance;
31577c478bd9Sstevel@tonic-gate 
31587c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
31597c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(sign_ctx, softc, instance);
31607c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_sign_encrypt_update: started\n",
31617c478bd9Sstevel@tonic-gate 	    instance));
31627c478bd9Sstevel@tonic-gate 
31637c478bd9Sstevel@tonic-gate 	if (sign_ctx->cc_provider != encrypt_ctx->cc_provider)
31647c478bd9Sstevel@tonic-gate 		return (CRYPTO_INVALID_CONTEXT);
31657c478bd9Sstevel@tonic-gate 
31667c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
31677c478bd9Sstevel@tonic-gate 	error = dprov_dual_submit_req(DPROV_REQ_SIGN_ENCRYPT_UPDATE,
31687c478bd9Sstevel@tonic-gate 	    softc, req, sign_ctx, encrypt_ctx, plaintext, ciphertext);
31697c478bd9Sstevel@tonic-gate 
31707c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_sign_encrypt_update: done "
31717c478bd9Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
31727c478bd9Sstevel@tonic-gate 
31737c478bd9Sstevel@tonic-gate 	return (error);
31747c478bd9Sstevel@tonic-gate }
31757c478bd9Sstevel@tonic-gate 
31767c478bd9Sstevel@tonic-gate static int
31777c478bd9Sstevel@tonic-gate dprov_decrypt_verify_update(crypto_ctx_t *decrypt_ctx, crypto_ctx_t *verify_ctx,
31787c478bd9Sstevel@tonic-gate     crypto_data_t *ciphertext, crypto_data_t *plaintext,
31797c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
31807c478bd9Sstevel@tonic-gate {
31817c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
31827c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
31837c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
31847c478bd9Sstevel@tonic-gate 	int instance;
31857c478bd9Sstevel@tonic-gate 
31867c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
31877c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(decrypt_ctx, softc, instance);
31887c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_verify_update: started\n",
31897c478bd9Sstevel@tonic-gate 	    instance));
31907c478bd9Sstevel@tonic-gate 
31917c478bd9Sstevel@tonic-gate 	if (decrypt_ctx->cc_provider != verify_ctx->cc_provider)
31927c478bd9Sstevel@tonic-gate 		return (CRYPTO_INVALID_CONTEXT);
31937c478bd9Sstevel@tonic-gate 
31947c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
31957c478bd9Sstevel@tonic-gate 	error = dprov_dual_submit_req(DPROV_REQ_DECRYPT_VERIFY_UPDATE,
31967c478bd9Sstevel@tonic-gate 	    softc, req, verify_ctx, decrypt_ctx, plaintext, ciphertext);
31977c478bd9Sstevel@tonic-gate 
31987c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_verify_update: done "
31997c478bd9Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
32007c478bd9Sstevel@tonic-gate 
32017c478bd9Sstevel@tonic-gate 	return (error);
32027c478bd9Sstevel@tonic-gate }
32037c478bd9Sstevel@tonic-gate 
32047c478bd9Sstevel@tonic-gate /*
32057c478bd9Sstevel@tonic-gate  * Dual cipher-mac entry points.
32067c478bd9Sstevel@tonic-gate  */
32077c478bd9Sstevel@tonic-gate 
32087c478bd9Sstevel@tonic-gate static int
32097c478bd9Sstevel@tonic-gate dprov_encrypt_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *encrypt_mech,
32107c478bd9Sstevel@tonic-gate     crypto_key_t *encrypt_key, crypto_mechanism_t *mac_mech,
32117c478bd9Sstevel@tonic-gate     crypto_key_t *mac_key, crypto_spi_ctx_template_t encr_ctx_template,
32127c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t mac_ctx_template,
32137c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
32147c478bd9Sstevel@tonic-gate {
32157c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
32167c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
32177c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
32187c478bd9Sstevel@tonic-gate 	int instance;
32197c478bd9Sstevel@tonic-gate 
32207c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
32217c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
32227c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_init: started\n",
32237c478bd9Sstevel@tonic-gate 	    instance));
32247c478bd9Sstevel@tonic-gate 
32257c478bd9Sstevel@tonic-gate 	/* check mechanisms */
32267c478bd9Sstevel@tonic-gate 	if (!dprov_valid_cipher_mech(encrypt_mech->cm_type)) {
32277c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_encrypt_mac_init: unexpected encrypt "
32287c478bd9Sstevel@tonic-gate 		    "mech type 0x%llx\n",
32297c478bd9Sstevel@tonic-gate 		    (unsigned long long)encrypt_mech->cm_type);
32307c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
32317c478bd9Sstevel@tonic-gate 	}
32327c478bd9Sstevel@tonic-gate 	if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
32337c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_encrypt_mac_init: unexpected mac "
32347c478bd9Sstevel@tonic-gate 		    "mech type 0x%llx\n",
32357c478bd9Sstevel@tonic-gate 		    (unsigned long long)mac_mech->cm_type);
32367c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
32377c478bd9Sstevel@tonic-gate 	}
32387c478bd9Sstevel@tonic-gate 
32397c478bd9Sstevel@tonic-gate 	if (encr_ctx_template != NULL || mac_ctx_template != NULL)
32407c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
32417c478bd9Sstevel@tonic-gate 
32427c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
32437c478bd9Sstevel@tonic-gate 	error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_INIT,
32447c478bd9Sstevel@tonic-gate 	    softc, req, ctx, 0, encrypt_mech, encrypt_key, mac_mech, mac_key,
32457c478bd9Sstevel@tonic-gate 	    NULL, NULL, NULL, KM_SLEEP);
32467c478bd9Sstevel@tonic-gate 
32477c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_init: done "
32487c478bd9Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
32497c478bd9Sstevel@tonic-gate 
32507c478bd9Sstevel@tonic-gate 	return (error);
32517c478bd9Sstevel@tonic-gate }
32527c478bd9Sstevel@tonic-gate 
32537c478bd9Sstevel@tonic-gate static int
32547c478bd9Sstevel@tonic-gate dprov_encrypt_mac(crypto_ctx_t *ctx, crypto_data_t *plaintext,
32557c478bd9Sstevel@tonic-gate     crypto_dual_data_t *ciphertext, crypto_data_t *mac, crypto_req_handle_t req)
32567c478bd9Sstevel@tonic-gate {
32577c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
32587c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
32597c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
32607c478bd9Sstevel@tonic-gate 	int instance;
32617c478bd9Sstevel@tonic-gate 
32627c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
32637c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
32647c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac: started\n",
32657c478bd9Sstevel@tonic-gate 	    instance));
32667c478bd9Sstevel@tonic-gate 
32677c478bd9Sstevel@tonic-gate 	/*
32687c478bd9Sstevel@tonic-gate 	 * submit request to the taskq
32697c478bd9Sstevel@tonic-gate 	 * Careful! cihertext/plaintext order inversion
32707c478bd9Sstevel@tonic-gate 	 */
32717c478bd9Sstevel@tonic-gate 	error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC,
32727c478bd9Sstevel@tonic-gate 	    softc, req, ctx, 0, NULL, NULL, NULL, NULL,
32737c478bd9Sstevel@tonic-gate 	    ciphertext, plaintext, mac, KM_NOSLEEP);
32747c478bd9Sstevel@tonic-gate 
32757c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac: done "
32767c478bd9Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
32777c478bd9Sstevel@tonic-gate 
32787c478bd9Sstevel@tonic-gate 	return (error);
32797c478bd9Sstevel@tonic-gate }
32807c478bd9Sstevel@tonic-gate 
32817c478bd9Sstevel@tonic-gate static int
32827c478bd9Sstevel@tonic-gate dprov_encrypt_mac_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
32837c478bd9Sstevel@tonic-gate     crypto_dual_data_t *ciphertext, crypto_req_handle_t req)
32847c478bd9Sstevel@tonic-gate {
32857c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
32867c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
32877c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
32887c478bd9Sstevel@tonic-gate 	int instance;
32897c478bd9Sstevel@tonic-gate 
32907c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
32917c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
32927c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_update: started\n",
32937c478bd9Sstevel@tonic-gate 	    instance));
32947c478bd9Sstevel@tonic-gate 
32957c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
32967c478bd9Sstevel@tonic-gate 	error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_UPDATE,
32977c478bd9Sstevel@tonic-gate 	    softc, req, ctx, 0, NULL, NULL, NULL, NULL,
32987c478bd9Sstevel@tonic-gate 	    ciphertext, plaintext, NULL, KM_NOSLEEP);
32997c478bd9Sstevel@tonic-gate 
33007c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_update: done "
33017c478bd9Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
33027c478bd9Sstevel@tonic-gate 
33037c478bd9Sstevel@tonic-gate 	return (error);
33047c478bd9Sstevel@tonic-gate }
33057c478bd9Sstevel@tonic-gate 
33067c478bd9Sstevel@tonic-gate static int
33077c478bd9Sstevel@tonic-gate dprov_encrypt_mac_final(crypto_ctx_t *ctx,
33087c478bd9Sstevel@tonic-gate     crypto_dual_data_t *ciphertext, crypto_data_t *mac,
33097c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
33107c478bd9Sstevel@tonic-gate {
33117c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
33127c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
33137c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
33147c478bd9Sstevel@tonic-gate 	int instance;
33157c478bd9Sstevel@tonic-gate 
33167c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
33177c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
33187c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_final: started\n",
33197c478bd9Sstevel@tonic-gate 	    instance));
33207c478bd9Sstevel@tonic-gate 
33217c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
33227c478bd9Sstevel@tonic-gate 	error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_FINAL,
33237c478bd9Sstevel@tonic-gate 	    softc, req, ctx, 0, NULL, NULL, NULL, NULL,
33247c478bd9Sstevel@tonic-gate 	    ciphertext, NULL, mac, KM_NOSLEEP);
33257c478bd9Sstevel@tonic-gate 
33267c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_final: done "
33277c478bd9Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
33287c478bd9Sstevel@tonic-gate 
33297c478bd9Sstevel@tonic-gate 	return (error);
33307c478bd9Sstevel@tonic-gate }
33317c478bd9Sstevel@tonic-gate 
33327c478bd9Sstevel@tonic-gate static int
33337c478bd9Sstevel@tonic-gate dprov_encrypt_mac_atomic(crypto_provider_handle_t provider,
33347c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *encrypt_mech,
33357c478bd9Sstevel@tonic-gate     crypto_key_t *encrypt_key, crypto_mechanism_t *mac_mech,
33367c478bd9Sstevel@tonic-gate     crypto_key_t *mac_key, crypto_data_t *plaintext,
33377c478bd9Sstevel@tonic-gate     crypto_dual_data_t *ciphertext, crypto_data_t *mac,
33387c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t encr_ctx_template,
33397c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t mac_ctx_template,
33407c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
33417c478bd9Sstevel@tonic-gate {
33427c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
33437c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
33447c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
33457c478bd9Sstevel@tonic-gate 	int instance;
33467c478bd9Sstevel@tonic-gate 
33477c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
33487c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_atomic: started\n",
33497c478bd9Sstevel@tonic-gate 	    instance));
33507c478bd9Sstevel@tonic-gate 
33517c478bd9Sstevel@tonic-gate 	/* check mechanisms */
33527c478bd9Sstevel@tonic-gate 	if (!dprov_valid_cipher_mech(encrypt_mech->cm_type)) {
33537c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_encrypt_mac_atomic: unexpected encrypt "
33547c478bd9Sstevel@tonic-gate 		    "mech type 0x%llx\n",
33557c478bd9Sstevel@tonic-gate 		    (unsigned long long)encrypt_mech->cm_type);
33567c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
33577c478bd9Sstevel@tonic-gate 	}
33587c478bd9Sstevel@tonic-gate 	if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
33597c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_encrypt_mac_atomic: unexpected mac "
33607c478bd9Sstevel@tonic-gate 		    "mech type 0x%llx\n",
33617c478bd9Sstevel@tonic-gate 		    (unsigned long long)mac_mech->cm_type);
33627c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
33637c478bd9Sstevel@tonic-gate 	}
33647c478bd9Sstevel@tonic-gate 
33657c478bd9Sstevel@tonic-gate 	if (encr_ctx_template != NULL || mac_ctx_template != NULL)
33667c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
33677c478bd9Sstevel@tonic-gate 
33687c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
33697c478bd9Sstevel@tonic-gate 	error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_ATOMIC,
33707c478bd9Sstevel@tonic-gate 	    softc, req, NULL, session_id, encrypt_mech, encrypt_key, mac_mech,
33717c478bd9Sstevel@tonic-gate 	    mac_key, ciphertext, plaintext, mac, KM_SLEEP);
33727c478bd9Sstevel@tonic-gate 
33737c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_atomic: done "
33747c478bd9Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
33757c478bd9Sstevel@tonic-gate 
33767c478bd9Sstevel@tonic-gate 	return (error);
33777c478bd9Sstevel@tonic-gate }
33787c478bd9Sstevel@tonic-gate 
33797c478bd9Sstevel@tonic-gate static int
33807c478bd9Sstevel@tonic-gate dprov_mac_decrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mac_mech,
33817c478bd9Sstevel@tonic-gate     crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech,
33827c478bd9Sstevel@tonic-gate     crypto_key_t *decrypt_key, crypto_spi_ctx_template_t mac_ctx_template,
33837c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t decr_ctx_template,
33847c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
33857c478bd9Sstevel@tonic-gate {
33867c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
33877c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
33887c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
33897c478bd9Sstevel@tonic-gate 	int instance;
33907c478bd9Sstevel@tonic-gate 
33917c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
33927c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
33937c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_init: started\n",
33947c478bd9Sstevel@tonic-gate 	    instance));
33957c478bd9Sstevel@tonic-gate 
33967c478bd9Sstevel@tonic-gate 	/* check mechanisms */
33977c478bd9Sstevel@tonic-gate 	if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) {
33987c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_mac_decrypt_init: unexpected decrypt "
33997c478bd9Sstevel@tonic-gate 		    "mech type 0x%llx\n",
34007c478bd9Sstevel@tonic-gate 		    (unsigned long long)decrypt_mech->cm_type);
34017c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
34027c478bd9Sstevel@tonic-gate 	}
34037c478bd9Sstevel@tonic-gate 	if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
34047c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_mac_decrypt_init: unexpected mac "
34057c478bd9Sstevel@tonic-gate 		    "mech type 0x%llx\n",
34067c478bd9Sstevel@tonic-gate 		    (unsigned long long)mac_mech->cm_type);
34077c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
34087c478bd9Sstevel@tonic-gate 	}
34097c478bd9Sstevel@tonic-gate 
34107c478bd9Sstevel@tonic-gate 	if (decr_ctx_template != NULL || mac_ctx_template != NULL)
34117c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
34127c478bd9Sstevel@tonic-gate 
34137c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
34147c478bd9Sstevel@tonic-gate 	error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_INIT,
34157c478bd9Sstevel@tonic-gate 	    softc, req, ctx, 0, decrypt_mech, decrypt_key, mac_mech, mac_key,
34167c478bd9Sstevel@tonic-gate 	    NULL, NULL, NULL, KM_SLEEP);
34177c478bd9Sstevel@tonic-gate 
34187c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_init: done "
34197c478bd9Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
34207c478bd9Sstevel@tonic-gate 
34217c478bd9Sstevel@tonic-gate 	return (error);
34227c478bd9Sstevel@tonic-gate }
34237c478bd9Sstevel@tonic-gate 
34247c478bd9Sstevel@tonic-gate static int
34257c478bd9Sstevel@tonic-gate dprov_mac_decrypt(crypto_ctx_t *ctx, crypto_dual_data_t *ciphertext,
34267c478bd9Sstevel@tonic-gate     crypto_data_t *mac, crypto_data_t *plaintext, crypto_req_handle_t req)
34277c478bd9Sstevel@tonic-gate {
34287c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
34297c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
34307c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
34317c478bd9Sstevel@tonic-gate 	int instance;
34327c478bd9Sstevel@tonic-gate 
34337c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
34347c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
34357c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt: started\n",
34367c478bd9Sstevel@tonic-gate 	    instance));
34377c478bd9Sstevel@tonic-gate 
34387c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
34397c478bd9Sstevel@tonic-gate 	error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT,
34407c478bd9Sstevel@tonic-gate 	    softc, req, ctx, 0, NULL, NULL, NULL, NULL,
34417c478bd9Sstevel@tonic-gate 	    ciphertext, plaintext, mac, KM_NOSLEEP);
34427c478bd9Sstevel@tonic-gate 
34437c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt: done "
34447c478bd9Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
34457c478bd9Sstevel@tonic-gate 
34467c478bd9Sstevel@tonic-gate 	return (error);
34477c478bd9Sstevel@tonic-gate }
34487c478bd9Sstevel@tonic-gate 
34497c478bd9Sstevel@tonic-gate static int
34507c478bd9Sstevel@tonic-gate dprov_mac_decrypt_update(crypto_ctx_t *ctx, crypto_dual_data_t *ciphertext,
34517c478bd9Sstevel@tonic-gate     crypto_data_t *plaintext, crypto_req_handle_t req)
34527c478bd9Sstevel@tonic-gate {
34537c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
34547c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
34557c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
34567c478bd9Sstevel@tonic-gate 	int instance;
34577c478bd9Sstevel@tonic-gate 
34587c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
34597c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
34607c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_update: started\n",
34617c478bd9Sstevel@tonic-gate 	    instance));
34627c478bd9Sstevel@tonic-gate 
34637c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
34647c478bd9Sstevel@tonic-gate 	error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_UPDATE,
34657c478bd9Sstevel@tonic-gate 	    softc, req, ctx, 0, NULL, NULL, NULL, NULL,
34667c478bd9Sstevel@tonic-gate 	    ciphertext, plaintext, NULL, KM_NOSLEEP);
34677c478bd9Sstevel@tonic-gate 
34687c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_update: done "
34697c478bd9Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
34707c478bd9Sstevel@tonic-gate 
34717c478bd9Sstevel@tonic-gate 	return (error);
34727c478bd9Sstevel@tonic-gate }
34737c478bd9Sstevel@tonic-gate 
34747c478bd9Sstevel@tonic-gate static int
34757c478bd9Sstevel@tonic-gate dprov_mac_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *mac,
34767c478bd9Sstevel@tonic-gate     crypto_data_t *plaintext, crypto_req_handle_t req)
34777c478bd9Sstevel@tonic-gate {
34787c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
34797c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
34807c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
34817c478bd9Sstevel@tonic-gate 	int instance;
34827c478bd9Sstevel@tonic-gate 
34837c478bd9Sstevel@tonic-gate 	/* extract softc and instance number from context */
34847c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
34857c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_final: started\n",
34867c478bd9Sstevel@tonic-gate 	    instance));
34877c478bd9Sstevel@tonic-gate 
34887c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
34897c478bd9Sstevel@tonic-gate 	error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_FINAL,
34907c478bd9Sstevel@tonic-gate 	    softc, req, ctx, 0, NULL, NULL, NULL, NULL,
34917c478bd9Sstevel@tonic-gate 	    NULL, plaintext, mac, KM_NOSLEEP);
34927c478bd9Sstevel@tonic-gate 
34937c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_final: done "
34947c478bd9Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
34957c478bd9Sstevel@tonic-gate 
34967c478bd9Sstevel@tonic-gate 	return (error);
34977c478bd9Sstevel@tonic-gate }
34987c478bd9Sstevel@tonic-gate 
34997c478bd9Sstevel@tonic-gate static int
35007c478bd9Sstevel@tonic-gate dprov_mac_decrypt_atomic(crypto_provider_handle_t provider,
35017c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mac_mech,
35027c478bd9Sstevel@tonic-gate     crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech,
35037c478bd9Sstevel@tonic-gate     crypto_key_t *decrypt_key, crypto_dual_data_t *ciphertext,
35047c478bd9Sstevel@tonic-gate     crypto_data_t *mac, crypto_data_t *plaintext,
35057c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t mac_ctx_template,
35067c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t decr_ctx_template,
35077c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
35087c478bd9Sstevel@tonic-gate {
35097c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
35107c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
35117c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
35127c478bd9Sstevel@tonic-gate 	int instance;
35137c478bd9Sstevel@tonic-gate 
35147c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
35157c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_atomic: started\n",
35167c478bd9Sstevel@tonic-gate 	    instance));
35177c478bd9Sstevel@tonic-gate 
35187c478bd9Sstevel@tonic-gate 	/* check mechanisms */
35197c478bd9Sstevel@tonic-gate 	if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) {
35207c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_mac_decrypt_atomic: unexpected encrypt "
35217c478bd9Sstevel@tonic-gate 		    "mech type 0x%llx\n",
35227c478bd9Sstevel@tonic-gate 		    (unsigned long long)decrypt_mech->cm_type);
35237c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
35247c478bd9Sstevel@tonic-gate 	}
35257c478bd9Sstevel@tonic-gate 	if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
35267c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_mac_decrypt_atomic: unexpected mac "
35277c478bd9Sstevel@tonic-gate 		    "mech type 0x%llx\n",
35287c478bd9Sstevel@tonic-gate 		    (unsigned long long)mac_mech->cm_type);
35297c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
35307c478bd9Sstevel@tonic-gate 	}
35317c478bd9Sstevel@tonic-gate 
35327c478bd9Sstevel@tonic-gate 	if (decr_ctx_template != NULL || mac_ctx_template != NULL)
35337c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
35347c478bd9Sstevel@tonic-gate 
35357c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
35367c478bd9Sstevel@tonic-gate 	error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_ATOMIC,
35377c478bd9Sstevel@tonic-gate 	    softc, req, NULL, session_id, decrypt_mech, decrypt_key, mac_mech,
35387c478bd9Sstevel@tonic-gate 	    mac_key, ciphertext, plaintext, mac, KM_SLEEP);
35397c478bd9Sstevel@tonic-gate 
35407c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_atomic: done "
35417c478bd9Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
35427c478bd9Sstevel@tonic-gate 
35437c478bd9Sstevel@tonic-gate 	return (error);
35447c478bd9Sstevel@tonic-gate }
35457c478bd9Sstevel@tonic-gate 
35467c478bd9Sstevel@tonic-gate static int
35477c478bd9Sstevel@tonic-gate dprov_mac_verify_decrypt_atomic(crypto_provider_handle_t provider,
35487c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mac_mech,
35497c478bd9Sstevel@tonic-gate     crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech,
35507c478bd9Sstevel@tonic-gate     crypto_key_t *decrypt_key, crypto_dual_data_t *ciphertext,
35517c478bd9Sstevel@tonic-gate     crypto_data_t *mac, crypto_data_t *plaintext,
35527c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t mac_ctx_template,
35537c478bd9Sstevel@tonic-gate     crypto_spi_ctx_template_t decr_ctx_template,
35547c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
35557c478bd9Sstevel@tonic-gate {
35567c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
35577c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
35587c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
35597c478bd9Sstevel@tonic-gate 	int instance;
35607c478bd9Sstevel@tonic-gate 
35617c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
35627c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_verify_decrypt_atomic:"
35637c478bd9Sstevel@tonic-gate 	    "started\n", instance));
35647c478bd9Sstevel@tonic-gate 
35657c478bd9Sstevel@tonic-gate 	/* check mechanisms */
35667c478bd9Sstevel@tonic-gate 	if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) {
35677c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_mac_verify_decrypt_atomic: "
35687c478bd9Sstevel@tonic-gate 		    "unexpected encrypt mech type 0x%llx\n",
35697c478bd9Sstevel@tonic-gate 		    (unsigned long long)decrypt_mech->cm_type);
35707c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
35717c478bd9Sstevel@tonic-gate 	}
35727c478bd9Sstevel@tonic-gate 	if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
35737c478bd9Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_mac_verify_decrypt_atomic: "
35747c478bd9Sstevel@tonic-gate 		    "unexpected mac mech type 0x%llx\n",
35757c478bd9Sstevel@tonic-gate 		    (unsigned long long)mac_mech->cm_type);
35767c478bd9Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
35777c478bd9Sstevel@tonic-gate 	}
35787c478bd9Sstevel@tonic-gate 
35797c478bd9Sstevel@tonic-gate 	if (decr_ctx_template != NULL || mac_ctx_template != NULL)
35807c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
35817c478bd9Sstevel@tonic-gate 
35827c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
35837c478bd9Sstevel@tonic-gate 	error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC,
35847c478bd9Sstevel@tonic-gate 	    softc, req, NULL, session_id, decrypt_mech, decrypt_key, mac_mech,
35857c478bd9Sstevel@tonic-gate 	    mac_key, ciphertext, plaintext, mac, KM_SLEEP);
35867c478bd9Sstevel@tonic-gate 
35877c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_verify_decrypt_atomic: done "
35887c478bd9Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
35897c478bd9Sstevel@tonic-gate 
35907c478bd9Sstevel@tonic-gate 	return (error);
35917c478bd9Sstevel@tonic-gate }
35927c478bd9Sstevel@tonic-gate 
35937c478bd9Sstevel@tonic-gate /*
35947c478bd9Sstevel@tonic-gate  * Random number entry points.
35957c478bd9Sstevel@tonic-gate  */
35967c478bd9Sstevel@tonic-gate 
35977c478bd9Sstevel@tonic-gate static int
35987c478bd9Sstevel@tonic-gate dprov_seed_random(crypto_provider_handle_t provider,  crypto_session_id_t sid,
35998047c9fbSmcpowers     uchar_t *buf, size_t len, uint_t entropy_est, uint32_t flags,
36008047c9fbSmcpowers     crypto_req_handle_t req)
36017c478bd9Sstevel@tonic-gate {
36027c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
36037c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
36047c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
36057c478bd9Sstevel@tonic-gate 	int instance;
36067c478bd9Sstevel@tonic-gate 
36077c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
36087c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_RANDOM, ("(%d) dprov_seed_random: started\n",
36097c478bd9Sstevel@tonic-gate 	    instance));
36107c478bd9Sstevel@tonic-gate 
36117c478bd9Sstevel@tonic-gate 	error = dprov_random_submit_req(DPROV_REQ_RANDOM_SEED, softc,
36128047c9fbSmcpowers 	    req, buf, len, sid, entropy_est, flags);
36137c478bd9Sstevel@tonic-gate 
36147c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_RANDOM, ("(%d) dprov_seed_random: done err = 0x0%x\n",
36157c478bd9Sstevel@tonic-gate 	    instance, error));
36167c478bd9Sstevel@tonic-gate 
36177c478bd9Sstevel@tonic-gate 	return (error);
36187c478bd9Sstevel@tonic-gate }
36197c478bd9Sstevel@tonic-gate 
36207c478bd9Sstevel@tonic-gate static int
36217c478bd9Sstevel@tonic-gate dprov_generate_random(crypto_provider_handle_t provider,
36227c478bd9Sstevel@tonic-gate     crypto_session_id_t sid, uchar_t *buf, size_t len, crypto_req_handle_t req)
36237c478bd9Sstevel@tonic-gate {
36247c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
36257c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
36267c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
36277c478bd9Sstevel@tonic-gate 	int instance;
36287c478bd9Sstevel@tonic-gate 
36297c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
36307c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_RANDOM, ("(%d) dprov_generate_random: started\n",
36317c478bd9Sstevel@tonic-gate 	    instance));
36327c478bd9Sstevel@tonic-gate 
36337c478bd9Sstevel@tonic-gate 	error = dprov_random_submit_req(DPROV_REQ_RANDOM_GENERATE, softc,
36348047c9fbSmcpowers 	    req, buf, len, sid, 0, 0);
36357c478bd9Sstevel@tonic-gate 
36367c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_RANDOM, ("(%d) dprov_generate_random: done "
36377c478bd9Sstevel@tonic-gate 	    "err = 0x0%x\n", instance, error));
36387c478bd9Sstevel@tonic-gate 
36397c478bd9Sstevel@tonic-gate 	return (error);
36407c478bd9Sstevel@tonic-gate }
36417c478bd9Sstevel@tonic-gate 
36427c478bd9Sstevel@tonic-gate /*
36437c478bd9Sstevel@tonic-gate  * Session Management entry points.
36447c478bd9Sstevel@tonic-gate  */
36457c478bd9Sstevel@tonic-gate 
36467c478bd9Sstevel@tonic-gate static int
36477c478bd9Sstevel@tonic-gate dprov_session_open(crypto_provider_handle_t provider,
36487c478bd9Sstevel@tonic-gate     crypto_session_id_t *session_id, crypto_req_handle_t req)
36497c478bd9Sstevel@tonic-gate {
36507c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
36517c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
36527c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
36537c478bd9Sstevel@tonic-gate 	int instance;
36547c478bd9Sstevel@tonic-gate 
36557c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
36567c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_open: started\n",
36577c478bd9Sstevel@tonic-gate 	    instance));
36587c478bd9Sstevel@tonic-gate 
36597c478bd9Sstevel@tonic-gate 	error = dprov_session_submit_req(DPROV_REQ_SESSION_OPEN, softc,
36607c478bd9Sstevel@tonic-gate 	    req, session_id, 0, 0, NULL, 0);
36617c478bd9Sstevel@tonic-gate 
36627c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_open: done err = 0x0%x\n",
36637c478bd9Sstevel@tonic-gate 	    instance, error));
36647c478bd9Sstevel@tonic-gate 
36657c478bd9Sstevel@tonic-gate 	return (error);
36667c478bd9Sstevel@tonic-gate }
36677c478bd9Sstevel@tonic-gate 
36687c478bd9Sstevel@tonic-gate static int
36697c478bd9Sstevel@tonic-gate dprov_session_close(crypto_provider_handle_t provider,
36707c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_req_handle_t req)
36717c478bd9Sstevel@tonic-gate {
36727c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
36737c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
36747c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
36757c478bd9Sstevel@tonic-gate 	int instance;
36767c478bd9Sstevel@tonic-gate 
36777c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
36787c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_close: started\n",
36797c478bd9Sstevel@tonic-gate 	    instance));
36807c478bd9Sstevel@tonic-gate 
36817c478bd9Sstevel@tonic-gate 	error = dprov_session_submit_req(DPROV_REQ_SESSION_CLOSE, softc,
36827c478bd9Sstevel@tonic-gate 	    req, 0, session_id, 0, NULL, 0);
36837c478bd9Sstevel@tonic-gate 
36847c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_close: done err = 0x0%x\n",
36857c478bd9Sstevel@tonic-gate 	    instance, error));
36867c478bd9Sstevel@tonic-gate 
36877c478bd9Sstevel@tonic-gate 	return (error);
36887c478bd9Sstevel@tonic-gate }
36897c478bd9Sstevel@tonic-gate 
36907c478bd9Sstevel@tonic-gate static int
36917c478bd9Sstevel@tonic-gate dprov_session_login(crypto_provider_handle_t provider,
36927c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_user_type_t user_type,
36937c478bd9Sstevel@tonic-gate     char *pin, size_t pin_len, crypto_req_handle_t req)
36947c478bd9Sstevel@tonic-gate {
36957c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
36967c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
36977c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
36987c478bd9Sstevel@tonic-gate 	int instance;
36997c478bd9Sstevel@tonic-gate 
37007c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
37017c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_login: started\n",
37027c478bd9Sstevel@tonic-gate 	    instance));
37037c478bd9Sstevel@tonic-gate 
37047c478bd9Sstevel@tonic-gate 	error = dprov_session_submit_req(DPROV_REQ_SESSION_LOGIN, softc,
37057c478bd9Sstevel@tonic-gate 	    req, 0, session_id, user_type, pin, pin_len);
37067c478bd9Sstevel@tonic-gate 
37077c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_login: done err = 0x0%x\n",
37087c478bd9Sstevel@tonic-gate 	    instance, error));
37097c478bd9Sstevel@tonic-gate 
37107c478bd9Sstevel@tonic-gate 	return (error);
37117c478bd9Sstevel@tonic-gate }
37127c478bd9Sstevel@tonic-gate 
37137c478bd9Sstevel@tonic-gate static int
37147c478bd9Sstevel@tonic-gate dprov_session_logout(crypto_provider_handle_t provider,
37157c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_req_handle_t req)
37167c478bd9Sstevel@tonic-gate {
37177c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
37187c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
37197c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
37207c478bd9Sstevel@tonic-gate 	int instance;
37217c478bd9Sstevel@tonic-gate 
37227c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
37237c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_logout: started\n",
37247c478bd9Sstevel@tonic-gate 	    instance));
37257c478bd9Sstevel@tonic-gate 
37267c478bd9Sstevel@tonic-gate 	error = dprov_session_submit_req(DPROV_REQ_SESSION_LOGOUT, softc,
37277c478bd9Sstevel@tonic-gate 	    req, 0, session_id, 0, NULL, 0);
37287c478bd9Sstevel@tonic-gate 
37297c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_logout: done err = 0x0%x\n",
37307c478bd9Sstevel@tonic-gate 	    instance, error));
37317c478bd9Sstevel@tonic-gate 
37327c478bd9Sstevel@tonic-gate 	return (error);
37337c478bd9Sstevel@tonic-gate }
37347c478bd9Sstevel@tonic-gate 
37357c478bd9Sstevel@tonic-gate /*
37367c478bd9Sstevel@tonic-gate  * Object management entry points.
37377c478bd9Sstevel@tonic-gate  */
37387c478bd9Sstevel@tonic-gate 
37397c478bd9Sstevel@tonic-gate static int
37407c478bd9Sstevel@tonic-gate dprov_object_create(crypto_provider_handle_t provider,
37417c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_object_attribute_t *template,
37427c478bd9Sstevel@tonic-gate     uint_t attribute_count, crypto_object_id_t *object,
37437c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
37447c478bd9Sstevel@tonic-gate {
37457c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
37467c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
37477c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
37487c478bd9Sstevel@tonic-gate 	int instance;
37497c478bd9Sstevel@tonic-gate 
37507c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
37517c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_create: started\n",
37527c478bd9Sstevel@tonic-gate 	    instance));
37537c478bd9Sstevel@tonic-gate 
37547c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
37557c478bd9Sstevel@tonic-gate 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_CREATE, softc, req,
37567c478bd9Sstevel@tonic-gate 	    session_id, 0, template, attribute_count, object, NULL, NULL,
37577c478bd9Sstevel@tonic-gate 	    NULL, 0, NULL, KM_NOSLEEP);
37587c478bd9Sstevel@tonic-gate 
37597c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_create: done err = 0x0%x\n",
37607c478bd9Sstevel@tonic-gate 	    instance, error));
37617c478bd9Sstevel@tonic-gate 
37627c478bd9Sstevel@tonic-gate 	return (error);
37637c478bd9Sstevel@tonic-gate }
37647c478bd9Sstevel@tonic-gate 
37657c478bd9Sstevel@tonic-gate static int
37667c478bd9Sstevel@tonic-gate dprov_object_copy(crypto_provider_handle_t provider,
37677c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_object_id_t object,
37687c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *template, uint_t attribute_count,
37697c478bd9Sstevel@tonic-gate     crypto_object_id_t *new_object, crypto_req_handle_t req)
37707c478bd9Sstevel@tonic-gate {
37717c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
37727c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
37737c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
37747c478bd9Sstevel@tonic-gate 	int instance;
37757c478bd9Sstevel@tonic-gate 
37767c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
37777c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_copy: started\n",
37787c478bd9Sstevel@tonic-gate 	    instance));
37797c478bd9Sstevel@tonic-gate 
37807c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
37817c478bd9Sstevel@tonic-gate 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_COPY, softc, req,
37827c478bd9Sstevel@tonic-gate 	    session_id, object, template, attribute_count, new_object,
37837c478bd9Sstevel@tonic-gate 	    NULL, NULL, NULL, 0, NULL, KM_NOSLEEP);
37847c478bd9Sstevel@tonic-gate 
37857c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_copy: done err = 0x0%x\n",
37867c478bd9Sstevel@tonic-gate 	    instance, error));
37877c478bd9Sstevel@tonic-gate 
37887c478bd9Sstevel@tonic-gate 	return (error);
37897c478bd9Sstevel@tonic-gate }
37907c478bd9Sstevel@tonic-gate 
37917c478bd9Sstevel@tonic-gate static int
37927c478bd9Sstevel@tonic-gate dprov_object_destroy(crypto_provider_handle_t provider,
37937c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_object_id_t object,
37947c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
37957c478bd9Sstevel@tonic-gate {
37967c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
37977c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
37987c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
37997c478bd9Sstevel@tonic-gate 	int instance;
38007c478bd9Sstevel@tonic-gate 
38017c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
38027c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_destroy: started\n",
38037c478bd9Sstevel@tonic-gate 	    instance));
38047c478bd9Sstevel@tonic-gate 
38057c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
38067c478bd9Sstevel@tonic-gate 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_DESTROY, softc, req,
38077c478bd9Sstevel@tonic-gate 	    session_id, object, NULL, 0, NULL, NULL, NULL, NULL, 0, NULL,
38087c478bd9Sstevel@tonic-gate 	    KM_NOSLEEP);
38097c478bd9Sstevel@tonic-gate 
38107c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_destroy: done err = 0x0%x\n",
38117c478bd9Sstevel@tonic-gate 	    instance, error));
38127c478bd9Sstevel@tonic-gate 
38137c478bd9Sstevel@tonic-gate 	return (error);
38147c478bd9Sstevel@tonic-gate }
38157c478bd9Sstevel@tonic-gate 
38167c478bd9Sstevel@tonic-gate static int
38177c478bd9Sstevel@tonic-gate dprov_object_get_size(crypto_provider_handle_t provider,
38187c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_object_id_t object,
38197c478bd9Sstevel@tonic-gate     size_t *size, crypto_req_handle_t req)
38207c478bd9Sstevel@tonic-gate {
38217c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
38227c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
38237c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
38247c478bd9Sstevel@tonic-gate 	int instance;
38257c478bd9Sstevel@tonic-gate 
38267c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
38277c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_size: started\n",
38287c478bd9Sstevel@tonic-gate 	    instance));
38297c478bd9Sstevel@tonic-gate 
38307c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
38317c478bd9Sstevel@tonic-gate 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_GET_SIZE, softc, req,
38327c478bd9Sstevel@tonic-gate 	    session_id, object, NULL, 0, NULL, size, NULL, NULL, 0, NULL,
38337c478bd9Sstevel@tonic-gate 	    KM_NOSLEEP);
38347c478bd9Sstevel@tonic-gate 
38357c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_size: done err = 0x0%x\n",
38367c478bd9Sstevel@tonic-gate 	    instance, error));
38377c478bd9Sstevel@tonic-gate 
38387c478bd9Sstevel@tonic-gate 	return (error);
38397c478bd9Sstevel@tonic-gate }
38407c478bd9Sstevel@tonic-gate 
38417c478bd9Sstevel@tonic-gate static int
38427c478bd9Sstevel@tonic-gate dprov_object_get_attribute_value(crypto_provider_handle_t provider,
38437c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_object_id_t object,
38447c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *template, uint_t attribute_count,
38457c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
38467c478bd9Sstevel@tonic-gate {
38477c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
38487c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
38497c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
38507c478bd9Sstevel@tonic-gate 	int instance;
38517c478bd9Sstevel@tonic-gate 
38527c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
38537c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_attribute_value: "
38547c478bd9Sstevel@tonic-gate 	    "started\n", instance));
38557c478bd9Sstevel@tonic-gate 
38567c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
38577c478bd9Sstevel@tonic-gate 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE,
38587c478bd9Sstevel@tonic-gate 	    softc, req, session_id, object, template, attribute_count,
38597c478bd9Sstevel@tonic-gate 	    NULL, NULL, NULL, NULL, 0, NULL, KM_NOSLEEP);
38607c478bd9Sstevel@tonic-gate 
38617c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_attribute_value: "
38627c478bd9Sstevel@tonic-gate 	    "done err = 0x0%x\n", instance, error));
38637c478bd9Sstevel@tonic-gate 
38647c478bd9Sstevel@tonic-gate 	return (error);
38657c478bd9Sstevel@tonic-gate }
38667c478bd9Sstevel@tonic-gate 
38677c478bd9Sstevel@tonic-gate static int
38687c478bd9Sstevel@tonic-gate dprov_object_set_attribute_value(crypto_provider_handle_t provider,
38697c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_object_id_t object,
38707c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *template, uint_t attribute_count,
38717c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
38727c478bd9Sstevel@tonic-gate {
38737c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
38747c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
38757c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
38767c478bd9Sstevel@tonic-gate 	int instance;
38777c478bd9Sstevel@tonic-gate 
38787c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
38797c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_set_attribute_value: "
38807c478bd9Sstevel@tonic-gate 	    "started\n", instance));
38817c478bd9Sstevel@tonic-gate 
38827c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
38837c478bd9Sstevel@tonic-gate 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE,
38847c478bd9Sstevel@tonic-gate 	    softc, req, session_id, object, template, attribute_count,
38857c478bd9Sstevel@tonic-gate 	    NULL, NULL, NULL, NULL, 0, NULL, KM_NOSLEEP);
38867c478bd9Sstevel@tonic-gate 
38877c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_set_attribute_value: "
38887c478bd9Sstevel@tonic-gate 	    "done err = 0x0%x\n", instance, error));
38897c478bd9Sstevel@tonic-gate 
38907c478bd9Sstevel@tonic-gate 	return (error);
38917c478bd9Sstevel@tonic-gate }
38927c478bd9Sstevel@tonic-gate 
38937c478bd9Sstevel@tonic-gate static int
38947c478bd9Sstevel@tonic-gate dprov_object_find_init(crypto_provider_handle_t provider,
38957c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_object_attribute_t *template,
38967c478bd9Sstevel@tonic-gate     uint_t attribute_count, void **provider_private,
38977c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
38987c478bd9Sstevel@tonic-gate {
38997c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
39007c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
39017c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
39027c478bd9Sstevel@tonic-gate 	int instance;
39037c478bd9Sstevel@tonic-gate 
39047c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
39057c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_init: started\n",
39067c478bd9Sstevel@tonic-gate 	    instance));
39077c478bd9Sstevel@tonic-gate 
39087c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
39097c478bd9Sstevel@tonic-gate 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND_INIT, softc, req,
39107c478bd9Sstevel@tonic-gate 	    session_id, 0, template, attribute_count, NULL, NULL,
39117c478bd9Sstevel@tonic-gate 	    provider_private, NULL, 0, NULL, KM_SLEEP);
39127c478bd9Sstevel@tonic-gate 
39137c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_init: done "
39147c478bd9Sstevel@tonic-gate 	    "err = 0x0%x\n", instance, error));
39157c478bd9Sstevel@tonic-gate 
39167c478bd9Sstevel@tonic-gate 	return (error);
39177c478bd9Sstevel@tonic-gate }
39187c478bd9Sstevel@tonic-gate 
39197c478bd9Sstevel@tonic-gate static int
39207c478bd9Sstevel@tonic-gate dprov_object_find(crypto_provider_handle_t provider, void *provider_private,
39217c478bd9Sstevel@tonic-gate     crypto_object_id_t *objects, uint_t max_object_count,
39227c478bd9Sstevel@tonic-gate     uint_t *object_count, crypto_req_handle_t req)
39237c478bd9Sstevel@tonic-gate {
39247c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
39257c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
39267c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
39277c478bd9Sstevel@tonic-gate 	int instance;
39287c478bd9Sstevel@tonic-gate 
39297c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
39307c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find: started\n",
39317c478bd9Sstevel@tonic-gate 	    instance));
39327c478bd9Sstevel@tonic-gate 
39337c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
39347c478bd9Sstevel@tonic-gate 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND, softc, req,
39357c478bd9Sstevel@tonic-gate 	    0, 0, NULL, 0, objects, NULL, NULL, provider_private,
39367c478bd9Sstevel@tonic-gate 	    max_object_count, object_count, KM_NOSLEEP);
39377c478bd9Sstevel@tonic-gate 
39387c478bd9Sstevel@tonic-gate 
39397c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find: done err = 0x0%x\n",
39407c478bd9Sstevel@tonic-gate 	    instance, error));
39417c478bd9Sstevel@tonic-gate 
39427c478bd9Sstevel@tonic-gate 	return (error);
39437c478bd9Sstevel@tonic-gate }
39447c478bd9Sstevel@tonic-gate 
39457c478bd9Sstevel@tonic-gate static int
39467c478bd9Sstevel@tonic-gate dprov_object_find_final(crypto_provider_handle_t provider,
39477c478bd9Sstevel@tonic-gate     void *provider_private, crypto_req_handle_t req)
39487c478bd9Sstevel@tonic-gate {
39497c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
39507c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
39517c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
39527c478bd9Sstevel@tonic-gate 	int instance;
39537c478bd9Sstevel@tonic-gate 
39547c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
39557c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_final: started\n",
39567c478bd9Sstevel@tonic-gate 	    instance));
39577c478bd9Sstevel@tonic-gate 
39587c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
39597c478bd9Sstevel@tonic-gate 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND_FINAL, softc, req,
39607c478bd9Sstevel@tonic-gate 	    0, 0, NULL, 0, NULL, NULL, NULL, provider_private,
39617c478bd9Sstevel@tonic-gate 	    0, NULL, KM_NOSLEEP);
39627c478bd9Sstevel@tonic-gate 
39637c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_final: done "
39647c478bd9Sstevel@tonic-gate 	    "err = 0x0%x\n", instance, error));
39657c478bd9Sstevel@tonic-gate 
39667c478bd9Sstevel@tonic-gate 	return (error);
39677c478bd9Sstevel@tonic-gate }
39687c478bd9Sstevel@tonic-gate 
39697c478bd9Sstevel@tonic-gate /*
39707c478bd9Sstevel@tonic-gate  * Key management entry points.
39717c478bd9Sstevel@tonic-gate  */
39727c478bd9Sstevel@tonic-gate 
39737c478bd9Sstevel@tonic-gate static int
39747c478bd9Sstevel@tonic-gate dprov_key_generate(crypto_provider_handle_t provider,
39757c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
39767c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *template, uint_t attribute_count,
39777c478bd9Sstevel@tonic-gate     crypto_object_id_t *object, crypto_req_handle_t req)
39787c478bd9Sstevel@tonic-gate {
39797c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
39807c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
39817c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
39827c478bd9Sstevel@tonic-gate 	int instance;
39837c478bd9Sstevel@tonic-gate 
39847c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
39857c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate: started\n",
39867c478bd9Sstevel@tonic-gate 	    instance));
39877c478bd9Sstevel@tonic-gate 
39887c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
39897c478bd9Sstevel@tonic-gate 	error = dprov_key_submit_req(DPROV_REQ_KEY_GENERATE, softc, req,
39907c478bd9Sstevel@tonic-gate 	    session_id, mechanism, template, attribute_count, object, NULL,
3991034448feSmcpowers 	    0, NULL, NULL, NULL, 0, NULL, 0, NULL, 0);
39927c478bd9Sstevel@tonic-gate 
39937c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate: done err = 0x0%x\n",
39947c478bd9Sstevel@tonic-gate 	    instance, error));
39957c478bd9Sstevel@tonic-gate 
39967c478bd9Sstevel@tonic-gate 	return (error);
39977c478bd9Sstevel@tonic-gate }
39987c478bd9Sstevel@tonic-gate 
39997c478bd9Sstevel@tonic-gate static int
40007c478bd9Sstevel@tonic-gate dprov_key_generate_pair(crypto_provider_handle_t provider,
40017c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
40027c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *public_key_template,
40037c478bd9Sstevel@tonic-gate     uint_t public_key_attribute_count,
40047c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *private_key_template,
40057c478bd9Sstevel@tonic-gate     uint_t private_key_attribute_count,
40067c478bd9Sstevel@tonic-gate     crypto_object_id_t *public_key, crypto_object_id_t *private_key,
40077c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
40087c478bd9Sstevel@tonic-gate {
40097c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
40107c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
40117c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
40127c478bd9Sstevel@tonic-gate 	int instance;
40137c478bd9Sstevel@tonic-gate 
40147c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
40157c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate_pair: started\n",
40167c478bd9Sstevel@tonic-gate 	    instance));
40177c478bd9Sstevel@tonic-gate 
40187c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
40197c478bd9Sstevel@tonic-gate 	error = dprov_key_submit_req(DPROV_REQ_KEY_GENERATE_PAIR, softc, req,
40207c478bd9Sstevel@tonic-gate 	    session_id, mechanism, public_key_template,
40217c478bd9Sstevel@tonic-gate 	    public_key_attribute_count, public_key, private_key_template,
4022034448feSmcpowers 	    private_key_attribute_count, private_key, NULL, NULL, 0, NULL, 0,
4023034448feSmcpowers 	    NULL, 0);
40247c478bd9Sstevel@tonic-gate 
40257c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate_pair: done err = 0x0%x\n",
40267c478bd9Sstevel@tonic-gate 	    instance, error));
40277c478bd9Sstevel@tonic-gate 
40287c478bd9Sstevel@tonic-gate 	return (error);
40297c478bd9Sstevel@tonic-gate }
40307c478bd9Sstevel@tonic-gate 
40317c478bd9Sstevel@tonic-gate static int
40327c478bd9Sstevel@tonic-gate dprov_key_wrap(crypto_provider_handle_t provider,
40337c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
40347c478bd9Sstevel@tonic-gate     crypto_key_t *wrapping_key, crypto_object_id_t *key,
40357c478bd9Sstevel@tonic-gate     uchar_t *wrapped_key, size_t *wrapped_key_len_ptr, crypto_req_handle_t req)
40367c478bd9Sstevel@tonic-gate {
40377c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
40387c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
40397c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
40407c478bd9Sstevel@tonic-gate 	int instance;
40417c478bd9Sstevel@tonic-gate 
40427c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
40437c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_wrap: started\n",
40447c478bd9Sstevel@tonic-gate 	    instance));
40457c478bd9Sstevel@tonic-gate 
40467c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
40477c478bd9Sstevel@tonic-gate 	error = dprov_key_submit_req(DPROV_REQ_KEY_WRAP, softc, req,
40487c478bd9Sstevel@tonic-gate 	    session_id, mechanism, NULL, 0, key, NULL,
4049034448feSmcpowers 	    0, NULL, wrapping_key, wrapped_key, wrapped_key_len_ptr,
4050034448feSmcpowers 	    NULL, 0, NULL, 0);
40517c478bd9Sstevel@tonic-gate 
40527c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_wrap: done err = 0x0%x\n",
40537c478bd9Sstevel@tonic-gate 	    instance, error));
40547c478bd9Sstevel@tonic-gate 
40557c478bd9Sstevel@tonic-gate 	return (error);
40567c478bd9Sstevel@tonic-gate }
40577c478bd9Sstevel@tonic-gate 
40587c478bd9Sstevel@tonic-gate static int
40597c478bd9Sstevel@tonic-gate dprov_key_unwrap(crypto_provider_handle_t provider,
40607c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
40617c478bd9Sstevel@tonic-gate     crypto_key_t *unwrapping_key, uchar_t *wrapped_key,
40627c478bd9Sstevel@tonic-gate     size_t *wrapped_key_len_ptr, crypto_object_attribute_t *template,
40637c478bd9Sstevel@tonic-gate     uint_t attribute_count, crypto_object_id_t *key, crypto_req_handle_t req)
40647c478bd9Sstevel@tonic-gate {
40657c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
40667c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
40677c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
40687c478bd9Sstevel@tonic-gate 	int instance;
40697c478bd9Sstevel@tonic-gate 
40707c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
40717c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_unwrap: started\n",
40727c478bd9Sstevel@tonic-gate 	    instance));
40737c478bd9Sstevel@tonic-gate 
40747c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
40757c478bd9Sstevel@tonic-gate 	error = dprov_key_submit_req(DPROV_REQ_KEY_UNWRAP, softc, req,
40767c478bd9Sstevel@tonic-gate 	    session_id, mechanism, template, attribute_count, key, NULL,
4077034448feSmcpowers 	    0, NULL, unwrapping_key, wrapped_key, wrapped_key_len_ptr,
4078034448feSmcpowers 	    NULL, 0, NULL, 0);
40797c478bd9Sstevel@tonic-gate 
40807c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_unwrap: done err = 0x0%x\n",
40817c478bd9Sstevel@tonic-gate 	    instance, error));
40827c478bd9Sstevel@tonic-gate 
40837c478bd9Sstevel@tonic-gate 	return (error);
40847c478bd9Sstevel@tonic-gate }
40857c478bd9Sstevel@tonic-gate 
40867c478bd9Sstevel@tonic-gate static int
40877c478bd9Sstevel@tonic-gate dprov_key_derive(crypto_provider_handle_t provider,
40887c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
40897c478bd9Sstevel@tonic-gate     crypto_key_t *base_key, crypto_object_attribute_t *template,
40907c478bd9Sstevel@tonic-gate     uint_t attribute_count, crypto_object_id_t *key, crypto_req_handle_t req)
40917c478bd9Sstevel@tonic-gate {
40927c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
40937c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
40947c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
40957c478bd9Sstevel@tonic-gate 	int instance;
40967c478bd9Sstevel@tonic-gate 
40977c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
40987c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_derive: started\n",
40997c478bd9Sstevel@tonic-gate 	    instance));
41007c478bd9Sstevel@tonic-gate 
41017c478bd9Sstevel@tonic-gate 	/* submit request to the taskq */
41027c478bd9Sstevel@tonic-gate 	error = dprov_key_submit_req(DPROV_REQ_KEY_DERIVE, softc, req,
41037c478bd9Sstevel@tonic-gate 	    session_id, mechanism, template, attribute_count, key, NULL,
4104034448feSmcpowers 	    0, NULL, base_key, NULL, 0, NULL, 0, NULL, 0);
41057c478bd9Sstevel@tonic-gate 
41067c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_derive: done err = 0x0%x\n",
41077c478bd9Sstevel@tonic-gate 	    instance, error));
41087c478bd9Sstevel@tonic-gate 
41097c478bd9Sstevel@tonic-gate 	return (error);
41107c478bd9Sstevel@tonic-gate }
41117c478bd9Sstevel@tonic-gate 
41127c478bd9Sstevel@tonic-gate /*
41137c478bd9Sstevel@tonic-gate  * Provider management entry points.
41147c478bd9Sstevel@tonic-gate  */
41157c478bd9Sstevel@tonic-gate 
41167c478bd9Sstevel@tonic-gate static int
41177c478bd9Sstevel@tonic-gate dprov_ext_info(crypto_provider_handle_t provider,
41187c478bd9Sstevel@tonic-gate     crypto_provider_ext_info_t *ext_info, crypto_req_handle_t req)
41197c478bd9Sstevel@tonic-gate {
41207c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
41217c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
41227c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
41237c478bd9Sstevel@tonic-gate 	int instance;
41247c478bd9Sstevel@tonic-gate 
41257c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
41267c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_ext_info: started\n",
41277c478bd9Sstevel@tonic-gate 	    instance));
41287c478bd9Sstevel@tonic-gate 
41297c478bd9Sstevel@tonic-gate 	error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_EXTINFO, softc, req,
41307c478bd9Sstevel@tonic-gate 	    0, NULL, 0, NULL, 0, NULL, ext_info);
41317c478bd9Sstevel@tonic-gate 
41327c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_ext_info: done err = 0x0%x\n",
41337c478bd9Sstevel@tonic-gate 	    instance, error));
41347c478bd9Sstevel@tonic-gate 
41357c478bd9Sstevel@tonic-gate 	return (error);
41367c478bd9Sstevel@tonic-gate }
41377c478bd9Sstevel@tonic-gate 
41387c478bd9Sstevel@tonic-gate static int
41397c478bd9Sstevel@tonic-gate dprov_init_token(crypto_provider_handle_t provider, char *pin, size_t pin_len,
41407c478bd9Sstevel@tonic-gate     char *label, crypto_req_handle_t req)
41417c478bd9Sstevel@tonic-gate {
41427c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
41437c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
41447c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
41457c478bd9Sstevel@tonic-gate 	int instance;
41467c478bd9Sstevel@tonic-gate 
41477c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
41487c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_token: started\n",
41497c478bd9Sstevel@tonic-gate 	    instance));
41507c478bd9Sstevel@tonic-gate 
41517c478bd9Sstevel@tonic-gate 	error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_INITTOKEN, softc, req,
41527c478bd9Sstevel@tonic-gate 	    0, pin, pin_len, NULL, 0, label, NULL);
41537c478bd9Sstevel@tonic-gate 
41547c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_token: done err = 0x0%x\n",
41557c478bd9Sstevel@tonic-gate 	    instance, error));
41567c478bd9Sstevel@tonic-gate 
41577c478bd9Sstevel@tonic-gate 	return (error);
41587c478bd9Sstevel@tonic-gate }
41597c478bd9Sstevel@tonic-gate 
41607c478bd9Sstevel@tonic-gate static int
41617c478bd9Sstevel@tonic-gate dprov_init_pin(crypto_provider_handle_t provider,
41627c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, char *pin, size_t pin_len,
41637c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
41647c478bd9Sstevel@tonic-gate {
41657c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
41667c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
41677c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
41687c478bd9Sstevel@tonic-gate 	int instance;
41697c478bd9Sstevel@tonic-gate 
41707c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
41717c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_pin: started\n",
41727c478bd9Sstevel@tonic-gate 	    instance));
41737c478bd9Sstevel@tonic-gate 
41747c478bd9Sstevel@tonic-gate 	error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_INITPIN, softc, req,
41757c478bd9Sstevel@tonic-gate 	    session_id, pin, pin_len, NULL, 0, NULL, NULL);
41767c478bd9Sstevel@tonic-gate 
41777c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_pin: done err = 0x0%x\n",
41787c478bd9Sstevel@tonic-gate 	    instance, error));
41797c478bd9Sstevel@tonic-gate 
41807c478bd9Sstevel@tonic-gate 	return (error);
41817c478bd9Sstevel@tonic-gate }
41827c478bd9Sstevel@tonic-gate 
41837c478bd9Sstevel@tonic-gate static int
41847c478bd9Sstevel@tonic-gate dprov_set_pin(crypto_provider_handle_t provider, crypto_session_id_t session_id,
41857c478bd9Sstevel@tonic-gate     char *old_pin, size_t old_pin_len, char *new_pin, size_t new_pin_len,
41867c478bd9Sstevel@tonic-gate     crypto_req_handle_t req)
41877c478bd9Sstevel@tonic-gate {
41887c478bd9Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
41897c478bd9Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
41907c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
41917c478bd9Sstevel@tonic-gate 	int instance;
41927c478bd9Sstevel@tonic-gate 
41937c478bd9Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
41947c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_set_pin: started\n",
41957c478bd9Sstevel@tonic-gate 	    instance));
41967c478bd9Sstevel@tonic-gate 
41977c478bd9Sstevel@tonic-gate 	error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_SETPIN, softc, req,
41987c478bd9Sstevel@tonic-gate 	    session_id, new_pin, new_pin_len, old_pin, old_pin_len, NULL, NULL);
41997c478bd9Sstevel@tonic-gate 
42007c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_set_pin: done err = 0x0%x\n",
42017c478bd9Sstevel@tonic-gate 	    instance, error));
42027c478bd9Sstevel@tonic-gate 
42037c478bd9Sstevel@tonic-gate 	return (error);
42047c478bd9Sstevel@tonic-gate }
42057c478bd9Sstevel@tonic-gate 
42067c478bd9Sstevel@tonic-gate 
42077c478bd9Sstevel@tonic-gate /*
42087c478bd9Sstevel@tonic-gate  * Context management entry points.
42097c478bd9Sstevel@tonic-gate  */
42107c478bd9Sstevel@tonic-gate 
42117c478bd9Sstevel@tonic-gate /*
42127c478bd9Sstevel@tonic-gate  * Allocate a dprov-private context based on the specified dprov request.
42137c478bd9Sstevel@tonic-gate  * For dual cipher/mac requests, the allocated context will
42147c478bd9Sstevel@tonic-gate  * contain a structure dprov_ctx_dual_t, for other request types,
42157c478bd9Sstevel@tonic-gate  * it will contain a dprov_ctx_single.
42167c478bd9Sstevel@tonic-gate  * Returns one of the CRYPTO_ status codes.
42177c478bd9Sstevel@tonic-gate  */
42187c478bd9Sstevel@tonic-gate static int
42197c478bd9Sstevel@tonic-gate dprov_alloc_context(dprov_req_type_t req_type, crypto_ctx_t *spi_ctx)
42207c478bd9Sstevel@tonic-gate {
42217c478bd9Sstevel@tonic-gate 	dprov_ctx_single_t *dprov_private;
42227c478bd9Sstevel@tonic-gate 
42237c478bd9Sstevel@tonic-gate 	switch (req_type) {
42247c478bd9Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_MAC_INIT:
42257c478bd9Sstevel@tonic-gate 	case DPROV_REQ_MAC_DECRYPT_INIT:
42267c478bd9Sstevel@tonic-gate 		dprov_private = kmem_zalloc(sizeof (dprov_ctx_dual_t),
42277c478bd9Sstevel@tonic-gate 		    KM_NOSLEEP);
42287c478bd9Sstevel@tonic-gate 		if (dprov_private == NULL)
42297c478bd9Sstevel@tonic-gate 			return (CRYPTO_HOST_MEMORY);
42307c478bd9Sstevel@tonic-gate 		dprov_private->dc_type = DPROV_CTX_DUAL;
42317c478bd9Sstevel@tonic-gate 		break;
42327c478bd9Sstevel@tonic-gate 	default:
42337c478bd9Sstevel@tonic-gate 		dprov_private = kmem_zalloc(sizeof (dprov_ctx_single_t),
42347c478bd9Sstevel@tonic-gate 		    KM_NOSLEEP);
42357c478bd9Sstevel@tonic-gate 		if (dprov_private == NULL)
42367c478bd9Sstevel@tonic-gate 			return (CRYPTO_HOST_MEMORY);
42377c478bd9Sstevel@tonic-gate 		dprov_private->dc_type = DPROV_CTX_SINGLE;
4238ba5f469cSkrishna 		dprov_private->dc_svrfy_to_mac = B_FALSE;
42397c478bd9Sstevel@tonic-gate 		break;
42407c478bd9Sstevel@tonic-gate 	}
42417c478bd9Sstevel@tonic-gate 
42427c478bd9Sstevel@tonic-gate 	spi_ctx->cc_provider_private = (void *)dprov_private;
42437c478bd9Sstevel@tonic-gate 
42447c478bd9Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
42457c478bd9Sstevel@tonic-gate }
42467c478bd9Sstevel@tonic-gate 
42477c478bd9Sstevel@tonic-gate static int
42487c478bd9Sstevel@tonic-gate dprov_free_context(crypto_ctx_t *ctx)
42497c478bd9Sstevel@tonic-gate {
42507c478bd9Sstevel@tonic-gate 	if (ctx->cc_provider_private == NULL)
42517c478bd9Sstevel@tonic-gate 		return (CRYPTO_SUCCESS);
42527c478bd9Sstevel@tonic-gate 
42537c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CONTEXT, ("dprov_free_context\n"));
42547c478bd9Sstevel@tonic-gate 
42557c478bd9Sstevel@tonic-gate 	{
42567c478bd9Sstevel@tonic-gate 		/*
42577c478bd9Sstevel@tonic-gate 		 * The dprov private context could contain either
42587c478bd9Sstevel@tonic-gate 		 * a dprov_ctx_single_t or a dprov_ctx_dual_t. Free
42597c478bd9Sstevel@tonic-gate 		 * the context based on its type. The k-API contexts
42607c478bd9Sstevel@tonic-gate 		 * that were attached to the dprov private context
42617c478bd9Sstevel@tonic-gate 		 * are freed by the framework.
42627c478bd9Sstevel@tonic-gate 		 */
42637c478bd9Sstevel@tonic-gate 		dprov_ctx_single_t *ctx_single =
42647c478bd9Sstevel@tonic-gate 		    (dprov_ctx_single_t *)(ctx->cc_provider_private);
42657c478bd9Sstevel@tonic-gate 
42667c478bd9Sstevel@tonic-gate 		if (ctx_single->dc_type == DPROV_CTX_SINGLE) {
42677c478bd9Sstevel@tonic-gate 			crypto_context_t context = DPROV_CTX_SINGLE(ctx);
42687c478bd9Sstevel@tonic-gate 
42697c478bd9Sstevel@tonic-gate 			/*
42707c478bd9Sstevel@tonic-gate 			 * This case happens for the crypto_cancel_ctx() case.
42717c478bd9Sstevel@tonic-gate 			 * We have to cancel the SW provider context also.
42727c478bd9Sstevel@tonic-gate 			 */
42737c478bd9Sstevel@tonic-gate 			if (context != NULL)
42747c478bd9Sstevel@tonic-gate 				crypto_cancel_ctx(context);
42757c478bd9Sstevel@tonic-gate 
42767c478bd9Sstevel@tonic-gate 			kmem_free(ctx_single, sizeof (dprov_ctx_single_t));
42777c478bd9Sstevel@tonic-gate 		} else {
42787c478bd9Sstevel@tonic-gate 			crypto_context_t cipher_context =
42797c478bd9Sstevel@tonic-gate 			    DPROV_CTX_DUAL_CIPHER(ctx);
42807c478bd9Sstevel@tonic-gate 			crypto_context_t mac_context = DPROV_CTX_DUAL_MAC(ctx);
42817c478bd9Sstevel@tonic-gate 
42827c478bd9Sstevel@tonic-gate 			/* See comments above. */
42837c478bd9Sstevel@tonic-gate 			if (cipher_context != NULL)
42847c478bd9Sstevel@tonic-gate 				crypto_cancel_ctx(cipher_context);
42857c478bd9Sstevel@tonic-gate 			if (mac_context != NULL)
42867c478bd9Sstevel@tonic-gate 				crypto_cancel_ctx(mac_context);
42877c478bd9Sstevel@tonic-gate 
42887c478bd9Sstevel@tonic-gate 			ASSERT(ctx_single->dc_type == DPROV_CTX_DUAL);
42897c478bd9Sstevel@tonic-gate 			kmem_free(ctx_single, sizeof (dprov_ctx_dual_t));
42907c478bd9Sstevel@tonic-gate 		}
42917c478bd9Sstevel@tonic-gate 		ctx->cc_provider_private = NULL;
42927c478bd9Sstevel@tonic-gate 	}
42937c478bd9Sstevel@tonic-gate 
42947c478bd9Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
42957c478bd9Sstevel@tonic-gate }
42967c478bd9Sstevel@tonic-gate 
4297894b2776Smcpowers /*
4298894b2776Smcpowers  * Resource control checks don't need to be done. Why? Because this routine
4299894b2776Smcpowers  * knows the size of the structure, and it can't be overridden by a user.
4300894b2776Smcpowers  * This is different from the crypto module, which has no knowledge of
4301894b2776Smcpowers  * specific mechanisms, and therefore has to trust specified size of the
4302894b2776Smcpowers  * parameter.  This trust, or lack of trust, is why the size of the
4303894b2776Smcpowers  * parameter has to be charged against the project resource control.
4304894b2776Smcpowers  */
4305894b2776Smcpowers static int
43062d864512Sdinak copyin_aes_ccm_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
43072d864512Sdinak     int *out_error, int mode)
43082d864512Sdinak {
43092d864512Sdinak 	STRUCT_DECL(crypto_mechanism, mech);
43102d864512Sdinak 	STRUCT_DECL(CK_AES_CCM_PARAMS, params);
43112d864512Sdinak 	CK_AES_CCM_PARAMS *aes_ccm_params;
43122d864512Sdinak 	caddr_t pp;
43132d864512Sdinak 	size_t param_len;
43142d864512Sdinak 	int error = 0;
43152d864512Sdinak 	int rv = 0;
43162d864512Sdinak 
43172d864512Sdinak 	STRUCT_INIT(mech, mode);
43182d864512Sdinak 	STRUCT_INIT(params, mode);
43192d864512Sdinak 	bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
43202d864512Sdinak 	pp = STRUCT_FGETP(mech, cm_param);
43212d864512Sdinak 	param_len = STRUCT_FGET(mech, cm_param_len);
43222d864512Sdinak 
43232d864512Sdinak 	if (param_len != STRUCT_SIZE(params)) {
43242d864512Sdinak 		rv = CRYPTO_ARGUMENTS_BAD;
43252d864512Sdinak 		goto out;
43262d864512Sdinak 	}
43272d864512Sdinak 
43282d864512Sdinak 	out_mech->cm_type = STRUCT_FGET(mech, cm_type);
43292d864512Sdinak 	out_mech->cm_param = NULL;
43302d864512Sdinak 	out_mech->cm_param_len = 0;
43312d864512Sdinak 	if (pp != NULL) {
43322d864512Sdinak 		size_t nonce_len, auth_data_len, total_param_len;
43332d864512Sdinak 
43342d864512Sdinak 		if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
43352d864512Sdinak 			out_mech->cm_param = NULL;
43362d864512Sdinak 			error = EFAULT;
43372d864512Sdinak 			goto out;
43382d864512Sdinak 		}
43392d864512Sdinak 
43402d864512Sdinak 		nonce_len = STRUCT_FGET(params, ulNonceSize);
43412d864512Sdinak 		auth_data_len = STRUCT_FGET(params, ulAuthDataSize);
43422d864512Sdinak 
43432d864512Sdinak 		/* allocate param structure */
43442d864512Sdinak 		total_param_len =
43452d864512Sdinak 		    sizeof (CK_AES_CCM_PARAMS) + nonce_len + auth_data_len;
43462d864512Sdinak 		aes_ccm_params = kmem_alloc(total_param_len, KM_NOSLEEP);
43472d864512Sdinak 		if (aes_ccm_params == NULL) {
43482d864512Sdinak 			rv = CRYPTO_HOST_MEMORY;
43492d864512Sdinak 			goto out;
43502d864512Sdinak 		}
43512d864512Sdinak 		aes_ccm_params->ulMACSize = STRUCT_FGET(params, ulMACSize);
43522d864512Sdinak 		aes_ccm_params->ulNonceSize = nonce_len;
43532d864512Sdinak 		aes_ccm_params->ulAuthDataSize = auth_data_len;
43542d864512Sdinak 		aes_ccm_params->ulDataSize
43552d864512Sdinak 		    = STRUCT_FGET(params, ulDataSize);
43562d864512Sdinak 		aes_ccm_params->nonce
43572d864512Sdinak 		    = (uchar_t *)aes_ccm_params + sizeof (CK_AES_CCM_PARAMS);
43582d864512Sdinak 		aes_ccm_params->authData
43592d864512Sdinak 		    = aes_ccm_params->nonce + nonce_len;
43602d864512Sdinak 
43612d864512Sdinak 		if (copyin((char *)STRUCT_FGETP(params, nonce),
43622d864512Sdinak 		    aes_ccm_params->nonce, nonce_len) != 0) {
43632d864512Sdinak 			kmem_free(aes_ccm_params, total_param_len);
43642d864512Sdinak 			out_mech->cm_param = NULL;
43652d864512Sdinak 			error = EFAULT;
43662d864512Sdinak 			goto out;
43672d864512Sdinak 		}
43682d864512Sdinak 		if (copyin((char *)STRUCT_FGETP(params, authData),
43692d864512Sdinak 		    aes_ccm_params->authData, auth_data_len) != 0) {
43702d864512Sdinak 			kmem_free(aes_ccm_params, total_param_len);
43712d864512Sdinak 			out_mech->cm_param = NULL;
43722d864512Sdinak 			error = EFAULT;
43732d864512Sdinak 			goto out;
43742d864512Sdinak 		}
43752d864512Sdinak 		out_mech->cm_param = (char *)aes_ccm_params;
43762d864512Sdinak 		out_mech->cm_param_len = sizeof (CK_AES_CCM_PARAMS);
43772d864512Sdinak 	}
43782d864512Sdinak out:
43792d864512Sdinak 	*out_error = error;
43802d864512Sdinak 	return (rv);
43812d864512Sdinak }
43822d864512Sdinak 
43834d703b5cSMark Powers /*
43844d703b5cSMark Powers  * Resource control checks don't need to be done. Why? Because this routine
43854d703b5cSMark Powers  * knows the size of the structure, and it can't be overridden by a user.
43864d703b5cSMark Powers  * This is different from the crypto module, which has no knowledge of
43874d703b5cSMark Powers  * specific mechanisms, and therefore has to trust specified size of the
43884d703b5cSMark Powers  * parameter.  This trust, or lack of trust, is why the size of the
43894d703b5cSMark Powers  * parameter has to be charged against the project resource control.
43904d703b5cSMark Powers  */
43914d703b5cSMark Powers static int
43924d703b5cSMark Powers copyin_aes_gcm_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
43934d703b5cSMark Powers     int *out_error, int mode)
43944d703b5cSMark Powers {
43954d703b5cSMark Powers 	STRUCT_DECL(crypto_mechanism, mech);
43964d703b5cSMark Powers 	STRUCT_DECL(CK_AES_GCM_PARAMS, params);
43974d703b5cSMark Powers 	CK_AES_GCM_PARAMS *aes_gcm_params;
43984d703b5cSMark Powers 	caddr_t pp;
43994d703b5cSMark Powers 	size_t param_len;
44004d703b5cSMark Powers 	int error = 0;
44014d703b5cSMark Powers 	int rv = 0;
44024d703b5cSMark Powers 
44034d703b5cSMark Powers 	STRUCT_INIT(mech, mode);
44044d703b5cSMark Powers 	STRUCT_INIT(params, mode);
44054d703b5cSMark Powers 	bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
44064d703b5cSMark Powers 	pp = STRUCT_FGETP(mech, cm_param);
44074d703b5cSMark Powers 	param_len = STRUCT_FGET(mech, cm_param_len);
44084d703b5cSMark Powers 
44094d703b5cSMark Powers 	if (param_len != STRUCT_SIZE(params)) {
44104d703b5cSMark Powers 		rv = CRYPTO_ARGUMENTS_BAD;
44114d703b5cSMark Powers 		goto out;
44124d703b5cSMark Powers 	}
44134d703b5cSMark Powers 
44144d703b5cSMark Powers 	out_mech->cm_type = STRUCT_FGET(mech, cm_type);
44154d703b5cSMark Powers 	out_mech->cm_param = NULL;
44164d703b5cSMark Powers 	out_mech->cm_param_len = 0;
44174d703b5cSMark Powers 	if (pp != NULL) {
44184d703b5cSMark Powers 		size_t nonce_len, auth_data_len, total_param_len;
44194d703b5cSMark Powers 
44204d703b5cSMark Powers 		if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
44214d703b5cSMark Powers 			out_mech->cm_param = NULL;
44224d703b5cSMark Powers 			error = EFAULT;
44234d703b5cSMark Powers 			goto out;
44244d703b5cSMark Powers 		}
44254d703b5cSMark Powers 
44264d703b5cSMark Powers 		nonce_len = STRUCT_FGET(params, ulIvLen);
44274d703b5cSMark Powers 		auth_data_len = STRUCT_FGET(params, ulAADLen);
44284d703b5cSMark Powers 
44294d703b5cSMark Powers 		/* allocate param structure */
44304d703b5cSMark Powers 		total_param_len =
44314d703b5cSMark Powers 		    sizeof (CK_AES_GCM_PARAMS) + nonce_len + auth_data_len;
44324d703b5cSMark Powers 		aes_gcm_params = kmem_alloc(total_param_len, KM_NOSLEEP);
44334d703b5cSMark Powers 		if (aes_gcm_params == NULL) {
44344d703b5cSMark Powers 			rv = CRYPTO_HOST_MEMORY;
44354d703b5cSMark Powers 			goto out;
44364d703b5cSMark Powers 		}
44374d703b5cSMark Powers 		aes_gcm_params->ulTagBits = STRUCT_FGET(params, ulTagBits);
44384d703b5cSMark Powers 		aes_gcm_params->ulIvLen = nonce_len;
44394d703b5cSMark Powers 		aes_gcm_params->ulAADLen = auth_data_len;
44404d703b5cSMark Powers 		aes_gcm_params->pIv
44414d703b5cSMark Powers 		    = (uchar_t *)aes_gcm_params + sizeof (CK_AES_GCM_PARAMS);
44424d703b5cSMark Powers 		aes_gcm_params->pAAD = aes_gcm_params->pIv + nonce_len;
44434d703b5cSMark Powers 
44444d703b5cSMark Powers 		if (copyin((char *)STRUCT_FGETP(params, pIv),
44454d703b5cSMark Powers 		    aes_gcm_params->pIv, nonce_len) != 0) {
44464d703b5cSMark Powers 			kmem_free(aes_gcm_params, total_param_len);
44474d703b5cSMark Powers 			out_mech->cm_param = NULL;
44484d703b5cSMark Powers 			error = EFAULT;
44494d703b5cSMark Powers 			goto out;
44504d703b5cSMark Powers 		}
44514d703b5cSMark Powers 		if (copyin((char *)STRUCT_FGETP(params, pAAD),
44524d703b5cSMark Powers 		    aes_gcm_params->pAAD, auth_data_len) != 0) {
44534d703b5cSMark Powers 			kmem_free(aes_gcm_params, total_param_len);
44544d703b5cSMark Powers 			out_mech->cm_param = NULL;
44554d703b5cSMark Powers 			error = EFAULT;
44564d703b5cSMark Powers 			goto out;
44574d703b5cSMark Powers 		}
44584d703b5cSMark Powers 		out_mech->cm_param = (char *)aes_gcm_params;
44594d703b5cSMark Powers 		out_mech->cm_param_len = sizeof (CK_AES_GCM_PARAMS);
44604d703b5cSMark Powers 	}
44614d703b5cSMark Powers out:
44624d703b5cSMark Powers 	*out_error = error;
44634d703b5cSMark Powers 	return (rv);
44644d703b5cSMark Powers }
44652d864512Sdinak 
4466983a1033SMark Powers static int
4467983a1033SMark Powers copyin_aes_gmac_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
4468983a1033SMark Powers     int *out_error, int mode)
4469983a1033SMark Powers {
4470983a1033SMark Powers 	STRUCT_DECL(crypto_mechanism, mech);
4471983a1033SMark Powers 	STRUCT_DECL(CK_AES_GMAC_PARAMS, params);
4472983a1033SMark Powers 	CK_AES_GMAC_PARAMS *aes_gmac_params;
4473983a1033SMark Powers 	caddr_t pp;
4474983a1033SMark Powers 	size_t param_len;
4475983a1033SMark Powers 	int error = 0;
4476983a1033SMark Powers 	int rv = 0;
4477983a1033SMark Powers 
4478983a1033SMark Powers 	STRUCT_INIT(mech, mode);
4479983a1033SMark Powers 	STRUCT_INIT(params, mode);
4480983a1033SMark Powers 	bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4481983a1033SMark Powers 	pp = STRUCT_FGETP(mech, cm_param);
4482983a1033SMark Powers 	param_len = STRUCT_FGET(mech, cm_param_len);
4483983a1033SMark Powers 
4484983a1033SMark Powers 	if (param_len != STRUCT_SIZE(params)) {
4485983a1033SMark Powers 		rv = CRYPTO_ARGUMENTS_BAD;
4486983a1033SMark Powers 		goto out;
4487983a1033SMark Powers 	}
4488983a1033SMark Powers 
4489983a1033SMark Powers 	out_mech->cm_type = STRUCT_FGET(mech, cm_type);
4490983a1033SMark Powers 	out_mech->cm_param = NULL;
4491983a1033SMark Powers 	out_mech->cm_param_len = 0;
4492983a1033SMark Powers 	if (pp != NULL) {
4493983a1033SMark Powers 		size_t auth_data_len, total_param_len;
4494983a1033SMark Powers 
4495983a1033SMark Powers 		if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
4496983a1033SMark Powers 			out_mech->cm_param = NULL;
4497983a1033SMark Powers 			error = EFAULT;
4498983a1033SMark Powers 			goto out;
4499983a1033SMark Powers 		}
4500983a1033SMark Powers 
4501983a1033SMark Powers 		auth_data_len = STRUCT_FGET(params, ulAADLen);
4502983a1033SMark Powers 
4503983a1033SMark Powers 		/* allocate param structure */
4504983a1033SMark Powers 		total_param_len = sizeof (CK_AES_GMAC_PARAMS) +
4505983a1033SMark Powers 		    AES_GMAC_IV_LEN + auth_data_len;
4506983a1033SMark Powers 		aes_gmac_params = kmem_alloc(total_param_len, KM_NOSLEEP);
4507983a1033SMark Powers 		if (aes_gmac_params == NULL) {
4508983a1033SMark Powers 			rv = CRYPTO_HOST_MEMORY;
4509983a1033SMark Powers 			goto out;
4510983a1033SMark Powers 		}
4511983a1033SMark Powers 		aes_gmac_params->ulAADLen = auth_data_len;
4512983a1033SMark Powers 		aes_gmac_params->pIv
4513983a1033SMark Powers 		    = (uchar_t *)aes_gmac_params + sizeof (CK_AES_GMAC_PARAMS);
4514983a1033SMark Powers 		aes_gmac_params->pAAD = aes_gmac_params->pIv + AES_GMAC_IV_LEN;
4515983a1033SMark Powers 
4516983a1033SMark Powers 		if (copyin((char *)STRUCT_FGETP(params, pIv),
4517983a1033SMark Powers 		    aes_gmac_params->pIv, AES_GMAC_IV_LEN) != 0) {
4518983a1033SMark Powers 			kmem_free(aes_gmac_params, total_param_len);
4519983a1033SMark Powers 			out_mech->cm_param = NULL;
4520983a1033SMark Powers 			error = EFAULT;
4521983a1033SMark Powers 			goto out;
4522983a1033SMark Powers 		}
4523983a1033SMark Powers 		if (copyin((char *)STRUCT_FGETP(params, pAAD),
4524983a1033SMark Powers 		    aes_gmac_params->pAAD, auth_data_len) != 0) {
4525983a1033SMark Powers 			kmem_free(aes_gmac_params, total_param_len);
4526983a1033SMark Powers 			out_mech->cm_param = NULL;
4527983a1033SMark Powers 			error = EFAULT;
4528983a1033SMark Powers 			goto out;
4529983a1033SMark Powers 		}
4530983a1033SMark Powers 		out_mech->cm_param = (char *)aes_gmac_params;
4531983a1033SMark Powers 		out_mech->cm_param_len = sizeof (CK_AES_GMAC_PARAMS);
4532983a1033SMark Powers 	}
4533983a1033SMark Powers out:
4534983a1033SMark Powers 	*out_error = error;
4535983a1033SMark Powers 	return (rv);
4536983a1033SMark Powers }
4537983a1033SMark Powers 
45382d864512Sdinak /*
45392d864512Sdinak  * Resource control checks don't need to be done. Why? Because this routine
45402d864512Sdinak  * knows the size of the structure, and it can't be overridden by a user.
45412d864512Sdinak  * This is different from the crypto module, which has no knowledge of
45422d864512Sdinak  * specific mechanisms, and therefore has to trust specified size of the
45432d864512Sdinak  * parameter.  This trust, or lack of trust, is why the size of the
45442d864512Sdinak  * parameter has to be charged against the project resource control.
45452d864512Sdinak  */
45462d864512Sdinak static int
4547894b2776Smcpowers copyin_aes_ctr_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
4548894b2776Smcpowers     int *out_error, int mode)
4549894b2776Smcpowers {
4550894b2776Smcpowers 	STRUCT_DECL(crypto_mechanism, mech);
4551894b2776Smcpowers 	STRUCT_DECL(CK_AES_CTR_PARAMS, params);
4552894b2776Smcpowers 	CK_AES_CTR_PARAMS *aes_ctr_params;
4553894b2776Smcpowers 	caddr_t pp;
4554894b2776Smcpowers 	size_t param_len;
4555894b2776Smcpowers 	int error = 0;
4556894b2776Smcpowers 	int rv = 0;
4557894b2776Smcpowers 
4558894b2776Smcpowers 	STRUCT_INIT(mech, mode);
4559894b2776Smcpowers 	STRUCT_INIT(params, mode);
4560894b2776Smcpowers 	bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4561894b2776Smcpowers 	pp = STRUCT_FGETP(mech, cm_param);
4562894b2776Smcpowers 	param_len = STRUCT_FGET(mech, cm_param_len);
4563894b2776Smcpowers 
4564894b2776Smcpowers 	if (param_len != STRUCT_SIZE(params)) {
4565894b2776Smcpowers 		rv = CRYPTO_ARGUMENTS_BAD;
4566894b2776Smcpowers 		goto out;
4567894b2776Smcpowers 	}
4568894b2776Smcpowers 
4569894b2776Smcpowers 	out_mech->cm_type = STRUCT_FGET(mech, cm_type);
4570894b2776Smcpowers 	out_mech->cm_param = NULL;
4571894b2776Smcpowers 	out_mech->cm_param_len = 0;
4572894b2776Smcpowers 	if (pp != NULL) {
4573894b2776Smcpowers 		if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
4574894b2776Smcpowers 			out_mech->cm_param = NULL;
4575894b2776Smcpowers 			error = EFAULT;
4576894b2776Smcpowers 			goto out;
4577894b2776Smcpowers 		}
4578894b2776Smcpowers 		/* allocate param structure and counter block */
4579d2b32306Smcpowers 		aes_ctr_params = kmem_alloc(sizeof (CK_AES_CTR_PARAMS),
4580894b2776Smcpowers 		    KM_NOSLEEP);
4581894b2776Smcpowers 		if (aes_ctr_params == NULL) {
4582894b2776Smcpowers 			rv = CRYPTO_HOST_MEMORY;
4583894b2776Smcpowers 			goto out;
4584894b2776Smcpowers 		}
4585894b2776Smcpowers 		aes_ctr_params->ulCounterBits = STRUCT_FGET(params,
4586894b2776Smcpowers 		    ulCounterBits);
4587d2b32306Smcpowers 		bcopy(STRUCT_FGETP(params, cb), aes_ctr_params->cb, 16);
4588894b2776Smcpowers 		out_mech->cm_param = (char *)aes_ctr_params;
4589894b2776Smcpowers 		out_mech->cm_param_len = sizeof (CK_AES_CTR_PARAMS);
4590894b2776Smcpowers 	}
4591894b2776Smcpowers out:
4592894b2776Smcpowers 	*out_error = error;
4593894b2776Smcpowers 	return (rv);
4594894b2776Smcpowers }
4595894b2776Smcpowers 
4596f9fbec18Smcpowers static int
4597f9fbec18Smcpowers copyin_ecc_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
4598f9fbec18Smcpowers     int *out_error, int mode)
4599f9fbec18Smcpowers {
4600f9fbec18Smcpowers 	STRUCT_DECL(crypto_mechanism, mech);
4601f9fbec18Smcpowers 	STRUCT_DECL(CK_ECDH1_DERIVE_PARAMS, params);
4602f9fbec18Smcpowers 	CK_ECDH1_DERIVE_PARAMS *ecc_params;
4603f9fbec18Smcpowers 	caddr_t pp;
4604f9fbec18Smcpowers 	size_t param_len, shared_data_len, public_data_len;
4605f9fbec18Smcpowers 	int error = 0;
4606f9fbec18Smcpowers 	int rv = 0;
4607f9fbec18Smcpowers 
4608f9fbec18Smcpowers 	STRUCT_INIT(mech, mode);
4609f9fbec18Smcpowers 	STRUCT_INIT(params, mode);
4610f9fbec18Smcpowers 	bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4611f9fbec18Smcpowers 	pp = STRUCT_FGETP(mech, cm_param);
4612f9fbec18Smcpowers 	param_len = STRUCT_FGET(mech, cm_param_len);
4613f9fbec18Smcpowers 
4614f9fbec18Smcpowers 	if (param_len != STRUCT_SIZE(params)) {
4615f9fbec18Smcpowers 		rv = CRYPTO_ARGUMENTS_BAD;
4616f9fbec18Smcpowers 		goto out;
4617f9fbec18Smcpowers 	}
4618f9fbec18Smcpowers 
4619f9fbec18Smcpowers 	out_mech->cm_type = STRUCT_FGET(mech, cm_type);
4620f9fbec18Smcpowers 	out_mech->cm_param = NULL;
4621f9fbec18Smcpowers 	out_mech->cm_param_len = 0;
4622f9fbec18Smcpowers 	if (pp != NULL) {
4623f9fbec18Smcpowers 		if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
4624f9fbec18Smcpowers 			out_mech->cm_param = NULL;
4625f9fbec18Smcpowers 			error = EFAULT;
4626f9fbec18Smcpowers 			goto out;
4627f9fbec18Smcpowers 		}
4628f9fbec18Smcpowers 		shared_data_len = STRUCT_FGET(params, ulSharedDataLen);
4629f9fbec18Smcpowers 		public_data_len = STRUCT_FGET(params, ulPublicDataLen);
4630f9fbec18Smcpowers 		/* allocate param structure and buffers */
4631f9fbec18Smcpowers 		ecc_params = kmem_alloc(sizeof (CK_ECDH1_DERIVE_PARAMS) +
4632f9fbec18Smcpowers 		    roundup(shared_data_len, sizeof (caddr_t)) +
4633f9fbec18Smcpowers 		    roundup(public_data_len, sizeof (caddr_t)), KM_NOSLEEP);
4634f9fbec18Smcpowers 		if (ecc_params == NULL) {
4635f9fbec18Smcpowers 			rv = CRYPTO_HOST_MEMORY;
4636f9fbec18Smcpowers 			goto out;
4637f9fbec18Smcpowers 		}
4638f9fbec18Smcpowers 		ecc_params->pSharedData = (uchar_t *)ecc_params +
4639f9fbec18Smcpowers 		    sizeof (CK_ECDH1_DERIVE_PARAMS);
4640f9fbec18Smcpowers 		ecc_params->pPublicData = (uchar_t *)ecc_params->pSharedData +
4641f9fbec18Smcpowers 		    roundup(shared_data_len, sizeof (caddr_t));
4642f9fbec18Smcpowers 		if (copyin((char *)STRUCT_FGETP(params, pSharedData),
4643f9fbec18Smcpowers 		    ecc_params->pSharedData, shared_data_len) != 0) {
4644f9fbec18Smcpowers 			kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) +
4645f9fbec18Smcpowers 			    roundup(shared_data_len, sizeof (caddr_t)) +
4646f9fbec18Smcpowers 			    roundup(public_data_len, sizeof (caddr_t)));
4647f9fbec18Smcpowers 			out_mech->cm_param = NULL;
4648f9fbec18Smcpowers 			error = EFAULT;
4649f9fbec18Smcpowers 			goto out;
4650f9fbec18Smcpowers 		}
4651f9fbec18Smcpowers 		ecc_params->ulSharedDataLen = shared_data_len;
4652f9fbec18Smcpowers 
4653f9fbec18Smcpowers 		if (copyin((char *)STRUCT_FGETP(params, pPublicData),
4654f9fbec18Smcpowers 		    ecc_params->pPublicData, public_data_len) != 0) {
4655f9fbec18Smcpowers 			kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) +
4656f9fbec18Smcpowers 			    roundup(shared_data_len, sizeof (caddr_t)) +
4657f9fbec18Smcpowers 			    roundup(public_data_len, sizeof (caddr_t)));
4658f9fbec18Smcpowers 			out_mech->cm_param = NULL;
4659f9fbec18Smcpowers 			error = EFAULT;
4660f9fbec18Smcpowers 			goto out;
4661f9fbec18Smcpowers 		}
4662f9fbec18Smcpowers 		ecc_params->ulPublicDataLen = public_data_len;
4663f9fbec18Smcpowers 		ecc_params->kdf = STRUCT_FGET(params, kdf);
4664f9fbec18Smcpowers 		out_mech->cm_param = (char *)ecc_params;
4665f9fbec18Smcpowers 		out_mech->cm_param_len = sizeof (CK_ECDH1_DERIVE_PARAMS);
4666f9fbec18Smcpowers 	}
4667f9fbec18Smcpowers out:
4668f9fbec18Smcpowers 	*out_error = error;
4669f9fbec18Smcpowers 	return (rv);
4670f9fbec18Smcpowers }
4671f9fbec18Smcpowers 
4672894b2776Smcpowers /* ARGSUSED */
4673894b2776Smcpowers static int
4674894b2776Smcpowers copyout_aes_ctr_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
4675894b2776Smcpowers     int *out_error, int mode)
4676894b2776Smcpowers {
4677894b2776Smcpowers 	STRUCT_DECL(crypto_mechanism, mech);
4678894b2776Smcpowers 	STRUCT_DECL(CK_AES_CTR_PARAMS, params);
4679894b2776Smcpowers 	caddr_t pp;
4680894b2776Smcpowers 	size_t param_len;
4681894b2776Smcpowers 	int error = 0;
4682894b2776Smcpowers 	int rv = 0;
4683894b2776Smcpowers 
4684894b2776Smcpowers 	STRUCT_INIT(mech, mode);
4685894b2776Smcpowers 	STRUCT_INIT(params, mode);
4686894b2776Smcpowers 	bcopy(out_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4687894b2776Smcpowers 	pp = STRUCT_FGETP(mech, cm_param);
4688894b2776Smcpowers 	param_len = STRUCT_FGET(mech, cm_param_len);
4689894b2776Smcpowers 	if (param_len != STRUCT_SIZE(params)) {
4690894b2776Smcpowers 		rv = CRYPTO_ARGUMENTS_BAD;
4691894b2776Smcpowers 		goto out;
4692894b2776Smcpowers 	}
4693894b2776Smcpowers 
4694894b2776Smcpowers 	if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
4695894b2776Smcpowers 		error = EFAULT;
4696894b2776Smcpowers 		goto out;
4697894b2776Smcpowers 	}
4698894b2776Smcpowers 
4699894b2776Smcpowers 	/* for testing, overwrite the iv with 16 X 'A' */
4700d2b32306Smcpowers 	(void) memset(STRUCT_FGETP(params, cb), 'A', 16);
4701d2b32306Smcpowers 	if (copyout((char *)pp, STRUCT_BUF(params),  param_len) != 0) {
4702894b2776Smcpowers 		error = EFAULT;
4703894b2776Smcpowers 		goto out;
4704894b2776Smcpowers 	}
4705894b2776Smcpowers out:
4706894b2776Smcpowers 	*out_error = error;
4707894b2776Smcpowers 	return (rv);
4708894b2776Smcpowers }
4709894b2776Smcpowers 
4710894b2776Smcpowers /* ARGSUSED */
4711894b2776Smcpowers static int
4712894b2776Smcpowers dprov_copyin_mechanism(crypto_provider_handle_t provider,
4713894b2776Smcpowers     crypto_mechanism_t *umech, crypto_mechanism_t *kmech,
4714894b2776Smcpowers     int *out_error, int mode)
4715894b2776Smcpowers {
4716894b2776Smcpowers 	STRUCT_DECL(crypto_mechanism, mech);
4717894b2776Smcpowers 	size_t param_len, expected_param_len;
4718894b2776Smcpowers 	caddr_t pp;
4719894b2776Smcpowers 	char *param;
4720894b2776Smcpowers 	int rv;
4721894b2776Smcpowers 	int error = 0;
4722894b2776Smcpowers 
4723894b2776Smcpowers 	ASSERT(!servicing_interrupt());
4724894b2776Smcpowers 
4725894b2776Smcpowers 	STRUCT_INIT(mech, mode);
4726894b2776Smcpowers 	bcopy(umech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4727894b2776Smcpowers 	pp = STRUCT_FGETP(mech, cm_param);
4728894b2776Smcpowers 	param_len = STRUCT_FGET(mech, cm_param_len);
4729894b2776Smcpowers 
4730894b2776Smcpowers 	kmech->cm_param = NULL;
4731894b2776Smcpowers 	kmech->cm_param_len = 0;
4732894b2776Smcpowers 
4733894b2776Smcpowers 	switch (kmech->cm_type) {
4734894b2776Smcpowers 	case DES_CBC_MECH_INFO_TYPE:
4735894b2776Smcpowers 	case DES3_CBC_MECH_INFO_TYPE:
4736894b2776Smcpowers 		expected_param_len = DES_BLOCK_LEN;
4737894b2776Smcpowers 		break;
4738894b2776Smcpowers 
4739894b2776Smcpowers 	case BLOWFISH_CBC_MECH_INFO_TYPE:
4740894b2776Smcpowers 		expected_param_len = BLOWFISH_BLOCK_LEN;
4741894b2776Smcpowers 		break;
4742894b2776Smcpowers 
4743894b2776Smcpowers 	case AES_CBC_MECH_INFO_TYPE:
4744894b2776Smcpowers 		expected_param_len = AES_BLOCK_LEN;
4745894b2776Smcpowers 		break;
4746894b2776Smcpowers 
4747894b2776Smcpowers 	case AES_CTR_MECH_INFO_TYPE:
4748894b2776Smcpowers 	case SHA1_KEY_DERIVATION_MECH_INFO_TYPE:	/* for testing only */
4749894b2776Smcpowers 		rv = copyin_aes_ctr_mech(umech, kmech, &error, mode);
4750894b2776Smcpowers 		goto out;
4751894b2776Smcpowers 
4752f9fbec18Smcpowers 	case ECDH1_DERIVE_MECH_INFO_TYPE:
4753f9fbec18Smcpowers 		rv = copyin_ecc_mech(umech, kmech, &error, mode);
4754f9fbec18Smcpowers 		goto out;
4755f9fbec18Smcpowers 
47562d864512Sdinak 	case AES_CCM_MECH_INFO_TYPE:
47572d864512Sdinak 		rv = copyin_aes_ccm_mech(umech, kmech, &error, mode);
47582d864512Sdinak 		goto out;
47592d864512Sdinak 
47604d703b5cSMark Powers 	case AES_GCM_MECH_INFO_TYPE:
47614d703b5cSMark Powers 		rv = copyin_aes_gcm_mech(umech, kmech, &error, mode);
47624d703b5cSMark Powers 		goto out;
47634d703b5cSMark Powers 
4764983a1033SMark Powers 	case AES_GMAC_MECH_INFO_TYPE:
4765983a1033SMark Powers 		rv = copyin_aes_gmac_mech(umech, kmech, &error, mode);
4766983a1033SMark Powers 		goto out;
4767983a1033SMark Powers 
47685b0c7657Sizick 	case DH_PKCS_DERIVE_MECH_INFO_TYPE:
47695b0c7657Sizick 		expected_param_len = param_len;
47705b0c7657Sizick 		break;
47715b0c7657Sizick 
4772894b2776Smcpowers 	default:
4773fd11a81eSmcpowers 		/* nothing to do - mechanism has no parameters */
4774fd11a81eSmcpowers 		rv = CRYPTO_SUCCESS;
4775894b2776Smcpowers 		goto out;
4776894b2776Smcpowers 	}
4777894b2776Smcpowers 
4778894b2776Smcpowers 	if (param_len != expected_param_len) {
4779894b2776Smcpowers 		rv = CRYPTO_MECHANISM_PARAM_INVALID;
4780894b2776Smcpowers 		goto out;
4781894b2776Smcpowers 	}
4782894b2776Smcpowers 	if (pp == NULL) {
4783894b2776Smcpowers 		rv = CRYPTO_MECHANISM_PARAM_INVALID;
4784894b2776Smcpowers 		goto out;
4785894b2776Smcpowers 	}
4786894b2776Smcpowers 	if ((param = kmem_alloc(param_len, KM_NOSLEEP)) == NULL) {
4787894b2776Smcpowers 		rv = CRYPTO_HOST_MEMORY;
4788894b2776Smcpowers 		goto out;
4789894b2776Smcpowers 	}
4790894b2776Smcpowers 	if (copyin((char *)pp, param, param_len) != 0) {
4791894b2776Smcpowers 		kmem_free(param, param_len);
4792894b2776Smcpowers 		error = EFAULT;
4793894b2776Smcpowers 		rv = CRYPTO_FAILED;
4794894b2776Smcpowers 		goto out;
4795894b2776Smcpowers 	}
4796894b2776Smcpowers 	kmech->cm_param = (char *)param;
4797894b2776Smcpowers 	kmech->cm_param_len = param_len;
4798894b2776Smcpowers 	rv = CRYPTO_SUCCESS;
4799894b2776Smcpowers out:
4800894b2776Smcpowers 	*out_error = error;
4801894b2776Smcpowers 	return (rv);
4802894b2776Smcpowers }
4803894b2776Smcpowers 
4804894b2776Smcpowers /* ARGSUSED */
4805894b2776Smcpowers static int
4806894b2776Smcpowers dprov_copyout_mechanism(crypto_provider_handle_t provider,
4807894b2776Smcpowers     crypto_mechanism_t *kmech, crypto_mechanism_t *umech,
4808894b2776Smcpowers     int *out_error, int mode)
4809894b2776Smcpowers {
4810894b2776Smcpowers 	ASSERT(!servicing_interrupt());
4811894b2776Smcpowers 
4812894b2776Smcpowers 	switch (kmech->cm_type) {
4813894b2776Smcpowers 	case AES_CTR_MECH_INFO_TYPE:
4814894b2776Smcpowers 	case SHA1_KEY_DERIVATION_MECH_INFO_TYPE:	/* for testing only */
4815894b2776Smcpowers 		return (copyout_aes_ctr_mech(kmech, umech, out_error, mode));
4816f9fbec18Smcpowers 	case ECDH1_DERIVE_MECH_INFO_TYPE:
4817f9fbec18Smcpowers 		return (CRYPTO_SUCCESS);
4818894b2776Smcpowers 	default:
4819894b2776Smcpowers 		return (CRYPTO_MECHANISM_INVALID);
4820894b2776Smcpowers 	}
4821894b2776Smcpowers }
4822894b2776Smcpowers 
4823894b2776Smcpowers /*
4824894b2776Smcpowers  * Free mechanism parameter that was allocated by the provider.
4825894b2776Smcpowers  */
4826894b2776Smcpowers /* ARGSUSED */
4827894b2776Smcpowers static int
4828894b2776Smcpowers dprov_free_mechanism(crypto_provider_handle_t provider,
4829894b2776Smcpowers     crypto_mechanism_t *mech)
4830894b2776Smcpowers {
4831894b2776Smcpowers 	size_t len;
4832894b2776Smcpowers 
4833894b2776Smcpowers 	if (mech->cm_param == NULL || mech->cm_param_len == 0)
4834894b2776Smcpowers 		return (CRYPTO_SUCCESS);
4835894b2776Smcpowers 
4836f9fbec18Smcpowers 	switch (mech->cm_type) {
4837f9fbec18Smcpowers 	case AES_CTR_MECH_INFO_TYPE:
4838f9fbec18Smcpowers 	case SHA1_KEY_DERIVATION_MECH_INFO_TYPE:
4839d2b32306Smcpowers 		len = sizeof (CK_AES_CTR_PARAMS);
4840f9fbec18Smcpowers 		break;
4841f9fbec18Smcpowers 	case ECDH1_DERIVE_MECH_INFO_TYPE: {
4842f9fbec18Smcpowers 		CK_ECDH1_DERIVE_PARAMS *ecc_params;
4843f9fbec18Smcpowers 
4844f9fbec18Smcpowers 		/* LINTED: pointer alignment */
4845f9fbec18Smcpowers 		ecc_params = (CK_ECDH1_DERIVE_PARAMS *)mech->cm_param;
4846f9fbec18Smcpowers 		kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) +
4847f9fbec18Smcpowers 		    roundup(ecc_params->ulSharedDataLen, sizeof (caddr_t)) +
4848f9fbec18Smcpowers 		    roundup(ecc_params->ulPublicDataLen, sizeof (caddr_t)));
4849f9fbec18Smcpowers 		return (CRYPTO_SUCCESS);
4850f9fbec18Smcpowers 	}
485123c57df7Smcpowers 	case AES_CCM_MECH_INFO_TYPE: {
485223c57df7Smcpowers 		CK_AES_CCM_PARAMS *params;
485323c57df7Smcpowers 		size_t total_param_len;
485423c57df7Smcpowers 
485523c57df7Smcpowers 		if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) {
485623c57df7Smcpowers 			/* LINTED: pointer alignment */
485723c57df7Smcpowers 			params = (CK_AES_CCM_PARAMS *)mech->cm_param;
485823c57df7Smcpowers 			total_param_len = mech->cm_param_len +
485923c57df7Smcpowers 			    params->ulNonceSize + params->ulAuthDataSize;
486023c57df7Smcpowers 			kmem_free(params, total_param_len);
486123c57df7Smcpowers 			mech->cm_param = NULL;
486223c57df7Smcpowers 			mech->cm_param_len = 0;
486323c57df7Smcpowers 		}
48644d703b5cSMark Powers 		return (CRYPTO_SUCCESS);
48654d703b5cSMark Powers 	}
4866983a1033SMark Powers 	case AES_GMAC_MECH_INFO_TYPE: {
4867983a1033SMark Powers 		CK_AES_GMAC_PARAMS *params;
4868983a1033SMark Powers 		size_t total_param_len;
4869983a1033SMark Powers 
4870983a1033SMark Powers 		if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) {
4871983a1033SMark Powers 			/* LINTED: pointer alignment */
4872983a1033SMark Powers 			params = (CK_AES_GMAC_PARAMS *)mech->cm_param;
4873983a1033SMark Powers 			total_param_len = mech->cm_param_len +
4874983a1033SMark Powers 			    AES_GMAC_IV_LEN + params->ulAADLen;
4875983a1033SMark Powers 			kmem_free(params, total_param_len);
4876983a1033SMark Powers 			mech->cm_param = NULL;
4877983a1033SMark Powers 			mech->cm_param_len = 0;
4878983a1033SMark Powers 		}
4879983a1033SMark Powers 		return (CRYPTO_SUCCESS);
4880983a1033SMark Powers 	}
48814d703b5cSMark Powers 	case AES_GCM_MECH_INFO_TYPE: {
48824d703b5cSMark Powers 		CK_AES_GCM_PARAMS *params;
48834d703b5cSMark Powers 		size_t total_param_len;
48844d703b5cSMark Powers 
48854d703b5cSMark Powers 		if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) {
48864d703b5cSMark Powers 			/* LINTED: pointer alignment */
48874d703b5cSMark Powers 			params = (CK_AES_GCM_PARAMS *)mech->cm_param;
48884d703b5cSMark Powers 			total_param_len = mech->cm_param_len +
48894d703b5cSMark Powers 			    params->ulIvLen + params->ulAADLen;
48904d703b5cSMark Powers 			kmem_free(params, total_param_len);
48914d703b5cSMark Powers 			mech->cm_param = NULL;
48924d703b5cSMark Powers 			mech->cm_param_len = 0;
48934d703b5cSMark Powers 		}
48944d703b5cSMark Powers 		return (CRYPTO_SUCCESS);
489523c57df7Smcpowers 	}
489623c57df7Smcpowers 
4897f9fbec18Smcpowers 	default:
4898894b2776Smcpowers 		len = mech->cm_param_len;
4899894b2776Smcpowers 	}
4900894b2776Smcpowers 	kmem_free(mech->cm_param, len);
4901894b2776Smcpowers 	return (CRYPTO_SUCCESS);
4902894b2776Smcpowers }
49037c478bd9Sstevel@tonic-gate 
49047c478bd9Sstevel@tonic-gate /*
4905034448feSmcpowers  * No (Key)Store Key management entry point.
4906034448feSmcpowers  */
4907034448feSmcpowers static int
4908034448feSmcpowers dprov_nostore_key_generate(crypto_provider_handle_t provider,
4909034448feSmcpowers     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
4910034448feSmcpowers     crypto_object_attribute_t *template, uint_t attribute_count,
4911034448feSmcpowers     crypto_object_attribute_t *out_template, uint_t out_attribute_count,
4912034448feSmcpowers     crypto_req_handle_t req)
4913034448feSmcpowers {
4914034448feSmcpowers 	int error = CRYPTO_FAILED;
4915034448feSmcpowers 	dprov_state_t *softc = (dprov_state_t *)provider;
4916034448feSmcpowers 	/* LINTED E_FUNC_SET_NOT_USED */
4917034448feSmcpowers 	int instance;
4918034448feSmcpowers 
4919034448feSmcpowers 	instance = ddi_get_instance(softc->ds_dip);
4920034448feSmcpowers 	DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate: started\n",
4921034448feSmcpowers 	    instance));
4922034448feSmcpowers 
4923034448feSmcpowers 	/* submit request to the taskq */
4924034448feSmcpowers 	error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_GENERATE,
4925034448feSmcpowers 	    softc, req, session_id, mechanism, template, attribute_count,
4926034448feSmcpowers 	    NULL, NULL, 0, NULL, NULL, NULL, 0, out_template,
4927034448feSmcpowers 	    out_attribute_count, NULL, 0);
4928034448feSmcpowers 
4929034448feSmcpowers 	DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate: "
4930034448feSmcpowers 	    "done err = 0x0%x\n", instance, error));
4931034448feSmcpowers 
4932034448feSmcpowers 	return (error);
4933034448feSmcpowers }
4934034448feSmcpowers 
49355b0c7657Sizick static int
49365b0c7657Sizick dprov_nostore_key_generate_pair(crypto_provider_handle_t provider,
49375b0c7657Sizick     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
49385b0c7657Sizick     crypto_object_attribute_t *public_key_template,
49395b0c7657Sizick     uint_t public_key_attribute_count,
49405b0c7657Sizick     crypto_object_attribute_t *private_key_template,
49415b0c7657Sizick     uint_t private_key_attribute_count,
49425b0c7657Sizick     crypto_object_attribute_t *out_public_key_template,
49435b0c7657Sizick     uint_t out_public_key_attribute_count,
49445b0c7657Sizick     crypto_object_attribute_t *out_private_key_template,
49455b0c7657Sizick     uint_t out_private_key_attribute_count,
49465b0c7657Sizick     crypto_req_handle_t req)
49475b0c7657Sizick {
49485b0c7657Sizick 	int error = CRYPTO_FAILED;
49495b0c7657Sizick 	dprov_state_t *softc = (dprov_state_t *)provider;
49505b0c7657Sizick 	/* LINTED E_FUNC_SET_NOT_USED */
49515b0c7657Sizick 	int instance;
49525b0c7657Sizick 
49535b0c7657Sizick 	instance = ddi_get_instance(softc->ds_dip);
49545b0c7657Sizick 	DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate_pair: started\n",
49555b0c7657Sizick 	    instance));
49565b0c7657Sizick 
49575b0c7657Sizick 	/* submit request to the taskq */
49585b0c7657Sizick 	error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR,
49595b0c7657Sizick 	    softc, req, session_id, mechanism, public_key_template,
49605b0c7657Sizick 	    public_key_attribute_count, NULL, private_key_template,
49615b0c7657Sizick 	    private_key_attribute_count, NULL, NULL, NULL, 0,
49625b0c7657Sizick 	    out_public_key_template, out_public_key_attribute_count,
49635b0c7657Sizick 	    out_private_key_template, out_private_key_attribute_count);
49645b0c7657Sizick 
49655b0c7657Sizick 	DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate_pair: "
49665b0c7657Sizick 	    "done err = 0x0%x\n", instance, error));
49675b0c7657Sizick 
49685b0c7657Sizick 	return (error);
49695b0c7657Sizick }
49705b0c7657Sizick 
49715b0c7657Sizick static int
49725b0c7657Sizick dprov_nostore_key_derive(crypto_provider_handle_t provider,
49735b0c7657Sizick     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
49745b0c7657Sizick     crypto_key_t *base_key, crypto_object_attribute_t *template,
49755b0c7657Sizick     uint_t attribute_count, crypto_object_attribute_t *out_template,
49765b0c7657Sizick     uint_t out_attribute_count, crypto_req_handle_t req)
49775b0c7657Sizick {
49785b0c7657Sizick 	int error = CRYPTO_FAILED;
49795b0c7657Sizick 	dprov_state_t *softc = (dprov_state_t *)provider;
49805b0c7657Sizick 	/* LINTED E_FUNC_SET_NOT_USED */
49815b0c7657Sizick 	int instance;
49825b0c7657Sizick 
49835b0c7657Sizick 	instance = ddi_get_instance(softc->ds_dip);
49845b0c7657Sizick 	DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_derive: started\n",
49855b0c7657Sizick 	    instance));
49865b0c7657Sizick 
49875b0c7657Sizick 	/* submit request to the taskq */
49885b0c7657Sizick 	error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_DERIVE, softc, req,
49895b0c7657Sizick 	    session_id, mechanism, template, attribute_count, NULL, NULL,
49905b0c7657Sizick 	    0, NULL, base_key, NULL, 0, out_template, out_attribute_count,
49915b0c7657Sizick 	    NULL, 0);
49925b0c7657Sizick 
49935b0c7657Sizick 	DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_derive: "
49945b0c7657Sizick 	    "done err = 0x0%x\n", instance, error));
49955b0c7657Sizick 
49965b0c7657Sizick 	return (error);
49975b0c7657Sizick }
49985b0c7657Sizick 
4999034448feSmcpowers /*
50007c478bd9Sstevel@tonic-gate  * Allocate a dprov taskq request and initialize the common fields.
50017c478bd9Sstevel@tonic-gate  * Return NULL if the memory allocation failed.
50027c478bd9Sstevel@tonic-gate  */
50037c478bd9Sstevel@tonic-gate static dprov_req_t *
50047c478bd9Sstevel@tonic-gate dprov_alloc_req(dprov_req_type_t req_type, dprov_state_t *softc,
50057c478bd9Sstevel@tonic-gate     crypto_req_handle_t kcf_req, int kmflag)
50067c478bd9Sstevel@tonic-gate {
50077c478bd9Sstevel@tonic-gate 	dprov_req_t *taskq_req;
50087c478bd9Sstevel@tonic-gate 
50097c478bd9Sstevel@tonic-gate 	if ((taskq_req = kmem_alloc(sizeof (dprov_req_t), kmflag)) == NULL)
50107c478bd9Sstevel@tonic-gate 		return (NULL);
50117c478bd9Sstevel@tonic-gate 
50127c478bd9Sstevel@tonic-gate 	taskq_req->dr_type = req_type;
50137c478bd9Sstevel@tonic-gate 	taskq_req->dr_softc = softc;
50147c478bd9Sstevel@tonic-gate 	taskq_req->dr_kcf_req = kcf_req;
50157c478bd9Sstevel@tonic-gate 
50167c478bd9Sstevel@tonic-gate 	return (taskq_req);
50177c478bd9Sstevel@tonic-gate }
50187c478bd9Sstevel@tonic-gate 
50197c478bd9Sstevel@tonic-gate /*
50207c478bd9Sstevel@tonic-gate  * Dispatch a dprov request on the taskq associated with a softc.
50217c478bd9Sstevel@tonic-gate  * Returns CRYPTO_HOST_MEMORY if the request cannot be queued,
50227c478bd9Sstevel@tonic-gate  * CRYPTO_QUEUED on success.
50237c478bd9Sstevel@tonic-gate  */
50247c478bd9Sstevel@tonic-gate static int
50257c478bd9Sstevel@tonic-gate dprov_taskq_dispatch(dprov_state_t *softc, dprov_req_t *taskq_req,
50267c478bd9Sstevel@tonic-gate     task_func_t *func, int kmflag)
50277c478bd9Sstevel@tonic-gate {
50287c478bd9Sstevel@tonic-gate 	if (taskq_dispatch(softc->ds_taskq, func, taskq_req,
50297c478bd9Sstevel@tonic-gate 	    kmflag == KM_NOSLEEP ? TQ_NOSLEEP : TQ_SLEEP) == (taskqid_t)0) {
50307c478bd9Sstevel@tonic-gate 		kmem_free(taskq_req, sizeof (dprov_req_t));
50317c478bd9Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
50327c478bd9Sstevel@tonic-gate 	} else
50337c478bd9Sstevel@tonic-gate 		return (CRYPTO_QUEUED);
50347c478bd9Sstevel@tonic-gate }
50357c478bd9Sstevel@tonic-gate 
50367c478bd9Sstevel@tonic-gate /*
50377c478bd9Sstevel@tonic-gate  * Helper function to submit digest operations to the taskq.
50387c478bd9Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
50397c478bd9Sstevel@tonic-gate  */
50407c478bd9Sstevel@tonic-gate static int
50417c478bd9Sstevel@tonic-gate dprov_digest_submit_req(dprov_req_type_t req_type,
50427c478bd9Sstevel@tonic-gate     dprov_state_t *softc, crypto_req_handle_t req,
50437c478bd9Sstevel@tonic-gate     crypto_mechanism_t *mechanism, crypto_data_t *data, crypto_key_t *key,
50447c478bd9Sstevel@tonic-gate     crypto_data_t *digest, crypto_ctx_t *ctx, int kmflag)
50457c478bd9Sstevel@tonic-gate {
50467c478bd9Sstevel@tonic-gate 	dprov_req_t *taskq_req;
50477c478bd9Sstevel@tonic-gate 
50487c478bd9Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
50497c478bd9Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
50507c478bd9Sstevel@tonic-gate 
50517c478bd9Sstevel@tonic-gate 	taskq_req->dr_digest_req.dr_mechanism = mechanism;
50527c478bd9Sstevel@tonic-gate 	taskq_req->dr_digest_req.dr_ctx = ctx;
50537c478bd9Sstevel@tonic-gate 	taskq_req->dr_digest_req.dr_data = data;
50547c478bd9Sstevel@tonic-gate 	taskq_req->dr_digest_req.dr_key = key;
50557c478bd9Sstevel@tonic-gate 	taskq_req->dr_digest_req.dr_digest = digest;
50567c478bd9Sstevel@tonic-gate 
50577c478bd9Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
50587c478bd9Sstevel@tonic-gate 	    (task_func_t *)dprov_digest_task, kmflag));
50597c478bd9Sstevel@tonic-gate }
50607c478bd9Sstevel@tonic-gate 
50617c478bd9Sstevel@tonic-gate /*
50627c478bd9Sstevel@tonic-gate  * Helper function to submit mac operations to the taskq.
50637c478bd9Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
50647c478bd9Sstevel@tonic-gate  */
50657c478bd9Sstevel@tonic-gate static int
50667c478bd9Sstevel@tonic-gate dprov_mac_submit_req(dprov_req_type_t req_type,
50677c478bd9Sstevel@tonic-gate     dprov_state_t *softc, crypto_req_handle_t req,
50687c478bd9Sstevel@tonic-gate     crypto_mechanism_t *mechanism, crypto_data_t *data, crypto_key_t *key,
50697c478bd9Sstevel@tonic-gate     crypto_data_t *mac, crypto_ctx_t *ctx, crypto_session_id_t sid, int kmflag)
50707c478bd9Sstevel@tonic-gate {
50717c478bd9Sstevel@tonic-gate 	dprov_req_t *taskq_req;
50727c478bd9Sstevel@tonic-gate 
50737c478bd9Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
50747c478bd9Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
50757c478bd9Sstevel@tonic-gate 
50767c478bd9Sstevel@tonic-gate 	taskq_req->dr_mac_req.dr_mechanism = mechanism;
50777c478bd9Sstevel@tonic-gate 	taskq_req->dr_mac_req.dr_ctx = ctx;
50787c478bd9Sstevel@tonic-gate 	taskq_req->dr_mac_req.dr_data = data;
50797c478bd9Sstevel@tonic-gate 	taskq_req->dr_mac_req.dr_key = key;
50807c478bd9Sstevel@tonic-gate 	taskq_req->dr_mac_req.dr_mac = mac;
50817c478bd9Sstevel@tonic-gate 	taskq_req->dr_mac_req.dr_session_id = sid;
50827c478bd9Sstevel@tonic-gate 
50837c478bd9Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
50847c478bd9Sstevel@tonic-gate 	    (task_func_t *)dprov_mac_task, kmflag));
50857c478bd9Sstevel@tonic-gate }
50867c478bd9Sstevel@tonic-gate 
50877c478bd9Sstevel@tonic-gate /*
50887c478bd9Sstevel@tonic-gate  * Helper function to submit sign operations to the taskq.
50897c478bd9Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
50907c478bd9Sstevel@tonic-gate  */
50917c478bd9Sstevel@tonic-gate static int
50927c478bd9Sstevel@tonic-gate dprov_sign_submit_req(dprov_req_type_t req_type,
50937c478bd9Sstevel@tonic-gate     dprov_state_t *softc, crypto_req_handle_t req,
50947c478bd9Sstevel@tonic-gate     crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data,
50957c478bd9Sstevel@tonic-gate     crypto_data_t *signature, crypto_ctx_t *ctx, crypto_session_id_t sid,
50967c478bd9Sstevel@tonic-gate     int kmflag)
50977c478bd9Sstevel@tonic-gate {
50987c478bd9Sstevel@tonic-gate 	dprov_req_t *taskq_req;
50997c478bd9Sstevel@tonic-gate 
51007c478bd9Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
51017c478bd9Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
51027c478bd9Sstevel@tonic-gate 
51037c478bd9Sstevel@tonic-gate 	taskq_req->dr_sign_req.sr_mechanism = mechanism;
51047c478bd9Sstevel@tonic-gate 	taskq_req->dr_sign_req.sr_ctx = ctx;
51057c478bd9Sstevel@tonic-gate 	taskq_req->dr_sign_req.sr_key = key;
51067c478bd9Sstevel@tonic-gate 	taskq_req->dr_sign_req.sr_data = data;
51077c478bd9Sstevel@tonic-gate 	taskq_req->dr_sign_req.sr_signature = signature;
51087c478bd9Sstevel@tonic-gate 	taskq_req->dr_sign_req.sr_session_id = sid;
51097c478bd9Sstevel@tonic-gate 
51107c478bd9Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
51117c478bd9Sstevel@tonic-gate 	    (task_func_t *)dprov_sign_task, kmflag));
51127c478bd9Sstevel@tonic-gate }
51137c478bd9Sstevel@tonic-gate 
51147c478bd9Sstevel@tonic-gate /*
51157c478bd9Sstevel@tonic-gate  * Helper function to submit verify operations to the taskq.
51167c478bd9Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
51177c478bd9Sstevel@tonic-gate  */
51187c478bd9Sstevel@tonic-gate static int
51197c478bd9Sstevel@tonic-gate dprov_verify_submit_req(dprov_req_type_t req_type,
51207c478bd9Sstevel@tonic-gate     dprov_state_t *softc, crypto_req_handle_t req,
51217c478bd9Sstevel@tonic-gate     crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data,
51227c478bd9Sstevel@tonic-gate     crypto_data_t *signature, crypto_ctx_t *ctx, crypto_session_id_t sid,
51237c478bd9Sstevel@tonic-gate     int kmflag)
51247c478bd9Sstevel@tonic-gate {
51257c478bd9Sstevel@tonic-gate 	dprov_req_t *taskq_req;
51267c478bd9Sstevel@tonic-gate 
51277c478bd9Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
51287c478bd9Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
51297c478bd9Sstevel@tonic-gate 
51307c478bd9Sstevel@tonic-gate 	taskq_req->dr_verify_req.vr_mechanism = mechanism;
51317c478bd9Sstevel@tonic-gate 	taskq_req->dr_verify_req.vr_ctx = ctx;
51327c478bd9Sstevel@tonic-gate 	taskq_req->dr_verify_req.vr_key = key;
51337c478bd9Sstevel@tonic-gate 	taskq_req->dr_verify_req.vr_data = data;
51347c478bd9Sstevel@tonic-gate 	taskq_req->dr_verify_req.vr_signature = signature;
51357c478bd9Sstevel@tonic-gate 	taskq_req->dr_verify_req.vr_session_id = sid;
51367c478bd9Sstevel@tonic-gate 
51377c478bd9Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
51387c478bd9Sstevel@tonic-gate 	    (task_func_t *)dprov_verify_task, kmflag));
51397c478bd9Sstevel@tonic-gate }
51407c478bd9Sstevel@tonic-gate 
51417c478bd9Sstevel@tonic-gate /*
51427c478bd9Sstevel@tonic-gate  * Helper function to submit dual operations to the taskq.
51437c478bd9Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
51447c478bd9Sstevel@tonic-gate  */
51457c478bd9Sstevel@tonic-gate static int
51467c478bd9Sstevel@tonic-gate dprov_dual_submit_req(dprov_req_type_t req_type, dprov_state_t *softc,
51477c478bd9Sstevel@tonic-gate     crypto_req_handle_t req, crypto_ctx_t *signverify_ctx,
51487c478bd9Sstevel@tonic-gate     crypto_ctx_t *cipher_ctx, crypto_data_t *plaintext,
51497c478bd9Sstevel@tonic-gate     crypto_data_t *ciphertext)
51507c478bd9Sstevel@tonic-gate {
51517c478bd9Sstevel@tonic-gate 	dprov_req_t *taskq_req;
51527c478bd9Sstevel@tonic-gate 
51537c478bd9Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req,
51547c478bd9Sstevel@tonic-gate 	    KM_NOSLEEP)) == NULL)
51557c478bd9Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
51567c478bd9Sstevel@tonic-gate 
51577c478bd9Sstevel@tonic-gate 	taskq_req->dr_dual_req.dr_signverify_ctx = signverify_ctx;
51587c478bd9Sstevel@tonic-gate 	taskq_req->dr_dual_req.dr_cipher_ctx = cipher_ctx;
51597c478bd9Sstevel@tonic-gate 	taskq_req->dr_dual_req.dr_plaintext = plaintext;
51607c478bd9Sstevel@tonic-gate 	taskq_req->dr_dual_req.dr_ciphertext = ciphertext;
51617c478bd9Sstevel@tonic-gate 
51627c478bd9Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
51637c478bd9Sstevel@tonic-gate 	    (task_func_t *)dprov_dual_task, KM_NOSLEEP));
51647c478bd9Sstevel@tonic-gate }
51657c478bd9Sstevel@tonic-gate 
51667c478bd9Sstevel@tonic-gate /*
51677c478bd9Sstevel@tonic-gate  * Helper function to submit dual cipher/mac operations to the taskq.
51687c478bd9Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
51697c478bd9Sstevel@tonic-gate  */
51707c478bd9Sstevel@tonic-gate static int
51717c478bd9Sstevel@tonic-gate dprov_cipher_mac_submit_req(dprov_req_type_t req_type,
51727c478bd9Sstevel@tonic-gate     dprov_state_t *softc, crypto_req_handle_t req, crypto_ctx_t *ctx,
51737c478bd9Sstevel@tonic-gate     crypto_session_id_t sid, crypto_mechanism_t *cipher_mech,
51747c478bd9Sstevel@tonic-gate     crypto_key_t *cipher_key, crypto_mechanism_t *mac_mech,
51757c478bd9Sstevel@tonic-gate     crypto_key_t *mac_key, crypto_dual_data_t *dual_data,
51767c478bd9Sstevel@tonic-gate     crypto_data_t *data, crypto_data_t *mac, int kmflag)
51777c478bd9Sstevel@tonic-gate {
51787c478bd9Sstevel@tonic-gate 	dprov_req_t *taskq_req;
51797c478bd9Sstevel@tonic-gate 
51807c478bd9Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
51817c478bd9Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
51827c478bd9Sstevel@tonic-gate 
51837c478bd9Sstevel@tonic-gate 	taskq_req->dr_cipher_mac_req.mr_session_id = sid;
51847c478bd9Sstevel@tonic-gate 	taskq_req->dr_cipher_mac_req.mr_ctx = ctx;
51857c478bd9Sstevel@tonic-gate 	taskq_req->dr_cipher_mac_req.mr_cipher_mech = cipher_mech;
51867c478bd9Sstevel@tonic-gate 	taskq_req->dr_cipher_mac_req.mr_cipher_key = cipher_key;
51877c478bd9Sstevel@tonic-gate 	taskq_req->dr_cipher_mac_req.mr_mac_mech = mac_mech;
51887c478bd9Sstevel@tonic-gate 	taskq_req->dr_cipher_mac_req.mr_mac_key = mac_key;
51897c478bd9Sstevel@tonic-gate 	taskq_req->dr_cipher_mac_req.mr_dual_data = dual_data;
51907c478bd9Sstevel@tonic-gate 	taskq_req->dr_cipher_mac_req.mr_data = data;
51917c478bd9Sstevel@tonic-gate 	taskq_req->dr_cipher_mac_req.mr_mac = mac;
51927c478bd9Sstevel@tonic-gate 
51937c478bd9Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
51947c478bd9Sstevel@tonic-gate 	    (task_func_t *)dprov_cipher_mac_task, kmflag));
51957c478bd9Sstevel@tonic-gate }
51967c478bd9Sstevel@tonic-gate 
51977c478bd9Sstevel@tonic-gate /*
51987c478bd9Sstevel@tonic-gate  * Helper function to submit cipher operations to the taskq.
51997c478bd9Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
52007c478bd9Sstevel@tonic-gate  */
52017c478bd9Sstevel@tonic-gate static int
52027c478bd9Sstevel@tonic-gate dprov_cipher_submit_req(dprov_req_type_t req_type,
52037c478bd9Sstevel@tonic-gate     dprov_state_t *softc, crypto_req_handle_t req,
52047c478bd9Sstevel@tonic-gate     crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *plaintext,
52057c478bd9Sstevel@tonic-gate     crypto_data_t *ciphertext, crypto_ctx_t *ctx, crypto_session_id_t sid,
52067c478bd9Sstevel@tonic-gate     int kmflag)
52077c478bd9Sstevel@tonic-gate {
52087c478bd9Sstevel@tonic-gate 	dprov_req_t *taskq_req;
52097c478bd9Sstevel@tonic-gate 
52107c478bd9Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
52117c478bd9Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
52127c478bd9Sstevel@tonic-gate 
52137c478bd9Sstevel@tonic-gate 	taskq_req->dr_cipher_req.dr_mechanism = mechanism;
52147c478bd9Sstevel@tonic-gate 	taskq_req->dr_cipher_req.dr_ctx = ctx;
52157c478bd9Sstevel@tonic-gate 	taskq_req->dr_cipher_req.dr_key = key;
52167c478bd9Sstevel@tonic-gate 	taskq_req->dr_cipher_req.dr_plaintext = plaintext;
52177c478bd9Sstevel@tonic-gate 	taskq_req->dr_cipher_req.dr_ciphertext = ciphertext;
52187c478bd9Sstevel@tonic-gate 	taskq_req->dr_cipher_req.dr_session_id = sid;
52197c478bd9Sstevel@tonic-gate 
52207c478bd9Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
52217c478bd9Sstevel@tonic-gate 	    (task_func_t *)dprov_cipher_task, kmflag));
52227c478bd9Sstevel@tonic-gate }
52237c478bd9Sstevel@tonic-gate 
52247c478bd9Sstevel@tonic-gate /*
52257c478bd9Sstevel@tonic-gate  * Helper function to submit random number operations to the taskq.
52267c478bd9Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
52277c478bd9Sstevel@tonic-gate  */
52287c478bd9Sstevel@tonic-gate static int
52297c478bd9Sstevel@tonic-gate dprov_random_submit_req(dprov_req_type_t req_type,
52307c478bd9Sstevel@tonic-gate     dprov_state_t *softc, crypto_req_handle_t req, uchar_t *buf, size_t len,
52318047c9fbSmcpowers     crypto_session_id_t sid, uint_t entropy_est, uint32_t flags)
52327c478bd9Sstevel@tonic-gate {
52337c478bd9Sstevel@tonic-gate 	dprov_req_t *taskq_req;
52347c478bd9Sstevel@tonic-gate 
52357c478bd9Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req,
52367c478bd9Sstevel@tonic-gate 	    KM_NOSLEEP)) == NULL)
52377c478bd9Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
52387c478bd9Sstevel@tonic-gate 
52397c478bd9Sstevel@tonic-gate 	taskq_req->dr_random_req.rr_buf = buf;
52407c478bd9Sstevel@tonic-gate 	taskq_req->dr_random_req.rr_len = len;
52417c478bd9Sstevel@tonic-gate 	taskq_req->dr_random_req.rr_session_id = sid;
52428047c9fbSmcpowers 	taskq_req->dr_random_req.rr_entropy_est = entropy_est;
52438047c9fbSmcpowers 	taskq_req->dr_random_req.rr_flags = flags;
52447c478bd9Sstevel@tonic-gate 
52457c478bd9Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
52467c478bd9Sstevel@tonic-gate 	    (task_func_t *)dprov_random_task, KM_NOSLEEP));
52477c478bd9Sstevel@tonic-gate }
52487c478bd9Sstevel@tonic-gate 
52497c478bd9Sstevel@tonic-gate 
52507c478bd9Sstevel@tonic-gate /*
52517c478bd9Sstevel@tonic-gate  * Helper function to submit session management operations to the taskq.
52527c478bd9Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
52537c478bd9Sstevel@tonic-gate  */
52547c478bd9Sstevel@tonic-gate static int
52557c478bd9Sstevel@tonic-gate dprov_session_submit_req(dprov_req_type_t req_type,
52567c478bd9Sstevel@tonic-gate     dprov_state_t *softc, crypto_req_handle_t req,
52577c478bd9Sstevel@tonic-gate     crypto_session_id_t *session_id_ptr, crypto_session_id_t session_id,
52587c478bd9Sstevel@tonic-gate     crypto_user_type_t user_type, char *pin, size_t pin_len)
52597c478bd9Sstevel@tonic-gate {
52607c478bd9Sstevel@tonic-gate 	dprov_req_t *taskq_req;
52617c478bd9Sstevel@tonic-gate 
52627c478bd9Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req,
52637c478bd9Sstevel@tonic-gate 	    KM_NOSLEEP)) == NULL)
52647c478bd9Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
52657c478bd9Sstevel@tonic-gate 
52667c478bd9Sstevel@tonic-gate 	taskq_req->dr_session_req.sr_session_id_ptr = session_id_ptr;
52677c478bd9Sstevel@tonic-gate 	taskq_req->dr_session_req.sr_session_id = session_id;
52687c478bd9Sstevel@tonic-gate 	taskq_req->dr_session_req.sr_user_type = user_type;
52697c478bd9Sstevel@tonic-gate 	taskq_req->dr_session_req.sr_pin = pin;
52707c478bd9Sstevel@tonic-gate 	taskq_req->dr_session_req.sr_pin_len = pin_len;
52717c478bd9Sstevel@tonic-gate 
52727c478bd9Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
52737c478bd9Sstevel@tonic-gate 	    (task_func_t *)dprov_session_task, KM_NOSLEEP));
52747c478bd9Sstevel@tonic-gate }
52757c478bd9Sstevel@tonic-gate 
52767c478bd9Sstevel@tonic-gate /*
52777c478bd9Sstevel@tonic-gate  * Helper function to submit object management operations to the taskq.
52787c478bd9Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
52797c478bd9Sstevel@tonic-gate  */
52807c478bd9Sstevel@tonic-gate static int
52817c478bd9Sstevel@tonic-gate dprov_object_submit_req(dprov_req_type_t req_type,
52827c478bd9Sstevel@tonic-gate     dprov_state_t *softc, crypto_req_handle_t req,
52837c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_object_id_t object_id,
52847c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *template, uint_t attribute_count,
52857c478bd9Sstevel@tonic-gate     crypto_object_id_t *object_id_ptr, size_t *object_size,
52867c478bd9Sstevel@tonic-gate     void **find_pp, void *find_p, uint_t max_object_count,
52877c478bd9Sstevel@tonic-gate     uint_t *object_count_ptr, int kmflag)
52887c478bd9Sstevel@tonic-gate {
52897c478bd9Sstevel@tonic-gate 	dprov_req_t *taskq_req;
52907c478bd9Sstevel@tonic-gate 
52917c478bd9Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req,
52927c478bd9Sstevel@tonic-gate 	    kmflag)) == NULL)
52937c478bd9Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
52947c478bd9Sstevel@tonic-gate 
52957c478bd9Sstevel@tonic-gate 	taskq_req->dr_object_req.or_session_id = session_id;
52967c478bd9Sstevel@tonic-gate 	taskq_req->dr_object_req.or_object_id = object_id;
52977c478bd9Sstevel@tonic-gate 	taskq_req->dr_object_req.or_template = template;
52987c478bd9Sstevel@tonic-gate 	taskq_req->dr_object_req.or_attribute_count = attribute_count;
52997c478bd9Sstevel@tonic-gate 	taskq_req->dr_object_req.or_object_id_ptr = object_id_ptr;
53007c478bd9Sstevel@tonic-gate 	taskq_req->dr_object_req.or_object_size = object_size;
53017c478bd9Sstevel@tonic-gate 	taskq_req->dr_object_req.or_find_pp = find_pp;
53027c478bd9Sstevel@tonic-gate 	taskq_req->dr_object_req.or_find_p = find_p;
53037c478bd9Sstevel@tonic-gate 	taskq_req->dr_object_req.or_max_object_count = max_object_count;
53047c478bd9Sstevel@tonic-gate 	taskq_req->dr_object_req.or_object_count_ptr = object_count_ptr;
53057c478bd9Sstevel@tonic-gate 
53067c478bd9Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
53077c478bd9Sstevel@tonic-gate 	    (task_func_t *)dprov_object_task, KM_NOSLEEP));
53087c478bd9Sstevel@tonic-gate }
53097c478bd9Sstevel@tonic-gate 
53107c478bd9Sstevel@tonic-gate /*
53117c478bd9Sstevel@tonic-gate  * Helper function to submit key management operations to the taskq.
53127c478bd9Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
53137c478bd9Sstevel@tonic-gate  */
53147c478bd9Sstevel@tonic-gate static int
53157c478bd9Sstevel@tonic-gate dprov_key_submit_req(dprov_req_type_t req_type,
53167c478bd9Sstevel@tonic-gate     dprov_state_t *softc, crypto_req_handle_t req,
53177c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
53187c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *template, uint_t attribute_count,
53197c478bd9Sstevel@tonic-gate     crypto_object_id_t *object_id_ptr,
53207c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *private_key_template,
53217c478bd9Sstevel@tonic-gate     uint_t private_key_attribute_count,
53227c478bd9Sstevel@tonic-gate     crypto_object_id_t *private_key_object_id_ptr, crypto_key_t *key,
5323034448feSmcpowers     uchar_t *wrapped_key, size_t *wrapped_key_len_ptr,
5324034448feSmcpowers     crypto_object_attribute_t *out_template1, uint_t out_attribute_count1,
5325034448feSmcpowers     crypto_object_attribute_t *out_template2, uint_t out_attribute_count2)
53267c478bd9Sstevel@tonic-gate {
53277c478bd9Sstevel@tonic-gate 	dprov_req_t *taskq_req;
53287c478bd9Sstevel@tonic-gate 
53297c478bd9Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req,
53307c478bd9Sstevel@tonic-gate 	    KM_NOSLEEP)) == NULL)
53317c478bd9Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
53327c478bd9Sstevel@tonic-gate 
53337c478bd9Sstevel@tonic-gate 	taskq_req->dr_key_req.kr_session_id = session_id;
53347c478bd9Sstevel@tonic-gate 	taskq_req->dr_key_req.kr_mechanism = mechanism;
53357c478bd9Sstevel@tonic-gate 	taskq_req->dr_key_req.kr_template = template;
53367c478bd9Sstevel@tonic-gate 	taskq_req->dr_key_req.kr_attribute_count = attribute_count;
53377c478bd9Sstevel@tonic-gate 	taskq_req->dr_key_req.kr_object_id_ptr = object_id_ptr;
53387c478bd9Sstevel@tonic-gate 	taskq_req->dr_key_req.kr_private_key_template = private_key_template;
53397c478bd9Sstevel@tonic-gate 	taskq_req->dr_key_req.kr_private_key_attribute_count =
53407c478bd9Sstevel@tonic-gate 	    private_key_attribute_count;
53417c478bd9Sstevel@tonic-gate 	taskq_req->dr_key_req.kr_private_key_object_id_ptr =
53427c478bd9Sstevel@tonic-gate 	    private_key_object_id_ptr;
53437c478bd9Sstevel@tonic-gate 	taskq_req->dr_key_req.kr_key = key;
53447c478bd9Sstevel@tonic-gate 	taskq_req->dr_key_req.kr_wrapped_key = wrapped_key;
53457c478bd9Sstevel@tonic-gate 	taskq_req->dr_key_req.kr_wrapped_key_len_ptr = wrapped_key_len_ptr;
5346034448feSmcpowers 	taskq_req->dr_key_req.kr_out_template1 = out_template1;
5347034448feSmcpowers 	taskq_req->dr_key_req.kr_out_attribute_count1 = out_attribute_count1;
5348034448feSmcpowers 	taskq_req->dr_key_req.kr_out_template2 = out_template2;
5349034448feSmcpowers 	taskq_req->dr_key_req.kr_out_attribute_count2 = out_attribute_count2;
53507c478bd9Sstevel@tonic-gate 
53517c478bd9Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
53527c478bd9Sstevel@tonic-gate 	    (task_func_t *)dprov_key_task, KM_NOSLEEP));
53537c478bd9Sstevel@tonic-gate }
53547c478bd9Sstevel@tonic-gate 
53557c478bd9Sstevel@tonic-gate /*
53567c478bd9Sstevel@tonic-gate  * Helper function to submit provider management operations to the taskq.
53577c478bd9Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
53587c478bd9Sstevel@tonic-gate  */
53597c478bd9Sstevel@tonic-gate static int
53607c478bd9Sstevel@tonic-gate dprov_mgmt_submit_req(dprov_req_type_t req_type,
53617c478bd9Sstevel@tonic-gate     dprov_state_t *softc, crypto_req_handle_t req,
53627c478bd9Sstevel@tonic-gate     crypto_session_id_t session_id, char *pin, size_t pin_len,
53637c478bd9Sstevel@tonic-gate     char *old_pin, size_t old_pin_len, char *label,
53647c478bd9Sstevel@tonic-gate     crypto_provider_ext_info_t *ext_info)
53657c478bd9Sstevel@tonic-gate {
53667c478bd9Sstevel@tonic-gate 	dprov_req_t *taskq_req;
53677c478bd9Sstevel@tonic-gate 
53687c478bd9Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req,
53697c478bd9Sstevel@tonic-gate 	    KM_NOSLEEP)) == NULL)
53707c478bd9Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
53717c478bd9Sstevel@tonic-gate 
53727c478bd9Sstevel@tonic-gate 	taskq_req->dr_mgmt_req.mr_session_id = session_id;
53737c478bd9Sstevel@tonic-gate 	taskq_req->dr_mgmt_req.mr_pin = pin;
53747c478bd9Sstevel@tonic-gate 	taskq_req->dr_mgmt_req.mr_pin_len = pin_len;
53757c478bd9Sstevel@tonic-gate 	taskq_req->dr_mgmt_req.mr_old_pin = old_pin;
53767c478bd9Sstevel@tonic-gate 	taskq_req->dr_mgmt_req.mr_old_pin_len = old_pin_len;
53777c478bd9Sstevel@tonic-gate 	taskq_req->dr_mgmt_req.mr_label = label;
53787c478bd9Sstevel@tonic-gate 	taskq_req->dr_mgmt_req.mr_ext_info = ext_info;
53797c478bd9Sstevel@tonic-gate 
53807c478bd9Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
53817c478bd9Sstevel@tonic-gate 	    (task_func_t *)dprov_mgmt_task, KM_NOSLEEP));
53827c478bd9Sstevel@tonic-gate }
53837c478bd9Sstevel@tonic-gate 
53847c478bd9Sstevel@tonic-gate /*
53857c478bd9Sstevel@tonic-gate  * Helper function for taskq dispatcher routines. Notify the framework
53867c478bd9Sstevel@tonic-gate  * that the operation corresponding to the specified request is done,
53877c478bd9Sstevel@tonic-gate  * and pass it the error code. Finally, free the taskq_req.
53887c478bd9Sstevel@tonic-gate  */
53897c478bd9Sstevel@tonic-gate static void
53907c478bd9Sstevel@tonic-gate dprov_op_done(dprov_req_t *taskq_req, int error)
53917c478bd9Sstevel@tonic-gate {
53927c478bd9Sstevel@tonic-gate 	/* notify framework that request is completed */
53937c478bd9Sstevel@tonic-gate 	crypto_op_notification(taskq_req->dr_kcf_req, error);
53947c478bd9Sstevel@tonic-gate 
53957c478bd9Sstevel@tonic-gate 	/* free taskq request structure */
53967c478bd9Sstevel@tonic-gate 	kmem_free(taskq_req, sizeof (dprov_req_t));
53977c478bd9Sstevel@tonic-gate }
53987c478bd9Sstevel@tonic-gate 
53997c478bd9Sstevel@tonic-gate /*
54007c478bd9Sstevel@tonic-gate  * taskq dispatcher function for digest operations.
54017c478bd9Sstevel@tonic-gate  */
54027c478bd9Sstevel@tonic-gate static void
54037c478bd9Sstevel@tonic-gate dprov_digest_task(dprov_req_t *taskq_req)
54047c478bd9Sstevel@tonic-gate {
54057c478bd9Sstevel@tonic-gate 	kcf_provider_desc_t *pd;
54067c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
54077c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
54087c478bd9Sstevel@tonic-gate 	int instance;
54097c478bd9Sstevel@tonic-gate 	int error = CRYPTO_NOT_SUPPORTED;
54107c478bd9Sstevel@tonic-gate 	crypto_ctx_t *ctx = taskq_req->dr_digest_req.dr_ctx;
54117c478bd9Sstevel@tonic-gate 	crypto_mechanism_t mech;
54127c478bd9Sstevel@tonic-gate 
54137c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
54147c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_task: started\n", instance));
54157c478bd9Sstevel@tonic-gate 
54167c478bd9Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
54177c478bd9Sstevel@tonic-gate 
54187c478bd9Sstevel@tonic-gate 	case DPROV_REQ_DIGEST_INIT:
54197c478bd9Sstevel@tonic-gate 		/* allocate a dprov-private context */
54207c478bd9Sstevel@tonic-gate 		if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
54217c478bd9Sstevel@tonic-gate 		    CRYPTO_SUCCESS)
54227c478bd9Sstevel@tonic-gate 			break;
54237c478bd9Sstevel@tonic-gate 
54247c478bd9Sstevel@tonic-gate 		/* structure assignment */
54257c478bd9Sstevel@tonic-gate 		mech = *taskq_req->dr_digest_req.dr_mechanism;
54267c478bd9Sstevel@tonic-gate 
54277c478bd9Sstevel@tonic-gate 		/* get the software provider for this mechanism */
54287c478bd9Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(
54297c478bd9Sstevel@tonic-gate 		    taskq_req->dr_digest_req.dr_mechanism, &pd,
54307c478bd9Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
54317c478bd9Sstevel@tonic-gate 			break;
54327c478bd9Sstevel@tonic-gate 
54337c478bd9Sstevel@tonic-gate 		/* Use a session id of zero since we use a software provider */
54347c478bd9Sstevel@tonic-gate 		error = crypto_digest_init_prov(pd, 0, &mech,
54357c478bd9Sstevel@tonic-gate 		    &DPROV_CTX_SINGLE(ctx), NULL);
54367c478bd9Sstevel@tonic-gate 
54377c478bd9Sstevel@tonic-gate 		/* release provider reference */
54387c478bd9Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
54397c478bd9Sstevel@tonic-gate 		break;
54407c478bd9Sstevel@tonic-gate 
54417c478bd9Sstevel@tonic-gate 	case DPROV_REQ_DIGEST:
54427c478bd9Sstevel@tonic-gate 		error = crypto_digest_single(DPROV_CTX_SINGLE(ctx),
54437c478bd9Sstevel@tonic-gate 		    taskq_req->dr_digest_req.dr_data,
54447c478bd9Sstevel@tonic-gate 		    taskq_req->dr_digest_req.dr_digest, NULL);
54457c478bd9Sstevel@tonic-gate 
54467c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
54477c478bd9Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
54487c478bd9Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
54497c478bd9Sstevel@tonic-gate 		}
54507c478bd9Sstevel@tonic-gate 		break;
54517c478bd9Sstevel@tonic-gate 
54527c478bd9Sstevel@tonic-gate 	case DPROV_REQ_DIGEST_UPDATE:
54537c478bd9Sstevel@tonic-gate 		error = crypto_digest_update(DPROV_CTX_SINGLE(ctx),
54547c478bd9Sstevel@tonic-gate 		    taskq_req->dr_digest_req.dr_data, NULL);
54557c478bd9Sstevel@tonic-gate 		break;
54567c478bd9Sstevel@tonic-gate 
54577c478bd9Sstevel@tonic-gate 	case DPROV_REQ_DIGEST_KEY: {
54587c478bd9Sstevel@tonic-gate 		crypto_data_t data;
54597c478bd9Sstevel@tonic-gate 		crypto_key_t key;
54607c478bd9Sstevel@tonic-gate 		size_t len;
54617c478bd9Sstevel@tonic-gate 
54627c478bd9Sstevel@tonic-gate 		mutex_enter(&softc->ds_lock);
54637c478bd9Sstevel@tonic-gate 		error = dprov_key_value_secret(softc, ctx->cc_session,
54647c478bd9Sstevel@tonic-gate 		    taskq_req->dr_type, taskq_req->dr_digest_req.dr_key, &key);
54657c478bd9Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
54667c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
54677c478bd9Sstevel@tonic-gate 			break;
54687c478bd9Sstevel@tonic-gate 
54697c478bd9Sstevel@tonic-gate 		/* key lengths are specified in bits */
54707c478bd9Sstevel@tonic-gate 		len = CRYPTO_BITS2BYTES(key.ck_length);
54717c478bd9Sstevel@tonic-gate 		data.cd_format = CRYPTO_DATA_RAW;
54727c478bd9Sstevel@tonic-gate 		data.cd_offset = 0;
54737c478bd9Sstevel@tonic-gate 		data.cd_length = len;
54747c478bd9Sstevel@tonic-gate 		data.cd_raw.iov_base = key.ck_data;
54757c478bd9Sstevel@tonic-gate 		data.cd_raw.iov_len = len;
54767c478bd9Sstevel@tonic-gate 		error = crypto_digest_update(DPROV_CTX_SINGLE(ctx),
54777c478bd9Sstevel@tonic-gate 		    &data, NULL);
54787c478bd9Sstevel@tonic-gate 		break;
54797c478bd9Sstevel@tonic-gate 	}
54807c478bd9Sstevel@tonic-gate 
54817c478bd9Sstevel@tonic-gate 	case DPROV_REQ_DIGEST_FINAL:
54827c478bd9Sstevel@tonic-gate 		error = crypto_digest_final(DPROV_CTX_SINGLE(ctx),
54837c478bd9Sstevel@tonic-gate 		    taskq_req->dr_digest_req.dr_digest, NULL);
54847c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
54857c478bd9Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
54867c478bd9Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
54877c478bd9Sstevel@tonic-gate 		}
54887c478bd9Sstevel@tonic-gate 		break;
54897c478bd9Sstevel@tonic-gate 
54907c478bd9Sstevel@tonic-gate 	case DPROV_REQ_DIGEST_ATOMIC:
54917c478bd9Sstevel@tonic-gate 		/* structure assignment */
54927c478bd9Sstevel@tonic-gate 		mech = *taskq_req->dr_digest_req.dr_mechanism;
54937c478bd9Sstevel@tonic-gate 
54947c478bd9Sstevel@tonic-gate 		/* get the software provider for this mechanism */
54957c478bd9Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(
54967c478bd9Sstevel@tonic-gate 		    taskq_req->dr_digest_req.dr_mechanism, &pd,
54977c478bd9Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
54987c478bd9Sstevel@tonic-gate 			break;
54997c478bd9Sstevel@tonic-gate 
55007c478bd9Sstevel@tonic-gate 		/* use a session id of zero since we use a software provider */
5501894b2776Smcpowers 		error = crypto_digest_prov(pd, 0, &mech,
55027c478bd9Sstevel@tonic-gate 		    taskq_req->dr_digest_req.dr_data,
5503894b2776Smcpowers 		    taskq_req->dr_digest_req.dr_digest, NULL);
55047c478bd9Sstevel@tonic-gate 
55057c478bd9Sstevel@tonic-gate 		/* release provider reference */
55067c478bd9Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
55077c478bd9Sstevel@tonic-gate 
55087c478bd9Sstevel@tonic-gate 		break;
55097c478bd9Sstevel@tonic-gate 	}
55107c478bd9Sstevel@tonic-gate 
55117c478bd9Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
55127c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_task: end\n", instance));
55137c478bd9Sstevel@tonic-gate }
55147c478bd9Sstevel@tonic-gate 
55157c478bd9Sstevel@tonic-gate /*
55167c478bd9Sstevel@tonic-gate  * taskq dispatcher function for mac operations.
55177c478bd9Sstevel@tonic-gate  */
55187c478bd9Sstevel@tonic-gate static void
55197c478bd9Sstevel@tonic-gate dprov_mac_task(dprov_req_t *taskq_req)
55207c478bd9Sstevel@tonic-gate {
55217c478bd9Sstevel@tonic-gate 	kcf_provider_desc_t *pd;
55227c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
55237c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
55247c478bd9Sstevel@tonic-gate 	int instance;
55257c478bd9Sstevel@tonic-gate 	int error = CRYPTO_NOT_SUPPORTED;
55267c478bd9Sstevel@tonic-gate 	crypto_ctx_t *ctx = taskq_req->dr_mac_req.dr_ctx;
55277c478bd9Sstevel@tonic-gate 	crypto_key_t key;
55287c478bd9Sstevel@tonic-gate 	crypto_mechanism_t mech;
55297c478bd9Sstevel@tonic-gate 
55307c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
55317c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: started\n", instance));
55327c478bd9Sstevel@tonic-gate 
55337c478bd9Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
55347c478bd9Sstevel@tonic-gate 
55357c478bd9Sstevel@tonic-gate 	case DPROV_REQ_MAC_INIT:
55367c478bd9Sstevel@tonic-gate 		/* allocate a dprov-private context */
55377c478bd9Sstevel@tonic-gate 		if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
55387c478bd9Sstevel@tonic-gate 		    CRYPTO_SUCCESS)
55397c478bd9Sstevel@tonic-gate 			break;
55407c478bd9Sstevel@tonic-gate 
55417c478bd9Sstevel@tonic-gate 		/* get key value */
55427c478bd9Sstevel@tonic-gate 		mutex_enter(&softc->ds_lock);
55437c478bd9Sstevel@tonic-gate 		error = dprov_key_value_secret(softc, ctx->cc_session,
55447c478bd9Sstevel@tonic-gate 		    taskq_req->dr_type, taskq_req->dr_mac_req.dr_key, &key);
55457c478bd9Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
55467c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
55477c478bd9Sstevel@tonic-gate 			break;
55487c478bd9Sstevel@tonic-gate 
55497c478bd9Sstevel@tonic-gate 		/* structure assignment */
55507c478bd9Sstevel@tonic-gate 		mech = *taskq_req->dr_mac_req.dr_mechanism;
55517c478bd9Sstevel@tonic-gate 
55527c478bd9Sstevel@tonic-gate 		/* get the software provider for this mechanism */
55537c478bd9Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(
55547c478bd9Sstevel@tonic-gate 		    taskq_req->dr_mac_req.dr_mechanism, &pd,
55557c478bd9Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
55567c478bd9Sstevel@tonic-gate 			break;
55577c478bd9Sstevel@tonic-gate 
55587c478bd9Sstevel@tonic-gate 		/* Use a session id of zero since we use a software provider */
55597c478bd9Sstevel@tonic-gate 		error = crypto_mac_init_prov(pd, 0, &mech, &key, NULL,
55607c478bd9Sstevel@tonic-gate 		    &DPROV_CTX_SINGLE(ctx), NULL);
55617c478bd9Sstevel@tonic-gate 
55627c478bd9Sstevel@tonic-gate 		/* release provider reference */
55637c478bd9Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
55647c478bd9Sstevel@tonic-gate 		break;
55657c478bd9Sstevel@tonic-gate 
55667c478bd9Sstevel@tonic-gate 	case DPROV_REQ_MAC:
55677c478bd9Sstevel@tonic-gate 		error = crypto_mac_single(DPROV_CTX_SINGLE(ctx),
55687c478bd9Sstevel@tonic-gate 		    taskq_req->dr_mac_req.dr_data,
55697c478bd9Sstevel@tonic-gate 		    taskq_req->dr_mac_req.dr_mac, NULL);
55707c478bd9Sstevel@tonic-gate 
55717c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
55727c478bd9Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
55737c478bd9Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
55747c478bd9Sstevel@tonic-gate 		}
55757c478bd9Sstevel@tonic-gate 		break;
55767c478bd9Sstevel@tonic-gate 
55777c478bd9Sstevel@tonic-gate 	case DPROV_REQ_MAC_UPDATE:
55787c478bd9Sstevel@tonic-gate 		error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
55797c478bd9Sstevel@tonic-gate 		    taskq_req->dr_mac_req.dr_data, NULL);
55807c478bd9Sstevel@tonic-gate 		break;
55817c478bd9Sstevel@tonic-gate 
55827c478bd9Sstevel@tonic-gate 	case DPROV_REQ_MAC_FINAL:
55837c478bd9Sstevel@tonic-gate 		error = crypto_mac_final(DPROV_CTX_SINGLE(ctx),
55847c478bd9Sstevel@tonic-gate 		    taskq_req->dr_mac_req.dr_mac, NULL);
55857c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
55867c478bd9Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
55877c478bd9Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
55887c478bd9Sstevel@tonic-gate 		}
55897c478bd9Sstevel@tonic-gate 		break;
55907c478bd9Sstevel@tonic-gate 
55917c478bd9Sstevel@tonic-gate 	case DPROV_REQ_MAC_ATOMIC:
55927c478bd9Sstevel@tonic-gate 	case DPROV_REQ_MAC_VERIFY_ATOMIC:
55937c478bd9Sstevel@tonic-gate 		/* get key value */
55947c478bd9Sstevel@tonic-gate 		mutex_enter(&softc->ds_lock);
55957c478bd9Sstevel@tonic-gate 		error = dprov_key_value_secret(softc,
55967c478bd9Sstevel@tonic-gate 		    taskq_req->dr_mac_req.dr_session_id,
55977c478bd9Sstevel@tonic-gate 		    taskq_req->dr_type, taskq_req->dr_mac_req.dr_key, &key);
55987c478bd9Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
55997c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
56007c478bd9Sstevel@tonic-gate 			break;
56017c478bd9Sstevel@tonic-gate 
56027c478bd9Sstevel@tonic-gate 		/* structure assignment */
56037c478bd9Sstevel@tonic-gate 		mech = *taskq_req->dr_mac_req.dr_mechanism;
56047c478bd9Sstevel@tonic-gate 
56057c478bd9Sstevel@tonic-gate 		/* get the software provider for this mechanism */
56067c478bd9Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(
56077c478bd9Sstevel@tonic-gate 		    taskq_req->dr_mac_req.dr_mechanism, &pd,
56087c478bd9Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
56097c478bd9Sstevel@tonic-gate 			break;
56107c478bd9Sstevel@tonic-gate 
56117c478bd9Sstevel@tonic-gate 		/* use a session id of zero since we use a software provider */
56127c478bd9Sstevel@tonic-gate 		if (taskq_req->dr_type == DPROV_REQ_MAC_ATOMIC)
5613894b2776Smcpowers 			error = crypto_mac_prov(pd, 0, &mech,
56147c478bd9Sstevel@tonic-gate 			    taskq_req->dr_mac_req.dr_data,
5615894b2776Smcpowers 			    &key, NULL, taskq_req->dr_mac_req.dr_mac, NULL);
56167c478bd9Sstevel@tonic-gate 		else
5617894b2776Smcpowers 			error = crypto_mac_verify_prov(pd, 0, &mech,
56187c478bd9Sstevel@tonic-gate 			    taskq_req->dr_mac_req.dr_data,
5619894b2776Smcpowers 			    &key, NULL, taskq_req->dr_mac_req.dr_mac, NULL);
56207c478bd9Sstevel@tonic-gate 
56217c478bd9Sstevel@tonic-gate 		/* release provider reference */
56227c478bd9Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
56237c478bd9Sstevel@tonic-gate 
56247c478bd9Sstevel@tonic-gate 		break;
56257c478bd9Sstevel@tonic-gate 	}
56267c478bd9Sstevel@tonic-gate 
56277c478bd9Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
56287c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: end\n", instance));
56297c478bd9Sstevel@tonic-gate }
56307c478bd9Sstevel@tonic-gate 
56317c478bd9Sstevel@tonic-gate /*
56327c478bd9Sstevel@tonic-gate  * taskq dispatcher function for sign operations.
56337c478bd9Sstevel@tonic-gate  */
56347c478bd9Sstevel@tonic-gate static void
56357c478bd9Sstevel@tonic-gate dprov_sign_task(dprov_req_t *taskq_req)
56367c478bd9Sstevel@tonic-gate {
56377c478bd9Sstevel@tonic-gate 	kcf_provider_desc_t *pd;
56387c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
56397c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
56407c478bd9Sstevel@tonic-gate 	int instance;
56417c478bd9Sstevel@tonic-gate 	int error = CRYPTO_NOT_SUPPORTED;
5642ba5f469cSkrishna 	crypto_ctx_t *ctx = taskq_req->dr_sign_req.sr_ctx;
56437c478bd9Sstevel@tonic-gate 	crypto_key_t key, *keyp;
56447c478bd9Sstevel@tonic-gate 	crypto_mechanism_t mech;
56457c478bd9Sstevel@tonic-gate 
56467c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
56477c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_task: started\n", instance));
56487c478bd9Sstevel@tonic-gate 
56497c478bd9Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
56507c478bd9Sstevel@tonic-gate 
56517c478bd9Sstevel@tonic-gate 	case DPROV_REQ_SIGN_INIT:
56527c478bd9Sstevel@tonic-gate 	case DPROV_REQ_SIGN_RECOVER_INIT:
56537c478bd9Sstevel@tonic-gate 		/* allocate a dprov-private context */
56547c478bd9Sstevel@tonic-gate 		if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
56557c478bd9Sstevel@tonic-gate 		    CRYPTO_SUCCESS)
56567c478bd9Sstevel@tonic-gate 			break;
56577c478bd9Sstevel@tonic-gate 
56587c478bd9Sstevel@tonic-gate 		/* structure assignment */
56597c478bd9Sstevel@tonic-gate 		mech = *taskq_req->dr_sign_req.sr_mechanism;
5660ba5f469cSkrishna 		if (dprov_valid_mac_mech(mech.cm_type)) {
5661ba5f469cSkrishna 			DPROV_CTX_P(ctx)->dc_svrfy_to_mac = B_TRUE;
5662ba5f469cSkrishna 		}
56637c478bd9Sstevel@tonic-gate 
56647c478bd9Sstevel@tonic-gate 		mutex_enter(&softc->ds_lock);
56657c478bd9Sstevel@tonic-gate 		if (is_publickey_mech(mech.cm_type)) {
56667c478bd9Sstevel@tonic-gate 			if ((error = dprov_key_attr_asymmetric(softc,
56677c478bd9Sstevel@tonic-gate 			    ctx->cc_session, taskq_req->dr_type,
56687c478bd9Sstevel@tonic-gate 			    taskq_req->dr_sign_req.sr_key, &key))
56697c478bd9Sstevel@tonic-gate 			    != CRYPTO_SUCCESS) {
56707c478bd9Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
56717c478bd9Sstevel@tonic-gate 				break;
56727c478bd9Sstevel@tonic-gate 			}
56737c478bd9Sstevel@tonic-gate 			keyp = &key;
56747c478bd9Sstevel@tonic-gate 		} else {
56757c478bd9Sstevel@tonic-gate 			if ((error = dprov_key_value_secret(softc,
56767c478bd9Sstevel@tonic-gate 			    ctx->cc_session, taskq_req->dr_type,
56777c478bd9Sstevel@tonic-gate 			    taskq_req->dr_sign_req.sr_key, &key))
56787c478bd9Sstevel@tonic-gate 			    != CRYPTO_SUCCESS) {
56797c478bd9Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
56807c478bd9Sstevel@tonic-gate 				break;
56817c478bd9Sstevel@tonic-gate 			}
56827c478bd9Sstevel@tonic-gate 			keyp = &key;
56837c478bd9Sstevel@tonic-gate 		}
56847c478bd9Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
56857c478bd9Sstevel@tonic-gate 
56867c478bd9Sstevel@tonic-gate 		/* get the software provider for this mechanism */
56877c478bd9Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(
56887c478bd9Sstevel@tonic-gate 		    taskq_req->dr_sign_req.sr_mechanism, &pd,
56897c478bd9Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
56907c478bd9Sstevel@tonic-gate 			break;
56917c478bd9Sstevel@tonic-gate 
5692ba5f469cSkrishna 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5693ba5f469cSkrishna 			error = crypto_mac_init_prov(pd, 0, &mech, keyp, NULL,
5694ba5f469cSkrishna 			    &DPROV_CTX_SINGLE(ctx), NULL);
5695ba5f469cSkrishna 
5696ba5f469cSkrishna 			/* release provider reference */
5697ba5f469cSkrishna 			KCF_PROV_REFRELE(pd);
5698ba5f469cSkrishna 			break;
5699ba5f469cSkrishna 		}
5700ba5f469cSkrishna 
57017c478bd9Sstevel@tonic-gate 		/* Use a session id of zero since we use a software provider */
57027c478bd9Sstevel@tonic-gate 		if (taskq_req->dr_type == DPROV_REQ_SIGN_INIT)
57037c478bd9Sstevel@tonic-gate 			error = crypto_sign_init_prov(pd, 0, &mech, keyp,
57047c478bd9Sstevel@tonic-gate 			    NULL, &DPROV_CTX_SINGLE(ctx), NULL);
57057c478bd9Sstevel@tonic-gate 		else
57067c478bd9Sstevel@tonic-gate 			error = crypto_sign_recover_init_prov(pd, 0, &mech,
57077c478bd9Sstevel@tonic-gate 			    keyp, NULL, &DPROV_CTX_SINGLE(ctx), NULL);
57087c478bd9Sstevel@tonic-gate 
57097c478bd9Sstevel@tonic-gate 		/* release provider reference */
57107c478bd9Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
57117c478bd9Sstevel@tonic-gate 
57127c478bd9Sstevel@tonic-gate 		break;
57137c478bd9Sstevel@tonic-gate 
57147c478bd9Sstevel@tonic-gate 	case DPROV_REQ_SIGN:
5715ba5f469cSkrishna 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5716ba5f469cSkrishna 			/* Emulate using update and final */
5717ba5f469cSkrishna 			error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
5718ba5f469cSkrishna 			    taskq_req->dr_mac_req.dr_data, NULL);
5719ba5f469cSkrishna 			if (error == CRYPTO_SUCCESS) {
5720ba5f469cSkrishna 				error = crypto_mac_final(DPROV_CTX_SINGLE(ctx),
5721ba5f469cSkrishna 				    taskq_req->dr_mac_req.dr_mac, NULL);
5722ba5f469cSkrishna 			}
5723ba5f469cSkrishna 		} else {
57247c478bd9Sstevel@tonic-gate 			error = crypto_sign_single(DPROV_CTX_SINGLE(ctx),
57257c478bd9Sstevel@tonic-gate 			    taskq_req->dr_sign_req.sr_data,
57267c478bd9Sstevel@tonic-gate 			    taskq_req->dr_sign_req.sr_signature, NULL);
5727ba5f469cSkrishna 		}
57287c478bd9Sstevel@tonic-gate 
57297c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
57307c478bd9Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
57317c478bd9Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
57327c478bd9Sstevel@tonic-gate 		}
57337c478bd9Sstevel@tonic-gate 		break;
57347c478bd9Sstevel@tonic-gate 
57357c478bd9Sstevel@tonic-gate 	case DPROV_REQ_SIGN_UPDATE:
5736ba5f469cSkrishna 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5737ba5f469cSkrishna 			error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
5738ba5f469cSkrishna 			    taskq_req->dr_mac_req.dr_data, NULL);
5739ba5f469cSkrishna 		} else {
57407c478bd9Sstevel@tonic-gate 			error = crypto_sign_update(DPROV_CTX_SINGLE(ctx),
57417c478bd9Sstevel@tonic-gate 			    taskq_req->dr_sign_req.sr_data, NULL);
5742ba5f469cSkrishna 		}
57437c478bd9Sstevel@tonic-gate 		break;
57447c478bd9Sstevel@tonic-gate 
57457c478bd9Sstevel@tonic-gate 	case DPROV_REQ_SIGN_FINAL:
5746ba5f469cSkrishna 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5747ba5f469cSkrishna 			error = crypto_mac_final(DPROV_CTX_SINGLE(ctx),
5748ba5f469cSkrishna 			    taskq_req->dr_mac_req.dr_mac, NULL);
5749ba5f469cSkrishna 		} else {
57507c478bd9Sstevel@tonic-gate 			error = crypto_sign_final(DPROV_CTX_SINGLE(ctx),
57517c478bd9Sstevel@tonic-gate 			    taskq_req->dr_sign_req.sr_signature, NULL);
5752ba5f469cSkrishna 		}
57537c478bd9Sstevel@tonic-gate 
57547c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
57557c478bd9Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
57567c478bd9Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
57577c478bd9Sstevel@tonic-gate 		}
57587c478bd9Sstevel@tonic-gate 		break;
57597c478bd9Sstevel@tonic-gate 
57607c478bd9Sstevel@tonic-gate 	case DPROV_REQ_SIGN_ATOMIC:
57617c478bd9Sstevel@tonic-gate 	case DPROV_REQ_SIGN_RECOVER_ATOMIC:
57627c478bd9Sstevel@tonic-gate 		/* structure assignment */
57637c478bd9Sstevel@tonic-gate 		mech = *taskq_req->dr_sign_req.sr_mechanism;
57647c478bd9Sstevel@tonic-gate 
57657c478bd9Sstevel@tonic-gate 		mutex_enter(&softc->ds_lock);
57667c478bd9Sstevel@tonic-gate 		/* get key value for secret key algorithms */
57677c478bd9Sstevel@tonic-gate 		if (is_publickey_mech(mech.cm_type)) {
57687c478bd9Sstevel@tonic-gate 			if ((error = dprov_key_attr_asymmetric(softc,
57697c478bd9Sstevel@tonic-gate 			    taskq_req->dr_sign_req.sr_session_id,
57707c478bd9Sstevel@tonic-gate 			    taskq_req->dr_type,
57717c478bd9Sstevel@tonic-gate 			    taskq_req->dr_sign_req.sr_key, &key))
57727c478bd9Sstevel@tonic-gate 			    != CRYPTO_SUCCESS) {
57737c478bd9Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
57747c478bd9Sstevel@tonic-gate 				break;
57757c478bd9Sstevel@tonic-gate 			}
57767c478bd9Sstevel@tonic-gate 			keyp = &key;
57777c478bd9Sstevel@tonic-gate 		} else {
57787c478bd9Sstevel@tonic-gate 			if ((error = dprov_key_value_secret(softc,
57797c478bd9Sstevel@tonic-gate 			    taskq_req->dr_sign_req.sr_session_id,
57807c478bd9Sstevel@tonic-gate 			    taskq_req->dr_type,
57817c478bd9Sstevel@tonic-gate 			    taskq_req->dr_sign_req.sr_key, &key))
57827c478bd9Sstevel@tonic-gate 			    != CRYPTO_SUCCESS) {
57837c478bd9Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
57847c478bd9Sstevel@tonic-gate 				break;
57857c478bd9Sstevel@tonic-gate 			}
57867c478bd9Sstevel@tonic-gate 			keyp = &key;
57877c478bd9Sstevel@tonic-gate 		}
57887c478bd9Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
57897c478bd9Sstevel@tonic-gate 
57907c478bd9Sstevel@tonic-gate 		/* get the software provider for this mechanism */
57917c478bd9Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(
57927c478bd9Sstevel@tonic-gate 		    taskq_req->dr_sign_req.sr_mechanism, &pd,
57937c478bd9Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
57947c478bd9Sstevel@tonic-gate 			break;
57957c478bd9Sstevel@tonic-gate 
57967c478bd9Sstevel@tonic-gate 		/* Use a session id of zero since we use a software provider */
57977c478bd9Sstevel@tonic-gate 		if (taskq_req->dr_type == DPROV_REQ_SIGN_ATOMIC)
57987c478bd9Sstevel@tonic-gate 			error = crypto_sign_prov(pd, 0, &mech, keyp,
57997c478bd9Sstevel@tonic-gate 			    taskq_req->dr_sign_req.sr_data,
58007c478bd9Sstevel@tonic-gate 			    NULL, taskq_req->dr_sign_req.sr_signature, NULL);
58017c478bd9Sstevel@tonic-gate 		else
58027c478bd9Sstevel@tonic-gate 			error = crypto_sign_recover_prov(pd, 0, &mech, keyp,
58037c478bd9Sstevel@tonic-gate 			    taskq_req->dr_sign_req.sr_data,
58047c478bd9Sstevel@tonic-gate 			    NULL, taskq_req->dr_sign_req.sr_signature, NULL);
58057c478bd9Sstevel@tonic-gate 
58067c478bd9Sstevel@tonic-gate 		/* release provider reference */
58077c478bd9Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
58087c478bd9Sstevel@tonic-gate 		break;
58097c478bd9Sstevel@tonic-gate 
58107c478bd9Sstevel@tonic-gate 	case DPROV_REQ_SIGN_RECOVER:
58117c478bd9Sstevel@tonic-gate 		error = crypto_sign_recover_single(DPROV_CTX_SINGLE(ctx),
58127c478bd9Sstevel@tonic-gate 		    taskq_req->dr_sign_req.sr_data,
58137c478bd9Sstevel@tonic-gate 		    taskq_req->dr_sign_req.sr_signature, NULL);
58147c478bd9Sstevel@tonic-gate 
58157c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
58167c478bd9Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
58177c478bd9Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
58187c478bd9Sstevel@tonic-gate 		}
58197c478bd9Sstevel@tonic-gate 		break;
58207c478bd9Sstevel@tonic-gate 	}
58217c478bd9Sstevel@tonic-gate 
58227c478bd9Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
58237c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_task: end\n", instance));
58247c478bd9Sstevel@tonic-gate }
58257c478bd9Sstevel@tonic-gate 
5826ba5f469cSkrishna static int
5827ba5f469cSkrishna emulate_verify_with_mac(crypto_ctx_t *ctx, crypto_data_t *in_mac)
5828ba5f469cSkrishna {
5829ba5f469cSkrishna 	int error;
5830ba5f469cSkrishna 	crypto_data_t tmpd;
5831ba5f469cSkrishna 	crypto_data_t *out_mac;
5832ba5f469cSkrishna 	char digest[SHA512_DIGEST_LENGTH];
5833ba5f469cSkrishna 
5834ba5f469cSkrishna 	bzero(&tmpd, sizeof (crypto_data_t));
5835ba5f469cSkrishna 	tmpd.cd_format = CRYPTO_DATA_RAW;
5836ba5f469cSkrishna 	tmpd.cd_length = SHA512_DIGEST_LENGTH;
5837ba5f469cSkrishna 	tmpd.cd_raw.iov_base = digest;
5838ba5f469cSkrishna 	tmpd.cd_raw.iov_len = SHA512_DIGEST_LENGTH;
5839ba5f469cSkrishna 	out_mac = &tmpd;
5840ba5f469cSkrishna 
5841ba5f469cSkrishna 	error = crypto_mac_final(DPROV_CTX_SINGLE(ctx), out_mac, NULL);
5842ba5f469cSkrishna 	if (in_mac->cd_length != out_mac->cd_length ||
5843ba5f469cSkrishna 	    (bcmp(digest, (unsigned char *)in_mac->cd_raw.iov_base +
5844ba5f469cSkrishna 	    in_mac->cd_offset, out_mac->cd_length) != 0)) {
5845ba5f469cSkrishna 		error = CRYPTO_INVALID_MAC;
5846ba5f469cSkrishna 	}
5847ba5f469cSkrishna 
5848ba5f469cSkrishna 	return (error);
5849ba5f469cSkrishna }
5850ba5f469cSkrishna 
58517c478bd9Sstevel@tonic-gate /*
58527c478bd9Sstevel@tonic-gate  * taskq dispatcher function for verify operations.
58537c478bd9Sstevel@tonic-gate  */
58547c478bd9Sstevel@tonic-gate static void
58557c478bd9Sstevel@tonic-gate dprov_verify_task(dprov_req_t *taskq_req)
58567c478bd9Sstevel@tonic-gate {
58577c478bd9Sstevel@tonic-gate 	kcf_provider_desc_t *pd;
58587c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
58597c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
58607c478bd9Sstevel@tonic-gate 	int instance;
58617c478bd9Sstevel@tonic-gate 	int error = CRYPTO_NOT_SUPPORTED;
58627c478bd9Sstevel@tonic-gate 	crypto_ctx_t *ctx = taskq_req->dr_verify_req.vr_ctx;
58637c478bd9Sstevel@tonic-gate 	crypto_key_t key, *keyp;
58647c478bd9Sstevel@tonic-gate 	crypto_mechanism_t mech;
58657c478bd9Sstevel@tonic-gate 
58667c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
58677c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_task: started\n", instance));
58687c478bd9Sstevel@tonic-gate 
58697c478bd9Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
58707c478bd9Sstevel@tonic-gate 
58717c478bd9Sstevel@tonic-gate 	case DPROV_REQ_VERIFY_INIT:
58727c478bd9Sstevel@tonic-gate 	case DPROV_REQ_VERIFY_RECOVER_INIT:
58737c478bd9Sstevel@tonic-gate 		/* allocate a dprov-private context */
58747c478bd9Sstevel@tonic-gate 		if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
58757c478bd9Sstevel@tonic-gate 		    CRYPTO_SUCCESS)
58767c478bd9Sstevel@tonic-gate 			break;
58777c478bd9Sstevel@tonic-gate 
58787c478bd9Sstevel@tonic-gate 		/* structure assignment */
58797c478bd9Sstevel@tonic-gate 		mech = *taskq_req->dr_verify_req.vr_mechanism;
5880ba5f469cSkrishna 		if (dprov_valid_mac_mech(mech.cm_type)) {
5881ba5f469cSkrishna 			DPROV_CTX_P(ctx)->dc_svrfy_to_mac = B_TRUE;
5882ba5f469cSkrishna 		}
58837c478bd9Sstevel@tonic-gate 
58847c478bd9Sstevel@tonic-gate 		mutex_enter(&softc->ds_lock);
58857c478bd9Sstevel@tonic-gate 		/* get key value for secret key algorithms */
58867c478bd9Sstevel@tonic-gate 		if (is_publickey_mech(mech.cm_type)) {
58877c478bd9Sstevel@tonic-gate 			if ((error = dprov_key_attr_asymmetric(softc,
58887c478bd9Sstevel@tonic-gate 			    ctx->cc_session, taskq_req->dr_type,
58897c478bd9Sstevel@tonic-gate 			    taskq_req->dr_verify_req.vr_key, &key))
58907c478bd9Sstevel@tonic-gate 			    != CRYPTO_SUCCESS) {
58917c478bd9Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
58927c478bd9Sstevel@tonic-gate 				break;
58937c478bd9Sstevel@tonic-gate 			}
58947c478bd9Sstevel@tonic-gate 			keyp = &key;
58957c478bd9Sstevel@tonic-gate 		} else {
58967c478bd9Sstevel@tonic-gate 			if ((error = dprov_key_value_secret(softc,
58977c478bd9Sstevel@tonic-gate 			    ctx->cc_session, taskq_req->dr_type,
58987c478bd9Sstevel@tonic-gate 			    taskq_req->dr_verify_req.vr_key, &key))
58997c478bd9Sstevel@tonic-gate 			    != CRYPTO_SUCCESS) {
59007c478bd9Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
59017c478bd9Sstevel@tonic-gate 				break;
59027c478bd9Sstevel@tonic-gate 			}
59037c478bd9Sstevel@tonic-gate 			keyp = &key;
59047c478bd9Sstevel@tonic-gate 		}
59057c478bd9Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
59067c478bd9Sstevel@tonic-gate 
59077c478bd9Sstevel@tonic-gate 		/* get the software provider for this mechanism */
59087c478bd9Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(
59097c478bd9Sstevel@tonic-gate 		    taskq_req->dr_verify_req.vr_mechanism, &pd,
59107c478bd9Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
59117c478bd9Sstevel@tonic-gate 			break;
59127c478bd9Sstevel@tonic-gate 
5913ba5f469cSkrishna 
5914ba5f469cSkrishna 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5915ba5f469cSkrishna 			error = crypto_mac_init_prov(pd, 0, &mech, keyp, NULL,
5916ba5f469cSkrishna 			    &DPROV_CTX_SINGLE(ctx), NULL);
5917ba5f469cSkrishna 
5918ba5f469cSkrishna 			/* release provider reference */
5919ba5f469cSkrishna 			KCF_PROV_REFRELE(pd);
5920ba5f469cSkrishna 			break;
5921ba5f469cSkrishna 		}
5922ba5f469cSkrishna 
59237c478bd9Sstevel@tonic-gate 		/* Use a session id of zero since we use a software provider */
59247c478bd9Sstevel@tonic-gate 		if (taskq_req->dr_type == DPROV_REQ_VERIFY_INIT)
59257c478bd9Sstevel@tonic-gate 			error = crypto_verify_init_prov(pd, 0, &mech, keyp,
59267c478bd9Sstevel@tonic-gate 			    NULL, &DPROV_CTX_SINGLE(ctx), NULL);
59277c478bd9Sstevel@tonic-gate 		else
59287c478bd9Sstevel@tonic-gate 			error = crypto_verify_recover_init_prov(pd, 0, &mech,
59297c478bd9Sstevel@tonic-gate 			    keyp, NULL, &DPROV_CTX_SINGLE(ctx), NULL);
59307c478bd9Sstevel@tonic-gate 
59317c478bd9Sstevel@tonic-gate 		/* release provider reference */
59327c478bd9Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
59337c478bd9Sstevel@tonic-gate 
59347c478bd9Sstevel@tonic-gate 		break;
59357c478bd9Sstevel@tonic-gate 
59367c478bd9Sstevel@tonic-gate 	case DPROV_REQ_VERIFY:
5937ba5f469cSkrishna 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5938ba5f469cSkrishna 			/* Emulate using update and final */
5939ba5f469cSkrishna 			error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
5940ba5f469cSkrishna 			    taskq_req->dr_mac_req.dr_data, NULL);
5941ba5f469cSkrishna 			if (error == CRYPTO_SUCCESS) {
5942ba5f469cSkrishna 				error = emulate_verify_with_mac(ctx,
5943ba5f469cSkrishna 				    taskq_req->dr_mac_req.dr_mac);
5944ba5f469cSkrishna 			}
5945ba5f469cSkrishna 		} else {
59467c478bd9Sstevel@tonic-gate 			error = crypto_verify_single(DPROV_CTX_SINGLE(ctx),
59477c478bd9Sstevel@tonic-gate 			    taskq_req->dr_verify_req.vr_data,
59487c478bd9Sstevel@tonic-gate 			    taskq_req->dr_verify_req.vr_signature, NULL);
5949ba5f469cSkrishna 		}
59507c478bd9Sstevel@tonic-gate 
59517c478bd9Sstevel@tonic-gate 		ASSERT(error != CRYPTO_BUFFER_TOO_SMALL);
59527c478bd9Sstevel@tonic-gate 		DPROV_CTX_SINGLE(ctx) = NULL;
59537c478bd9Sstevel@tonic-gate 		(void) dprov_free_context(ctx);
59547c478bd9Sstevel@tonic-gate 		break;
59557c478bd9Sstevel@tonic-gate 
59567c478bd9Sstevel@tonic-gate 	case DPROV_REQ_VERIFY_UPDATE:
5957ba5f469cSkrishna 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5958ba5f469cSkrishna 			error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
5959ba5f469cSkrishna 			    taskq_req->dr_mac_req.dr_data, NULL);
5960ba5f469cSkrishna 		} else {
59617c478bd9Sstevel@tonic-gate 			error = crypto_verify_update(DPROV_CTX_SINGLE(ctx),
59627c478bd9Sstevel@tonic-gate 			    taskq_req->dr_verify_req.vr_data, NULL);
5963ba5f469cSkrishna 		}
59647c478bd9Sstevel@tonic-gate 		break;
59657c478bd9Sstevel@tonic-gate 
59667c478bd9Sstevel@tonic-gate 	case DPROV_REQ_VERIFY_FINAL:
5967ba5f469cSkrishna 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5968ba5f469cSkrishna 			error = emulate_verify_with_mac(ctx,
5969ba5f469cSkrishna 			    taskq_req->dr_mac_req.dr_mac);
5970ba5f469cSkrishna 		} else {
59717c478bd9Sstevel@tonic-gate 			error = crypto_verify_final(DPROV_CTX_SINGLE(ctx),
59727c478bd9Sstevel@tonic-gate 			    taskq_req->dr_verify_req.vr_signature, NULL);
5973ba5f469cSkrishna 		}
59747c478bd9Sstevel@tonic-gate 
59757c478bd9Sstevel@tonic-gate 		ASSERT(error != CRYPTO_BUFFER_TOO_SMALL);
59767c478bd9Sstevel@tonic-gate 		DPROV_CTX_SINGLE(ctx) = NULL;
59777c478bd9Sstevel@tonic-gate 		(void) dprov_free_context(ctx);
59787c478bd9Sstevel@tonic-gate 		break;
59797c478bd9Sstevel@tonic-gate 
59807c478bd9Sstevel@tonic-gate 	case DPROV_REQ_VERIFY_ATOMIC:
59817c478bd9Sstevel@tonic-gate 	case DPROV_REQ_VERIFY_RECOVER_ATOMIC:
59827c478bd9Sstevel@tonic-gate 		/* structure assignment */
59837c478bd9Sstevel@tonic-gate 		mech = *taskq_req->dr_verify_req.vr_mechanism;
59847c478bd9Sstevel@tonic-gate 
59857c478bd9Sstevel@tonic-gate 		mutex_enter(&softc->ds_lock);
59867c478bd9Sstevel@tonic-gate 		/* get key value for secret key algorithms */
59877c478bd9Sstevel@tonic-gate 		if (is_publickey_mech(mech.cm_type)) {
59887c478bd9Sstevel@tonic-gate 			if ((error = dprov_key_attr_asymmetric(softc,
59897c478bd9Sstevel@tonic-gate 			    taskq_req->dr_verify_req.vr_session_id,
59907c478bd9Sstevel@tonic-gate 			    taskq_req->dr_type,
59917c478bd9Sstevel@tonic-gate 			    taskq_req->dr_verify_req.vr_key, &key))
59927c478bd9Sstevel@tonic-gate 			    != CRYPTO_SUCCESS) {
59937c478bd9Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
59947c478bd9Sstevel@tonic-gate 				break;
59957c478bd9Sstevel@tonic-gate 			}
59967c478bd9Sstevel@tonic-gate 			keyp = &key;
59977c478bd9Sstevel@tonic-gate 		} else {
59987c478bd9Sstevel@tonic-gate 			if ((error = dprov_key_value_secret(softc,
59997c478bd9Sstevel@tonic-gate 			    taskq_req->dr_verify_req.vr_session_id,
60007c478bd9Sstevel@tonic-gate 			    taskq_req->dr_type,
60017c478bd9Sstevel@tonic-gate 			    taskq_req->dr_verify_req.vr_key, &key))
60027c478bd9Sstevel@tonic-gate 			    != CRYPTO_SUCCESS) {
60037c478bd9Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
60047c478bd9Sstevel@tonic-gate 				break;
60057c478bd9Sstevel@tonic-gate 			}
60067c478bd9Sstevel@tonic-gate 			keyp = &key;
60077c478bd9Sstevel@tonic-gate 		}
60087c478bd9Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
60097c478bd9Sstevel@tonic-gate 
60107c478bd9Sstevel@tonic-gate 		/* get the software provider for this mechanism */
60117c478bd9Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(
60127c478bd9Sstevel@tonic-gate 		    taskq_req->dr_verify_req.vr_mechanism, &pd,
60137c478bd9Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
60147c478bd9Sstevel@tonic-gate 			break;
60157c478bd9Sstevel@tonic-gate 
60167c478bd9Sstevel@tonic-gate 		/* Use a session id of zero since we use a software provider */
60177c478bd9Sstevel@tonic-gate 		if (taskq_req->dr_type == DPROV_REQ_VERIFY_ATOMIC)
60187c478bd9Sstevel@tonic-gate 			error = crypto_verify_prov(pd, 0, &mech, keyp,
60197c478bd9Sstevel@tonic-gate 			    taskq_req->dr_verify_req.vr_data,
60207c478bd9Sstevel@tonic-gate 			    NULL, taskq_req->dr_verify_req.vr_signature, NULL);
60217c478bd9Sstevel@tonic-gate 		else
60227c478bd9Sstevel@tonic-gate 			/*
60237c478bd9Sstevel@tonic-gate 			 * crypto_verify_recover_prov() has different argument
60247c478bd9Sstevel@tonic-gate 			 * order than crypto_verify_prov().
60257c478bd9Sstevel@tonic-gate 			 */
60267c478bd9Sstevel@tonic-gate 			error = crypto_verify_recover_prov(pd, 0, &mech, keyp,
60277c478bd9Sstevel@tonic-gate 			    taskq_req->dr_verify_req.vr_signature,
60287c478bd9Sstevel@tonic-gate 			    NULL, taskq_req->dr_verify_req.vr_data, NULL);
60297c478bd9Sstevel@tonic-gate 
60307c478bd9Sstevel@tonic-gate 		/* release provider reference */
60317c478bd9Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
60327c478bd9Sstevel@tonic-gate 		break;
60337c478bd9Sstevel@tonic-gate 
60347c478bd9Sstevel@tonic-gate 	case DPROV_REQ_VERIFY_RECOVER:
60357c478bd9Sstevel@tonic-gate 		/*
60367c478bd9Sstevel@tonic-gate 		 * crypto_verify_recover_single() has different argument
60377c478bd9Sstevel@tonic-gate 		 * order than crypto_verify_single().
60387c478bd9Sstevel@tonic-gate 		 */
60397c478bd9Sstevel@tonic-gate 		error = crypto_verify_recover_single(DPROV_CTX_SINGLE(ctx),
60407c478bd9Sstevel@tonic-gate 		    taskq_req->dr_verify_req.vr_signature,
60417c478bd9Sstevel@tonic-gate 		    taskq_req->dr_verify_req.vr_data, NULL);
60427c478bd9Sstevel@tonic-gate 
60437c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
60447c478bd9Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
60457c478bd9Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
60467c478bd9Sstevel@tonic-gate 		}
60477c478bd9Sstevel@tonic-gate 		break;
60487c478bd9Sstevel@tonic-gate 	}
60497c478bd9Sstevel@tonic-gate 
60507c478bd9Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
60517c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_task: end\n", instance));
60527c478bd9Sstevel@tonic-gate }
60537c478bd9Sstevel@tonic-gate 
60547c478bd9Sstevel@tonic-gate /*
60557c478bd9Sstevel@tonic-gate  * taskq dispatcher function for dual operations.
60567c478bd9Sstevel@tonic-gate  */
60577c478bd9Sstevel@tonic-gate static void
60587c478bd9Sstevel@tonic-gate dprov_dual_task(dprov_req_t *taskq_req)
60597c478bd9Sstevel@tonic-gate {
60607c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
60617c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
60627c478bd9Sstevel@tonic-gate 	int instance;
60637c478bd9Sstevel@tonic-gate 	int error = CRYPTO_NOT_SUPPORTED;
60647c478bd9Sstevel@tonic-gate 	crypto_ctx_t *signverify_ctx = taskq_req->dr_dual_req.dr_signverify_ctx;
60657c478bd9Sstevel@tonic-gate 	crypto_ctx_t *cipher_ctx = taskq_req->dr_dual_req.dr_cipher_ctx;
60667c478bd9Sstevel@tonic-gate 
60677c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
60687c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_dual_task: started\n", instance));
60697c478bd9Sstevel@tonic-gate 
60707c478bd9Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
60717c478bd9Sstevel@tonic-gate 
60727c478bd9Sstevel@tonic-gate 	case DPROV_REQ_DIGEST_ENCRYPT_UPDATE:
60737c478bd9Sstevel@tonic-gate 		error = crypto_digest_encrypt_update(
60747c478bd9Sstevel@tonic-gate 		    DPROV_CTX_SINGLE(signverify_ctx),
60757c478bd9Sstevel@tonic-gate 		    DPROV_CTX_SINGLE(cipher_ctx),
60767c478bd9Sstevel@tonic-gate 		    taskq_req->dr_dual_req.dr_plaintext,
60777c478bd9Sstevel@tonic-gate 		    taskq_req->dr_dual_req.dr_ciphertext, NULL);
60787c478bd9Sstevel@tonic-gate 		break;
60797c478bd9Sstevel@tonic-gate 
60807c478bd9Sstevel@tonic-gate 	case DPROV_REQ_DECRYPT_DIGEST_UPDATE:
60817c478bd9Sstevel@tonic-gate 		error = crypto_decrypt_digest_update(
60827c478bd9Sstevel@tonic-gate 		    DPROV_CTX_SINGLE(cipher_ctx),
60837c478bd9Sstevel@tonic-gate 		    DPROV_CTX_SINGLE(signverify_ctx),
60847c478bd9Sstevel@tonic-gate 		    taskq_req->dr_dual_req.dr_ciphertext,
60857c478bd9Sstevel@tonic-gate 		    taskq_req->dr_dual_req.dr_plaintext, NULL);
60867c478bd9Sstevel@tonic-gate 		break;
60877c478bd9Sstevel@tonic-gate 
60887c478bd9Sstevel@tonic-gate 	case DPROV_REQ_SIGN_ENCRYPT_UPDATE:
60897c478bd9Sstevel@tonic-gate 		error = crypto_sign_encrypt_update(
60907c478bd9Sstevel@tonic-gate 		    DPROV_CTX_SINGLE(signverify_ctx),
60917c478bd9Sstevel@tonic-gate 		    DPROV_CTX_SINGLE(cipher_ctx),
60927c478bd9Sstevel@tonic-gate 		    taskq_req->dr_dual_req.dr_plaintext,
60937c478bd9Sstevel@tonic-gate 		    taskq_req->dr_dual_req.dr_ciphertext, NULL);
60947c478bd9Sstevel@tonic-gate 		break;
60957c478bd9Sstevel@tonic-gate 
60967c478bd9Sstevel@tonic-gate 	case DPROV_REQ_DECRYPT_VERIFY_UPDATE:
60977c478bd9Sstevel@tonic-gate 		error = crypto_decrypt_verify_update(
60987c478bd9Sstevel@tonic-gate 		    DPROV_CTX_SINGLE(cipher_ctx),
60997c478bd9Sstevel@tonic-gate 		    DPROV_CTX_SINGLE(signverify_ctx),
61007c478bd9Sstevel@tonic-gate 		    taskq_req->dr_dual_req.dr_ciphertext,
61017c478bd9Sstevel@tonic-gate 		    taskq_req->dr_dual_req.dr_plaintext, NULL);
61027c478bd9Sstevel@tonic-gate 		break;
61037c478bd9Sstevel@tonic-gate 	}
61047c478bd9Sstevel@tonic-gate 
61057c478bd9Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
61067c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_dual_task: end\n", instance));
61077c478bd9Sstevel@tonic-gate }
61087c478bd9Sstevel@tonic-gate 
61097c478bd9Sstevel@tonic-gate /*
61107c478bd9Sstevel@tonic-gate  * taskq dispatcher function for cipher operations.
61117c478bd9Sstevel@tonic-gate  */
61127c478bd9Sstevel@tonic-gate static void
61137c478bd9Sstevel@tonic-gate dprov_cipher_task(dprov_req_t *taskq_req)
61147c478bd9Sstevel@tonic-gate {
61157c478bd9Sstevel@tonic-gate 	kcf_provider_desc_t *pd;
61167c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
61177c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
61187c478bd9Sstevel@tonic-gate 	int instance;
61197c478bd9Sstevel@tonic-gate 	int error = CRYPTO_NOT_SUPPORTED;
61207c478bd9Sstevel@tonic-gate 	crypto_ctx_t *ctx = taskq_req->dr_cipher_req.dr_ctx;
61217c478bd9Sstevel@tonic-gate 	crypto_key_t key, *keyp;
61227c478bd9Sstevel@tonic-gate 	crypto_mechanism_t mech;
61237c478bd9Sstevel@tonic-gate 
61247c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
61257c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_cipher_task: started\n", instance));
61267c478bd9Sstevel@tonic-gate 
61277c478bd9Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
61287c478bd9Sstevel@tonic-gate 
61297c478bd9Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_INIT:
61307c478bd9Sstevel@tonic-gate 	case DPROV_REQ_DECRYPT_INIT:
61317c478bd9Sstevel@tonic-gate 		/* allocate a dprov-private context */
61327c478bd9Sstevel@tonic-gate 		if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
61337c478bd9Sstevel@tonic-gate 		    CRYPTO_SUCCESS)
61347c478bd9Sstevel@tonic-gate 			break;
61357c478bd9Sstevel@tonic-gate 
61367c478bd9Sstevel@tonic-gate 		/* structure assignment */
61377c478bd9Sstevel@tonic-gate 		mech = *taskq_req->dr_cipher_req.dr_mechanism;
61387c478bd9Sstevel@tonic-gate 
61397c478bd9Sstevel@tonic-gate 		mutex_enter(&softc->ds_lock);
61407c478bd9Sstevel@tonic-gate 		/* get key value for secret key algorithms */
61417c478bd9Sstevel@tonic-gate 		if (is_publickey_mech(mech.cm_type)) {
61427c478bd9Sstevel@tonic-gate 			if ((error = dprov_key_attr_asymmetric(softc,
61437c478bd9Sstevel@tonic-gate 			    ctx->cc_session, taskq_req->dr_type,
61447c478bd9Sstevel@tonic-gate 			    taskq_req->dr_cipher_req.dr_key, &key))
61457c478bd9Sstevel@tonic-gate 			    != CRYPTO_SUCCESS) {
61467c478bd9Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
61477c478bd9Sstevel@tonic-gate 				break;
61487c478bd9Sstevel@tonic-gate 			}
61497c478bd9Sstevel@tonic-gate 			keyp = &key;
61507c478bd9Sstevel@tonic-gate 		} else {
61517c478bd9Sstevel@tonic-gate 			if ((error = dprov_key_value_secret(softc,
61527c478bd9Sstevel@tonic-gate 			    ctx->cc_session, taskq_req->dr_type,
61537c478bd9Sstevel@tonic-gate 			    taskq_req->dr_cipher_req.dr_key, &key))
61547c478bd9Sstevel@tonic-gate 			    != CRYPTO_SUCCESS) {
61557c478bd9Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
61567c478bd9Sstevel@tonic-gate 				break;
61577c478bd9Sstevel@tonic-gate 			}
61587c478bd9Sstevel@tonic-gate 			keyp = &key;
61597c478bd9Sstevel@tonic-gate 		}
61607c478bd9Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
61617c478bd9Sstevel@tonic-gate 
61627c478bd9Sstevel@tonic-gate 		/* get the software provider for this mechanism */
61637c478bd9Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(
61647c478bd9Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_mechanism, &pd,
61657c478bd9Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
61667c478bd9Sstevel@tonic-gate 			break;
61677c478bd9Sstevel@tonic-gate 
61687c478bd9Sstevel@tonic-gate 		/* Use a session id of zero since we use a software provider */
61697c478bd9Sstevel@tonic-gate 		if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_INIT)
61707c478bd9Sstevel@tonic-gate 			error = crypto_encrypt_init_prov(pd, 0, &mech, keyp,
61717c478bd9Sstevel@tonic-gate 			    NULL, &DPROV_CTX_SINGLE(ctx), NULL);
61727c478bd9Sstevel@tonic-gate 		else
61737c478bd9Sstevel@tonic-gate 			error = crypto_decrypt_init_prov(pd, 0, &mech, keyp,
61747c478bd9Sstevel@tonic-gate 			    NULL, &DPROV_CTX_SINGLE(ctx), NULL);
61757c478bd9Sstevel@tonic-gate 
61766a1073f8Skrishna 		if (ctx->cc_flags & CRYPTO_INIT_OPSTATE) {
61776a1073f8Skrishna 			crypto_ctx_t *lctx =
61786a1073f8Skrishna 			    (crypto_ctx_t *)(DPROV_CTX_SINGLE(ctx));
61796a1073f8Skrishna 
61806a1073f8Skrishna 			ctx->cc_opstate = lctx->cc_provider_private;
61816a1073f8Skrishna 			ctx->cc_flags |= CRYPTO_USE_OPSTATE;
61826a1073f8Skrishna 		}
61836a1073f8Skrishna 
61847c478bd9Sstevel@tonic-gate 		/* release provider reference */
61857c478bd9Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
61867c478bd9Sstevel@tonic-gate 		break;
61877c478bd9Sstevel@tonic-gate 
61887c478bd9Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT:
61897c478bd9Sstevel@tonic-gate 		error = crypto_encrypt_single(DPROV_CTX_SINGLE(ctx),
61907c478bd9Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_plaintext,
61917c478bd9Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_ciphertext, NULL);
61927c478bd9Sstevel@tonic-gate 
61937c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
61947c478bd9Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
61957c478bd9Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
61967c478bd9Sstevel@tonic-gate 		}
61977c478bd9Sstevel@tonic-gate 		break;
61987c478bd9Sstevel@tonic-gate 
61997c478bd9Sstevel@tonic-gate 	case DPROV_REQ_DECRYPT:
62007c478bd9Sstevel@tonic-gate 		error = crypto_decrypt_single(DPROV_CTX_SINGLE(ctx),
62017c478bd9Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_ciphertext,
62027c478bd9Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_plaintext, NULL);
62037c478bd9Sstevel@tonic-gate 
62047c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
62057c478bd9Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
62067c478bd9Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
62077c478bd9Sstevel@tonic-gate 		}
62087c478bd9Sstevel@tonic-gate 		break;
62097c478bd9Sstevel@tonic-gate 
62107c478bd9Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_UPDATE:
62116a1073f8Skrishna 		ASSERT(!(ctx->cc_flags & CRYPTO_INIT_OPSTATE) ||
62126a1073f8Skrishna 		    (ctx->cc_flags & CRYPTO_USE_OPSTATE));
62137c478bd9Sstevel@tonic-gate 		error = crypto_encrypt_update(DPROV_CTX_SINGLE(ctx),
62147c478bd9Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_plaintext,
62157c478bd9Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_ciphertext, NULL);
62167c478bd9Sstevel@tonic-gate 		break;
62177c478bd9Sstevel@tonic-gate 
62187c478bd9Sstevel@tonic-gate 	case DPROV_REQ_DECRYPT_UPDATE:
62196a1073f8Skrishna 		ASSERT(!(ctx->cc_flags & CRYPTO_INIT_OPSTATE) ||
62206a1073f8Skrishna 		    (ctx->cc_flags & CRYPTO_USE_OPSTATE));
62217c478bd9Sstevel@tonic-gate 		error = crypto_decrypt_update(DPROV_CTX_SINGLE(ctx),
62227c478bd9Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_ciphertext,
62237c478bd9Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_plaintext, NULL);
62247c478bd9Sstevel@tonic-gate 		break;
62257c478bd9Sstevel@tonic-gate 
62267c478bd9Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_FINAL:
62277c478bd9Sstevel@tonic-gate 		error = crypto_encrypt_final(DPROV_CTX_SINGLE(ctx),
62287c478bd9Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_ciphertext, NULL);
62297c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
62307c478bd9Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
62317c478bd9Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
62327c478bd9Sstevel@tonic-gate 		}
62337c478bd9Sstevel@tonic-gate 		break;
62347c478bd9Sstevel@tonic-gate 
62357c478bd9Sstevel@tonic-gate 	case DPROV_REQ_DECRYPT_FINAL:
62367c478bd9Sstevel@tonic-gate 		error = crypto_decrypt_final(DPROV_CTX_SINGLE(ctx),
62377c478bd9Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_plaintext, NULL);
62387c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
62397c478bd9Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
62407c478bd9Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
62417c478bd9Sstevel@tonic-gate 		}
62427c478bd9Sstevel@tonic-gate 		break;
62437c478bd9Sstevel@tonic-gate 
62447c478bd9Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_ATOMIC:
62457c478bd9Sstevel@tonic-gate 	case DPROV_REQ_DECRYPT_ATOMIC:
62467c478bd9Sstevel@tonic-gate 		/* structure assignment */
62477c478bd9Sstevel@tonic-gate 		mech = *taskq_req->dr_cipher_req.dr_mechanism;
62487c478bd9Sstevel@tonic-gate 
62497c478bd9Sstevel@tonic-gate 		mutex_enter(&softc->ds_lock);
62507c478bd9Sstevel@tonic-gate 		/* get key value for secret key algorithms */
62517c478bd9Sstevel@tonic-gate 		if (is_publickey_mech(mech.cm_type)) {
62527c478bd9Sstevel@tonic-gate 			if ((error = dprov_key_attr_asymmetric(softc,
62537c478bd9Sstevel@tonic-gate 			    taskq_req->dr_cipher_req.dr_session_id,
62547c478bd9Sstevel@tonic-gate 			    taskq_req->dr_type,
62557c478bd9Sstevel@tonic-gate 			    taskq_req->dr_cipher_req.dr_key,
62567c478bd9Sstevel@tonic-gate 			    &key)) != CRYPTO_SUCCESS) {
62577c478bd9Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
62587c478bd9Sstevel@tonic-gate 				break;
62597c478bd9Sstevel@tonic-gate 			}
62607c478bd9Sstevel@tonic-gate 			keyp = &key;
62617c478bd9Sstevel@tonic-gate 		} else {
62627c478bd9Sstevel@tonic-gate 			if ((error = dprov_key_value_secret(softc,
62637c478bd9Sstevel@tonic-gate 			    taskq_req->dr_cipher_req.dr_session_id,
62647c478bd9Sstevel@tonic-gate 			    taskq_req->dr_type, taskq_req->dr_cipher_req.dr_key,
62657c478bd9Sstevel@tonic-gate 			    &key))
62667c478bd9Sstevel@tonic-gate 			    != CRYPTO_SUCCESS) {
62677c478bd9Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
62687c478bd9Sstevel@tonic-gate 				break;
62697c478bd9Sstevel@tonic-gate 			}
62707c478bd9Sstevel@tonic-gate 			keyp = &key;
62717c478bd9Sstevel@tonic-gate 		}
62727c478bd9Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
62737c478bd9Sstevel@tonic-gate 
62747c478bd9Sstevel@tonic-gate 		/* get the software provider for this mechanism */
62757c478bd9Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(
62767c478bd9Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_mechanism, &pd,
62777c478bd9Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
62787c478bd9Sstevel@tonic-gate 			break;
62797c478bd9Sstevel@tonic-gate 
62807c478bd9Sstevel@tonic-gate 		/* use a session id of zero since we use a software provider */
62817c478bd9Sstevel@tonic-gate 		if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_ATOMIC)
6282894b2776Smcpowers 			error = crypto_encrypt_prov(pd, 0, &mech,
62837c478bd9Sstevel@tonic-gate 			    taskq_req->dr_cipher_req.dr_plaintext,
62847c478bd9Sstevel@tonic-gate 			    keyp, NULL,
6285894b2776Smcpowers 			    taskq_req->dr_cipher_req.dr_ciphertext, NULL);
62867c478bd9Sstevel@tonic-gate 		else
6287894b2776Smcpowers 			error = crypto_decrypt_prov(pd, 0, &mech,
62887c478bd9Sstevel@tonic-gate 			    taskq_req->dr_cipher_req.dr_ciphertext,
62897c478bd9Sstevel@tonic-gate 			    keyp, NULL,
6290894b2776Smcpowers 			    taskq_req->dr_cipher_req.dr_plaintext, NULL);
62917c478bd9Sstevel@tonic-gate 
62927c478bd9Sstevel@tonic-gate 		/* release provider reference */
62937c478bd9Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
62947c478bd9Sstevel@tonic-gate 
62957c478bd9Sstevel@tonic-gate 		break;
62967c478bd9Sstevel@tonic-gate 	}
62977c478bd9Sstevel@tonic-gate 
62987c478bd9Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
62997c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: end\n", instance));
63007c478bd9Sstevel@tonic-gate }
63017c478bd9Sstevel@tonic-gate 
63027c478bd9Sstevel@tonic-gate /*
63037c478bd9Sstevel@tonic-gate  * Helper function for the cipher/mac dual operation taskq dispatch
63047c478bd9Sstevel@tonic-gate  * function. Initialize the cipher and mac key values and find the
63057c478bd9Sstevel@tonic-gate  * providers that can process the request for the specified mechanisms.
63067c478bd9Sstevel@tonic-gate  */
63077c478bd9Sstevel@tonic-gate static int
63087c478bd9Sstevel@tonic-gate dprov_cipher_mac_key_pd(dprov_state_t *softc, crypto_session_id_t sid,
63097c478bd9Sstevel@tonic-gate     dprov_req_t *taskq_req, crypto_key_t *cipher_key, crypto_key_t *mac_key,
63107c478bd9Sstevel@tonic-gate     kcf_provider_desc_t **cipher_pd, kcf_provider_desc_t **mac_pd,
63117c478bd9Sstevel@tonic-gate     crypto_mech_type_t *cipher_mech_type, crypto_mech_type_t *mac_mech_type)
63127c478bd9Sstevel@tonic-gate {
63137c478bd9Sstevel@tonic-gate 	int error;
63147c478bd9Sstevel@tonic-gate 
63157c478bd9Sstevel@tonic-gate 	/* get the cipher key value */
63167c478bd9Sstevel@tonic-gate 	mutex_enter(&softc->ds_lock);
6317894b2776Smcpowers 	error = dprov_key_value_secret(softc, sid, DPROV_REQ_ENCRYPT_ATOMIC,
63187c478bd9Sstevel@tonic-gate 	    taskq_req->dr_cipher_mac_req.mr_cipher_key, cipher_key);
63197c478bd9Sstevel@tonic-gate 	if (error != CRYPTO_SUCCESS) {
63207c478bd9Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
63217c478bd9Sstevel@tonic-gate 		return (error);
63227c478bd9Sstevel@tonic-gate 	}
63237c478bd9Sstevel@tonic-gate 
63247c478bd9Sstevel@tonic-gate 	/* get the mac key value */
6325894b2776Smcpowers 	error = dprov_key_value_secret(softc, sid, DPROV_REQ_MAC_ATOMIC,
63267c478bd9Sstevel@tonic-gate 	    taskq_req->dr_cipher_mac_req.mr_mac_key, mac_key);
63277c478bd9Sstevel@tonic-gate 	mutex_exit(&softc->ds_lock);
63287c478bd9Sstevel@tonic-gate 	if (error != CRYPTO_SUCCESS)
63297c478bd9Sstevel@tonic-gate 		return (error);
63307c478bd9Sstevel@tonic-gate 
63317c478bd9Sstevel@tonic-gate 	/* get the SW provider to perform the cipher operation */
63327c478bd9Sstevel@tonic-gate 	if ((error = dprov_get_sw_prov(
63337c478bd9Sstevel@tonic-gate 	    taskq_req->dr_cipher_mac_req.mr_cipher_mech, cipher_pd,
63347c478bd9Sstevel@tonic-gate 	    cipher_mech_type)) != CRYPTO_SUCCESS)
63357c478bd9Sstevel@tonic-gate 		return (error);
63367c478bd9Sstevel@tonic-gate 
63377c478bd9Sstevel@tonic-gate 	/* get the SW provider to perform the mac operation */
63387c478bd9Sstevel@tonic-gate 	error = dprov_get_sw_prov(taskq_req->dr_cipher_mac_req.mr_mac_mech,
63397c478bd9Sstevel@tonic-gate 	    mac_pd, mac_mech_type);
63407c478bd9Sstevel@tonic-gate 
63417c478bd9Sstevel@tonic-gate 	return (error);
63427c478bd9Sstevel@tonic-gate }
63437c478bd9Sstevel@tonic-gate 
63447c478bd9Sstevel@tonic-gate /*
63457c478bd9Sstevel@tonic-gate  * taskq dispatcher function for cipher/mac dual operations.
63467c478bd9Sstevel@tonic-gate  */
63477c478bd9Sstevel@tonic-gate static void
63487c478bd9Sstevel@tonic-gate dprov_cipher_mac_task(dprov_req_t *taskq_req)
63497c478bd9Sstevel@tonic-gate {
63507c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
63517c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
63527c478bd9Sstevel@tonic-gate 	int instance;
63537c478bd9Sstevel@tonic-gate 	int error = CRYPTO_NOT_SUPPORTED;
63547c478bd9Sstevel@tonic-gate 	crypto_ctx_t *ctx = taskq_req->dr_cipher_mac_req.mr_ctx;
63557c478bd9Sstevel@tonic-gate 	kcf_provider_desc_t *cipher_pd;
63567c478bd9Sstevel@tonic-gate 	kcf_provider_desc_t *mac_pd;
63577c478bd9Sstevel@tonic-gate 	crypto_key_t cipher_key;
63587c478bd9Sstevel@tonic-gate 	crypto_key_t mac_key;
63597c478bd9Sstevel@tonic-gate 	crypto_dual_data_t *dual_data =
63607c478bd9Sstevel@tonic-gate 	    taskq_req->dr_cipher_mac_req.mr_dual_data;
63617c478bd9Sstevel@tonic-gate 	crypto_data_t cipher_data;
63627c478bd9Sstevel@tonic-gate 	crypto_data_t mac_data;
63637c478bd9Sstevel@tonic-gate 	crypto_mechanism_t cipher_mech, mac_mech;
63647c478bd9Sstevel@tonic-gate 	crypto_session_id_t session_id;
63657c478bd9Sstevel@tonic-gate 
63667c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
63677c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_cipher_mac_task: started\n",
63687c478bd9Sstevel@tonic-gate 	    instance));
63697c478bd9Sstevel@tonic-gate 
63707c478bd9Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
63717c478bd9Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_MAC_INIT:
63727c478bd9Sstevel@tonic-gate 	case DPROV_REQ_MAC_DECRYPT_INIT:
63737c478bd9Sstevel@tonic-gate 		/* structure assignment */
63747c478bd9Sstevel@tonic-gate 		cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech;
63757c478bd9Sstevel@tonic-gate 		mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech;
63767c478bd9Sstevel@tonic-gate 
63777c478bd9Sstevel@tonic-gate 		/* get the keys values and providers to use for operations */
63787c478bd9Sstevel@tonic-gate 		if ((error = dprov_cipher_mac_key_pd(softc, ctx->cc_session,
63797c478bd9Sstevel@tonic-gate 		    taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd,
63807c478bd9Sstevel@tonic-gate 		    &cipher_mech.cm_type, &mac_mech.cm_type)) != CRYPTO_SUCCESS)
63817c478bd9Sstevel@tonic-gate 			break;
63827c478bd9Sstevel@tonic-gate 
63837c478bd9Sstevel@tonic-gate 		/* allocate a dprov-private context */
63847c478bd9Sstevel@tonic-gate 		if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
63857c478bd9Sstevel@tonic-gate 		    CRYPTO_SUCCESS)
63867c478bd9Sstevel@tonic-gate 			break;
63877c478bd9Sstevel@tonic-gate 
63887c478bd9Sstevel@tonic-gate 		if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_MAC_INIT)
63897c478bd9Sstevel@tonic-gate 			/* do the encryption initialization */
63907c478bd9Sstevel@tonic-gate 			error = crypto_encrypt_init_prov(cipher_pd, 0,
63917c478bd9Sstevel@tonic-gate 			    &cipher_mech, &cipher_key, NULL,
63927c478bd9Sstevel@tonic-gate 			    &DPROV_CTX_DUAL_CIPHER(ctx), NULL);
63937c478bd9Sstevel@tonic-gate 		else
63947c478bd9Sstevel@tonic-gate 			/* do the decryption initialization */
63957c478bd9Sstevel@tonic-gate 			error = crypto_decrypt_init_prov(cipher_pd, 0,
63967c478bd9Sstevel@tonic-gate 			    &cipher_mech, &cipher_key, NULL,
63977c478bd9Sstevel@tonic-gate 			    &DPROV_CTX_DUAL_CIPHER(ctx), NULL);
63987c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
63997c478bd9Sstevel@tonic-gate 			break;
64007c478bd9Sstevel@tonic-gate 
64017c478bd9Sstevel@tonic-gate 		/* do the mac initialization */
64027c478bd9Sstevel@tonic-gate 		if ((error = crypto_mac_init_prov(mac_pd, 0,
64037c478bd9Sstevel@tonic-gate 		    &mac_mech, &mac_key, NULL, &DPROV_CTX_DUAL_MAC(ctx),
64047c478bd9Sstevel@tonic-gate 		    NULL)) != CRYPTO_SUCCESS)
64057c478bd9Sstevel@tonic-gate 			break;
64067c478bd9Sstevel@tonic-gate 
64077c478bd9Sstevel@tonic-gate 		/* release references to providers */
64087c478bd9Sstevel@tonic-gate 		KCF_PROV_REFRELE(cipher_pd);
64097c478bd9Sstevel@tonic-gate 		KCF_PROV_REFRELE(mac_pd);
64107c478bd9Sstevel@tonic-gate 
64117c478bd9Sstevel@tonic-gate 		break;
64127c478bd9Sstevel@tonic-gate 
64137c478bd9Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_MAC: {
64147c478bd9Sstevel@tonic-gate 		size_t encrypted;
64157c478bd9Sstevel@tonic-gate 		boolean_t inplace;
64167c478bd9Sstevel@tonic-gate 
64177c478bd9Sstevel@tonic-gate 		crypto_data_t *plaintext_tmp, *ciphertext_tmp;
64187c478bd9Sstevel@tonic-gate 
64197c478bd9Sstevel@tonic-gate 		cipher_data = *((crypto_data_t *)dual_data);
64207c478bd9Sstevel@tonic-gate 
64217c478bd9Sstevel@tonic-gate 		/* do an encrypt update */
64227c478bd9Sstevel@tonic-gate 		inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL);
64237c478bd9Sstevel@tonic-gate 		if (inplace) {
64247c478bd9Sstevel@tonic-gate 			plaintext_tmp = &cipher_data;
64257c478bd9Sstevel@tonic-gate 			ciphertext_tmp = NULL;
64267c478bd9Sstevel@tonic-gate 		} else {
64277c478bd9Sstevel@tonic-gate 			plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data;
64287c478bd9Sstevel@tonic-gate 			ciphertext_tmp = &cipher_data;
64297c478bd9Sstevel@tonic-gate 		}
64307c478bd9Sstevel@tonic-gate 		if ((error = crypto_encrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
64317c478bd9Sstevel@tonic-gate 		    plaintext_tmp, ciphertext_tmp, NULL)) != CRYPTO_SUCCESS)
64327c478bd9Sstevel@tonic-gate 			break;
64337c478bd9Sstevel@tonic-gate 
64347c478bd9Sstevel@tonic-gate 		/* do an encrypt final */
64357c478bd9Sstevel@tonic-gate 		encrypted = cipher_data.cd_length;
64367c478bd9Sstevel@tonic-gate 
64377c478bd9Sstevel@tonic-gate 		cipher_data.cd_offset += encrypted;
64387c478bd9Sstevel@tonic-gate 		cipher_data.cd_length = dual_data->dd_len1 - encrypted;
64397c478bd9Sstevel@tonic-gate 
64407c478bd9Sstevel@tonic-gate 		if ((error = crypto_encrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
64417c478bd9Sstevel@tonic-gate 		    &cipher_data, NULL)) != CRYPTO_SUCCESS)
64427c478bd9Sstevel@tonic-gate 			break;
64437c478bd9Sstevel@tonic-gate 
64447c478bd9Sstevel@tonic-gate 		/*
64457c478bd9Sstevel@tonic-gate 		 * Do a mac update on the resulting ciphertext, but with no
64467c478bd9Sstevel@tonic-gate 		 * more bytes than specified by dual_data, and starting at
64477c478bd9Sstevel@tonic-gate 		 * offset specified by dual_data. For in-place operations,
64487c478bd9Sstevel@tonic-gate 		 * we use the length specified by the dual_data.
64497c478bd9Sstevel@tonic-gate 		 */
64507c478bd9Sstevel@tonic-gate 		mac_data = cipher_data;
64517c478bd9Sstevel@tonic-gate 		mac_data.cd_offset = dual_data->dd_offset2;
64527c478bd9Sstevel@tonic-gate 		mac_data.cd_length = dual_data->dd_len2;
64537c478bd9Sstevel@tonic-gate 		if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
64547c478bd9Sstevel@tonic-gate 		    &mac_data, NULL)) != CRYPTO_SUCCESS)
64557c478bd9Sstevel@tonic-gate 			break;
64567c478bd9Sstevel@tonic-gate 
64577c478bd9Sstevel@tonic-gate 		/* do a mac final */
64587c478bd9Sstevel@tonic-gate 		error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
64597c478bd9Sstevel@tonic-gate 		    taskq_req->dr_cipher_mac_req.mr_mac, NULL);
64607c478bd9Sstevel@tonic-gate 
64617c478bd9Sstevel@tonic-gate 		/* Set the total size of the ciphertext, when successful */
64627c478bd9Sstevel@tonic-gate 		if (error == CRYPTO_SUCCESS)
64637c478bd9Sstevel@tonic-gate 			dual_data->dd_len1 = encrypted + cipher_data.cd_length;
64647c478bd9Sstevel@tonic-gate 
64657c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
64667c478bd9Sstevel@tonic-gate 			DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
64677c478bd9Sstevel@tonic-gate 			DPROV_CTX_DUAL_MAC(ctx) = NULL;
64687c478bd9Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
64697c478bd9Sstevel@tonic-gate 		}
64707c478bd9Sstevel@tonic-gate 		break;
64717c478bd9Sstevel@tonic-gate 	}
64727c478bd9Sstevel@tonic-gate 
64737c478bd9Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_MAC_UPDATE: {
64747c478bd9Sstevel@tonic-gate 		crypto_data_t *plaintext_tmp, *ciphertext_tmp;
64757c478bd9Sstevel@tonic-gate 		size_t encrypted;
64767c478bd9Sstevel@tonic-gate 		ssize_t maclen;
64777c478bd9Sstevel@tonic-gate 		boolean_t inplace;
64787c478bd9Sstevel@tonic-gate 
64797c478bd9Sstevel@tonic-gate 		cipher_data = *((crypto_data_t *)dual_data);
64807c478bd9Sstevel@tonic-gate 
64817c478bd9Sstevel@tonic-gate 		/* do an encrypt update */
64827c478bd9Sstevel@tonic-gate 		inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL);
64837c478bd9Sstevel@tonic-gate 		if (inplace) {
64847c478bd9Sstevel@tonic-gate 			plaintext_tmp = &cipher_data;
64857c478bd9Sstevel@tonic-gate 			ciphertext_tmp = NULL;
64867c478bd9Sstevel@tonic-gate 		} else {
64877c478bd9Sstevel@tonic-gate 			plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data;
64887c478bd9Sstevel@tonic-gate 			ciphertext_tmp = &cipher_data;
64897c478bd9Sstevel@tonic-gate 		}
64907c478bd9Sstevel@tonic-gate 		if ((error = crypto_encrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
64917c478bd9Sstevel@tonic-gate 		    plaintext_tmp, ciphertext_tmp, NULL)) != CRYPTO_SUCCESS)
64927c478bd9Sstevel@tonic-gate 			break;
64937c478bd9Sstevel@tonic-gate 
64947c478bd9Sstevel@tonic-gate 		encrypted = cipher_data.cd_length;
64957c478bd9Sstevel@tonic-gate 
64967c478bd9Sstevel@tonic-gate 		/*
64977c478bd9Sstevel@tonic-gate 		 * Do a mac update on the resulting ciphertext, but with no
64987c478bd9Sstevel@tonic-gate 		 * more bytes than specified by dual_data, and starting at
64997c478bd9Sstevel@tonic-gate 		 * offset specified by dual_data. For in-place operations,
65007c478bd9Sstevel@tonic-gate 		 * we use the length specified by the dual_data.
65017c478bd9Sstevel@tonic-gate 		 * There is an edge case, when the encryption step produced
65027c478bd9Sstevel@tonic-gate 		 * zero bytes in the ciphertext. Only the portion between
65037c478bd9Sstevel@tonic-gate 		 * offset2 and offset1 is then thrown in the MAC mix.
65047c478bd9Sstevel@tonic-gate 		 */
65057c478bd9Sstevel@tonic-gate 		maclen = dual_data->dd_offset1 - dual_data->dd_offset2 +
65067c478bd9Sstevel@tonic-gate 		    encrypted;
65077c478bd9Sstevel@tonic-gate 		if (maclen > 0) {
65087c478bd9Sstevel@tonic-gate 			mac_data = cipher_data;
65097c478bd9Sstevel@tonic-gate 			mac_data.cd_offset = dual_data->dd_offset2;
65107c478bd9Sstevel@tonic-gate 			mac_data.cd_length = min(dual_data->dd_len2, maclen);
65117c478bd9Sstevel@tonic-gate 			if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
65127c478bd9Sstevel@tonic-gate 			    &mac_data, NULL)) != CRYPTO_SUCCESS)
65137c478bd9Sstevel@tonic-gate 				break;
65147c478bd9Sstevel@tonic-gate 		}
65157c478bd9Sstevel@tonic-gate 		/* Set the total size of the ciphertext, when successful */
65167c478bd9Sstevel@tonic-gate 		if (error == CRYPTO_SUCCESS)
65177c478bd9Sstevel@tonic-gate 			dual_data->dd_len1 = encrypted;
65187c478bd9Sstevel@tonic-gate 
65197c478bd9Sstevel@tonic-gate 		break;
65207c478bd9Sstevel@tonic-gate 	}
65217c478bd9Sstevel@tonic-gate 
65227c478bd9Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_MAC_FINAL:
65237c478bd9Sstevel@tonic-gate 		cipher_data = *((crypto_data_t *)dual_data);
65247c478bd9Sstevel@tonic-gate 
65257c478bd9Sstevel@tonic-gate 		/* do an encrypt final */
65267c478bd9Sstevel@tonic-gate 		if ((error = crypto_encrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
65277c478bd9Sstevel@tonic-gate 		    taskq_req->dr_cipher_mac_req.mr_data == NULL ?
65287c478bd9Sstevel@tonic-gate 		    &cipher_data : taskq_req->dr_cipher_mac_req.mr_data,
65297c478bd9Sstevel@tonic-gate 		    NULL)) != CRYPTO_SUCCESS)
65307c478bd9Sstevel@tonic-gate 			break;
65317c478bd9Sstevel@tonic-gate 
65327c478bd9Sstevel@tonic-gate 		/*
65337c478bd9Sstevel@tonic-gate 		 * If ciphertext length is different from zero, do a mac
65347c478bd9Sstevel@tonic-gate 		 * update on it. This does not apply to in-place since we
65357c478bd9Sstevel@tonic-gate 		 * do not allow partial updates, hence no final residual.
65367c478bd9Sstevel@tonic-gate 		 */
65377c478bd9Sstevel@tonic-gate 		if (taskq_req->dr_cipher_mac_req.mr_data != NULL &&
65387c478bd9Sstevel@tonic-gate 		    taskq_req->dr_cipher_mac_req.mr_data->cd_length > 0)
65397c478bd9Sstevel@tonic-gate 			if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
65407c478bd9Sstevel@tonic-gate 			    taskq_req->dr_cipher_mac_req.mr_data, NULL)) !=
65417c478bd9Sstevel@tonic-gate 			    CRYPTO_SUCCESS)
65427c478bd9Sstevel@tonic-gate 				break;
65437c478bd9Sstevel@tonic-gate 
65447c478bd9Sstevel@tonic-gate 		/* do a mac final */
65457c478bd9Sstevel@tonic-gate 		error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
65467c478bd9Sstevel@tonic-gate 		    taskq_req->dr_cipher_mac_req.mr_mac, NULL);
65477c478bd9Sstevel@tonic-gate 
65487c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
65497c478bd9Sstevel@tonic-gate 			DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
65507c478bd9Sstevel@tonic-gate 			DPROV_CTX_DUAL_MAC(ctx) = NULL;
65517c478bd9Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
65527c478bd9Sstevel@tonic-gate 		}
65537c478bd9Sstevel@tonic-gate 		break;
65547c478bd9Sstevel@tonic-gate 
65557c478bd9Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_MAC_ATOMIC: {
65567c478bd9Sstevel@tonic-gate 		crypto_data_t *plaintext_tmp, *ciphertext_tmp;
65577c478bd9Sstevel@tonic-gate 		boolean_t inplace;
65587c478bd9Sstevel@tonic-gate 
65597c478bd9Sstevel@tonic-gate 		cipher_data = *((crypto_data_t *)dual_data);
65607c478bd9Sstevel@tonic-gate 
65617c478bd9Sstevel@tonic-gate 		/* do an encrypt atomic */
65627c478bd9Sstevel@tonic-gate 		inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL);
65637c478bd9Sstevel@tonic-gate 		if (inplace) {
65647c478bd9Sstevel@tonic-gate 			plaintext_tmp = &cipher_data;
65657c478bd9Sstevel@tonic-gate 			ciphertext_tmp = NULL;
65667c478bd9Sstevel@tonic-gate 		} else {
65677c478bd9Sstevel@tonic-gate 			plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data;
65687c478bd9Sstevel@tonic-gate 			ciphertext_tmp = &cipher_data;
65697c478bd9Sstevel@tonic-gate 		}
65707c478bd9Sstevel@tonic-gate 
65717c478bd9Sstevel@tonic-gate 		/* structure assignment */
65727c478bd9Sstevel@tonic-gate 		cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech;
65737c478bd9Sstevel@tonic-gate 		mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech;
65747c478bd9Sstevel@tonic-gate 		session_id = taskq_req->dr_cipher_mac_req.mr_session_id;
65757c478bd9Sstevel@tonic-gate 
65767c478bd9Sstevel@tonic-gate 		/* get the keys values and providers to use for operations */
65777c478bd9Sstevel@tonic-gate 		if ((error = dprov_cipher_mac_key_pd(softc, session_id,
65787c478bd9Sstevel@tonic-gate 		    taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd,
65797c478bd9Sstevel@tonic-gate 		    &cipher_mech.cm_type, &mac_mech.cm_type)) !=
65807c478bd9Sstevel@tonic-gate 		    CRYPTO_SUCCESS)
65817c478bd9Sstevel@tonic-gate 			break;
65827c478bd9Sstevel@tonic-gate 
65837c478bd9Sstevel@tonic-gate 		/* do the atomic encrypt */
6584894b2776Smcpowers 		if ((error = crypto_encrypt_prov(cipher_pd, 0,
65857c478bd9Sstevel@tonic-gate 		    &cipher_mech, plaintext_tmp, &cipher_key, NULL,
6586894b2776Smcpowers 		    ciphertext_tmp, NULL)) != CRYPTO_SUCCESS)
65877c478bd9Sstevel@tonic-gate 			break;
65887c478bd9Sstevel@tonic-gate 
65897c478bd9Sstevel@tonic-gate 		/* do the atomic mac */
65907c478bd9Sstevel@tonic-gate 		mac_data = cipher_data;
65917c478bd9Sstevel@tonic-gate 		mac_data.cd_length = dual_data->dd_len2;
65927c478bd9Sstevel@tonic-gate 		mac_data.cd_offset = dual_data->dd_offset2;
6593894b2776Smcpowers 		error = crypto_mac_prov(mac_pd, 0, &mac_mech, &mac_data,
6594894b2776Smcpowers 		    &mac_key, NULL, taskq_req->dr_cipher_mac_req.mr_mac, NULL);
65957c478bd9Sstevel@tonic-gate 
65967c478bd9Sstevel@tonic-gate 		dual_data->dd_len1 = cipher_data.cd_length;
65977c478bd9Sstevel@tonic-gate 
65987c478bd9Sstevel@tonic-gate 		break;
65997c478bd9Sstevel@tonic-gate 	}
66007c478bd9Sstevel@tonic-gate 
66017c478bd9Sstevel@tonic-gate 	case DPROV_REQ_MAC_DECRYPT: {
66027c478bd9Sstevel@tonic-gate 		uint_t decrypted;
66037c478bd9Sstevel@tonic-gate 		crypto_data_t plaintext_tmp;
66047c478bd9Sstevel@tonic-gate 
66057c478bd9Sstevel@tonic-gate 		cipher_data = *((crypto_data_t *)dual_data);
66067c478bd9Sstevel@tonic-gate 
66077c478bd9Sstevel@tonic-gate 		/* do a mac update and final on the ciphertext */
66087c478bd9Sstevel@tonic-gate 		if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
66097c478bd9Sstevel@tonic-gate 		    &mac_data, NULL)) != CRYPTO_SUCCESS)
66107c478bd9Sstevel@tonic-gate 			break;
66117c478bd9Sstevel@tonic-gate 
66127c478bd9Sstevel@tonic-gate 		/* do a mac final */
66137c478bd9Sstevel@tonic-gate 		if ((error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
66147c478bd9Sstevel@tonic-gate 		    taskq_req->dr_cipher_mac_req.mr_mac, NULL)) !=
66157c478bd9Sstevel@tonic-gate 		    CRYPTO_SUCCESS)
66167c478bd9Sstevel@tonic-gate 			break;
66177c478bd9Sstevel@tonic-gate 
66187c478bd9Sstevel@tonic-gate 		/* do an decrypt update */
66197c478bd9Sstevel@tonic-gate 		cipher_data = mac_data;
66207c478bd9Sstevel@tonic-gate 		cipher_data.cd_length = dual_data->dd_len2;
66217c478bd9Sstevel@tonic-gate 		cipher_data.cd_offset = dual_data->dd_offset2;
66227c478bd9Sstevel@tonic-gate 		if (taskq_req->dr_cipher_mac_req.mr_data == NULL)
66237c478bd9Sstevel@tonic-gate 			/* in-place */
66247c478bd9Sstevel@tonic-gate 			plaintext_tmp = cipher_data;
66257c478bd9Sstevel@tonic-gate 		else
66267c478bd9Sstevel@tonic-gate 			plaintext_tmp = *taskq_req->dr_cipher_mac_req.mr_data;
66277c478bd9Sstevel@tonic-gate 
66287c478bd9Sstevel@tonic-gate 		if ((error = crypto_decrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
66297c478bd9Sstevel@tonic-gate 		    &cipher_data, taskq_req->dr_cipher_mac_req.mr_data,
66307c478bd9Sstevel@tonic-gate 		    NULL)) != CRYPTO_SUCCESS)
66317c478bd9Sstevel@tonic-gate 			break;
66327c478bd9Sstevel@tonic-gate 
66337c478bd9Sstevel@tonic-gate 		/* do an decrypt final */
66347c478bd9Sstevel@tonic-gate 		if (taskq_req->dr_cipher_mac_req.mr_data == NULL)
66357c478bd9Sstevel@tonic-gate 			/* in-place, everything must have been decrypted */
66367c478bd9Sstevel@tonic-gate 			decrypted = cipher_data.cd_length;
66377c478bd9Sstevel@tonic-gate 		else
66387c478bd9Sstevel@tonic-gate 			decrypted =
66397c478bd9Sstevel@tonic-gate 			    taskq_req->dr_cipher_mac_req.mr_data->cd_length;
66407c478bd9Sstevel@tonic-gate 		plaintext_tmp.cd_offset += decrypted;
66417c478bd9Sstevel@tonic-gate 		plaintext_tmp.cd_length -= decrypted;
66427c478bd9Sstevel@tonic-gate 
66437c478bd9Sstevel@tonic-gate 		error = crypto_decrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
66447c478bd9Sstevel@tonic-gate 		    &plaintext_tmp, NULL);
66457c478bd9Sstevel@tonic-gate 		if (taskq_req->dr_cipher_mac_req.mr_data != NULL)
66467c478bd9Sstevel@tonic-gate 			taskq_req->dr_cipher_mac_req.mr_data->cd_length +=
66477c478bd9Sstevel@tonic-gate 			    plaintext_tmp.cd_length;
66487c478bd9Sstevel@tonic-gate 
66497c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
66507c478bd9Sstevel@tonic-gate 			DPROV_CTX_DUAL_MAC(ctx) = NULL;
66517c478bd9Sstevel@tonic-gate 			DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
66527c478bd9Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
66537c478bd9Sstevel@tonic-gate 		}
66547c478bd9Sstevel@tonic-gate 		break;
66557c478bd9Sstevel@tonic-gate 	}
66567c478bd9Sstevel@tonic-gate 
66577c478bd9Sstevel@tonic-gate 	case DPROV_REQ_MAC_DECRYPT_UPDATE:
66587c478bd9Sstevel@tonic-gate 		cipher_data = *((crypto_data_t *)dual_data);
66597c478bd9Sstevel@tonic-gate 
66607c478bd9Sstevel@tonic-gate 		/* do mac update */
66617c478bd9Sstevel@tonic-gate 		if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
66627c478bd9Sstevel@tonic-gate 		    &cipher_data, NULL)) != CRYPTO_SUCCESS)
66637c478bd9Sstevel@tonic-gate 			break;
66647c478bd9Sstevel@tonic-gate 
66657c478bd9Sstevel@tonic-gate 		/* do a decrypt update */
66667c478bd9Sstevel@tonic-gate 		cipher_data.cd_length = dual_data->dd_len2;
66677c478bd9Sstevel@tonic-gate 		cipher_data.cd_offset = dual_data->dd_offset2;
66687c478bd9Sstevel@tonic-gate 		error = crypto_decrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
66697c478bd9Sstevel@tonic-gate 		    &cipher_data, taskq_req->dr_cipher_mac_req.mr_data, NULL);
66707c478bd9Sstevel@tonic-gate 
66717c478bd9Sstevel@tonic-gate 		break;
66727c478bd9Sstevel@tonic-gate 
66737c478bd9Sstevel@tonic-gate 	case DPROV_REQ_MAC_DECRYPT_FINAL:
66747c478bd9Sstevel@tonic-gate 		/* do a mac final */
66757c478bd9Sstevel@tonic-gate 		if ((error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
66767c478bd9Sstevel@tonic-gate 		    taskq_req->dr_cipher_mac_req.mr_mac, NULL)) !=
66777c478bd9Sstevel@tonic-gate 		    CRYPTO_SUCCESS)
66787c478bd9Sstevel@tonic-gate 			break;
66797c478bd9Sstevel@tonic-gate 
66807c478bd9Sstevel@tonic-gate 		/* do a decrypt final */
66817c478bd9Sstevel@tonic-gate 		error = crypto_decrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
66827c478bd9Sstevel@tonic-gate 		    taskq_req->dr_cipher_mac_req.mr_data, NULL);
66837c478bd9Sstevel@tonic-gate 
66847c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
66857c478bd9Sstevel@tonic-gate 			DPROV_CTX_DUAL_MAC(ctx) = NULL;
66867c478bd9Sstevel@tonic-gate 			DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
66877c478bd9Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
66887c478bd9Sstevel@tonic-gate 		}
66897c478bd9Sstevel@tonic-gate 		break;
66907c478bd9Sstevel@tonic-gate 
66917c478bd9Sstevel@tonic-gate 	case DPROV_REQ_MAC_DECRYPT_ATOMIC:
66927c478bd9Sstevel@tonic-gate 	case DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC:
66937c478bd9Sstevel@tonic-gate 		cipher_data = *((crypto_data_t *)dual_data);
66947c478bd9Sstevel@tonic-gate 
66957c478bd9Sstevel@tonic-gate 		/* structure assignment */
66967c478bd9Sstevel@tonic-gate 		cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech;
66977c478bd9Sstevel@tonic-gate 		mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech;
66987c478bd9Sstevel@tonic-gate 		session_id = taskq_req->dr_cipher_mac_req.mr_session_id;
66997c478bd9Sstevel@tonic-gate 
67007c478bd9Sstevel@tonic-gate 		/* get the keys values and providers to use for operations */
67017c478bd9Sstevel@tonic-gate 		if ((error = dprov_cipher_mac_key_pd(softc, session_id,
67027c478bd9Sstevel@tonic-gate 		    taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd,
67037c478bd9Sstevel@tonic-gate 		    &cipher_mech.cm_type, &mac_mech.cm_type)) != CRYPTO_SUCCESS)
67047c478bd9Sstevel@tonic-gate 			break;
67057c478bd9Sstevel@tonic-gate 
67067c478bd9Sstevel@tonic-gate 		/* do the atomic mac */
67077c478bd9Sstevel@tonic-gate 		if (taskq_req->dr_type == DPROV_REQ_MAC_DECRYPT_ATOMIC)
6708894b2776Smcpowers 			error = crypto_mac_prov(mac_pd, 0, &mac_mech,
6709894b2776Smcpowers 			    &cipher_data, &mac_key, NULL,
6710894b2776Smcpowers 			    taskq_req->dr_cipher_mac_req.mr_mac, NULL);
67117c478bd9Sstevel@tonic-gate 		else
67127c478bd9Sstevel@tonic-gate 			/* DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC */
6713894b2776Smcpowers 			error = crypto_mac_verify_prov(mac_pd, 0, &mac_mech,
6714894b2776Smcpowers 			    &cipher_data, &mac_key, NULL,
6715894b2776Smcpowers 			    taskq_req->dr_cipher_mac_req.mr_mac, NULL);
67167c478bd9Sstevel@tonic-gate 
67177c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
67187c478bd9Sstevel@tonic-gate 			break;
67197c478bd9Sstevel@tonic-gate 
67207c478bd9Sstevel@tonic-gate 		/* do the atomic decrypt */
67217c478bd9Sstevel@tonic-gate 		cipher_data.cd_length = dual_data->dd_len2;
67227c478bd9Sstevel@tonic-gate 		cipher_data.cd_offset = dual_data->dd_offset2;
6723894b2776Smcpowers 		error = crypto_decrypt_prov(cipher_pd, 0, &cipher_mech,
6724894b2776Smcpowers 		    &cipher_data, &cipher_key, NULL,
6725894b2776Smcpowers 		    taskq_req->dr_cipher_mac_req.mr_data, NULL);
67267c478bd9Sstevel@tonic-gate 
67277c478bd9Sstevel@tonic-gate 		break;
67287c478bd9Sstevel@tonic-gate 	}
67297c478bd9Sstevel@tonic-gate 
67307c478bd9Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
67317c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_cipher_mac_task: end\n",
67327c478bd9Sstevel@tonic-gate 	    instance));
67337c478bd9Sstevel@tonic-gate }
67347c478bd9Sstevel@tonic-gate 
67357c478bd9Sstevel@tonic-gate /*
67367c478bd9Sstevel@tonic-gate  * taskq dispatcher function for random number generation.
67377c478bd9Sstevel@tonic-gate  */
67387c478bd9Sstevel@tonic-gate static void
67397c478bd9Sstevel@tonic-gate dprov_random_task(dprov_req_t *taskq_req)
67407c478bd9Sstevel@tonic-gate {
67417c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
67427c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
67437c478bd9Sstevel@tonic-gate 	int instance;
67447c478bd9Sstevel@tonic-gate 	int error = CRYPTO_SUCCESS;
67457c478bd9Sstevel@tonic-gate 
67467c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
67477c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_RANDOM, ("(%d) dprov_random_task: started\n", instance));
67487c478bd9Sstevel@tonic-gate 
67497c478bd9Sstevel@tonic-gate 	mutex_enter(&softc->ds_lock);
67507c478bd9Sstevel@tonic-gate 
67517c478bd9Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
67527c478bd9Sstevel@tonic-gate 
67537c478bd9Sstevel@tonic-gate 	DPROV_REQ_RANDOM_SEED:
67547c478bd9Sstevel@tonic-gate 		/*
67557c478bd9Sstevel@tonic-gate 		 * Since we don't really generate random numbers
67567c478bd9Sstevel@tonic-gate 		 * nothing to do.
67577c478bd9Sstevel@tonic-gate 		 */
67587c478bd9Sstevel@tonic-gate 		break;
67597c478bd9Sstevel@tonic-gate 
67607c478bd9Sstevel@tonic-gate 	case DPROV_REQ_RANDOM_GENERATE: {
67617c478bd9Sstevel@tonic-gate 		uint_t i;
67627c478bd9Sstevel@tonic-gate 		uchar_t c = 0;
67637c478bd9Sstevel@tonic-gate 
67647c478bd9Sstevel@tonic-gate 		/*
67657c478bd9Sstevel@tonic-gate 		 * We don't generate random numbers so that the result
67667c478bd9Sstevel@tonic-gate 		 * of the operation can be checked during testing.
67677c478bd9Sstevel@tonic-gate 		 */
67687c478bd9Sstevel@tonic-gate 
67697c478bd9Sstevel@tonic-gate 		for (i = 0; i < taskq_req->dr_random_req.rr_len; i++)
67707c478bd9Sstevel@tonic-gate 			taskq_req->dr_random_req.rr_buf[i] = c++;
67717c478bd9Sstevel@tonic-gate 
67727c478bd9Sstevel@tonic-gate 		break;
67737c478bd9Sstevel@tonic-gate 	}
67747c478bd9Sstevel@tonic-gate 	}
67757c478bd9Sstevel@tonic-gate 
67767c478bd9Sstevel@tonic-gate 	mutex_exit(&softc->ds_lock);
67777c478bd9Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
67787c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_RANDOM, ("(%d) dprov_random_task: end\n", instance));
67797c478bd9Sstevel@tonic-gate }
67807c478bd9Sstevel@tonic-gate 
67817c478bd9Sstevel@tonic-gate 
67827c478bd9Sstevel@tonic-gate /*
67837c478bd9Sstevel@tonic-gate  * taskq dispatcher function for session management operations.
67847c478bd9Sstevel@tonic-gate  */
67857c478bd9Sstevel@tonic-gate static void
67867c478bd9Sstevel@tonic-gate dprov_session_task(dprov_req_t *taskq_req)
67877c478bd9Sstevel@tonic-gate {
67887c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
67897c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
67907c478bd9Sstevel@tonic-gate 	int instance;
67917c478bd9Sstevel@tonic-gate 	int error = CRYPTO_NOT_SUPPORTED;
67927c478bd9Sstevel@tonic-gate 	crypto_session_id_t session_id =
67937c478bd9Sstevel@tonic-gate 	    taskq_req->dr_session_req.sr_session_id;
67947c478bd9Sstevel@tonic-gate 	dprov_session_t *session;
67957c478bd9Sstevel@tonic-gate 	dprov_object_t *object;
67967c478bd9Sstevel@tonic-gate 	int i;
67977c478bd9Sstevel@tonic-gate 
67987c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
67997c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_task: started\n",
68007c478bd9Sstevel@tonic-gate 	    instance));
68017c478bd9Sstevel@tonic-gate 
68027c478bd9Sstevel@tonic-gate 	mutex_enter(&softc->ds_lock);
68037c478bd9Sstevel@tonic-gate 
68047c478bd9Sstevel@tonic-gate 	if (taskq_req->dr_type != DPROV_REQ_SESSION_OPEN)
68057c478bd9Sstevel@tonic-gate 		/* validate session id and get ptr to session */
68067c478bd9Sstevel@tonic-gate 		if ((session = softc->ds_sessions[session_id]) == NULL) {
68077c478bd9Sstevel@tonic-gate 			mutex_exit(&softc->ds_lock);
68087c478bd9Sstevel@tonic-gate 			dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID);
68097c478bd9Sstevel@tonic-gate 			return;
68107c478bd9Sstevel@tonic-gate 		}
68117c478bd9Sstevel@tonic-gate 
68127c478bd9Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
68137c478bd9Sstevel@tonic-gate 
68147c478bd9Sstevel@tonic-gate 	case DPROV_REQ_SESSION_OPEN: {
68157c478bd9Sstevel@tonic-gate 		dprov_session_t **new_sessions;
68167c478bd9Sstevel@tonic-gate 
68177c478bd9Sstevel@tonic-gate 		if (softc->ds_token_initialized == B_FALSE) {
68187c478bd9Sstevel@tonic-gate 			error = CRYPTO_OPERATION_NOT_INITIALIZED;
68197c478bd9Sstevel@tonic-gate 			break;
68207c478bd9Sstevel@tonic-gate 		}
68217c478bd9Sstevel@tonic-gate 
68227c478bd9Sstevel@tonic-gate 		/* search for available session slot */
68237c478bd9Sstevel@tonic-gate 		for (i = 0; i < softc->ds_sessions_slots; i++)
68247c478bd9Sstevel@tonic-gate 			if (softc->ds_sessions[i] == NULL)
68257c478bd9Sstevel@tonic-gate 				break;
68267c478bd9Sstevel@tonic-gate 
68277c478bd9Sstevel@tonic-gate 		if (i == softc->ds_sessions_slots) {
68287c478bd9Sstevel@tonic-gate 			/* ran out of slots, grow sessions array */
68291ae80171SKrishna Yenduri 			new_sessions = kmem_zalloc(
68301ae80171SKrishna Yenduri 			    2 * softc->ds_sessions_slots *
68311ae80171SKrishna Yenduri 			    sizeof (dprov_session_t *), KM_NOSLEEP);
68327c478bd9Sstevel@tonic-gate 			if (new_sessions == NULL) {
68337c478bd9Sstevel@tonic-gate 				error = CRYPTO_SESSION_COUNT;
68347c478bd9Sstevel@tonic-gate 				break;
68357c478bd9Sstevel@tonic-gate 			}
68367c478bd9Sstevel@tonic-gate 			bcopy(softc->ds_sessions, new_sessions,
68371ae80171SKrishna Yenduri 			    softc->ds_sessions_slots *
68381ae80171SKrishna Yenduri 			    sizeof (dprov_session_t *));
68397c478bd9Sstevel@tonic-gate 			kmem_free(softc->ds_sessions, softc->ds_sessions_slots *
68407c478bd9Sstevel@tonic-gate 			    sizeof (dprov_session_t *));
68417c478bd9Sstevel@tonic-gate 			softc->ds_sessions = new_sessions;
68427c478bd9Sstevel@tonic-gate 			softc->ds_sessions_slots *= 2;
68437c478bd9Sstevel@tonic-gate 		}
68447c478bd9Sstevel@tonic-gate 
68457c478bd9Sstevel@tonic-gate 		/* allocate and initialize new session */
68467c478bd9Sstevel@tonic-gate 		softc->ds_sessions[i] = kmem_zalloc(
68477c478bd9Sstevel@tonic-gate 		    sizeof (dprov_session_t), KM_NOSLEEP);
68487c478bd9Sstevel@tonic-gate 		if (softc->ds_sessions[i] == NULL) {
68497c478bd9Sstevel@tonic-gate 			error = CRYPTO_HOST_MEMORY;
68507c478bd9Sstevel@tonic-gate 			break;
68517c478bd9Sstevel@tonic-gate 		}
68527c478bd9Sstevel@tonic-gate 		softc->ds_sessions_count++;
68537c478bd9Sstevel@tonic-gate 
68547c478bd9Sstevel@tonic-gate 		/* initialize session state */
68557c478bd9Sstevel@tonic-gate 		softc->ds_sessions[i]->ds_state = DPROV_SESSION_STATE_PUBLIC;
68567c478bd9Sstevel@tonic-gate 
68577c478bd9Sstevel@tonic-gate 		/* return new session id to caller */
68587c478bd9Sstevel@tonic-gate 		*(taskq_req->dr_session_req.sr_session_id_ptr) = i;
68597c478bd9Sstevel@tonic-gate 
68607c478bd9Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
68617c478bd9Sstevel@tonic-gate 		break;
68627c478bd9Sstevel@tonic-gate 	}
68637c478bd9Sstevel@tonic-gate 
68647c478bd9Sstevel@tonic-gate 	case DPROV_REQ_SESSION_CLOSE:
68657c478bd9Sstevel@tonic-gate 		softc->ds_sessions[session_id] = NULL;
68667c478bd9Sstevel@tonic-gate 
68677c478bd9Sstevel@tonic-gate 		if (softc->ds_token_initialized == B_FALSE) {
68687c478bd9Sstevel@tonic-gate 			error = CRYPTO_OPERATION_NOT_INITIALIZED;
68697c478bd9Sstevel@tonic-gate 			break;
68707c478bd9Sstevel@tonic-gate 		}
68717c478bd9Sstevel@tonic-gate 
68727c478bd9Sstevel@tonic-gate 		dprov_release_session_objects(session);
68737c478bd9Sstevel@tonic-gate 
68747c478bd9Sstevel@tonic-gate 		/* free session state and corresponding slot */
68757c478bd9Sstevel@tonic-gate 		kmem_free(session, sizeof (dprov_session_t));
68767c478bd9Sstevel@tonic-gate 		softc->ds_sessions_count--;
68777c478bd9Sstevel@tonic-gate 
68787c478bd9Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
68797c478bd9Sstevel@tonic-gate 		break;
68807c478bd9Sstevel@tonic-gate 
68817c478bd9Sstevel@tonic-gate 	case DPROV_REQ_SESSION_LOGIN: {
68827c478bd9Sstevel@tonic-gate 		char *pin = taskq_req->dr_session_req.sr_pin;
68837c478bd9Sstevel@tonic-gate 		size_t pin_len = taskq_req->dr_session_req.sr_pin_len;
68847c478bd9Sstevel@tonic-gate 		crypto_user_type_t user_type =
68857c478bd9Sstevel@tonic-gate 		    taskq_req->dr_session_req.sr_user_type;
68867c478bd9Sstevel@tonic-gate 
68877c478bd9Sstevel@tonic-gate 		/* check user type */
68887c478bd9Sstevel@tonic-gate 		if (user_type != CRYPTO_SO && user_type != CRYPTO_USER) {
68897c478bd9Sstevel@tonic-gate 			error = CRYPTO_USER_TYPE_INVALID;
68907c478bd9Sstevel@tonic-gate 			break;
68917c478bd9Sstevel@tonic-gate 		}
68927c478bd9Sstevel@tonic-gate 
68937c478bd9Sstevel@tonic-gate 		/* check pin length */
68947c478bd9Sstevel@tonic-gate 		if (pin_len > DPROV_MAX_PIN_LEN) {
68957c478bd9Sstevel@tonic-gate 			error = CRYPTO_PIN_LEN_RANGE;
68967c478bd9Sstevel@tonic-gate 			break;
68977c478bd9Sstevel@tonic-gate 		}
68987c478bd9Sstevel@tonic-gate 
68997c478bd9Sstevel@tonic-gate 		/* check pin */
69007c478bd9Sstevel@tonic-gate 		if (pin == NULL) {
69017c478bd9Sstevel@tonic-gate 			error = CRYPTO_PIN_INVALID;
69027c478bd9Sstevel@tonic-gate 			break;
69037c478bd9Sstevel@tonic-gate 		}
69047c478bd9Sstevel@tonic-gate 
69057c478bd9Sstevel@tonic-gate 		/* validate PIN state */
69067c478bd9Sstevel@tonic-gate 		if ((user_type == CRYPTO_SO) && !softc->ds_token_initialized ||
69077c478bd9Sstevel@tonic-gate 		    (user_type == CRYPTO_USER) && !softc->ds_user_pin_set) {
69087c478bd9Sstevel@tonic-gate 			error = CRYPTO_USER_PIN_NOT_INITIALIZED;
69097c478bd9Sstevel@tonic-gate 			break;
69107c478bd9Sstevel@tonic-gate 		}
69117c478bd9Sstevel@tonic-gate 
69127c478bd9Sstevel@tonic-gate 		if ((user_type == CRYPTO_SO &&
69137c478bd9Sstevel@tonic-gate 		    softc->ds_sessions[session_id]->ds_state ==
69147c478bd9Sstevel@tonic-gate 		    DPROV_SESSION_STATE_SO) ||
69157c478bd9Sstevel@tonic-gate 		    (user_type == CRYPTO_USER &&
69167c478bd9Sstevel@tonic-gate 		    softc->ds_sessions[session_id]->ds_state ==
69177c478bd9Sstevel@tonic-gate 		    DPROV_SESSION_STATE_USER)) {
69187c478bd9Sstevel@tonic-gate 			/* SO or user already logged in */
69197c478bd9Sstevel@tonic-gate 			error = CRYPTO_USER_ALREADY_LOGGED_IN;
69207c478bd9Sstevel@tonic-gate 			break;
69217c478bd9Sstevel@tonic-gate 		}
69227c478bd9Sstevel@tonic-gate 
69237c478bd9Sstevel@tonic-gate 		if (softc->ds_sessions[session_id]->ds_state !=
69247c478bd9Sstevel@tonic-gate 		    DPROV_SESSION_STATE_PUBLIC) {
69257c478bd9Sstevel@tonic-gate 			/* another user already logged in */
69267c478bd9Sstevel@tonic-gate 			error = CRYPTO_USER_ANOTHER_ALREADY_LOGGED_IN;
69277c478bd9Sstevel@tonic-gate 			break;
69287c478bd9Sstevel@tonic-gate 		}
69297c478bd9Sstevel@tonic-gate 
69307c478bd9Sstevel@tonic-gate 		/* everything's fine, update session */
69317c478bd9Sstevel@tonic-gate 		softc->ds_sessions[session_id]->ds_state =
69327c478bd9Sstevel@tonic-gate 		    user_type == CRYPTO_SO ?
69337c478bd9Sstevel@tonic-gate 		    DPROV_SESSION_STATE_SO : DPROV_SESSION_STATE_USER;
69347c478bd9Sstevel@tonic-gate 
69357c478bd9Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
69367c478bd9Sstevel@tonic-gate 		break;
69377c478bd9Sstevel@tonic-gate 	}
69387c478bd9Sstevel@tonic-gate 
69397c478bd9Sstevel@tonic-gate 	case DPROV_REQ_SESSION_LOGOUT:
69407c478bd9Sstevel@tonic-gate 		/* fail if not logged in */
69417c478bd9Sstevel@tonic-gate 		if (softc->ds_sessions[session_id]->ds_state ==
69427c478bd9Sstevel@tonic-gate 		    DPROV_SESSION_STATE_PUBLIC) {
69437c478bd9Sstevel@tonic-gate 			error = CRYPTO_USER_NOT_LOGGED_IN;
69447c478bd9Sstevel@tonic-gate 			break;
69457c478bd9Sstevel@tonic-gate 		}
69467c478bd9Sstevel@tonic-gate 
69477c478bd9Sstevel@tonic-gate 		/*
69487c478bd9Sstevel@tonic-gate 		 * Destroy all private session objects.
69497c478bd9Sstevel@tonic-gate 		 * Invalidate handles to all private objects.
69507c478bd9Sstevel@tonic-gate 		 */
69517c478bd9Sstevel@tonic-gate 		for (i = 0; i < DPROV_MAX_OBJECTS; i++) {
69527c478bd9Sstevel@tonic-gate 			object = softc->ds_sessions[session_id]->ds_objects[i];
69537c478bd9Sstevel@tonic-gate 			if (object != NULL && dprov_object_is_private(object)) {
69547c478bd9Sstevel@tonic-gate 				if (!dprov_object_is_token(object))
69557c478bd9Sstevel@tonic-gate 					/* It's a session object, free it */
69567c478bd9Sstevel@tonic-gate 					DPROV_OBJECT_REFRELE(object);
69577c478bd9Sstevel@tonic-gate 				softc->ds_sessions[session_id]->ds_objects[i] =
69587c478bd9Sstevel@tonic-gate 				    NULL;
69597c478bd9Sstevel@tonic-gate 			}
69607c478bd9Sstevel@tonic-gate 		}
69617c478bd9Sstevel@tonic-gate 
69627c478bd9Sstevel@tonic-gate 		/* update session state */
69637c478bd9Sstevel@tonic-gate 		softc->ds_sessions[session_id]->ds_state =
69647c478bd9Sstevel@tonic-gate 		    DPROV_SESSION_STATE_PUBLIC;
69657c478bd9Sstevel@tonic-gate 
69667c478bd9Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
69677c478bd9Sstevel@tonic-gate 		break;
69687c478bd9Sstevel@tonic-gate 	}
69697c478bd9Sstevel@tonic-gate 
69707c478bd9Sstevel@tonic-gate 	mutex_exit(&softc->ds_lock);
69717c478bd9Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
69727c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_task: end\n", instance));
69737c478bd9Sstevel@tonic-gate }
69747c478bd9Sstevel@tonic-gate 
6975894b2776Smcpowers /* return true if attribute is defined to be a PKCS#11 long */
6976894b2776Smcpowers static boolean_t
6977894b2776Smcpowers fixed_size_attribute(crypto_attr_type_t type)
6978894b2776Smcpowers {
6979894b2776Smcpowers 	return (type == DPROV_CKA_CLASS ||
6980894b2776Smcpowers 	    type == DPROV_CKA_CERTIFICATE_TYPE ||
6981894b2776Smcpowers 	    type == DPROV_CKA_KEY_TYPE ||
6982894b2776Smcpowers 	    type == DPROV_HW_FEATURE_TYPE);
6983894b2776Smcpowers }
6984894b2776Smcpowers 
6985894b2776Smcpowers /*
6986894b2776Smcpowers  * Attributes defined to be a PKCS#11 long causes problems for dprov
6987894b2776Smcpowers  * because 32-bit applications set the size to 4 and 64-bit applications
6988894b2776Smcpowers  * set the size to 8. dprov always stores these fixed-size attributes
6989894b2776Smcpowers  * as uint32_t.
6990894b2776Smcpowers  */
6991894b2776Smcpowers static ssize_t
6992894b2776Smcpowers attribute_size(crypto_attr_type_t type, ssize_t len)
6993894b2776Smcpowers {
6994894b2776Smcpowers 	if (fixed_size_attribute(type))
6995894b2776Smcpowers 		return (sizeof (uint32_t));
6996894b2776Smcpowers 
6997894b2776Smcpowers 	return (len);
6998894b2776Smcpowers }
6999894b2776Smcpowers 
70007c478bd9Sstevel@tonic-gate /*
70017c478bd9Sstevel@tonic-gate  * taskq dispatcher function for object management operations.
70027c478bd9Sstevel@tonic-gate  */
70037c478bd9Sstevel@tonic-gate static void
70047c478bd9Sstevel@tonic-gate dprov_object_task(dprov_req_t *taskq_req)
70057c478bd9Sstevel@tonic-gate {
70067c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
70077c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
70087c478bd9Sstevel@tonic-gate 	int instance;
70097c478bd9Sstevel@tonic-gate 	int error = CRYPTO_NOT_SUPPORTED;
70107c478bd9Sstevel@tonic-gate 	crypto_object_id_t object_id = taskq_req->dr_object_req.or_object_id;
70117c478bd9Sstevel@tonic-gate 	crypto_session_id_t session_id = taskq_req->dr_object_req.or_session_id;
70127c478bd9Sstevel@tonic-gate 	crypto_object_attribute_t *template =
70137c478bd9Sstevel@tonic-gate 	    taskq_req->dr_object_req.or_template;
70147c478bd9Sstevel@tonic-gate 	uint_t attr_count = taskq_req->dr_object_req.or_attribute_count;
70157c478bd9Sstevel@tonic-gate 	dprov_object_t *object;
70167c478bd9Sstevel@tonic-gate 	dprov_session_t *session;
70177c478bd9Sstevel@tonic-gate 
70187c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
70197c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_task: started\n", instance));
70207c478bd9Sstevel@tonic-gate 
70217c478bd9Sstevel@tonic-gate 	mutex_enter(&softc->ds_lock);
70227c478bd9Sstevel@tonic-gate 
70237c478bd9Sstevel@tonic-gate 	/* validate session id and get ptr to session */
70247c478bd9Sstevel@tonic-gate 	if ((session = softc->ds_sessions[session_id]) == NULL) {
70257c478bd9Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
70267c478bd9Sstevel@tonic-gate 		dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID);
70277c478bd9Sstevel@tonic-gate 		return;
70287c478bd9Sstevel@tonic-gate 	}
70297c478bd9Sstevel@tonic-gate 
70307c478bd9Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
70317c478bd9Sstevel@tonic-gate 
70327c478bd9Sstevel@tonic-gate 	case DPROV_REQ_OBJECT_CREATE:
70337c478bd9Sstevel@tonic-gate 		/* create the object from the specified template */
70347c478bd9Sstevel@tonic-gate 		if ((error = dprov_create_object_from_template(softc, session,
70357c478bd9Sstevel@tonic-gate 		    template, attr_count,
70367c478bd9Sstevel@tonic-gate 		    taskq_req->dr_object_req.or_object_id_ptr, B_TRUE,
70377c478bd9Sstevel@tonic-gate 		    B_FALSE)) != CRYPTO_SUCCESS)
70387c478bd9Sstevel@tonic-gate 			break;
70397c478bd9Sstevel@tonic-gate 
70407c478bd9Sstevel@tonic-gate 		break;
70417c478bd9Sstevel@tonic-gate 
70427c478bd9Sstevel@tonic-gate 	case DPROV_REQ_OBJECT_COPY:
70437c478bd9Sstevel@tonic-gate 		/* check object id */
70447c478bd9Sstevel@tonic-gate 		if (object_id >= DPROV_MAX_OBJECTS ||
70457c478bd9Sstevel@tonic-gate 		    (object = session->ds_objects[object_id]) == NULL) {
70467c478bd9Sstevel@tonic-gate 			error = CRYPTO_OBJECT_HANDLE_INVALID;
70477c478bd9Sstevel@tonic-gate 			break;
70487c478bd9Sstevel@tonic-gate 		}
70497c478bd9Sstevel@tonic-gate 
70507c478bd9Sstevel@tonic-gate 		/*
70517c478bd9Sstevel@tonic-gate 		 * Create a new object from the object passed as
70527c478bd9Sstevel@tonic-gate 		 * argument.
70537c478bd9Sstevel@tonic-gate 		 */
70547c478bd9Sstevel@tonic-gate 		if ((error = dprov_create_object_from_template(softc, session,
70557c478bd9Sstevel@tonic-gate 		    object->do_attr, DPROV_MAX_ATTR,
70567c478bd9Sstevel@tonic-gate 		    taskq_req->dr_object_req.or_object_id_ptr, B_TRUE,
70577c478bd9Sstevel@tonic-gate 		    B_FALSE)) != CRYPTO_SUCCESS)
70587c478bd9Sstevel@tonic-gate 			break;
70597c478bd9Sstevel@tonic-gate 
70607c478bd9Sstevel@tonic-gate 		/*
70617c478bd9Sstevel@tonic-gate 		 * Add the attributes specified by the template to the
70627c478bd9Sstevel@tonic-gate 		 * newly created object, replacing existing ones if needed.
70637c478bd9Sstevel@tonic-gate 		 */
70647c478bd9Sstevel@tonic-gate 		error = dprov_object_set_attr(session,
70657c478bd9Sstevel@tonic-gate 		    *taskq_req->dr_object_req.or_object_id_ptr,
70667c478bd9Sstevel@tonic-gate 		    taskq_req->dr_object_req.or_template,
70677c478bd9Sstevel@tonic-gate 		    taskq_req->dr_object_req.or_attribute_count, B_TRUE);
70687c478bd9Sstevel@tonic-gate 
70697c478bd9Sstevel@tonic-gate 		break;
70707c478bd9Sstevel@tonic-gate 
70717c478bd9Sstevel@tonic-gate 	case DPROV_REQ_OBJECT_DESTROY:
70727c478bd9Sstevel@tonic-gate 		/* destroy the object */
70737c478bd9Sstevel@tonic-gate 		error = dprov_destroy_object(softc, session,
70747c478bd9Sstevel@tonic-gate 		    taskq_req->dr_object_req.or_object_id);
70757c478bd9Sstevel@tonic-gate 
70767c478bd9Sstevel@tonic-gate 		break;
70777c478bd9Sstevel@tonic-gate 
70787c478bd9Sstevel@tonic-gate 	case DPROV_REQ_OBJECT_GET_SIZE:
70797c478bd9Sstevel@tonic-gate 		/* get ptr to object */
70807c478bd9Sstevel@tonic-gate 		if (object_id >= DPROV_MAX_OBJECTS ||
70817c478bd9Sstevel@tonic-gate 		    session->ds_objects[object_id] == NULL) {
70827c478bd9Sstevel@tonic-gate 			error = CRYPTO_OBJECT_HANDLE_INVALID;
70837c478bd9Sstevel@tonic-gate 			break;
70847c478bd9Sstevel@tonic-gate 		}
70857c478bd9Sstevel@tonic-gate 
70867c478bd9Sstevel@tonic-gate 		/*
70877c478bd9Sstevel@tonic-gate 		 * The PKCS11 specification does not specifies what
70887c478bd9Sstevel@tonic-gate 		 * the object size really is, here we just return
70897c478bd9Sstevel@tonic-gate 		 * the number of possible attributes of the object.
70907c478bd9Sstevel@tonic-gate 		 */
70917c478bd9Sstevel@tonic-gate 		*taskq_req->dr_object_req.or_object_size = DPROV_MAX_ATTR;
70927c478bd9Sstevel@tonic-gate 
70937c478bd9Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
70947c478bd9Sstevel@tonic-gate 		break;
70957c478bd9Sstevel@tonic-gate 
70967c478bd9Sstevel@tonic-gate 	case DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE: {
7097894b2776Smcpowers 		crypto_attr_type_t type;
7098894b2776Smcpowers 		size_t olen, tlen;
7099894b2776Smcpowers 		offset_t offset;
71007c478bd9Sstevel@tonic-gate 		int tmpl_idx;
71017c478bd9Sstevel@tonic-gate 		int object_idx;
71027c478bd9Sstevel@tonic-gate 		ulong_t class = DPROV_CKO_DATA;
71037c478bd9Sstevel@tonic-gate 		boolean_t extractable = B_TRUE;
71047c478bd9Sstevel@tonic-gate 
71057c478bd9Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
71067c478bd9Sstevel@tonic-gate 
71077c478bd9Sstevel@tonic-gate 		/* get ptr to object */
71087c478bd9Sstevel@tonic-gate 		if (object_id >= DPROV_MAX_OBJECTS ||
71097c478bd9Sstevel@tonic-gate 		    (object = session->ds_objects[object_id]) == NULL) {
71107c478bd9Sstevel@tonic-gate 			error = CRYPTO_OBJECT_HANDLE_INVALID;
71117c478bd9Sstevel@tonic-gate 			break;
71127c478bd9Sstevel@tonic-gate 		}
71137c478bd9Sstevel@tonic-gate 
71147c478bd9Sstevel@tonic-gate 		(void) dprov_get_object_attr_boolean(object,
71157c478bd9Sstevel@tonic-gate 		    DPROV_CKA_EXTRACTABLE, &extractable);
71167c478bd9Sstevel@tonic-gate 
71177c478bd9Sstevel@tonic-gate 		(void) dprov_get_object_attr_ulong(object,
71187c478bd9Sstevel@tonic-gate 		    DPROV_CKA_CLASS, &class);
71197c478bd9Sstevel@tonic-gate 
71207c478bd9Sstevel@tonic-gate 		/* return the specified attributes, when possible */
71217c478bd9Sstevel@tonic-gate 		for (tmpl_idx = 0; tmpl_idx < attr_count; tmpl_idx++) {
71227c478bd9Sstevel@tonic-gate 			/*
71237c478bd9Sstevel@tonic-gate 			 * Attribute can't be revealed if the CKA_EXTRACTABLE
71247c478bd9Sstevel@tonic-gate 			 * attribute is set to false.
71257c478bd9Sstevel@tonic-gate 			 */
7126894b2776Smcpowers 			type = template[tmpl_idx].oa_type;
71277c478bd9Sstevel@tonic-gate 			if (!extractable && class == DPROV_CKO_SECRET_KEY) {
7128894b2776Smcpowers 				if (type == DPROV_CKA_VALUE) {
71297c478bd9Sstevel@tonic-gate 					template[tmpl_idx].oa_value_len = -1;
71307c478bd9Sstevel@tonic-gate 					error = CRYPTO_ATTRIBUTE_SENSITIVE;
71317c478bd9Sstevel@tonic-gate 					continue;
71327c478bd9Sstevel@tonic-gate 				}
71337c478bd9Sstevel@tonic-gate 			}
71347c478bd9Sstevel@tonic-gate 			if (!extractable && class == DPROV_CKO_PRIVATE_KEY) {
7135894b2776Smcpowers 				if (type == DPROV_CKA_PRIVATE_EXPONENT) {
71367c478bd9Sstevel@tonic-gate 					template[tmpl_idx].oa_value_len = -1;
71377c478bd9Sstevel@tonic-gate 					error = CRYPTO_ATTRIBUTE_SENSITIVE;
71387c478bd9Sstevel@tonic-gate 					continue;
71397c478bd9Sstevel@tonic-gate 				}
71407c478bd9Sstevel@tonic-gate 			}
71417c478bd9Sstevel@tonic-gate 
71427c478bd9Sstevel@tonic-gate 			object_idx = dprov_find_attr(object->do_attr,
7143894b2776Smcpowers 			    DPROV_MAX_ATTR, type);
71447c478bd9Sstevel@tonic-gate 			if (object_idx == -1) {
71457c478bd9Sstevel@tonic-gate 				/* attribute not found in object */
71467c478bd9Sstevel@tonic-gate 				template[tmpl_idx].oa_value_len = -1;
71477c478bd9Sstevel@tonic-gate 				error = CRYPTO_ATTRIBUTE_TYPE_INVALID;
71487c478bd9Sstevel@tonic-gate 				continue;
71497c478bd9Sstevel@tonic-gate 			}
71507c478bd9Sstevel@tonic-gate 
7151894b2776Smcpowers 			tlen = template[tmpl_idx].oa_value_len;
7152894b2776Smcpowers 			olen = object->do_attr[object_idx].oa_value_len;
71537c478bd9Sstevel@tonic-gate 			/* return attribute length */
7154894b2776Smcpowers 			if (template[tmpl_idx].oa_value == NULL) {
7155894b2776Smcpowers 				/*
7156894b2776Smcpowers 				 * The size of the attribute is set by the
7157894b2776Smcpowers 				 * library according to the data model of the
7158894b2776Smcpowers 				 * application, so don't overwrite it with
7159894b2776Smcpowers 				 * dprov's size.
7160894b2776Smcpowers 				 */
7161894b2776Smcpowers 				if (!fixed_size_attribute(type))
7162894b2776Smcpowers 					template[tmpl_idx].oa_value_len = olen;
71637c478bd9Sstevel@tonic-gate 				continue;
71647c478bd9Sstevel@tonic-gate 			}
7165894b2776Smcpowers 
7166894b2776Smcpowers 			if (tlen < olen) {
71677c478bd9Sstevel@tonic-gate 				template[tmpl_idx].oa_value_len = -1;
71687c478bd9Sstevel@tonic-gate 				error = CRYPTO_BUFFER_TOO_SMALL;
71697c478bd9Sstevel@tonic-gate 				continue;
71707c478bd9Sstevel@tonic-gate 			}
7171894b2776Smcpowers 
7172894b2776Smcpowers 			/* copy attribute value */
7173894b2776Smcpowers 			bzero(template[tmpl_idx].oa_value, tlen);
7174894b2776Smcpowers 
7175894b2776Smcpowers 			offset = 0;
7176894b2776Smcpowers #ifdef _BIG_ENDIAN
7177894b2776Smcpowers 			if (fixed_size_attribute(type)) {
7178894b2776Smcpowers 				offset = tlen - olen;
7179894b2776Smcpowers 			}
7180894b2776Smcpowers #endif
71817c478bd9Sstevel@tonic-gate 			bcopy(object->do_attr[object_idx].oa_value,
7182894b2776Smcpowers 			    &template[tmpl_idx].oa_value[offset], olen);
7183894b2776Smcpowers 
7184894b2776Smcpowers 			/* don't update length for fixed-size attributes */
7185894b2776Smcpowers 			if (!fixed_size_attribute(type))
7186894b2776Smcpowers 				template[tmpl_idx].oa_value_len = olen;
71877c478bd9Sstevel@tonic-gate 		}
71887c478bd9Sstevel@tonic-gate 
71897c478bd9Sstevel@tonic-gate 		break;
71907c478bd9Sstevel@tonic-gate 	}
71917c478bd9Sstevel@tonic-gate 
71927c478bd9Sstevel@tonic-gate 	case DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE:
71937c478bd9Sstevel@tonic-gate 		/*
71947c478bd9Sstevel@tonic-gate 		 * Add the attributes specified by the template to the
71957c478bd9Sstevel@tonic-gate 		 * newly created object, replacing existing ones if needed.
71967c478bd9Sstevel@tonic-gate 		 */
71977c478bd9Sstevel@tonic-gate 		error = dprov_object_set_attr(session,
71987c478bd9Sstevel@tonic-gate 		    taskq_req->dr_object_req.or_object_id,
71997c478bd9Sstevel@tonic-gate 		    taskq_req->dr_object_req.or_template,
72007c478bd9Sstevel@tonic-gate 		    taskq_req->dr_object_req.or_attribute_count, B_TRUE);
72017c478bd9Sstevel@tonic-gate 
72027c478bd9Sstevel@tonic-gate 		break;
72037c478bd9Sstevel@tonic-gate 
72047c478bd9Sstevel@tonic-gate 	case DPROV_REQ_OBJECT_FIND_INIT: {
72057c478bd9Sstevel@tonic-gate 		dprov_find_ctx_t *find_ctx;
72067c478bd9Sstevel@tonic-gate 		int so_idx;		/* session object index */
72077c478bd9Sstevel@tonic-gate 		int to_idx;		/* token object index */
72087c478bd9Sstevel@tonic-gate 
72097c478bd9Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
72107c478bd9Sstevel@tonic-gate 		/* allocate find context */
72117c478bd9Sstevel@tonic-gate 		find_ctx = kmem_zalloc(sizeof (dprov_find_ctx_t), KM_SLEEP);
72127c478bd9Sstevel@tonic-gate 		*taskq_req->dr_object_req.or_find_pp = find_ctx;
72137c478bd9Sstevel@tonic-gate 
72147c478bd9Sstevel@tonic-gate 		/* first go through the existing session objects */
72157c478bd9Sstevel@tonic-gate 		for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++) {
72167c478bd9Sstevel@tonic-gate 			if ((object = session->ds_objects[so_idx]) == NULL)
72177c478bd9Sstevel@tonic-gate 				continue;
72187c478bd9Sstevel@tonic-gate 
72197c478bd9Sstevel@tonic-gate 			/* setting count to zero means find all objects */
72207c478bd9Sstevel@tonic-gate 			if (attr_count > 0) {
72217c478bd9Sstevel@tonic-gate 				if (!dprov_attributes_match(object, template,
72227c478bd9Sstevel@tonic-gate 				    attr_count))
72237c478bd9Sstevel@tonic-gate 					continue;
72247c478bd9Sstevel@tonic-gate 			}
72257c478bd9Sstevel@tonic-gate 
72267c478bd9Sstevel@tonic-gate 			/* session object attributes matches template */
72277c478bd9Sstevel@tonic-gate 			find_ctx->fc_ids[find_ctx->fc_nids] = so_idx;
72287c478bd9Sstevel@tonic-gate 			find_ctx->fc_nids++;
72297c478bd9Sstevel@tonic-gate 		}
72307c478bd9Sstevel@tonic-gate 
72317c478bd9Sstevel@tonic-gate 		/*
72327c478bd9Sstevel@tonic-gate 		 * Go through the token object. For each token object
72337c478bd9Sstevel@tonic-gate 		 * that can be accessed:
72347c478bd9Sstevel@tonic-gate 		 * If there was already an session object id assigned
72357c478bd9Sstevel@tonic-gate 		 * to that token object, skip it, since it was returned
72367c478bd9Sstevel@tonic-gate 		 * during the check of session objects, else,
72377c478bd9Sstevel@tonic-gate 		 * assign a new object id for that token object and
72387c478bd9Sstevel@tonic-gate 		 * add it to the array of matching objects.
72397c478bd9Sstevel@tonic-gate 		 */
72407c478bd9Sstevel@tonic-gate 		for (to_idx = 0; to_idx < DPROV_MAX_OBJECTS &&
72417c478bd9Sstevel@tonic-gate 		    error == CRYPTO_SUCCESS; to_idx++) {
72427c478bd9Sstevel@tonic-gate 			if ((object = softc->ds_objects[to_idx]) == NULL)
72437c478bd9Sstevel@tonic-gate 				continue;
72447c478bd9Sstevel@tonic-gate 
72457c478bd9Sstevel@tonic-gate 			/* setting count to zero means find all objects */
72467c478bd9Sstevel@tonic-gate 			if (attr_count > 0) {
72477c478bd9Sstevel@tonic-gate 				if (!dprov_attributes_match(object, template,
72487c478bd9Sstevel@tonic-gate 				    attr_count))
72497c478bd9Sstevel@tonic-gate 					continue;
72507c478bd9Sstevel@tonic-gate 			}
72517c478bd9Sstevel@tonic-gate 
72527c478bd9Sstevel@tonic-gate 			/* if the the object has been destroyed, skip it */
72537c478bd9Sstevel@tonic-gate 			if (object->do_destroyed)
72547c478bd9Sstevel@tonic-gate 				continue;
72557c478bd9Sstevel@tonic-gate 
72567c478bd9Sstevel@tonic-gate 			/* skip object if it cannot be accessed from session */
72577c478bd9Sstevel@tonic-gate 			if (dprov_object_is_private(object) &&
72587c478bd9Sstevel@tonic-gate 			    session->ds_state != DPROV_SESSION_STATE_USER)
72597c478bd9Sstevel@tonic-gate 				continue;
72607c478bd9Sstevel@tonic-gate 
72617c478bd9Sstevel@tonic-gate 			/*
72627c478bd9Sstevel@tonic-gate 			 * Is there already a session object id for this
72637c478bd9Sstevel@tonic-gate 			 * token object?
72647c478bd9Sstevel@tonic-gate 			 */
72657c478bd9Sstevel@tonic-gate 			for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++)
72667c478bd9Sstevel@tonic-gate 				if (session->ds_objects[so_idx] != NULL &&
72677c478bd9Sstevel@tonic-gate 				    session->ds_objects[so_idx]->do_token_idx ==
72687c478bd9Sstevel@tonic-gate 				    to_idx)
72697c478bd9Sstevel@tonic-gate 					break;
72707c478bd9Sstevel@tonic-gate 			if (so_idx < DPROV_MAX_OBJECTS)
72717c478bd9Sstevel@tonic-gate 				/* object found in session table, skip it */
72727c478bd9Sstevel@tonic-gate 				continue;
72737c478bd9Sstevel@tonic-gate 
72747c478bd9Sstevel@tonic-gate 			/* find free session slot for this object */
72757c478bd9Sstevel@tonic-gate 			for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++)
72767c478bd9Sstevel@tonic-gate 				if (session->ds_objects[so_idx] == NULL)
72777c478bd9Sstevel@tonic-gate 					break;
72787c478bd9Sstevel@tonic-gate 			if (so_idx == DPROV_MAX_OBJECTS) {
72797c478bd9Sstevel@tonic-gate 				/* ran out of session objects slots */
72807c478bd9Sstevel@tonic-gate 				kmem_free(find_ctx, sizeof (dprov_find_ctx_t));
72817c478bd9Sstevel@tonic-gate 				error = CRYPTO_HOST_MEMORY;
72827c478bd9Sstevel@tonic-gate 				break;
72837c478bd9Sstevel@tonic-gate 			}
72847c478bd9Sstevel@tonic-gate 
72857c478bd9Sstevel@tonic-gate 			/* add object to session objects table */
72867c478bd9Sstevel@tonic-gate 			session->ds_objects[so_idx] = object;
72877c478bd9Sstevel@tonic-gate 			DPROV_OBJECT_REFHOLD(object);
72887c478bd9Sstevel@tonic-gate 
72897c478bd9Sstevel@tonic-gate 			/* add object to list of objects to return */
72907c478bd9Sstevel@tonic-gate 			find_ctx->fc_ids[find_ctx->fc_nids] = so_idx;
72917c478bd9Sstevel@tonic-gate 			find_ctx->fc_nids++;
72927c478bd9Sstevel@tonic-gate 		}
72937c478bd9Sstevel@tonic-gate 
72947c478bd9Sstevel@tonic-gate 		break;
72957c478bd9Sstevel@tonic-gate 	}
72967c478bd9Sstevel@tonic-gate 
72977c478bd9Sstevel@tonic-gate 	case DPROV_REQ_OBJECT_FIND: {
72987c478bd9Sstevel@tonic-gate 		crypto_object_id_t *object_ids =
72997c478bd9Sstevel@tonic-gate 		    taskq_req->dr_object_req.or_object_id_ptr;
73007c478bd9Sstevel@tonic-gate 		uint_t max_object_count =
73017c478bd9Sstevel@tonic-gate 		    taskq_req->dr_object_req.or_max_object_count;
73027c478bd9Sstevel@tonic-gate 		dprov_find_ctx_t *find_ctx =
73037c478bd9Sstevel@tonic-gate 		    taskq_req->dr_object_req.or_find_p;
73047c478bd9Sstevel@tonic-gate 		uint_t ret_oid_idx;
73057c478bd9Sstevel@tonic-gate 
73067c478bd9Sstevel@tonic-gate 		/* return the desired number of object ids */
73077c478bd9Sstevel@tonic-gate 		for (ret_oid_idx = 0; ret_oid_idx < max_object_count &&
73087c478bd9Sstevel@tonic-gate 		    find_ctx->fc_next < find_ctx->fc_nids; ret_oid_idx++)
73097c478bd9Sstevel@tonic-gate 			object_ids[ret_oid_idx] =
73107c478bd9Sstevel@tonic-gate 			    find_ctx->fc_ids[find_ctx->fc_next++];
73117c478bd9Sstevel@tonic-gate 
73127c478bd9Sstevel@tonic-gate 		*taskq_req->dr_object_req.or_object_count_ptr = ret_oid_idx;
73137c478bd9Sstevel@tonic-gate 
73147c478bd9Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
73157c478bd9Sstevel@tonic-gate 		break;
73167c478bd9Sstevel@tonic-gate 	}
73177c478bd9Sstevel@tonic-gate 
73187c478bd9Sstevel@tonic-gate 	case DPROV_REQ_OBJECT_FIND_FINAL:
73197c478bd9Sstevel@tonic-gate 		kmem_free(taskq_req->dr_object_req.or_find_p,
73207c478bd9Sstevel@tonic-gate 		    sizeof (dprov_find_ctx_t));
73217c478bd9Sstevel@tonic-gate 
73227c478bd9Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
73237c478bd9Sstevel@tonic-gate 		break;
73247c478bd9Sstevel@tonic-gate 	}
73257c478bd9Sstevel@tonic-gate 
73267c478bd9Sstevel@tonic-gate 	mutex_exit(&softc->ds_lock);
73277c478bd9Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
73287c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_task: end\n", instance));
73297c478bd9Sstevel@tonic-gate }
73307c478bd9Sstevel@tonic-gate 
73317c478bd9Sstevel@tonic-gate /*
73325b0c7657Sizick  * Copy attribute values into a template. RSA values are precomputed.
73335b0c7657Sizick  */
73345b0c7657Sizick static int
73355b0c7657Sizick nostore_copy_attribute(crypto_object_attribute_t *template, uint_t count,
73365b0c7657Sizick     uint64_t attr_type)
73375b0c7657Sizick {
73385b0c7657Sizick 	void *value, *dprov_attribute_value;
73395b0c7657Sizick 	size_t dprov_attribute_size;
73405b0c7657Sizick 	size_t value_len = 0;
73415b0c7657Sizick 	int error;
73425b0c7657Sizick 
73435b0c7657Sizick 	switch (attr_type) {
73445b0c7657Sizick 	case DPROV_CKA_VALUE:
73455b0c7657Sizick 		dprov_attribute_size = sizeof (dh_value);
73465b0c7657Sizick 		dprov_attribute_value = dh_value;
73475b0c7657Sizick 		break;
73485b0c7657Sizick 
73495b0c7657Sizick 	case DPROV_CKA_MODULUS:
73505b0c7657Sizick 		dprov_attribute_size = sizeof (modulus);
73515b0c7657Sizick 		dprov_attribute_value = modulus;
73525b0c7657Sizick 		break;
73535b0c7657Sizick 
73545b0c7657Sizick 	case DPROV_CKA_PUBLIC_EXPONENT:
73555b0c7657Sizick 		dprov_attribute_size = sizeof (public_exponent);
73565b0c7657Sizick 		dprov_attribute_value = public_exponent;
73575b0c7657Sizick 		break;
73585b0c7657Sizick 
73595b0c7657Sizick 	case DPROV_CKA_PRIVATE_EXPONENT:
73605b0c7657Sizick 		dprov_attribute_size = sizeof (private_exponent);
73615b0c7657Sizick 		dprov_attribute_value = private_exponent;
73625b0c7657Sizick 		break;
73635b0c7657Sizick 
73645b0c7657Sizick 	default:
73655b0c7657Sizick 		return (CRYPTO_ATTRIBUTE_TYPE_INVALID);
73665b0c7657Sizick 	}
73675b0c7657Sizick 
73685b0c7657Sizick 	error = dprov_get_template_attr_array(template, count, attr_type,
73695b0c7657Sizick 	    &value, &value_len);
73705b0c7657Sizick 	if (error != CRYPTO_SUCCESS)
73715b0c7657Sizick 		return (error);
73725b0c7657Sizick 
73735b0c7657Sizick 	if (value_len < dprov_attribute_size)
73745b0c7657Sizick 		return (CRYPTO_BUFFER_TOO_SMALL);
73755b0c7657Sizick 
73765b0c7657Sizick 	/*
73775b0c7657Sizick 	 * The updated template will be returned to libpkcs11.
73785b0c7657Sizick 	 */
73795b0c7657Sizick 	bcopy(dprov_attribute_value, value, dprov_attribute_size);
73805b0c7657Sizick 
73815b0c7657Sizick 	return (CRYPTO_SUCCESS);
73825b0c7657Sizick }
73835b0c7657Sizick 
73845b0c7657Sizick static void
73855b0c7657Sizick fill_dh(void *value, size_t len)
73865b0c7657Sizick {
73875b0c7657Sizick 	int i = 0;
73885b0c7657Sizick 	char *p = value;
73895b0c7657Sizick 	while (i < len) {
73905b0c7657Sizick 		p[i++] = 'D';
73915b0c7657Sizick 		if (i >= len)
73925b0c7657Sizick 			break;
73935b0c7657Sizick 		p[i++] = 'H';
73945b0c7657Sizick 	}
73955b0c7657Sizick }
73965b0c7657Sizick 
73975b0c7657Sizick /*
73987c478bd9Sstevel@tonic-gate  * taskq dispatcher function for key management operations.
73997c478bd9Sstevel@tonic-gate  */
74007c478bd9Sstevel@tonic-gate static void
74017c478bd9Sstevel@tonic-gate dprov_key_task(dprov_req_t *taskq_req)
74027c478bd9Sstevel@tonic-gate {
74037c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
74047c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
74057c478bd9Sstevel@tonic-gate 	int instance;
74067c478bd9Sstevel@tonic-gate 	int error = CRYPTO_NOT_SUPPORTED;
74077c478bd9Sstevel@tonic-gate 	kcf_provider_desc_t *pd;
74087c478bd9Sstevel@tonic-gate 	crypto_session_id_t session_id = taskq_req->dr_key_req.kr_session_id;
74097c478bd9Sstevel@tonic-gate 	dprov_session_t *session;
74107c478bd9Sstevel@tonic-gate 
74117c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
74127c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_task: started\n", instance));
74137c478bd9Sstevel@tonic-gate 
74147c478bd9Sstevel@tonic-gate 	mutex_enter(&softc->ds_lock);
74157c478bd9Sstevel@tonic-gate 
74167c478bd9Sstevel@tonic-gate 	/* validate session id and get ptr to session */
74177c478bd9Sstevel@tonic-gate 	if ((session = softc->ds_sessions[session_id]) == NULL) {
74187c478bd9Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
74197c478bd9Sstevel@tonic-gate 		dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID);
74207c478bd9Sstevel@tonic-gate 		return;
74217c478bd9Sstevel@tonic-gate 	}
74227c478bd9Sstevel@tonic-gate 
74237c478bd9Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
74247c478bd9Sstevel@tonic-gate 	case DPROV_REQ_KEY_GENERATE: {
74257c478bd9Sstevel@tonic-gate 		crypto_mechanism_t *mechp;
74267c478bd9Sstevel@tonic-gate 		crypto_object_id_t *object_id_ptr;
74277c478bd9Sstevel@tonic-gate 		crypto_object_attribute_t *template;
74287c478bd9Sstevel@tonic-gate 		crypto_object_attribute_t attribute;
74297c478bd9Sstevel@tonic-gate 		uint_t attribute_count;
74307c478bd9Sstevel@tonic-gate 		ulong_t key_type = ~0UL, class = ~0UL;
74317c478bd9Sstevel@tonic-gate 		ulong_t value_len;
74327c478bd9Sstevel@tonic-gate 		size_t key_len = 0;
74337c478bd9Sstevel@tonic-gate 
74347c478bd9Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
74357c478bd9Sstevel@tonic-gate 
74367c478bd9Sstevel@tonic-gate 		template = taskq_req->dr_key_req.kr_template;
74377c478bd9Sstevel@tonic-gate 		attribute_count = taskq_req->dr_key_req.kr_attribute_count;
74387c478bd9Sstevel@tonic-gate 		object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr;
74397c478bd9Sstevel@tonic-gate 		mechp = taskq_req->dr_key_req.kr_mechanism;
74407c478bd9Sstevel@tonic-gate 
74417c478bd9Sstevel@tonic-gate 		/* optional */
74427c478bd9Sstevel@tonic-gate 		(void) dprov_get_template_attr_ulong(template, attribute_count,
74437c478bd9Sstevel@tonic-gate 		    DPROV_CKA_CLASS, &class);
74447c478bd9Sstevel@tonic-gate 
74457c478bd9Sstevel@tonic-gate 		/* optional */
74467c478bd9Sstevel@tonic-gate 		(void) dprov_get_template_attr_ulong(template, attribute_count,
74477c478bd9Sstevel@tonic-gate 		    DPROV_CKA_KEY_TYPE, &key_type);
74487c478bd9Sstevel@tonic-gate 
74497c478bd9Sstevel@tonic-gate 		if (class != ~0UL && class != DPROV_CKO_SECRET_KEY) {
74507c478bd9Sstevel@tonic-gate 			error = CRYPTO_TEMPLATE_INCONSISTENT;
74517c478bd9Sstevel@tonic-gate 			break;
74527c478bd9Sstevel@tonic-gate 		}
74537c478bd9Sstevel@tonic-gate 
74547c478bd9Sstevel@tonic-gate 		switch (mechp->cm_type) {
74557c478bd9Sstevel@tonic-gate 		case DES_KEY_GEN_MECH_INFO_TYPE:
74567c478bd9Sstevel@tonic-gate 			if (key_type != ~0UL && key_type != DPROV_CKK_DES) {
74577c478bd9Sstevel@tonic-gate 				error = CRYPTO_TEMPLATE_INCONSISTENT;
74587c478bd9Sstevel@tonic-gate 				break;
74597c478bd9Sstevel@tonic-gate 			}
74607c478bd9Sstevel@tonic-gate 			key_len = DES_KEY_LEN;
74617c478bd9Sstevel@tonic-gate 			key_type = DPROV_CKK_DES;
74627c478bd9Sstevel@tonic-gate 			break;
74637c478bd9Sstevel@tonic-gate 
74647c478bd9Sstevel@tonic-gate 		case DES3_KEY_GEN_MECH_INFO_TYPE:
74657c478bd9Sstevel@tonic-gate 			if (key_type != ~0UL && key_type != DPROV_CKK_DES3) {
74667c478bd9Sstevel@tonic-gate 				error = CRYPTO_TEMPLATE_INCONSISTENT;
74677c478bd9Sstevel@tonic-gate 				break;
74687c478bd9Sstevel@tonic-gate 			}
74697c478bd9Sstevel@tonic-gate 			key_len = DES3_KEY_LEN;
74707c478bd9Sstevel@tonic-gate 			key_type = DPROV_CKK_DES3;
74717c478bd9Sstevel@tonic-gate 			break;
74727c478bd9Sstevel@tonic-gate 
74737c478bd9Sstevel@tonic-gate 		case AES_KEY_GEN_MECH_INFO_TYPE:
74747c478bd9Sstevel@tonic-gate 			if (key_type != ~0UL && key_type != DPROV_CKK_AES) {
74757c478bd9Sstevel@tonic-gate 				error = CRYPTO_TEMPLATE_INCONSISTENT;
74767c478bd9Sstevel@tonic-gate 				break;
74777c478bd9Sstevel@tonic-gate 			}
74787c478bd9Sstevel@tonic-gate 			if (dprov_get_template_attr_ulong(template,
74797c478bd9Sstevel@tonic-gate 			    attribute_count, DPROV_CKA_VALUE_LEN,
74807c478bd9Sstevel@tonic-gate 			    &value_len) != CRYPTO_SUCCESS) {
74817c478bd9Sstevel@tonic-gate 				error = CRYPTO_TEMPLATE_INCOMPLETE;
74827c478bd9Sstevel@tonic-gate 				break;
74837c478bd9Sstevel@tonic-gate 			}
74847c478bd9Sstevel@tonic-gate 			if (value_len >= AES_MAX_KEY_LEN) {
74857c478bd9Sstevel@tonic-gate 				error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
74867c478bd9Sstevel@tonic-gate 				break;
74877c478bd9Sstevel@tonic-gate 			}
74887c478bd9Sstevel@tonic-gate 			key_len = value_len;
74897c478bd9Sstevel@tonic-gate 			key_type = DPROV_CKK_AES;
74907c478bd9Sstevel@tonic-gate 			break;
74917c478bd9Sstevel@tonic-gate 
7492f66d273dSizick 		case BLOWFISH_KEY_GEN_MECH_INFO_TYPE:
7493f66d273dSizick 			if (key_type != ~0UL &&
7494f66d273dSizick 			    key_type != DPROV_CKK_BLOWFISH) {
7495f66d273dSizick 				error = CRYPTO_TEMPLATE_INCONSISTENT;
7496f66d273dSizick 				break;
7497f66d273dSizick 			}
7498f66d273dSizick 			if (dprov_get_template_attr_ulong(template,
7499f66d273dSizick 			    attribute_count, DPROV_CKA_VALUE_LEN,
7500f66d273dSizick 			    &value_len) != CRYPTO_SUCCESS) {
7501f66d273dSizick 				error = CRYPTO_TEMPLATE_INCOMPLETE;
7502f66d273dSizick 				break;
7503f66d273dSizick 			}
7504f66d273dSizick 			if (value_len >= BLOWFISH_MAX_KEY_LEN) {
7505f66d273dSizick 				error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
7506f66d273dSizick 				break;
7507f66d273dSizick 			}
7508f66d273dSizick 			key_len = value_len;
7509f66d273dSizick 			key_type = DPROV_CKK_BLOWFISH;
7510f66d273dSizick 			break;
7511f66d273dSizick 
75127c478bd9Sstevel@tonic-gate 		case RC4_KEY_GEN_MECH_INFO_TYPE:
75137c478bd9Sstevel@tonic-gate 			if (key_type != ~0UL && key_type != DPROV_CKK_RC4) {
75147c478bd9Sstevel@tonic-gate 				error = CRYPTO_TEMPLATE_INCONSISTENT;
75157c478bd9Sstevel@tonic-gate 				break;
75167c478bd9Sstevel@tonic-gate 			}
75177c478bd9Sstevel@tonic-gate 			if (dprov_get_template_attr_ulong(template,
75187c478bd9Sstevel@tonic-gate 			    attribute_count, DPROV_CKA_VALUE_LEN,
75197c478bd9Sstevel@tonic-gate 			    &value_len) != CRYPTO_SUCCESS) {
75207c478bd9Sstevel@tonic-gate 				error = CRYPTO_TEMPLATE_INCOMPLETE;
75217c478bd9Sstevel@tonic-gate 				break;
75227c478bd9Sstevel@tonic-gate 			}
75237c478bd9Sstevel@tonic-gate 			if (value_len >=
75247c478bd9Sstevel@tonic-gate 			    CRYPTO_BITS2BYTES(ARCFOUR_MAX_KEY_BITS)) {
75257c478bd9Sstevel@tonic-gate 				error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
75267c478bd9Sstevel@tonic-gate 				break;
75277c478bd9Sstevel@tonic-gate 			}
75287c478bd9Sstevel@tonic-gate 			key_len = value_len;
75297c478bd9Sstevel@tonic-gate 			key_type = DPROV_CKK_RC4;
75307c478bd9Sstevel@tonic-gate 			break;
75317c478bd9Sstevel@tonic-gate 
75327c478bd9Sstevel@tonic-gate 		default:
75337c478bd9Sstevel@tonic-gate 			error = CRYPTO_MECHANISM_INVALID;
75347c478bd9Sstevel@tonic-gate 		}
75357c478bd9Sstevel@tonic-gate 
75367c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
75377c478bd9Sstevel@tonic-gate 			break;
75387c478bd9Sstevel@tonic-gate 
75397c478bd9Sstevel@tonic-gate 		error = dprov_create_object_from_template(softc, session,
75407c478bd9Sstevel@tonic-gate 		    template, attribute_count, object_id_ptr, B_FALSE, B_TRUE);
75417c478bd9Sstevel@tonic-gate 
75427c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
75437c478bd9Sstevel@tonic-gate 			break;
75447c478bd9Sstevel@tonic-gate 
75457c478bd9Sstevel@tonic-gate 		/* make sure class is set */
75467c478bd9Sstevel@tonic-gate 		attribute.oa_type = DPROV_CKA_CLASS;
75477c478bd9Sstevel@tonic-gate 		attribute.oa_value = (char *)&class;
75487c478bd9Sstevel@tonic-gate 		attribute.oa_value_len = sizeof (ulong_t);
75497c478bd9Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *object_id_ptr,
75507c478bd9Sstevel@tonic-gate 		    &attribute, 1, B_FALSE);
75517c478bd9Sstevel@tonic-gate 
75527c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
75537c478bd9Sstevel@tonic-gate 			goto destroy_object;
75547c478bd9Sstevel@tonic-gate 		}
75557c478bd9Sstevel@tonic-gate 
75567c478bd9Sstevel@tonic-gate 		/* make sure key_type is set */
75577c478bd9Sstevel@tonic-gate 		attribute.oa_type = DPROV_CKA_KEY_TYPE;
75587c478bd9Sstevel@tonic-gate 		attribute.oa_value = (char *)&key_type;
75597c478bd9Sstevel@tonic-gate 		attribute.oa_value_len = sizeof (ulong_t);
75607c478bd9Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *object_id_ptr,
75617c478bd9Sstevel@tonic-gate 		    &attribute, 1, B_FALSE);
75627c478bd9Sstevel@tonic-gate 
75637c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
75647c478bd9Sstevel@tonic-gate 			goto destroy_object;
75657c478bd9Sstevel@tonic-gate 		}
75667c478bd9Sstevel@tonic-gate 
75677c478bd9Sstevel@tonic-gate 		attribute.oa_type = DPROV_CKA_VALUE;
75687c478bd9Sstevel@tonic-gate 		attribute.oa_value = kmem_alloc(key_len, KM_SLEEP);
75697c478bd9Sstevel@tonic-gate 		attribute.oa_value_len = key_len;
75707c478bd9Sstevel@tonic-gate 
75717c478bd9Sstevel@tonic-gate 		if (random_get_pseudo_bytes((uchar_t *)attribute.oa_value,
75727c478bd9Sstevel@tonic-gate 		    key_len) != 0) {
75737c478bd9Sstevel@tonic-gate 			bzero(attribute.oa_value, key_len);
75747c478bd9Sstevel@tonic-gate 			kmem_free(attribute.oa_value, key_len);
75757c478bd9Sstevel@tonic-gate 			goto destroy_object;
75767c478bd9Sstevel@tonic-gate 		}
75777c478bd9Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *object_id_ptr,
75787c478bd9Sstevel@tonic-gate 		    &attribute, 1, B_FALSE);
75797c478bd9Sstevel@tonic-gate 
75807c478bd9Sstevel@tonic-gate 		bzero(attribute.oa_value, key_len);
75817c478bd9Sstevel@tonic-gate 		kmem_free(attribute.oa_value, key_len);
75827c478bd9Sstevel@tonic-gate 
75837c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
75847c478bd9Sstevel@tonic-gate 			goto destroy_object;
75857c478bd9Sstevel@tonic-gate 		}
75867c478bd9Sstevel@tonic-gate 		break;
75877c478bd9Sstevel@tonic-gate 
75887c478bd9Sstevel@tonic-gate destroy_object:
75897c478bd9Sstevel@tonic-gate 		(void) dprov_destroy_object(softc, session, *object_id_ptr);
75907c478bd9Sstevel@tonic-gate 		break;
75917c478bd9Sstevel@tonic-gate 	}
75927c478bd9Sstevel@tonic-gate 
75937c478bd9Sstevel@tonic-gate 	case DPROV_REQ_KEY_GENERATE_PAIR: {
75947c478bd9Sstevel@tonic-gate 		crypto_mechanism_t *mechp;
75957c478bd9Sstevel@tonic-gate 		crypto_object_id_t *pub_object_id_ptr;
75967c478bd9Sstevel@tonic-gate 		crypto_object_id_t *pri_object_id_ptr;
75977c478bd9Sstevel@tonic-gate 		crypto_object_attribute_t *pub_template;
75987c478bd9Sstevel@tonic-gate 		crypto_object_attribute_t *pri_template;
75997c478bd9Sstevel@tonic-gate 		crypto_object_attribute_t attribute;
76007c478bd9Sstevel@tonic-gate 		uint_t pub_attribute_count;
76017c478bd9Sstevel@tonic-gate 		uint_t pri_attribute_count;
76027c478bd9Sstevel@tonic-gate 		ulong_t pub_key_type = ~0UL, pub_class = ~0UL;
76037c478bd9Sstevel@tonic-gate 		ulong_t pri_key_type = ~0UL, pri_class = ~0UL;
76047c478bd9Sstevel@tonic-gate 
76057c478bd9Sstevel@tonic-gate 		pub_template = taskq_req->dr_key_req.kr_template;
76067c478bd9Sstevel@tonic-gate 		pub_attribute_count = taskq_req->dr_key_req.kr_attribute_count;
76077c478bd9Sstevel@tonic-gate 		pub_object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr;
76087c478bd9Sstevel@tonic-gate 		pri_template = taskq_req->dr_key_req.kr_private_key_template;
76097c478bd9Sstevel@tonic-gate 		pri_attribute_count =
76107c478bd9Sstevel@tonic-gate 		    taskq_req->dr_key_req.kr_private_key_attribute_count;
76117c478bd9Sstevel@tonic-gate 		pri_object_id_ptr =
76127c478bd9Sstevel@tonic-gate 		    taskq_req->dr_key_req.kr_private_key_object_id_ptr;
76137c478bd9Sstevel@tonic-gate 		mechp = taskq_req->dr_key_req.kr_mechanism;
76147c478bd9Sstevel@tonic-gate 
76157c478bd9Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
76167c478bd9Sstevel@tonic-gate 
76177c478bd9Sstevel@tonic-gate 		/* optional */
76187c478bd9Sstevel@tonic-gate 		(void) dprov_get_template_attr_ulong(pub_template,
76197c478bd9Sstevel@tonic-gate 		    pub_attribute_count, DPROV_CKA_CLASS, &pub_class);
76207c478bd9Sstevel@tonic-gate 
76217c478bd9Sstevel@tonic-gate 		/* optional */
76227c478bd9Sstevel@tonic-gate 		(void) dprov_get_template_attr_ulong(pri_template,
76237c478bd9Sstevel@tonic-gate 		    pri_attribute_count, DPROV_CKA_CLASS, &pri_class);
76247c478bd9Sstevel@tonic-gate 
76257c478bd9Sstevel@tonic-gate 		/* optional */
76267c478bd9Sstevel@tonic-gate 		(void) dprov_get_template_attr_ulong(pub_template,
76277c478bd9Sstevel@tonic-gate 		    pub_attribute_count, DPROV_CKA_KEY_TYPE, &pub_key_type);
76287c478bd9Sstevel@tonic-gate 
76297c478bd9Sstevel@tonic-gate 		/* optional */
76307c478bd9Sstevel@tonic-gate 		(void) dprov_get_template_attr_ulong(pri_template,
76317c478bd9Sstevel@tonic-gate 		    pri_attribute_count, DPROV_CKA_KEY_TYPE, &pri_key_type);
76327c478bd9Sstevel@tonic-gate 
76337c478bd9Sstevel@tonic-gate 		if (pub_class != ~0UL && pub_class != DPROV_CKO_PUBLIC_KEY) {
76347c478bd9Sstevel@tonic-gate 			error = CRYPTO_TEMPLATE_INCONSISTENT;
76357c478bd9Sstevel@tonic-gate 			break;
76367c478bd9Sstevel@tonic-gate 		}
76377c478bd9Sstevel@tonic-gate 
76387c478bd9Sstevel@tonic-gate 		if (pri_class != ~0UL && pri_class != DPROV_CKO_PRIVATE_KEY) {
76397c478bd9Sstevel@tonic-gate 			error = CRYPTO_TEMPLATE_INCONSISTENT;
76407c478bd9Sstevel@tonic-gate 			break;
76417c478bd9Sstevel@tonic-gate 		}
76427c478bd9Sstevel@tonic-gate 
76437c478bd9Sstevel@tonic-gate 		switch (mechp->cm_type) {
76447c478bd9Sstevel@tonic-gate 		case RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE:
76457c478bd9Sstevel@tonic-gate 			if (pub_key_type != ~0UL &&
76467c478bd9Sstevel@tonic-gate 			    pub_key_type != DPROV_CKK_RSA) {
76477c478bd9Sstevel@tonic-gate 				error = CRYPTO_TEMPLATE_INCONSISTENT;
76487c478bd9Sstevel@tonic-gate 				break;
76497c478bd9Sstevel@tonic-gate 			}
7650034448feSmcpowers 			pub_key_type = DPROV_CKK_RSA;
76517c478bd9Sstevel@tonic-gate 
76527c478bd9Sstevel@tonic-gate 			if (pri_key_type != ~0UL &&
76537c478bd9Sstevel@tonic-gate 			    pri_key_type != DPROV_CKK_RSA) {
76547c478bd9Sstevel@tonic-gate 				error = CRYPTO_TEMPLATE_INCONSISTENT;
76557c478bd9Sstevel@tonic-gate 				break;
76567c478bd9Sstevel@tonic-gate 			}
76577c478bd9Sstevel@tonic-gate 			pri_key_type = DPROV_CKK_RSA;
76587c478bd9Sstevel@tonic-gate 
76597c478bd9Sstevel@tonic-gate 			if (pub_class != ~0UL &&
76607c478bd9Sstevel@tonic-gate 			    pub_class != DPROV_CKO_PUBLIC_KEY) {
76617c478bd9Sstevel@tonic-gate 				error = CRYPTO_TEMPLATE_INCONSISTENT;
76627c478bd9Sstevel@tonic-gate 				break;
76637c478bd9Sstevel@tonic-gate 			}
76647c478bd9Sstevel@tonic-gate 			pub_class = DPROV_CKO_PUBLIC_KEY;
76657c478bd9Sstevel@tonic-gate 
76667c478bd9Sstevel@tonic-gate 			if (pri_class != ~0UL &&
76677c478bd9Sstevel@tonic-gate 			    pri_class != DPROV_CKO_PRIVATE_KEY) {
76687c478bd9Sstevel@tonic-gate 				error = CRYPTO_TEMPLATE_INCONSISTENT;
76697c478bd9Sstevel@tonic-gate 				break;
76707c478bd9Sstevel@tonic-gate 			}
76717c478bd9Sstevel@tonic-gate 			pri_class = DPROV_CKO_PRIVATE_KEY;
76727c478bd9Sstevel@tonic-gate 			break;
76737c478bd9Sstevel@tonic-gate 
76747c478bd9Sstevel@tonic-gate 		default:
76757c478bd9Sstevel@tonic-gate 			error = CRYPTO_MECHANISM_INVALID;
76767c478bd9Sstevel@tonic-gate 		}
76777c478bd9Sstevel@tonic-gate 
76787c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
76797c478bd9Sstevel@tonic-gate 			break;
76807c478bd9Sstevel@tonic-gate 
76817c478bd9Sstevel@tonic-gate 		error = dprov_create_object_from_template(softc, session,
76827c478bd9Sstevel@tonic-gate 		    pub_template, pub_attribute_count, pub_object_id_ptr,
76837c478bd9Sstevel@tonic-gate 		    B_FALSE, B_TRUE);
76847c478bd9Sstevel@tonic-gate 
76857c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
76867c478bd9Sstevel@tonic-gate 			break;
76877c478bd9Sstevel@tonic-gate 
76887c478bd9Sstevel@tonic-gate 		/* make sure class is set */
76897c478bd9Sstevel@tonic-gate 		attribute.oa_type = DPROV_CKA_CLASS;
76907c478bd9Sstevel@tonic-gate 		attribute.oa_value = (char *)&pub_class;
76917c478bd9Sstevel@tonic-gate 		attribute.oa_value_len = sizeof (ulong_t);
76927c478bd9Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *pub_object_id_ptr,
76937c478bd9Sstevel@tonic-gate 		    &attribute, 1, B_FALSE);
76947c478bd9Sstevel@tonic-gate 
76957c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
76967c478bd9Sstevel@tonic-gate 			goto destroy_public_object;
76977c478bd9Sstevel@tonic-gate 		}
76987c478bd9Sstevel@tonic-gate 
76997c478bd9Sstevel@tonic-gate 		/* make sure key_type is set */
77007c478bd9Sstevel@tonic-gate 		attribute.oa_type = DPROV_CKA_KEY_TYPE;
77017c478bd9Sstevel@tonic-gate 		attribute.oa_value = (char *)&pub_key_type;
77027c478bd9Sstevel@tonic-gate 		attribute.oa_value_len = sizeof (ulong_t);
77037c478bd9Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *pub_object_id_ptr,
77047c478bd9Sstevel@tonic-gate 		    &attribute, 1, B_FALSE);
77057c478bd9Sstevel@tonic-gate 
77067c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
77077c478bd9Sstevel@tonic-gate 			goto destroy_public_object;
77087c478bd9Sstevel@tonic-gate 		}
77097c478bd9Sstevel@tonic-gate 
77107c478bd9Sstevel@tonic-gate 		attribute.oa_type = DPROV_CKA_MODULUS;
77117c478bd9Sstevel@tonic-gate 		attribute.oa_value = (char *)modulus;
77127c478bd9Sstevel@tonic-gate 		attribute.oa_value_len = sizeof (modulus);
77137c478bd9Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *pub_object_id_ptr,
77147c478bd9Sstevel@tonic-gate 		    &attribute, 1, B_FALSE);
77157c478bd9Sstevel@tonic-gate 
77167c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
77177c478bd9Sstevel@tonic-gate 			goto destroy_public_object;
77187c478bd9Sstevel@tonic-gate 		}
77197c478bd9Sstevel@tonic-gate 
77207c478bd9Sstevel@tonic-gate 		attribute.oa_type = DPROV_CKA_PUBLIC_EXPONENT;
77217c478bd9Sstevel@tonic-gate 		attribute.oa_value = public_exponent;
77227c478bd9Sstevel@tonic-gate 		attribute.oa_value_len = sizeof (public_exponent);
77237c478bd9Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *pub_object_id_ptr,
77247c478bd9Sstevel@tonic-gate 		    &attribute, 1, B_FALSE);
77257c478bd9Sstevel@tonic-gate 
77267c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
77277c478bd9Sstevel@tonic-gate 			goto destroy_public_object;
77287c478bd9Sstevel@tonic-gate 		}
77297c478bd9Sstevel@tonic-gate 
77307c478bd9Sstevel@tonic-gate 		error = dprov_create_object_from_template(softc, session,
77317c478bd9Sstevel@tonic-gate 		    pri_template, pri_attribute_count, pri_object_id_ptr,
77327c478bd9Sstevel@tonic-gate 		    B_FALSE, B_TRUE);
77337c478bd9Sstevel@tonic-gate 
77347c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
77357c478bd9Sstevel@tonic-gate 			break;
77367c478bd9Sstevel@tonic-gate 
77377c478bd9Sstevel@tonic-gate 		/* make sure class is set */
77387c478bd9Sstevel@tonic-gate 		attribute.oa_type = DPROV_CKA_CLASS;
77397c478bd9Sstevel@tonic-gate 		attribute.oa_value = (char *)&pri_class;
77407c478bd9Sstevel@tonic-gate 		attribute.oa_value_len = sizeof (ulong_t);
77417c478bd9Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *pri_object_id_ptr,
77427c478bd9Sstevel@tonic-gate 		    &attribute, 1, B_FALSE);
77437c478bd9Sstevel@tonic-gate 
77447c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
77457c478bd9Sstevel@tonic-gate 			goto destroy_private_object;
77467c478bd9Sstevel@tonic-gate 		}
77477c478bd9Sstevel@tonic-gate 
77487c478bd9Sstevel@tonic-gate 		/* make sure key_type is set */
77497c478bd9Sstevel@tonic-gate 		attribute.oa_type = DPROV_CKA_KEY_TYPE;
77507c478bd9Sstevel@tonic-gate 		attribute.oa_value = (char *)&pri_key_type;
77517c478bd9Sstevel@tonic-gate 		attribute.oa_value_len = sizeof (ulong_t);
77527c478bd9Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *pri_object_id_ptr,
77537c478bd9Sstevel@tonic-gate 		    &attribute, 1, B_FALSE);
77547c478bd9Sstevel@tonic-gate 
77557c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
77567c478bd9Sstevel@tonic-gate 			goto destroy_private_object;
77577c478bd9Sstevel@tonic-gate 		}
77587c478bd9Sstevel@tonic-gate 
77597c478bd9Sstevel@tonic-gate 		attribute.oa_type = DPROV_CKA_MODULUS;
77607c478bd9Sstevel@tonic-gate 		attribute.oa_value = (char *)modulus;
77617c478bd9Sstevel@tonic-gate 		attribute.oa_value_len = sizeof (modulus);
77627c478bd9Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *pri_object_id_ptr,
77637c478bd9Sstevel@tonic-gate 		    &attribute, 1, B_FALSE);
77647c478bd9Sstevel@tonic-gate 
77657c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
77667c478bd9Sstevel@tonic-gate 			goto destroy_private_object;
77677c478bd9Sstevel@tonic-gate 		}
77687c478bd9Sstevel@tonic-gate 
77697c478bd9Sstevel@tonic-gate 		attribute.oa_type = DPROV_CKA_PRIVATE_EXPONENT;
77707c478bd9Sstevel@tonic-gate 		attribute.oa_value = (char *)private_exponent;
77717c478bd9Sstevel@tonic-gate 		attribute.oa_value_len = sizeof (private_exponent);
77727c478bd9Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *pri_object_id_ptr,
77737c478bd9Sstevel@tonic-gate 		    &attribute, 1, B_FALSE);
77747c478bd9Sstevel@tonic-gate 
77757c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
77767c478bd9Sstevel@tonic-gate 			goto destroy_private_object;
77777c478bd9Sstevel@tonic-gate 		}
77787c478bd9Sstevel@tonic-gate 		break;
77797c478bd9Sstevel@tonic-gate 
77807c478bd9Sstevel@tonic-gate destroy_private_object:
77817c478bd9Sstevel@tonic-gate 		(void) dprov_destroy_object(softc, session,
77827c478bd9Sstevel@tonic-gate 		    *pri_object_id_ptr);
77837c478bd9Sstevel@tonic-gate destroy_public_object:
77847c478bd9Sstevel@tonic-gate 		(void) dprov_destroy_object(softc, session,
77857c478bd9Sstevel@tonic-gate 		    *pub_object_id_ptr);
77867c478bd9Sstevel@tonic-gate 
77877c478bd9Sstevel@tonic-gate 		break;
77887c478bd9Sstevel@tonic-gate 	}
77897c478bd9Sstevel@tonic-gate 
77907c478bd9Sstevel@tonic-gate 	case DPROV_REQ_KEY_WRAP: {
77917c478bd9Sstevel@tonic-gate 		crypto_mechanism_t mech, *mechp;
77927c478bd9Sstevel@tonic-gate 		crypto_key_t key, *keyp;
77937c478bd9Sstevel@tonic-gate 		crypto_object_id_t object_id;
77947c478bd9Sstevel@tonic-gate 		ulong_t class = DPROV_CKO_DATA;
77957c478bd9Sstevel@tonic-gate 		boolean_t extractable = B_TRUE;
77967c478bd9Sstevel@tonic-gate 		dprov_object_t *object;
77977c478bd9Sstevel@tonic-gate 		int object_idx;
77987c478bd9Sstevel@tonic-gate 		char *plaintext_key;
77997c478bd9Sstevel@tonic-gate 		size_t plaintext_key_len;
78007c478bd9Sstevel@tonic-gate 		crypto_data_t plaintext;
78017c478bd9Sstevel@tonic-gate 		crypto_data_t ciphertext;
78027c478bd9Sstevel@tonic-gate 		size_t *lenp;
78037c478bd9Sstevel@tonic-gate 
78047c478bd9Sstevel@tonic-gate 		mechp = taskq_req->dr_key_req.kr_mechanism;
78057c478bd9Sstevel@tonic-gate 		/* structure assignment */
78067c478bd9Sstevel@tonic-gate 		mech = *mechp;
78077c478bd9Sstevel@tonic-gate 
78087c478bd9Sstevel@tonic-gate 		/* get wrapping key value */
78097c478bd9Sstevel@tonic-gate 		if (is_publickey_mech(mech.cm_type)) {
78107c478bd9Sstevel@tonic-gate 			if ((error = dprov_key_attr_asymmetric(softc,
78117c478bd9Sstevel@tonic-gate 			    session_id, taskq_req->dr_type,
78127c478bd9Sstevel@tonic-gate 			    taskq_req->dr_key_req.kr_key,
78137c478bd9Sstevel@tonic-gate 			    &key)) != CRYPTO_SUCCESS)
78147c478bd9Sstevel@tonic-gate 				break;
78157c478bd9Sstevel@tonic-gate 			keyp = &key;
78167c478bd9Sstevel@tonic-gate 		} else {
78177c478bd9Sstevel@tonic-gate 			if ((error = dprov_key_value_secret(softc,
78187c478bd9Sstevel@tonic-gate 			    session_id, taskq_req->dr_type,
78197c478bd9Sstevel@tonic-gate 			    taskq_req->dr_key_req.kr_key,
78207c478bd9Sstevel@tonic-gate 			    &key)) != CRYPTO_SUCCESS)
78217c478bd9Sstevel@tonic-gate 				break;
78227c478bd9Sstevel@tonic-gate 			keyp = &key;
78237c478bd9Sstevel@tonic-gate 		}
78247c478bd9Sstevel@tonic-gate 
78257c478bd9Sstevel@tonic-gate 		/* get the software provider for this mechanism */
78267c478bd9Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(mechp, &pd,
78277c478bd9Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
78287c478bd9Sstevel@tonic-gate 			break;
78297c478bd9Sstevel@tonic-gate 
78307c478bd9Sstevel@tonic-gate 		object_id = *taskq_req->dr_key_req.kr_object_id_ptr;
78317c478bd9Sstevel@tonic-gate 		if (object_id >= DPROV_MAX_OBJECTS) {
78327c478bd9Sstevel@tonic-gate 			error = CRYPTO_KEY_HANDLE_INVALID;
78337c478bd9Sstevel@tonic-gate 			break;
78347c478bd9Sstevel@tonic-gate 		}
78357c478bd9Sstevel@tonic-gate 
78367c478bd9Sstevel@tonic-gate 		/* get ptr to object */
78377c478bd9Sstevel@tonic-gate 		if ((object = session->ds_objects[object_id]) == NULL) {
78387c478bd9Sstevel@tonic-gate 			error = CRYPTO_OBJECT_HANDLE_INVALID;
78397c478bd9Sstevel@tonic-gate 			break;
78407c478bd9Sstevel@tonic-gate 		}
78417c478bd9Sstevel@tonic-gate 
78427c478bd9Sstevel@tonic-gate 		(void) dprov_get_object_attr_boolean(object,
78437c478bd9Sstevel@tonic-gate 		    DPROV_CKA_EXTRACTABLE, &extractable);
78447c478bd9Sstevel@tonic-gate 
78457c478bd9Sstevel@tonic-gate 		if (!extractable) {
78467c478bd9Sstevel@tonic-gate 			error = CRYPTO_ATTRIBUTE_SENSITIVE;
78477c478bd9Sstevel@tonic-gate 			break;
78487c478bd9Sstevel@tonic-gate 		}
78497c478bd9Sstevel@tonic-gate 
78507c478bd9Sstevel@tonic-gate 		(void) dprov_get_object_attr_ulong(object,
78517c478bd9Sstevel@tonic-gate 		    DPROV_CKA_CLASS, &class);
78527c478bd9Sstevel@tonic-gate 
78537c478bd9Sstevel@tonic-gate 		switch (class) {
78547c478bd9Sstevel@tonic-gate 		case DPROV_CKO_SECRET_KEY:
78557c478bd9Sstevel@tonic-gate 			object_idx = dprov_find_attr(object->do_attr,
78567c478bd9Sstevel@tonic-gate 			    DPROV_MAX_ATTR, DPROV_CKA_VALUE);
78577c478bd9Sstevel@tonic-gate 			if (object_idx == -1) {
78587c478bd9Sstevel@tonic-gate 				error = CRYPTO_ATTRIBUTE_TYPE_INVALID;
78597c478bd9Sstevel@tonic-gate 				break;
78607c478bd9Sstevel@tonic-gate 			}
78617c478bd9Sstevel@tonic-gate 			break;
78627c478bd9Sstevel@tonic-gate 
78637c478bd9Sstevel@tonic-gate 			case DPROV_CKO_PRIVATE_KEY:
78647c478bd9Sstevel@tonic-gate 			/*
78657c478bd9Sstevel@tonic-gate 			 * PKCS#11 says that ASN.1 should be used to encode
78667c478bd9Sstevel@tonic-gate 			 * specific attributes before encrypting the blob.
78677c478bd9Sstevel@tonic-gate 			 * We only encrypt the private exponent for the
78687c478bd9Sstevel@tonic-gate 			 * purpose of testing.
78697c478bd9Sstevel@tonic-gate 			 */
78707c478bd9Sstevel@tonic-gate 			object_idx = dprov_find_attr(object->do_attr,
78717c478bd9Sstevel@tonic-gate 			    DPROV_MAX_ATTR, DPROV_CKA_PRIVATE_EXPONENT);
78727c478bd9Sstevel@tonic-gate 			if (object_idx == -1) {
78737c478bd9Sstevel@tonic-gate 				error = CRYPTO_ATTRIBUTE_TYPE_INVALID;
78747c478bd9Sstevel@tonic-gate 				break;
78757c478bd9Sstevel@tonic-gate 			}
78767c478bd9Sstevel@tonic-gate 			break;
78777c478bd9Sstevel@tonic-gate 		default:
78787c478bd9Sstevel@tonic-gate 			error = CRYPTO_KEY_NOT_WRAPPABLE;
78797c478bd9Sstevel@tonic-gate 			break;
78807c478bd9Sstevel@tonic-gate 		}
78817c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
78827c478bd9Sstevel@tonic-gate 			break;
78837c478bd9Sstevel@tonic-gate 
78847c478bd9Sstevel@tonic-gate 		plaintext_key = object->do_attr[object_idx].oa_value;
78857c478bd9Sstevel@tonic-gate 		plaintext_key_len = object->do_attr[object_idx].oa_value_len;
78867c478bd9Sstevel@tonic-gate 		lenp = taskq_req->dr_key_req.kr_wrapped_key_len_ptr;
78877c478bd9Sstevel@tonic-gate 
78887c478bd9Sstevel@tonic-gate 		/* session id is 0 for software provider */
78897c478bd9Sstevel@tonic-gate 		plaintext.cd_format = CRYPTO_DATA_RAW;
78907c478bd9Sstevel@tonic-gate 		plaintext.cd_offset = 0;
78917c478bd9Sstevel@tonic-gate 		plaintext.cd_length = plaintext_key_len;
78927c478bd9Sstevel@tonic-gate 		plaintext.cd_raw.iov_base = plaintext_key;
78937c478bd9Sstevel@tonic-gate 		plaintext.cd_raw.iov_len = plaintext_key_len;
78947c478bd9Sstevel@tonic-gate 		plaintext.cd_miscdata = NULL;
78957c478bd9Sstevel@tonic-gate 
78967c478bd9Sstevel@tonic-gate 		ciphertext.cd_format = CRYPTO_DATA_RAW;
78977c478bd9Sstevel@tonic-gate 		ciphertext.cd_offset = 0;
78987c478bd9Sstevel@tonic-gate 		ciphertext.cd_length = *lenp;
78997c478bd9Sstevel@tonic-gate 		ciphertext.cd_raw.iov_base =
79007c478bd9Sstevel@tonic-gate 		    (char *)taskq_req->dr_key_req.kr_wrapped_key;
79017c478bd9Sstevel@tonic-gate 		ciphertext.cd_raw.iov_len = ciphertext.cd_length;
79027c478bd9Sstevel@tonic-gate 		ciphertext.cd_miscdata = NULL;
79037c478bd9Sstevel@tonic-gate 
7904894b2776Smcpowers 		error = crypto_encrypt_prov(pd, 0, &mech, &plaintext, keyp,
7905894b2776Smcpowers 		    NULL, &ciphertext, NULL);
79067c478bd9Sstevel@tonic-gate 
79077c478bd9Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
79087c478bd9Sstevel@tonic-gate 		if (error == CRYPTO_SUCCESS ||
79097c478bd9Sstevel@tonic-gate 		    error == CRYPTO_BUFFER_TOO_SMALL) {
79107c478bd9Sstevel@tonic-gate 			*lenp = ciphertext.cd_length;
79117c478bd9Sstevel@tonic-gate 		}
79127c478bd9Sstevel@tonic-gate 		break;
79137c478bd9Sstevel@tonic-gate 	}
79147c478bd9Sstevel@tonic-gate 
79157c478bd9Sstevel@tonic-gate 	case DPROV_REQ_KEY_UNWRAP: {
79167c478bd9Sstevel@tonic-gate 		crypto_mechanism_t mech, *mechp;
79177c478bd9Sstevel@tonic-gate 		crypto_key_t key, *keyp;
79187c478bd9Sstevel@tonic-gate 		crypto_object_id_t *object_id_ptr;
79197c478bd9Sstevel@tonic-gate 		ulong_t class = DPROV_CKO_DATA;
79207c478bd9Sstevel@tonic-gate 		uchar_t *wrapped_key;
79217c478bd9Sstevel@tonic-gate 		char *plaintext_buf;
79227c478bd9Sstevel@tonic-gate 		size_t wrapped_key_len;
79237c478bd9Sstevel@tonic-gate 		crypto_data_t plaintext;
79247c478bd9Sstevel@tonic-gate 		crypto_data_t ciphertext;
79257c478bd9Sstevel@tonic-gate 		crypto_object_attribute_t unwrapped_key;
79267c478bd9Sstevel@tonic-gate 		crypto_object_attribute_t *template;
79277c478bd9Sstevel@tonic-gate 		uint_t attribute_count;
79287c478bd9Sstevel@tonic-gate 
79297c478bd9Sstevel@tonic-gate 		template = taskq_req->dr_key_req.kr_template;
79307c478bd9Sstevel@tonic-gate 		attribute_count = taskq_req->dr_key_req.kr_attribute_count;
79317c478bd9Sstevel@tonic-gate 		object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr;
79327c478bd9Sstevel@tonic-gate 
79337c478bd9Sstevel@tonic-gate 		/* all objects must have an object class attribute */
79347c478bd9Sstevel@tonic-gate 		if (dprov_get_template_attr_ulong(template, attribute_count,
79357c478bd9Sstevel@tonic-gate 		    DPROV_CKA_CLASS, &class) != CRYPTO_SUCCESS) {
79367c478bd9Sstevel@tonic-gate 			error = CRYPTO_TEMPLATE_INCOMPLETE;
79377c478bd9Sstevel@tonic-gate 			break;
79387c478bd9Sstevel@tonic-gate 		}
79397c478bd9Sstevel@tonic-gate 
79407c478bd9Sstevel@tonic-gate 		mechp = taskq_req->dr_key_req.kr_mechanism;
79417c478bd9Sstevel@tonic-gate 		/* structure assignment */
79427c478bd9Sstevel@tonic-gate 		mech = *mechp;
79437c478bd9Sstevel@tonic-gate 
79447c478bd9Sstevel@tonic-gate 		/* get unwrapping key value */
79457c478bd9Sstevel@tonic-gate 		if (is_publickey_mech(mech.cm_type)) {
79467c478bd9Sstevel@tonic-gate 			if ((error = dprov_key_attr_asymmetric(softc,
79477c478bd9Sstevel@tonic-gate 			    session_id, taskq_req->dr_type,
79487c478bd9Sstevel@tonic-gate 			    taskq_req->dr_key_req.kr_key,
79497c478bd9Sstevel@tonic-gate 			    &key)) != CRYPTO_SUCCESS)
79507c478bd9Sstevel@tonic-gate 				break;
79517c478bd9Sstevel@tonic-gate 			keyp = &key;
79527c478bd9Sstevel@tonic-gate 		} else {
79537c478bd9Sstevel@tonic-gate 			if ((error = dprov_key_value_secret(softc,
79547c478bd9Sstevel@tonic-gate 			    session_id, taskq_req->dr_type,
79557c478bd9Sstevel@tonic-gate 			    taskq_req->dr_key_req.kr_key,
79567c478bd9Sstevel@tonic-gate 			    &key)) != CRYPTO_SUCCESS)
79577c478bd9Sstevel@tonic-gate 				break;
79587c478bd9Sstevel@tonic-gate 			keyp = &key;
79597c478bd9Sstevel@tonic-gate 		}
79607c478bd9Sstevel@tonic-gate 
79617c478bd9Sstevel@tonic-gate 		/* get the software provider for this mechanism */
79627c478bd9Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(mechp, &pd,
79637c478bd9Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
79647c478bd9Sstevel@tonic-gate 			break;
79657c478bd9Sstevel@tonic-gate 
79667c478bd9Sstevel@tonic-gate 		wrapped_key = taskq_req->dr_key_req.kr_wrapped_key;
79677c478bd9Sstevel@tonic-gate 		wrapped_key_len = *taskq_req->dr_key_req.kr_wrapped_key_len_ptr;
79687c478bd9Sstevel@tonic-gate 		ciphertext.cd_format = CRYPTO_DATA_RAW;
79697c478bd9Sstevel@tonic-gate 		ciphertext.cd_offset = 0;
79707c478bd9Sstevel@tonic-gate 		ciphertext.cd_length = wrapped_key_len;
79717c478bd9Sstevel@tonic-gate 		ciphertext.cd_raw.iov_base = (char *)wrapped_key;
79727c478bd9Sstevel@tonic-gate 		ciphertext.cd_raw.iov_len = wrapped_key_len;
79737c478bd9Sstevel@tonic-gate 		ciphertext.cd_miscdata = NULL;
79747c478bd9Sstevel@tonic-gate 
79757c478bd9Sstevel@tonic-gate 		/*
79767c478bd9Sstevel@tonic-gate 		 * Plaintext length is less than or equal to
79777c478bd9Sstevel@tonic-gate 		 * the length of the ciphertext.
79787c478bd9Sstevel@tonic-gate 		 */
79797c478bd9Sstevel@tonic-gate 		plaintext_buf = kmem_alloc(wrapped_key_len, KM_SLEEP);
79807c478bd9Sstevel@tonic-gate 		plaintext.cd_format = CRYPTO_DATA_RAW;
79817c478bd9Sstevel@tonic-gate 		plaintext.cd_offset = 0;
79827c478bd9Sstevel@tonic-gate 		plaintext.cd_length = wrapped_key_len;
79837c478bd9Sstevel@tonic-gate 		plaintext.cd_raw.iov_base = plaintext_buf;
79847c478bd9Sstevel@tonic-gate 		plaintext.cd_raw.iov_len = wrapped_key_len;
79857c478bd9Sstevel@tonic-gate 		plaintext.cd_miscdata = NULL;
79867c478bd9Sstevel@tonic-gate 
7987894b2776Smcpowers 		error = crypto_decrypt_prov(pd, 0, &mech, &ciphertext, keyp,
7988894b2776Smcpowers 		    NULL, &plaintext, NULL);
79897c478bd9Sstevel@tonic-gate 
79907c478bd9Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
79917c478bd9Sstevel@tonic-gate 
79927c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
79937c478bd9Sstevel@tonic-gate 			goto free_unwrapped_key;
79947c478bd9Sstevel@tonic-gate 
79957c478bd9Sstevel@tonic-gate 		error = dprov_create_object_from_template(softc, session,
79967c478bd9Sstevel@tonic-gate 		    template, attribute_count, object_id_ptr, B_FALSE, B_FALSE);
79977c478bd9Sstevel@tonic-gate 
79987c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
79997c478bd9Sstevel@tonic-gate 			goto free_unwrapped_key;
80007c478bd9Sstevel@tonic-gate 
80017c478bd9Sstevel@tonic-gate 		switch (class) {
80027c478bd9Sstevel@tonic-gate 		case DPROV_CKO_SECRET_KEY:
80037c478bd9Sstevel@tonic-gate 			unwrapped_key.oa_type = DPROV_CKA_VALUE;
80047c478bd9Sstevel@tonic-gate 			unwrapped_key.oa_value_len = plaintext.cd_length;
80057c478bd9Sstevel@tonic-gate 			unwrapped_key.oa_value = plaintext_buf;
80067c478bd9Sstevel@tonic-gate 			break;
80077c478bd9Sstevel@tonic-gate 		case DPROV_CKO_PRIVATE_KEY:
80087c478bd9Sstevel@tonic-gate 			/*
80097c478bd9Sstevel@tonic-gate 			 * PKCS#11 says that ASN.1 should be used to encode
80107c478bd9Sstevel@tonic-gate 			 * specific attributes before encrypting the blob.
80117c478bd9Sstevel@tonic-gate 			 * We only encrypt the private exponent for the
80127c478bd9Sstevel@tonic-gate 			 * purpose of testing.
80137c478bd9Sstevel@tonic-gate 			 */
80147c478bd9Sstevel@tonic-gate 			unwrapped_key.oa_type = DPROV_CKA_PRIVATE_EXPONENT;
80157c478bd9Sstevel@tonic-gate 			unwrapped_key.oa_value_len = plaintext.cd_length;
80167c478bd9Sstevel@tonic-gate 			unwrapped_key.oa_value = plaintext_buf;
80177c478bd9Sstevel@tonic-gate 			break;
80187c478bd9Sstevel@tonic-gate 		default:
80197c478bd9Sstevel@tonic-gate 			error = CRYPTO_TEMPLATE_INCONSISTENT;
80207c478bd9Sstevel@tonic-gate 			goto free_unwrapped_key;
80217c478bd9Sstevel@tonic-gate 		}
80227c478bd9Sstevel@tonic-gate 
80237c478bd9Sstevel@tonic-gate 		if ((error = dprov_object_set_attr(session, *object_id_ptr,
80247c478bd9Sstevel@tonic-gate 		    &unwrapped_key, 1, B_FALSE)) == CRYPTO_SUCCESS)
80257c478bd9Sstevel@tonic-gate 			break;	/* don't free the unwrapped key */
80267c478bd9Sstevel@tonic-gate 
80277c478bd9Sstevel@tonic-gate 		/* failure */
80287c478bd9Sstevel@tonic-gate 		(void) dprov_destroy_object(softc, session, *object_id_ptr);
80297c478bd9Sstevel@tonic-gate 		break;
80307c478bd9Sstevel@tonic-gate 
80317c478bd9Sstevel@tonic-gate free_unwrapped_key:
80327c478bd9Sstevel@tonic-gate 		bzero(plaintext_buf, wrapped_key_len);
80337c478bd9Sstevel@tonic-gate 		kmem_free(plaintext_buf, wrapped_key_len);
80347c478bd9Sstevel@tonic-gate 		break;
80357c478bd9Sstevel@tonic-gate 	}
80367c478bd9Sstevel@tonic-gate 
80377c478bd9Sstevel@tonic-gate 	case DPROV_REQ_KEY_DERIVE: {
80387c478bd9Sstevel@tonic-gate 		crypto_mechanism_t digest_mech, *mechp;
80397c478bd9Sstevel@tonic-gate 		crypto_key_t key, *base_keyp;
80407c478bd9Sstevel@tonic-gate 		crypto_object_id_t *object_id_ptr;
80417c478bd9Sstevel@tonic-gate 		crypto_data_t data;
80427c478bd9Sstevel@tonic-gate 		crypto_data_t digest;
80437c478bd9Sstevel@tonic-gate 		size_t hash_size;
80447c478bd9Sstevel@tonic-gate 		char *digest_buf;
80457c478bd9Sstevel@tonic-gate 		crypto_object_attribute_t derived_key;
80467c478bd9Sstevel@tonic-gate 		crypto_object_attribute_t *template;
80477c478bd9Sstevel@tonic-gate 		uint_t attribute_count;
80487c478bd9Sstevel@tonic-gate 		ulong_t key_type;
80497c478bd9Sstevel@tonic-gate 		void *value;
80507c478bd9Sstevel@tonic-gate 		size_t value_len = 0;
80517c478bd9Sstevel@tonic-gate 
80527c478bd9Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
80537c478bd9Sstevel@tonic-gate 
80547c478bd9Sstevel@tonic-gate 		template = taskq_req->dr_key_req.kr_template;
80557c478bd9Sstevel@tonic-gate 		attribute_count = taskq_req->dr_key_req.kr_attribute_count;
80567c478bd9Sstevel@tonic-gate 		object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr;
80577c478bd9Sstevel@tonic-gate 
80587c478bd9Sstevel@tonic-gate 		/* required */
80597c478bd9Sstevel@tonic-gate 		if (dprov_get_template_attr_ulong(template, attribute_count,
80607c478bd9Sstevel@tonic-gate 		    DPROV_CKA_KEY_TYPE, &key_type) != CRYPTO_SUCCESS) {
80617c478bd9Sstevel@tonic-gate 			error = CRYPTO_TEMPLATE_INCOMPLETE;
80627c478bd9Sstevel@tonic-gate 			break;
80637c478bd9Sstevel@tonic-gate 		}
80647c478bd9Sstevel@tonic-gate 
80657c478bd9Sstevel@tonic-gate 		mechp = taskq_req->dr_key_req.kr_mechanism;
80667c478bd9Sstevel@tonic-gate 		/* structure assignment */
80677c478bd9Sstevel@tonic-gate 		digest_mech = *mechp;
80687c478bd9Sstevel@tonic-gate 
80697c478bd9Sstevel@tonic-gate 		switch (digest_mech.cm_type) {
80707c478bd9Sstevel@tonic-gate 		case SHA1_KEY_DERIVATION_MECH_INFO_TYPE:
80717c478bd9Sstevel@tonic-gate 			hash_size = SHA1_DIGEST_LEN;
80727c478bd9Sstevel@tonic-gate 			digest_mech.cm_type = SHA1_MECH_INFO_TYPE;
80737c478bd9Sstevel@tonic-gate 			break;
80747c478bd9Sstevel@tonic-gate 
8075f66d273dSizick 		case SHA256_KEY_DERIVATION_MECH_INFO_TYPE:
8076f66d273dSizick 			hash_size = SHA256_DIGEST_LENGTH;
8077f66d273dSizick 			digest_mech.cm_type = SHA256_MECH_INFO_TYPE;
8078f66d273dSizick 			break;
8079f66d273dSizick 
8080f66d273dSizick 		case SHA384_KEY_DERIVATION_MECH_INFO_TYPE:
8081f66d273dSizick 			hash_size = SHA384_DIGEST_LENGTH;
8082f66d273dSizick 			digest_mech.cm_type = SHA384_MECH_INFO_TYPE;
8083f66d273dSizick 			break;
8084f66d273dSizick 
8085f66d273dSizick 		case SHA512_KEY_DERIVATION_MECH_INFO_TYPE:
8086f66d273dSizick 			hash_size = SHA512_DIGEST_LENGTH;
8087f66d273dSizick 			digest_mech.cm_type = SHA512_MECH_INFO_TYPE;
8088f66d273dSizick 			break;
8089f66d273dSizick 
80907c478bd9Sstevel@tonic-gate 		case MD5_KEY_DERIVATION_MECH_INFO_TYPE:
80917c478bd9Sstevel@tonic-gate 			hash_size = MD5_DIGEST_LEN;
80927c478bd9Sstevel@tonic-gate 			digest_mech.cm_type = MD5_MECH_INFO_TYPE;
80937c478bd9Sstevel@tonic-gate 			break;
80947c478bd9Sstevel@tonic-gate 
80957c478bd9Sstevel@tonic-gate 		default:
80967c478bd9Sstevel@tonic-gate 			error = CRYPTO_MECHANISM_INVALID;
80977c478bd9Sstevel@tonic-gate 		}
80987c478bd9Sstevel@tonic-gate 
80997c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
81007c478bd9Sstevel@tonic-gate 			break;
81017c478bd9Sstevel@tonic-gate 
81027c478bd9Sstevel@tonic-gate 		/* CKA_VALUE is optional */
81037c478bd9Sstevel@tonic-gate 		(void) dprov_get_template_attr_array(template, attribute_count,
81047c478bd9Sstevel@tonic-gate 		    DPROV_CKA_VALUE, &value, &value_len);
81057c478bd9Sstevel@tonic-gate 
81067c478bd9Sstevel@tonic-gate 		/* check for inconsistent value length */
81077c478bd9Sstevel@tonic-gate 		switch (key_type) {
81087c478bd9Sstevel@tonic-gate 		case DPROV_CKK_GENERIC_SECRET:
81097c478bd9Sstevel@tonic-gate 			if (value_len > 0) {
81107c478bd9Sstevel@tonic-gate 				if (value_len > hash_size)
81117c478bd9Sstevel@tonic-gate 					error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
81127c478bd9Sstevel@tonic-gate 			} else {
81137c478bd9Sstevel@tonic-gate 				value_len = hash_size;
81147c478bd9Sstevel@tonic-gate 			}
81157c478bd9Sstevel@tonic-gate 			break;
81167c478bd9Sstevel@tonic-gate 
81177c478bd9Sstevel@tonic-gate 		case DPROV_CKK_RC4:
81187c478bd9Sstevel@tonic-gate 		case DPROV_CKK_AES:
81197c478bd9Sstevel@tonic-gate 			if (value_len == 0 ||
81207c478bd9Sstevel@tonic-gate 			    value_len > hash_size) {
81217c478bd9Sstevel@tonic-gate 				error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
81227c478bd9Sstevel@tonic-gate 			}
81237c478bd9Sstevel@tonic-gate 			break;
81247c478bd9Sstevel@tonic-gate 
81257c478bd9Sstevel@tonic-gate 		case DPROV_CKK_DES:
81267c478bd9Sstevel@tonic-gate 			if (value_len > 0 &&
81277c478bd9Sstevel@tonic-gate 			    value_len != DES_KEY_LEN) {
81287c478bd9Sstevel@tonic-gate 				error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
81297c478bd9Sstevel@tonic-gate 			}
81307c478bd9Sstevel@tonic-gate 			value_len = DES_KEY_LEN;
81317c478bd9Sstevel@tonic-gate 			break;
81327c478bd9Sstevel@tonic-gate 
81337c478bd9Sstevel@tonic-gate 		case DPROV_CKK_DES3:
81347c478bd9Sstevel@tonic-gate 			if (value_len > 0 &&
81357c478bd9Sstevel@tonic-gate 			    value_len != DES3_KEY_LEN) {
81367c478bd9Sstevel@tonic-gate 				error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
81377c478bd9Sstevel@tonic-gate 			}
81387c478bd9Sstevel@tonic-gate 			value_len = DES3_KEY_LEN;
81397c478bd9Sstevel@tonic-gate 			break;
81407c478bd9Sstevel@tonic-gate 
81417c478bd9Sstevel@tonic-gate 		default:
81427c478bd9Sstevel@tonic-gate 			error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
81437c478bd9Sstevel@tonic-gate 			break;
81447c478bd9Sstevel@tonic-gate 		}
81457c478bd9Sstevel@tonic-gate 
81467c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
81477c478bd9Sstevel@tonic-gate 			break;
81487c478bd9Sstevel@tonic-gate 
81497c478bd9Sstevel@tonic-gate 		/* get the software provider for this mechanism */
81507c478bd9Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(&digest_mech, &pd,
81517c478bd9Sstevel@tonic-gate 		    &digest_mech.cm_type)) != CRYPTO_SUCCESS)
81527c478bd9Sstevel@tonic-gate 			break;
81537c478bd9Sstevel@tonic-gate 
81547c478bd9Sstevel@tonic-gate 		/* get the base key */
81557c478bd9Sstevel@tonic-gate 		error = dprov_key_value_secret(softc, session_id,
81567c478bd9Sstevel@tonic-gate 		    taskq_req->dr_type, taskq_req->dr_key_req.kr_key, &key);
81577c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
81587c478bd9Sstevel@tonic-gate 			break;
81597c478bd9Sstevel@tonic-gate 
81607c478bd9Sstevel@tonic-gate 		base_keyp = &key;
81617c478bd9Sstevel@tonic-gate 
81627c478bd9Sstevel@tonic-gate 		data.cd_format = CRYPTO_DATA_RAW;
81637c478bd9Sstevel@tonic-gate 		data.cd_offset = 0;
81647c478bd9Sstevel@tonic-gate 		data.cd_length = CRYPTO_BITS2BYTES(base_keyp->ck_length);
81657c478bd9Sstevel@tonic-gate 		data.cd_raw.iov_base = base_keyp->ck_data;
81667c478bd9Sstevel@tonic-gate 		data.cd_raw.iov_len = data.cd_length;
81677c478bd9Sstevel@tonic-gate 
81687c478bd9Sstevel@tonic-gate 		digest_buf = kmem_alloc(hash_size, KM_SLEEP);
81697c478bd9Sstevel@tonic-gate 		digest.cd_format = CRYPTO_DATA_RAW;
81707c478bd9Sstevel@tonic-gate 		digest.cd_offset = 0;
81717c478bd9Sstevel@tonic-gate 		digest.cd_length = hash_size;
81727c478bd9Sstevel@tonic-gate 		digest.cd_raw.iov_base = digest_buf;
81737c478bd9Sstevel@tonic-gate 		digest.cd_raw.iov_len = hash_size;
81747c478bd9Sstevel@tonic-gate 
8175894b2776Smcpowers 		error = crypto_digest_prov(pd, 0, &digest_mech, &data,
8176894b2776Smcpowers 		    &digest, NULL);
81777c478bd9Sstevel@tonic-gate 
81787c478bd9Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
81797c478bd9Sstevel@tonic-gate 
81807c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
81817c478bd9Sstevel@tonic-gate 			goto free_derived_key;
81827c478bd9Sstevel@tonic-gate 
81837c478bd9Sstevel@tonic-gate 		error = dprov_create_object_from_template(softc, session,
81847c478bd9Sstevel@tonic-gate 		    template, attribute_count, object_id_ptr, B_FALSE, B_FALSE);
81857c478bd9Sstevel@tonic-gate 
81867c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
81877c478bd9Sstevel@tonic-gate 			goto free_derived_key;
81887c478bd9Sstevel@tonic-gate 
81897c478bd9Sstevel@tonic-gate 		derived_key.oa_type = DPROV_CKA_VALUE;
81907c478bd9Sstevel@tonic-gate 		derived_key.oa_value = digest_buf;
81917c478bd9Sstevel@tonic-gate 		derived_key.oa_value_len = value_len;
81927c478bd9Sstevel@tonic-gate 
81937c478bd9Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *object_id_ptr,
81947c478bd9Sstevel@tonic-gate 		    &derived_key, 1, B_FALSE);
81957c478bd9Sstevel@tonic-gate 
81967c478bd9Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
81977c478bd9Sstevel@tonic-gate 			(void) dprov_destroy_object(softc, session,
81987c478bd9Sstevel@tonic-gate 			    *object_id_ptr);
81997c478bd9Sstevel@tonic-gate 		}
82007c478bd9Sstevel@tonic-gate 
82017c478bd9Sstevel@tonic-gate free_derived_key:
82027c478bd9Sstevel@tonic-gate 		bzero(digest_buf, hash_size);
82037c478bd9Sstevel@tonic-gate 		kmem_free(digest_buf, hash_size);
8204034448feSmcpowers 		break;
8205034448feSmcpowers 	}
8206034448feSmcpowers 
8207034448feSmcpowers 	case DPROV_REQ_NOSTORE_KEY_GENERATE: {
8208034448feSmcpowers 		crypto_object_attribute_t *out_template;
8209034448feSmcpowers 		uint_t out_attribute_count;
8210034448feSmcpowers 		void *value;
8211034448feSmcpowers 		size_t value_len = 0;
8212034448feSmcpowers 
8213034448feSmcpowers 		out_template = taskq_req->dr_key_req.kr_out_template1;
8214034448feSmcpowers 		out_attribute_count =
8215034448feSmcpowers 		    taskq_req->dr_key_req.kr_out_attribute_count1;
8216034448feSmcpowers 
8217034448feSmcpowers 		error = dprov_get_template_attr_array(out_template,
8218034448feSmcpowers 		    out_attribute_count, DPROV_CKA_VALUE, &value, &value_len);
8219034448feSmcpowers 		if (error != CRYPTO_SUCCESS)
8220034448feSmcpowers 			break;
8221034448feSmcpowers 
8222034448feSmcpowers 		/* fill the entire array with pattern */
8223034448feSmcpowers 		{
8224034448feSmcpowers 			int i = 0;
8225034448feSmcpowers 			char *p = value;
8226034448feSmcpowers 			while (i < value_len) {
8227034448feSmcpowers 				p[i++] = 'A';
8228034448feSmcpowers 				if (i >= value_len)
8229034448feSmcpowers 					break;
8230034448feSmcpowers 				p[i++] = 'B';
8231034448feSmcpowers 				if (i >= value_len)
8232034448feSmcpowers 					break;
8233034448feSmcpowers 				p[i++] = 'C';
82347c478bd9Sstevel@tonic-gate 			}
82357c478bd9Sstevel@tonic-gate 		}
82367c478bd9Sstevel@tonic-gate 
8237034448feSmcpowers 		error = CRYPTO_SUCCESS;
8238034448feSmcpowers 		break;
8239034448feSmcpowers 	}
82405b0c7657Sizick 
82415b0c7657Sizick 	case DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR: {
82425b0c7657Sizick 		crypto_mechanism_t *mechp;
82435b0c7657Sizick 		crypto_object_attribute_t *pub_template;
8244f9fbec18Smcpowers 		crypto_object_attribute_t *pri_template;
82455b0c7657Sizick 		uint_t pub_attribute_count;
8246f9fbec18Smcpowers 		uint_t pri_attribute_count;
82475b0c7657Sizick 		crypto_object_attribute_t *out_pub_template;
82485b0c7657Sizick 		crypto_object_attribute_t *out_pri_template;
82495b0c7657Sizick 		uint_t out_pub_attribute_count;
82505b0c7657Sizick 		uint_t out_pri_attribute_count;
82515b0c7657Sizick 
82525b0c7657Sizick 		mechp = taskq_req->dr_key_req.kr_mechanism;
82535b0c7657Sizick 		pub_template = taskq_req->dr_key_req.kr_template;
82545b0c7657Sizick 		pub_attribute_count = taskq_req->dr_key_req.kr_attribute_count;
8255f9fbec18Smcpowers 		pri_template = taskq_req->dr_key_req.kr_private_key_template;
8256f9fbec18Smcpowers 		pri_attribute_count =
8257f9fbec18Smcpowers 		    taskq_req->dr_key_req.kr_private_key_attribute_count;
82585b0c7657Sizick 		out_pub_template = taskq_req->dr_key_req.kr_out_template1;
82595b0c7657Sizick 		out_pub_attribute_count =
82605b0c7657Sizick 		    taskq_req->dr_key_req.kr_out_attribute_count1;
82615b0c7657Sizick 		out_pri_template = taskq_req->dr_key_req.kr_out_template2;
82625b0c7657Sizick 		out_pri_attribute_count =
82635b0c7657Sizick 		    taskq_req->dr_key_req.kr_out_attribute_count2;
82645b0c7657Sizick 
82655b0c7657Sizick 		switch (mechp->cm_type) {
82665b0c7657Sizick 		case RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE:
82675b0c7657Sizick 			error = nostore_copy_attribute(out_pub_template,
82685b0c7657Sizick 			    out_pub_attribute_count, DPROV_CKA_MODULUS);
82695b0c7657Sizick 			if (error != CRYPTO_SUCCESS)
82705b0c7657Sizick 				break;
82715b0c7657Sizick 
82725b0c7657Sizick 			error = nostore_copy_attribute(out_pub_template,
82735b0c7657Sizick 			    out_pub_attribute_count, DPROV_CKA_PUBLIC_EXPONENT);
82745b0c7657Sizick 			if (error == CRYPTO_ARGUMENTS_BAD) {
82755b0c7657Sizick 				size_t tmp_len = 0;
82765b0c7657Sizick 				void *tmp;
82775b0c7657Sizick 
82785b0c7657Sizick 				/* public exponent must be here */
82795b0c7657Sizick 				error = dprov_get_template_attr_array(
82805b0c7657Sizick 				    pub_template, pub_attribute_count,
82815b0c7657Sizick 				    DPROV_CKA_PUBLIC_EXPONENT, &tmp, &tmp_len);
82825b0c7657Sizick 				if (error != CRYPTO_SUCCESS)
82835b0c7657Sizick 					break;
82845b0c7657Sizick 			}
82855b0c7657Sizick 			error = nostore_copy_attribute(out_pri_template,
82865b0c7657Sizick 			    out_pri_attribute_count, DPROV_CKA_MODULUS);
82875b0c7657Sizick 			if (error != CRYPTO_SUCCESS)
82885b0c7657Sizick 				break;
82895b0c7657Sizick 
82905b0c7657Sizick 			error = nostore_copy_attribute(out_pri_template,
82915b0c7657Sizick 			    out_pri_attribute_count,
82925b0c7657Sizick 			    DPROV_CKA_PRIVATE_EXPONENT);
82935b0c7657Sizick 			break;
82945b0c7657Sizick 
82955b0c7657Sizick 		case DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE:
82965b0c7657Sizick 			/*
82975b0c7657Sizick 			 * There is no software provider for DH mechanism;
82985b0c7657Sizick 			 * Just return pre-defined values.
82995b0c7657Sizick 			 */
83005b0c7657Sizick 			error = nostore_copy_attribute(out_pub_template,
83015b0c7657Sizick 			    out_pub_attribute_count, DPROV_CKA_VALUE);
83025b0c7657Sizick 			error = nostore_copy_attribute(out_pri_template,
83035b0c7657Sizick 			    out_pri_attribute_count, DPROV_CKA_VALUE);
83045b0c7657Sizick 			break;
83055b0c7657Sizick 
8306f9fbec18Smcpowers 		case EC_KEY_PAIR_GEN_MECH_INFO_TYPE: {
8307f9fbec18Smcpowers 			crypto_mechanism_t mech, *mechp;
8308f9fbec18Smcpowers 			kcf_req_params_t params;
8309f9fbec18Smcpowers 			crypto_object_attribute_t *pub_template;
8310f9fbec18Smcpowers 			uint_t pub_attribute_count;
8311f9fbec18Smcpowers 			crypto_object_attribute_t *out_pub_template;
8312f9fbec18Smcpowers 			crypto_object_attribute_t *out_pri_template;
8313f9fbec18Smcpowers 			uint_t out_pub_attribute_count;
8314f9fbec18Smcpowers 			uint_t out_pri_attribute_count;
8315f9fbec18Smcpowers 
8316f9fbec18Smcpowers 			mechp = taskq_req->dr_key_req.kr_mechanism;
8317f9fbec18Smcpowers 			pub_template = taskq_req->dr_key_req.kr_template;
8318f9fbec18Smcpowers 			pub_attribute_count =
8319f9fbec18Smcpowers 			    taskq_req->dr_key_req.kr_attribute_count;
8320f9fbec18Smcpowers 			out_pub_template =
8321f9fbec18Smcpowers 			    taskq_req->dr_key_req.kr_out_template1;
8322f9fbec18Smcpowers 			out_pub_attribute_count =
8323f9fbec18Smcpowers 			    taskq_req->dr_key_req.kr_out_attribute_count1;
8324f9fbec18Smcpowers 			out_pri_template =
8325f9fbec18Smcpowers 			    taskq_req->dr_key_req.kr_out_template2;
8326f9fbec18Smcpowers 			out_pri_attribute_count =
8327f9fbec18Smcpowers 			    taskq_req->dr_key_req.kr_out_attribute_count2;
8328f9fbec18Smcpowers 
8329f9fbec18Smcpowers 			/* get the software provider for this mechanism */
8330f9fbec18Smcpowers 			mech = *mechp;
8331f9fbec18Smcpowers 			if ((error = dprov_get_sw_prov(mechp, &pd,
8332f9fbec18Smcpowers 			    &mech.cm_type)) != CRYPTO_SUCCESS)
8333f9fbec18Smcpowers 				break;
8334f9fbec18Smcpowers 			/*
8335f9fbec18Smcpowers 			 * Turn 32-bit values into 64-bit values for certain
8336f9fbec18Smcpowers 			 * attributes like CKA_CLASS.
8337f9fbec18Smcpowers 			 */
8338f9fbec18Smcpowers 			dprov_adjust_attrs(pub_template, pub_attribute_count);
8339f9fbec18Smcpowers 			dprov_adjust_attrs(pri_template, pri_attribute_count);
8340f9fbec18Smcpowers 
8341f9fbec18Smcpowers 			/* bypass the kernel API for now */
8342f9fbec18Smcpowers 			KCF_WRAP_NOSTORE_KEY_OPS_PARAMS(&params,
8343f9fbec18Smcpowers 			    KCF_OP_KEY_GENERATE_PAIR,
8344f9fbec18Smcpowers 			    0, /* session 0 for sw provider */
8345f9fbec18Smcpowers 			    &mech, pub_template, pub_attribute_count,
8346f9fbec18Smcpowers 			    pri_template, pri_attribute_count, NULL,
8347f9fbec18Smcpowers 			    out_pub_template, out_pub_attribute_count,
8348f9fbec18Smcpowers 			    out_pri_template, out_pri_attribute_count);
8349f9fbec18Smcpowers 
8350f9fbec18Smcpowers 			error = kcf_submit_request(pd, NULL, NULL, &params,
8351f9fbec18Smcpowers 			    B_FALSE);
8352f9fbec18Smcpowers 
8353f9fbec18Smcpowers 			KCF_PROV_REFRELE(pd);
8354f9fbec18Smcpowers 			break;
8355f9fbec18Smcpowers 		}
83565b0c7657Sizick 		default:
83575b0c7657Sizick 			error = CRYPTO_MECHANISM_INVALID;
83585b0c7657Sizick 		}
83595b0c7657Sizick 		break;
83605b0c7657Sizick 	}
83615b0c7657Sizick 
83625b0c7657Sizick 	case DPROV_REQ_NOSTORE_KEY_DERIVE: {
83635b0c7657Sizick 		crypto_mechanism_t *mechp;
83645b0c7657Sizick 		crypto_object_attribute_t *in_template, *out_template;
83655b0c7657Sizick 		crypto_key_t *base_key;
83665b0c7657Sizick 		uint_t in_attribute_count, out_attribute_count;
83675b0c7657Sizick 		ulong_t key_type;
83685b0c7657Sizick 		void *value;
83695b0c7657Sizick 		size_t value_len = 0;
83705b0c7657Sizick 		size_t value_len_value = 0;
83715b0c7657Sizick 
83725b0c7657Sizick 		in_template = taskq_req->dr_key_req.kr_template;
83735b0c7657Sizick 		out_template = taskq_req->dr_key_req.kr_out_template1;
83745b0c7657Sizick 		in_attribute_count = taskq_req->dr_key_req.kr_attribute_count;
83755b0c7657Sizick 		out_attribute_count =
83765b0c7657Sizick 		    taskq_req->dr_key_req.kr_out_attribute_count1;
83775b0c7657Sizick 		mechp = taskq_req->dr_key_req.kr_mechanism;
83785b0c7657Sizick 		base_key = taskq_req->dr_key_req.kr_key;
83795b0c7657Sizick 
83805b0c7657Sizick 		/*
83815b0c7657Sizick 		 * CKA_VALUE must be present so the derived key can
83825b0c7657Sizick 		 * be returned by value.
83835b0c7657Sizick 		 */
83845b0c7657Sizick 		if (dprov_get_template_attr_array(out_template,
83855b0c7657Sizick 		    out_attribute_count, DPROV_CKA_VALUE, &value,
83865b0c7657Sizick 		    &value_len) != CRYPTO_SUCCESS) {
83875b0c7657Sizick 			error = CRYPTO_TEMPLATE_INCOMPLETE;
83885b0c7657Sizick 			break;
83895b0c7657Sizick 		}
83905b0c7657Sizick 
83915b0c7657Sizick 		if (dprov_get_template_attr_ulong(in_template,
83925b0c7657Sizick 		    in_attribute_count, DPROV_CKA_KEY_TYPE,
83935b0c7657Sizick 		    &key_type) != CRYPTO_SUCCESS) {
83945b0c7657Sizick 			error = CRYPTO_TEMPLATE_INCOMPLETE;
83955b0c7657Sizick 			break;
83965b0c7657Sizick 		}
83975b0c7657Sizick 		switch (mechp->cm_type) {
83985b0c7657Sizick 		case DH_PKCS_DERIVE_MECH_INFO_TYPE: {
83995b0c7657Sizick 			size_t tmp_len = 0;
84005b0c7657Sizick 			void *tmp;
84015b0c7657Sizick 
84025b0c7657Sizick 			if (base_key->ck_format != CRYPTO_KEY_ATTR_LIST) {
84035b0c7657Sizick 				error = CRYPTO_ARGUMENTS_BAD;
84045b0c7657Sizick 				break;
84055b0c7657Sizick 			}
84065b0c7657Sizick 
84075b0c7657Sizick 			if ((dprov_get_template_attr_array(base_key->ck_attrs,
84085b0c7657Sizick 			    base_key->ck_count, DPROV_CKA_BASE, &tmp,
84095b0c7657Sizick 			    &tmp_len) != CRYPTO_SUCCESS) ||
84105b0c7657Sizick 			    (dprov_get_template_attr_array(base_key->ck_attrs,
84115b0c7657Sizick 			    base_key->ck_count, DPROV_CKA_PRIME, &tmp,
84125b0c7657Sizick 			    &tmp_len) != CRYPTO_SUCCESS) ||
84135b0c7657Sizick 			    (dprov_get_template_attr_array(base_key->ck_attrs,
84145b0c7657Sizick 			    base_key->ck_count, DPROV_CKA_VALUE, &tmp,
84155b0c7657Sizick 			    &tmp_len) != CRYPTO_SUCCESS)) {
84165b0c7657Sizick 				error = CRYPTO_TEMPLATE_INCOMPLETE;
84175b0c7657Sizick 				break;
84185b0c7657Sizick 			}
84195b0c7657Sizick 
84205b0c7657Sizick 			/*
84215b0c7657Sizick 			 * CKA_VALUE is added to the derived key template by
84225b0c7657Sizick 			 * the library.
84235b0c7657Sizick 			 */
84245b0c7657Sizick 			error = CRYPTO_SUCCESS;
84255b0c7657Sizick 			switch (key_type) {
84265b0c7657Sizick 			case DPROV_CKK_AES:
84275b0c7657Sizick 				if (dprov_get_template_attr_ulong(in_template,
84285b0c7657Sizick 				    in_attribute_count, DPROV_CKA_VALUE_LEN,
84295b0c7657Sizick 				    &value_len_value) != CRYPTO_SUCCESS) {
84305b0c7657Sizick 					error = CRYPTO_TEMPLATE_INCOMPLETE;
84315b0c7657Sizick 					break;
84325b0c7657Sizick 				}
84335b0c7657Sizick 				if (value_len != value_len_value) {
84345b0c7657Sizick 					error = CRYPTO_TEMPLATE_INCONSISTENT;
84355b0c7657Sizick 					break;
84365b0c7657Sizick 				}
84375b0c7657Sizick 			default:
84385b0c7657Sizick 				error = CRYPTO_MECHANISM_INVALID;
84395b0c7657Sizick 			}
84405b0c7657Sizick 			if (error == CRYPTO_SUCCESS)
84415b0c7657Sizick 				fill_dh(value, value_len);
84425b0c7657Sizick 			break;
84435b0c7657Sizick 		}
8444f9fbec18Smcpowers 		case ECDH1_DERIVE_MECH_INFO_TYPE: {
8445f9fbec18Smcpowers 			crypto_mechanism_t mech;
8446f9fbec18Smcpowers 			kcf_req_params_t params;
8447f9fbec18Smcpowers 
8448f9fbec18Smcpowers 			/* get the software provider for this mechanism */
8449f9fbec18Smcpowers 			mech = *mechp;
8450f9fbec18Smcpowers 			if ((error = dprov_get_sw_prov(mechp, &pd,
8451f9fbec18Smcpowers 			    &mech.cm_type)) != CRYPTO_SUCCESS)
8452f9fbec18Smcpowers 				break;
8453f9fbec18Smcpowers 
8454f9fbec18Smcpowers 			/*
8455f9fbec18Smcpowers 			 * Turn 32-bit values into 64-bit values for certain
8456f9fbec18Smcpowers 			 * attributes like CKA_VALUE_LEN.
8457f9fbec18Smcpowers 			 */
8458f9fbec18Smcpowers 			dprov_adjust_attrs(in_template, in_attribute_count);
8459f9fbec18Smcpowers 
8460f9fbec18Smcpowers 			/* bypass the kernel API for now */
8461f9fbec18Smcpowers 			KCF_WRAP_NOSTORE_KEY_OPS_PARAMS(&params,
8462f9fbec18Smcpowers 			    KCF_OP_KEY_DERIVE,
8463f9fbec18Smcpowers 			    0, /* session 0 for sw provider */
8464f9fbec18Smcpowers 			    &mech, in_template, in_attribute_count,
8465f9fbec18Smcpowers 			    NULL, 0, base_key,
8466f9fbec18Smcpowers 			    out_template, out_attribute_count,
8467f9fbec18Smcpowers 			    NULL, 0);
8468f9fbec18Smcpowers 
8469f9fbec18Smcpowers 			error = kcf_submit_request(pd, NULL, NULL, &params,
8470f9fbec18Smcpowers 			    B_FALSE);
8471f9fbec18Smcpowers 
8472f9fbec18Smcpowers 			KCF_PROV_REFRELE(pd);
8473f9fbec18Smcpowers 			break;
8474f9fbec18Smcpowers 		}
8475f9fbec18Smcpowers 
84765b0c7657Sizick 		default:
84775b0c7657Sizick 			error = CRYPTO_MECHANISM_INVALID;
84785b0c7657Sizick 		}
84795b0c7657Sizick 		break;
84805b0c7657Sizick 	default:
84815b0c7657Sizick 		error = CRYPTO_MECHANISM_INVALID;
84825b0c7657Sizick 	}
8483034448feSmcpowers 	} /* end case */
8484034448feSmcpowers 
84857c478bd9Sstevel@tonic-gate 	mutex_exit(&softc->ds_lock);
84867c478bd9Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
84877c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_task: end\n", instance));
84887c478bd9Sstevel@tonic-gate }
84897c478bd9Sstevel@tonic-gate 
84907c478bd9Sstevel@tonic-gate /*
84917c478bd9Sstevel@tonic-gate  * taskq dispatcher function for provider management operations.
84927c478bd9Sstevel@tonic-gate  */
84937c478bd9Sstevel@tonic-gate static void
84947c478bd9Sstevel@tonic-gate dprov_mgmt_task(dprov_req_t *taskq_req)
84957c478bd9Sstevel@tonic-gate {
84967c478bd9Sstevel@tonic-gate 	dprov_state_t *softc;
84977c478bd9Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
84987c478bd9Sstevel@tonic-gate 	int instance;
84997c478bd9Sstevel@tonic-gate 	int error = CRYPTO_NOT_SUPPORTED;
85007c478bd9Sstevel@tonic-gate 
85017c478bd9Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
85027c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_mgmt_task: started\n", instance));
85037c478bd9Sstevel@tonic-gate 
85047c478bd9Sstevel@tonic-gate 	mutex_enter(&softc->ds_lock);
85057c478bd9Sstevel@tonic-gate 
85067c478bd9Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
85077c478bd9Sstevel@tonic-gate 	case DPROV_REQ_MGMT_EXTINFO: {
85087c478bd9Sstevel@tonic-gate 		crypto_provider_ext_info_t *ext_info =
85097c478bd9Sstevel@tonic-gate 		    taskq_req->dr_mgmt_req.mr_ext_info;
85107c478bd9Sstevel@tonic-gate 
85117c478bd9Sstevel@tonic-gate 		(void) memset(ext_info->ei_label, ' ', CRYPTO_EXT_SIZE_LABEL);
85127c478bd9Sstevel@tonic-gate 		if (!softc->ds_token_initialized) {
85137c478bd9Sstevel@tonic-gate 			bcopy("(not initialized)", ext_info->ei_label,
85147c478bd9Sstevel@tonic-gate 			    strlen("(not initialized)"));
85157c478bd9Sstevel@tonic-gate 		} else {
85167c478bd9Sstevel@tonic-gate 			bcopy(softc->ds_label, ext_info->ei_label,
85177c478bd9Sstevel@tonic-gate 			    CRYPTO_EXT_SIZE_LABEL);
85187c478bd9Sstevel@tonic-gate 		}
85197c478bd9Sstevel@tonic-gate 
85207c478bd9Sstevel@tonic-gate 		bcopy(DPROV_MANUFACTURER, ext_info->ei_manufacturerID,
85217c478bd9Sstevel@tonic-gate 		    CRYPTO_EXT_SIZE_MANUF);
85227c478bd9Sstevel@tonic-gate 		bcopy(DPROV_MODEL, ext_info->ei_model, CRYPTO_EXT_SIZE_MODEL);
85237c478bd9Sstevel@tonic-gate 
85247c478bd9Sstevel@tonic-gate 		(void) snprintf((char *)ext_info->ei_serial_number, 16, "%d%s",
85257c478bd9Sstevel@tonic-gate 		    instance, DPROV_ALLSPACES);
85267c478bd9Sstevel@tonic-gate 		/* PKCS#11 blank padding */
85277c478bd9Sstevel@tonic-gate 		ext_info->ei_serial_number[15] = ' ';
85287c478bd9Sstevel@tonic-gate 		ext_info->ei_max_session_count = CRYPTO_EFFECTIVELY_INFINITE;
85297c478bd9Sstevel@tonic-gate 		ext_info->ei_max_pin_len = (ulong_t)DPROV_MAX_PIN_LEN;
85307c478bd9Sstevel@tonic-gate 		ext_info->ei_min_pin_len = 1;
85317c478bd9Sstevel@tonic-gate 		ext_info->ei_total_public_memory = CRYPTO_EFFECTIVELY_INFINITE;
85327c478bd9Sstevel@tonic-gate 		ext_info->ei_free_public_memory = CRYPTO_EFFECTIVELY_INFINITE;
85337c478bd9Sstevel@tonic-gate 		ext_info->ei_total_private_memory = CRYPTO_EFFECTIVELY_INFINITE;
85347c478bd9Sstevel@tonic-gate 		ext_info->ei_free_private_memory = CRYPTO_EFFECTIVELY_INFINITE;
85357c478bd9Sstevel@tonic-gate 		ext_info->ei_hardware_version.cv_major = 1;
85367c478bd9Sstevel@tonic-gate 		ext_info->ei_hardware_version.cv_minor = 0;
85377c478bd9Sstevel@tonic-gate 		ext_info->ei_firmware_version.cv_major = 1;
85387c478bd9Sstevel@tonic-gate 		ext_info->ei_firmware_version.cv_minor = 0;
85397c478bd9Sstevel@tonic-gate 
85407c478bd9Sstevel@tonic-gate 		ext_info->ei_flags = CRYPTO_EXTF_RNG |
8541c892ebf1Skrishna 		    CRYPTO_EXTF_LOGIN_REQUIRED |
85427c478bd9Sstevel@tonic-gate 		    CRYPTO_EXTF_DUAL_CRYPTO_OPERATIONS;
85437c478bd9Sstevel@tonic-gate 		if (softc->ds_user_pin_set)
85447c478bd9Sstevel@tonic-gate 			ext_info->ei_flags |= CRYPTO_EXTF_USER_PIN_INITIALIZED;
85457c478bd9Sstevel@tonic-gate 		if (softc->ds_token_initialized)
85467c478bd9Sstevel@tonic-gate 			ext_info->ei_flags |= CRYPTO_EXTF_TOKEN_INITIALIZED;
85477c478bd9Sstevel@tonic-gate 
85484df55fdeSJanie Lu 		ext_info->ei_hash_max_input_len = dprov_max_digestsz;
85494df55fdeSJanie Lu 		ext_info->ei_hmac_max_input_len = dprov_max_digestsz;
85507c478bd9Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
85517c478bd9Sstevel@tonic-gate 		break;
85527c478bd9Sstevel@tonic-gate 	}
85537c478bd9Sstevel@tonic-gate 	case DPROV_REQ_MGMT_INITTOKEN: {
85547c478bd9Sstevel@tonic-gate 		char *pin = taskq_req->dr_mgmt_req.mr_pin;
85557c478bd9Sstevel@tonic-gate 		size_t pin_len = taskq_req->dr_mgmt_req.mr_pin_len;
85567c478bd9Sstevel@tonic-gate 		char *label = taskq_req->dr_mgmt_req.mr_label;
85577c478bd9Sstevel@tonic-gate 
85587c478bd9Sstevel@tonic-gate 		/* cannot initialize token when a session is open */
85597c478bd9Sstevel@tonic-gate 		if (softc->ds_sessions_count > 0) {
85607c478bd9Sstevel@tonic-gate 			error = CRYPTO_SESSION_EXISTS;
85617c478bd9Sstevel@tonic-gate 			break;
85627c478bd9Sstevel@tonic-gate 		}
85637c478bd9Sstevel@tonic-gate 
85647c478bd9Sstevel@tonic-gate 		/* check PIN length */
85657c478bd9Sstevel@tonic-gate 		if (pin_len > DPROV_MAX_PIN_LEN) {
85667c478bd9Sstevel@tonic-gate 			error = CRYPTO_PIN_LEN_RANGE;
85677c478bd9Sstevel@tonic-gate 			break;
85687c478bd9Sstevel@tonic-gate 		}
85697c478bd9Sstevel@tonic-gate 
85707c478bd9Sstevel@tonic-gate 		/* check PIN */
85717c478bd9Sstevel@tonic-gate 		if (pin == NULL) {
85727c478bd9Sstevel@tonic-gate 			error = CRYPTO_PIN_INVALID;
85737c478bd9Sstevel@tonic-gate 			break;
85747c478bd9Sstevel@tonic-gate 		}
85757c478bd9Sstevel@tonic-gate 
85767c478bd9Sstevel@tonic-gate 		/*
85777c478bd9Sstevel@tonic-gate 		 * If the token has already been initialized, need
85787c478bd9Sstevel@tonic-gate 		 * to validate supplied PIN.
85797c478bd9Sstevel@tonic-gate 		 */
85807c478bd9Sstevel@tonic-gate 		if (softc->ds_token_initialized &&
85817c478bd9Sstevel@tonic-gate 		    (softc->ds_so_pin_len != pin_len ||
85827c478bd9Sstevel@tonic-gate 		    strncmp(softc->ds_so_pin, pin, pin_len) != 0)) {
85837c478bd9Sstevel@tonic-gate 			/* invalid SO PIN */
85847c478bd9Sstevel@tonic-gate 			error = CRYPTO_PIN_INCORRECT;
85857c478bd9Sstevel@tonic-gate 			break;
85867c478bd9Sstevel@tonic-gate 		}
85877c478bd9Sstevel@tonic-gate 
85887c478bd9Sstevel@tonic-gate 		/* set label */
85897c478bd9Sstevel@tonic-gate 		bcopy(label, softc->ds_label, CRYPTO_EXT_SIZE_LABEL);
85907c478bd9Sstevel@tonic-gate 
85917c478bd9Sstevel@tonic-gate 		/* set new SO PIN, update state */
85927c478bd9Sstevel@tonic-gate 		bcopy(pin, softc->ds_so_pin, pin_len);
85937c478bd9Sstevel@tonic-gate 		softc->ds_so_pin_len = pin_len;
85947c478bd9Sstevel@tonic-gate 		softc->ds_token_initialized = B_TRUE;
85957c478bd9Sstevel@tonic-gate 		softc->ds_user_pin_set = B_FALSE;
85967c478bd9Sstevel@tonic-gate 
85977c478bd9Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
85987c478bd9Sstevel@tonic-gate 		break;
85997c478bd9Sstevel@tonic-gate 	}
86007c478bd9Sstevel@tonic-gate 	case DPROV_REQ_MGMT_INITPIN: {
86017c478bd9Sstevel@tonic-gate 		char *pin = taskq_req->dr_mgmt_req.mr_pin;
86027c478bd9Sstevel@tonic-gate 		size_t pin_len = taskq_req->dr_mgmt_req.mr_pin_len;
86037c478bd9Sstevel@tonic-gate 		crypto_session_id_t session_id =
86047c478bd9Sstevel@tonic-gate 		    taskq_req->dr_mgmt_req.mr_session_id;
86057c478bd9Sstevel@tonic-gate 
86067c478bd9Sstevel@tonic-gate 		/* check session id */
86077c478bd9Sstevel@tonic-gate 		if (softc->ds_sessions[session_id] == NULL) {
86087c478bd9Sstevel@tonic-gate 			error = CRYPTO_SESSION_HANDLE_INVALID;
86097c478bd9Sstevel@tonic-gate 			break;
86107c478bd9Sstevel@tonic-gate 		}
86117c478bd9Sstevel@tonic-gate 
86127c478bd9Sstevel@tonic-gate 		/* fail if not logged in as SO */
86137c478bd9Sstevel@tonic-gate 		if (softc->ds_sessions[session_id]->ds_state !=
86147c478bd9Sstevel@tonic-gate 		    DPROV_SESSION_STATE_SO) {
86157c478bd9Sstevel@tonic-gate 			error = CRYPTO_USER_NOT_LOGGED_IN;
86167c478bd9Sstevel@tonic-gate 			break;
86177c478bd9Sstevel@tonic-gate 		}
86187c478bd9Sstevel@tonic-gate 
86197c478bd9Sstevel@tonic-gate 		/* check PIN length */
86207c478bd9Sstevel@tonic-gate 		if (pin_len > DPROV_MAX_PIN_LEN) {
86217c478bd9Sstevel@tonic-gate 			error = CRYPTO_PIN_LEN_RANGE;
86227c478bd9Sstevel@tonic-gate 			break;
86237c478bd9Sstevel@tonic-gate 		}
86247c478bd9Sstevel@tonic-gate 
86257c478bd9Sstevel@tonic-gate 		/* check PIN */
86267c478bd9Sstevel@tonic-gate 		if (pin == NULL) {
86277c478bd9Sstevel@tonic-gate 			error = CRYPTO_PIN_INVALID;
86287c478bd9Sstevel@tonic-gate 			break;
86297c478bd9Sstevel@tonic-gate 		}
86307c478bd9Sstevel@tonic-gate 
86317c478bd9Sstevel@tonic-gate 		/* set new normal user PIN */
86327c478bd9Sstevel@tonic-gate 		bcopy(pin, softc->ds_user_pin, pin_len);
86337c478bd9Sstevel@tonic-gate 		softc->ds_user_pin_len = pin_len;
86347c478bd9Sstevel@tonic-gate 		softc->ds_user_pin_set = B_TRUE;
86357c478bd9Sstevel@tonic-gate 
86367c478bd9Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
86377c478bd9Sstevel@tonic-gate 		break;
86387c478bd9Sstevel@tonic-gate 	}
86397c478bd9Sstevel@tonic-gate 	case DPROV_REQ_MGMT_SETPIN: {
86407c478bd9Sstevel@tonic-gate 		char *new_pin = taskq_req->dr_mgmt_req.mr_pin;
86417c478bd9Sstevel@tonic-gate 		size_t new_pin_len = taskq_req->dr_mgmt_req.mr_pin_len;
86427c478bd9Sstevel@tonic-gate 		char *old_pin = taskq_req->dr_mgmt_req.mr_old_pin;
86437c478bd9Sstevel@tonic-gate 		size_t old_pin_len = taskq_req->dr_mgmt_req.mr_old_pin_len;
86447c478bd9Sstevel@tonic-gate 		crypto_session_id_t session_id =
86457c478bd9Sstevel@tonic-gate 		    taskq_req->dr_mgmt_req.mr_session_id;
86467c478bd9Sstevel@tonic-gate 
86477c478bd9Sstevel@tonic-gate 		/* check session id */
86487c478bd9Sstevel@tonic-gate 		if (softc->ds_sessions[session_id] == NULL) {
86497c478bd9Sstevel@tonic-gate 			error = CRYPTO_SESSION_HANDLE_INVALID;
86507c478bd9Sstevel@tonic-gate 			break;
86517c478bd9Sstevel@tonic-gate 		}
86527c478bd9Sstevel@tonic-gate 
86537c478bd9Sstevel@tonic-gate 		/* check PIN length */
86547c478bd9Sstevel@tonic-gate 		if (old_pin_len > DPROV_MAX_PIN_LEN ||
86557c478bd9Sstevel@tonic-gate 		    new_pin_len > DPROV_MAX_PIN_LEN) {
86567c478bd9Sstevel@tonic-gate 			error = CRYPTO_PIN_LEN_RANGE;
86577c478bd9Sstevel@tonic-gate 			break;
86587c478bd9Sstevel@tonic-gate 		}
86597c478bd9Sstevel@tonic-gate 
86607c478bd9Sstevel@tonic-gate 		/* check PIN */
86617c478bd9Sstevel@tonic-gate 		if (old_pin == NULL || new_pin == NULL) {
86627c478bd9Sstevel@tonic-gate 			error = CRYPTO_PIN_INVALID;
86637c478bd9Sstevel@tonic-gate 			break;
86647c478bd9Sstevel@tonic-gate 		}
86657c478bd9Sstevel@tonic-gate 
86667c478bd9Sstevel@tonic-gate 		/* check user PIN state */
86677c478bd9Sstevel@tonic-gate 		if (!softc->ds_user_pin_set) {
86687c478bd9Sstevel@tonic-gate 			error = CRYPTO_USER_PIN_NOT_INITIALIZED;
86697c478bd9Sstevel@tonic-gate 			break;
86707c478bd9Sstevel@tonic-gate 		}
86717c478bd9Sstevel@tonic-gate 
86727c478bd9Sstevel@tonic-gate 		/*
86737c478bd9Sstevel@tonic-gate 		 * If the token has already been initialized, need
86747c478bd9Sstevel@tonic-gate 		 * to validate supplied PIN.
86757c478bd9Sstevel@tonic-gate 		 */
86767c478bd9Sstevel@tonic-gate 		if (softc->ds_user_pin_len != old_pin_len ||
86777c478bd9Sstevel@tonic-gate 		    strncmp(softc->ds_user_pin, old_pin, old_pin_len) != 0) {
86787c478bd9Sstevel@tonic-gate 			/* invalid SO PIN */
86797c478bd9Sstevel@tonic-gate 			error = CRYPTO_PIN_INCORRECT;
86807c478bd9Sstevel@tonic-gate 			break;
86817c478bd9Sstevel@tonic-gate 		}
86827c478bd9Sstevel@tonic-gate 
86837c478bd9Sstevel@tonic-gate 		/* set new PIN */
86847c478bd9Sstevel@tonic-gate 		bcopy(new_pin, softc->ds_user_pin, new_pin_len);
86857c478bd9Sstevel@tonic-gate 		softc->ds_user_pin_len = new_pin_len;
86867c478bd9Sstevel@tonic-gate 
86877c478bd9Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
86887c478bd9Sstevel@tonic-gate 		break;
86897c478bd9Sstevel@tonic-gate 	}
86907c478bd9Sstevel@tonic-gate 	}
86917c478bd9Sstevel@tonic-gate 
86927c478bd9Sstevel@tonic-gate 	mutex_exit(&softc->ds_lock);
86937c478bd9Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
86947c478bd9Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_mgmt_task: end\n", instance));
86957c478bd9Sstevel@tonic-gate }
86967c478bd9Sstevel@tonic-gate 
86977c478bd9Sstevel@tonic-gate /*
86987c478bd9Sstevel@tonic-gate  * Returns in the location pointed to by pd a pointer to the descriptor
86997c478bd9Sstevel@tonic-gate  * for the software provider for the specified mechanism.
87007c478bd9Sstevel@tonic-gate  * The provider descriptor is returned held. Returns one of the CRYPTO_
87017c478bd9Sstevel@tonic-gate  * error codes on failure, CRYPTO_SUCCESS on success.
87027c478bd9Sstevel@tonic-gate  */
87037c478bd9Sstevel@tonic-gate static int
87047c478bd9Sstevel@tonic-gate dprov_get_sw_prov(crypto_mechanism_t *mech, kcf_provider_desc_t **pd,
87057c478bd9Sstevel@tonic-gate     crypto_mech_type_t *provider_mech_type)
87067c478bd9Sstevel@tonic-gate {
87077c478bd9Sstevel@tonic-gate 	crypto_mech_type_t kcf_mech_type = CRYPTO_MECH_INVALID;
87087c478bd9Sstevel@tonic-gate 	int i, rv;
87097c478bd9Sstevel@tonic-gate 
87107c478bd9Sstevel@tonic-gate 	/* lookup the KCF mech type associated with our mech type */
87117c478bd9Sstevel@tonic-gate 	for (i = 0; i < sizeof (dprov_mech_info_tab)/
87127c478bd9Sstevel@tonic-gate 	    sizeof (crypto_mech_info_t); i++) {
87137c478bd9Sstevel@tonic-gate 		if (mech->cm_type == dprov_mech_info_tab[i].cm_mech_number) {
87147c478bd9Sstevel@tonic-gate 			kcf_mech_type = crypto_mech2id_common(
87157c478bd9Sstevel@tonic-gate 			    dprov_mech_info_tab[i].cm_mech_name, B_TRUE);
87167c478bd9Sstevel@tonic-gate 		}
87177c478bd9Sstevel@tonic-gate 	}
87187c478bd9Sstevel@tonic-gate 
87196a1073f8Skrishna 	rv = kcf_get_sw_prov(kcf_mech_type, pd, NULL, B_TRUE);
87207c478bd9Sstevel@tonic-gate 	if (rv == CRYPTO_SUCCESS)
87217c478bd9Sstevel@tonic-gate 		*provider_mech_type = kcf_mech_type;
87227c478bd9Sstevel@tonic-gate 
87237c478bd9Sstevel@tonic-gate 	return (rv);
87247c478bd9Sstevel@tonic-gate }
87257c478bd9Sstevel@tonic-gate 
87267c478bd9Sstevel@tonic-gate /*
87277c478bd9Sstevel@tonic-gate  * Object management helper functions.
87287c478bd9Sstevel@tonic-gate  */
87297c478bd9Sstevel@tonic-gate 
87307c478bd9Sstevel@tonic-gate /*
87317c478bd9Sstevel@tonic-gate  * Given a crypto_key_t, return whether the key can be used or not
87327c478bd9Sstevel@tonic-gate  * for the specified request. The attributes used here are defined
87337c478bd9Sstevel@tonic-gate  * in table 42 of the PKCS#11 spec (Common secret key attributes).
87347c478bd9Sstevel@tonic-gate  */
87357c478bd9Sstevel@tonic-gate static int
87367c478bd9Sstevel@tonic-gate dprov_key_can_use(dprov_object_t *object, dprov_req_type_t req_type)
87377c478bd9Sstevel@tonic-gate {
87387c478bd9Sstevel@tonic-gate 	boolean_t ret = 0;
87397c478bd9Sstevel@tonic-gate 	int rv = CRYPTO_SUCCESS;
87407c478bd9Sstevel@tonic-gate 
87417c478bd9Sstevel@tonic-gate 	/* check if object is allowed for specified operation */
87427c478bd9Sstevel@tonic-gate 	switch (req_type) {
87437c478bd9Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_INIT:
87447c478bd9Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_ATOMIC:
87457c478bd9Sstevel@tonic-gate 		rv = dprov_get_object_attr_boolean(object,
87467c478bd9Sstevel@tonic-gate 		    DPROV_CKA_ENCRYPT, &ret);
87477c478bd9Sstevel@tonic-gate 		break;
87487c478bd9Sstevel@tonic-gate 	case DPROV_REQ_DECRYPT_INIT:
87497c478bd9Sstevel@tonic-gate 	case DPROV_REQ_DECRYPT_ATOMIC:
87507c478bd9Sstevel@tonic-gate 		rv = dprov_get_object_attr_boolean(object,
87517c478bd9Sstevel@tonic-gate 		    DPROV_CKA_DECRYPT, &ret);
87527c478bd9Sstevel@tonic-gate 		break;
87537c478bd9Sstevel@tonic-gate 	case DPROV_REQ_SIGN_INIT:
87547c478bd9Sstevel@tonic-gate 	case DPROV_REQ_SIGN_ATOMIC:
87557c478bd9Sstevel@tonic-gate 	case DPROV_REQ_MAC_INIT:
87567c478bd9Sstevel@tonic-gate 	case DPROV_REQ_MAC_ATOMIC:
8757894b2776Smcpowers 	case DPROV_REQ_MAC_VERIFY_ATOMIC:
87587c478bd9Sstevel@tonic-gate 		rv = dprov_get_object_attr_boolean(object,
87597c478bd9Sstevel@tonic-gate 		    DPROV_CKA_SIGN, &ret);
87607c478bd9Sstevel@tonic-gate 		break;
87617c478bd9Sstevel@tonic-gate 	case DPROV_REQ_SIGN_RECOVER_INIT:
87627c478bd9Sstevel@tonic-gate 	case DPROV_REQ_SIGN_RECOVER_ATOMIC:
87637c478bd9Sstevel@tonic-gate 		rv = dprov_get_object_attr_boolean(object,
87647c478bd9Sstevel@tonic-gate 		    DPROV_CKA_SIGN_RECOVER, &ret);
87657c478bd9Sstevel@tonic-gate 		break;
87667c478bd9Sstevel@tonic-gate 	case DPROV_REQ_VERIFY_INIT:
87677c478bd9Sstevel@tonic-gate 	case DPROV_REQ_VERIFY_ATOMIC:
87687c478bd9Sstevel@tonic-gate 		rv = dprov_get_object_attr_boolean(object,
87697c478bd9Sstevel@tonic-gate 		    DPROV_CKA_VERIFY, &ret);
87707c478bd9Sstevel@tonic-gate 		break;
87717c478bd9Sstevel@tonic-gate 	case DPROV_REQ_VERIFY_RECOVER_INIT:
87727c478bd9Sstevel@tonic-gate 	case DPROV_REQ_VERIFY_RECOVER_ATOMIC:
87737c478bd9Sstevel@tonic-gate 		rv = dprov_get_object_attr_boolean(object,
87747c478bd9Sstevel@tonic-gate 		    DPROV_CKA_VERIFY_RECOVER, &ret);
87757c478bd9Sstevel@tonic-gate 		break;
87767c478bd9Sstevel@tonic-gate 	case DPROV_REQ_KEY_WRAP:
87777c478bd9Sstevel@tonic-gate 		rv = dprov_get_object_attr_boolean(object,
87787c478bd9Sstevel@tonic-gate 		    DPROV_CKA_WRAP, &ret);
87797c478bd9Sstevel@tonic-gate 		break;
87807c478bd9Sstevel@tonic-gate 	case DPROV_REQ_KEY_UNWRAP:
87817c478bd9Sstevel@tonic-gate 		rv = dprov_get_object_attr_boolean(object,
87827c478bd9Sstevel@tonic-gate 		    DPROV_CKA_UNWRAP, &ret);
87837c478bd9Sstevel@tonic-gate 		break;
87847c478bd9Sstevel@tonic-gate 	case DPROV_REQ_DIGEST_KEY:
87857c478bd9Sstevel@tonic-gate 		/*
87867c478bd9Sstevel@tonic-gate 		 * There is no attribute to check for; therefore,
87877c478bd9Sstevel@tonic-gate 		 * any secret key can be used.
87887c478bd9Sstevel@tonic-gate 		 */
87897c478bd9Sstevel@tonic-gate 		ret = B_TRUE;
87907c478bd9Sstevel@tonic-gate 		rv = CRYPTO_SUCCESS;
87917c478bd9Sstevel@tonic-gate 		break;
87927c478bd9Sstevel@tonic-gate 	case DPROV_REQ_KEY_DERIVE:
87937c478bd9Sstevel@tonic-gate 		rv = dprov_get_object_attr_boolean(object,
87947c478bd9Sstevel@tonic-gate 		    DPROV_CKA_DERIVE, &ret);
87957c478bd9Sstevel@tonic-gate 		break;
87967c478bd9Sstevel@tonic-gate 	}
87977c478bd9Sstevel@tonic-gate 
87987c478bd9Sstevel@tonic-gate 	if (rv != CRYPTO_SUCCESS || !ret)
87997c478bd9Sstevel@tonic-gate 		return (CRYPTO_KEY_FUNCTION_NOT_PERMITTED);
88007c478bd9Sstevel@tonic-gate 
88017c478bd9Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
88027c478bd9Sstevel@tonic-gate }
88037c478bd9Sstevel@tonic-gate 
88047c478bd9Sstevel@tonic-gate /*
88057c478bd9Sstevel@tonic-gate  * Given a crypto_key_t corresponding to a secret key (i.e. for
88067c478bd9Sstevel@tonic-gate  * use with symmetric crypto algorithms) specified in raw format, by
88077c478bd9Sstevel@tonic-gate  * attribute, or by reference, initialize the ck_data and ck_length
88087c478bd9Sstevel@tonic-gate  * fields of the ret_key argument so that they specify the key value
88097c478bd9Sstevel@tonic-gate  * and length.
88107c478bd9Sstevel@tonic-gate  *
88117c478bd9Sstevel@tonic-gate  * For a key by value, this function uess the ck_data and ck_length,
88127c478bd9Sstevel@tonic-gate  * for a key by reference, it looks up the corresponding object and
88137c478bd9Sstevel@tonic-gate  * returns the appropriate attribute. For a key by attribute, it returns
88147c478bd9Sstevel@tonic-gate  * the appropriate attribute. The attributes used are CKA_VALUE to retrieve
88157c478bd9Sstevel@tonic-gate  * the value of the key, and CKA_VALUE_LEN to retrieve its length in bytes.
88167c478bd9Sstevel@tonic-gate  */
88177c478bd9Sstevel@tonic-gate static int
88187c478bd9Sstevel@tonic-gate dprov_key_value_secret(dprov_state_t *softc, crypto_session_id_t session_id,
88197c478bd9Sstevel@tonic-gate     dprov_req_type_t req_type, crypto_key_t *key, crypto_key_t *ret_key)
88207c478bd9Sstevel@tonic-gate {
88217c478bd9Sstevel@tonic-gate 	ulong_t key_type;
88227c478bd9Sstevel@tonic-gate 	int ret = CRYPTO_SUCCESS;
88237c478bd9Sstevel@tonic-gate 
88247c478bd9Sstevel@tonic-gate 	ret_key->ck_format = CRYPTO_KEY_RAW;
88257c478bd9Sstevel@tonic-gate 
88267c478bd9Sstevel@tonic-gate 	switch (key->ck_format) {
88277c478bd9Sstevel@tonic-gate 
88287c478bd9Sstevel@tonic-gate 	case CRYPTO_KEY_RAW:
88297c478bd9Sstevel@tonic-gate 		ret_key->ck_data = key->ck_data;
88307c478bd9Sstevel@tonic-gate 		ret_key->ck_length = key->ck_length;
88317c478bd9Sstevel@tonic-gate 		break;
88327c478bd9Sstevel@tonic-gate 
88337c478bd9Sstevel@tonic-gate 	case CRYPTO_KEY_ATTR_LIST: {
88347c478bd9Sstevel@tonic-gate 		void *value;
88357c478bd9Sstevel@tonic-gate 		size_t len, value_len;
88367c478bd9Sstevel@tonic-gate 
88377c478bd9Sstevel@tonic-gate 		if ((ret = dprov_get_key_attr_ulong(key, DPROV_CKA_KEY_TYPE,
88387c478bd9Sstevel@tonic-gate 		    &key_type)) != CRYPTO_SUCCESS)
88397c478bd9Sstevel@tonic-gate 			break;
88407c478bd9Sstevel@tonic-gate 
88417c478bd9Sstevel@tonic-gate 		if ((ret = dprov_get_key_attr_array(key, DPROV_CKA_VALUE,
88427c478bd9Sstevel@tonic-gate 		    &value, &len)) != CRYPTO_SUCCESS)
88437c478bd9Sstevel@tonic-gate 			break;
88447c478bd9Sstevel@tonic-gate 
88457c478bd9Sstevel@tonic-gate 		/*
88467c478bd9Sstevel@tonic-gate 		 * The length of the array is expressed in bytes.
88477c478bd9Sstevel@tonic-gate 		 * Convert to bits now since that's how keys are measured.
88487c478bd9Sstevel@tonic-gate 		 */
884995014fbbSDan OpenSolaris Anderson 		len  = CRYPTO_BYTES2BITS(len);
88507c478bd9Sstevel@tonic-gate 
88517c478bd9Sstevel@tonic-gate 		/* optional */
88527c478bd9Sstevel@tonic-gate 		if ((dprov_get_key_attr_ulong(key, DPROV_CKA_VALUE_LEN,
88537c478bd9Sstevel@tonic-gate 		    &value_len)) == CRYPTO_SUCCESS) {
88547c478bd9Sstevel@tonic-gate 			len = value_len;
88557c478bd9Sstevel@tonic-gate 		}
88567c478bd9Sstevel@tonic-gate 
88577c478bd9Sstevel@tonic-gate 		ret_key->ck_data = value;
88587c478bd9Sstevel@tonic-gate 		ret_key->ck_length = (uint_t)len;
88597c478bd9Sstevel@tonic-gate 
88607c478bd9Sstevel@tonic-gate 		break;
88617c478bd9Sstevel@tonic-gate 	}
88627c478bd9Sstevel@tonic-gate 
88637c478bd9Sstevel@tonic-gate 	case CRYPTO_KEY_REFERENCE: {
88647c478bd9Sstevel@tonic-gate 		dprov_object_t *object;
88657c478bd9Sstevel@tonic-gate 		void *value;
88667c478bd9Sstevel@tonic-gate 		size_t len, value_len;
88677c478bd9Sstevel@tonic-gate 
88687c478bd9Sstevel@tonic-gate 		/* check session id */
88697c478bd9Sstevel@tonic-gate 		if (softc->ds_sessions[session_id] == NULL) {
88707c478bd9Sstevel@tonic-gate 			ret = CRYPTO_SESSION_HANDLE_INVALID;
88717c478bd9Sstevel@tonic-gate 			break;
88727c478bd9Sstevel@tonic-gate 		}
88737c478bd9Sstevel@tonic-gate 
88747c478bd9Sstevel@tonic-gate 		if (key->ck_obj_id >= DPROV_MAX_OBJECTS) {
88757c478bd9Sstevel@tonic-gate 			ret = CRYPTO_KEY_HANDLE_INVALID;
88767c478bd9Sstevel@tonic-gate 			goto bail;
88777c478bd9Sstevel@tonic-gate 		}
88787c478bd9Sstevel@tonic-gate 
88797c478bd9Sstevel@tonic-gate 		/* check if object id specified by key is valid */
88807c478bd9Sstevel@tonic-gate 		object = softc->ds_sessions[session_id]->
88817c478bd9Sstevel@tonic-gate 		    ds_objects[key->ck_obj_id];
88827c478bd9Sstevel@tonic-gate 		if (object == NULL) {
88837c478bd9Sstevel@tonic-gate 			ret = CRYPTO_KEY_HANDLE_INVALID;
88847c478bd9Sstevel@tonic-gate 			goto bail;
88857c478bd9Sstevel@tonic-gate 		}
88867c478bd9Sstevel@tonic-gate 
88877c478bd9Sstevel@tonic-gate 		/* check if object can be used for operation */
88887c478bd9Sstevel@tonic-gate 		if ((ret = dprov_key_can_use(object, req_type)) !=
88897c478bd9Sstevel@tonic-gate 		    CRYPTO_SUCCESS)
88907c478bd9Sstevel@tonic-gate 			goto bail;
88917c478bd9Sstevel@tonic-gate 
88927c478bd9Sstevel@tonic-gate 		if ((ret = dprov_get_object_attr_ulong(object,
88937c478bd9Sstevel@tonic-gate 		    DPROV_CKA_KEY_TYPE, &key_type)) != CRYPTO_SUCCESS)
88947c478bd9Sstevel@tonic-gate 			goto bail;
88957c478bd9Sstevel@tonic-gate 
88967c478bd9Sstevel@tonic-gate 		if ((ret = dprov_get_object_attr_array(object,
88977c478bd9Sstevel@tonic-gate 		    DPROV_CKA_VALUE, &value, &len)) != CRYPTO_SUCCESS)
88987c478bd9Sstevel@tonic-gate 			goto bail;
88997c478bd9Sstevel@tonic-gate 
89007c478bd9Sstevel@tonic-gate 		/* optional */
89017c478bd9Sstevel@tonic-gate 		if ((dprov_get_object_attr_ulong(object, DPROV_CKA_VALUE_LEN,
89027c478bd9Sstevel@tonic-gate 		    &value_len)) == CRYPTO_SUCCESS) {
89037c478bd9Sstevel@tonic-gate 			len = value_len;
89047c478bd9Sstevel@tonic-gate 		}
89057c478bd9Sstevel@tonic-gate 
89067c478bd9Sstevel@tonic-gate 		/*
89077c478bd9Sstevel@tonic-gate 		 * The length of attributes are in bytes.
89087c478bd9Sstevel@tonic-gate 		 * Convert to bits now since that's how keys are measured.
89097c478bd9Sstevel@tonic-gate 		 */
891095014fbbSDan OpenSolaris Anderson 		len  = CRYPTO_BYTES2BITS(len);
89117c478bd9Sstevel@tonic-gate 
89127c478bd9Sstevel@tonic-gate 		ret_key->ck_data = value;
89137c478bd9Sstevel@tonic-gate 		ret_key->ck_length = (uint_t)len;
89147c478bd9Sstevel@tonic-gate bail:
89157c478bd9Sstevel@tonic-gate 		break;
89167c478bd9Sstevel@tonic-gate 	}
89177c478bd9Sstevel@tonic-gate 
89187c478bd9Sstevel@tonic-gate 	default:
89197c478bd9Sstevel@tonic-gate 		ret = CRYPTO_ARGUMENTS_BAD;
89207c478bd9Sstevel@tonic-gate 		break;
89217c478bd9Sstevel@tonic-gate 	}
89227c478bd9Sstevel@tonic-gate 
89237c478bd9Sstevel@tonic-gate 	return (ret);
89247c478bd9Sstevel@tonic-gate }
89257c478bd9Sstevel@tonic-gate 
89267c478bd9Sstevel@tonic-gate /*
89277c478bd9Sstevel@tonic-gate  * Get the attribute list for the specified asymmetric key.
89287c478bd9Sstevel@tonic-gate  */
89297c478bd9Sstevel@tonic-gate static int
89307c478bd9Sstevel@tonic-gate dprov_key_attr_asymmetric(dprov_state_t *softc, crypto_session_id_t session_id,
89317c478bd9Sstevel@tonic-gate     dprov_req_type_t req_type, crypto_key_t *key, crypto_key_t *ret_key)
89327c478bd9Sstevel@tonic-gate {
89337c478bd9Sstevel@tonic-gate 	int ret = CRYPTO_SUCCESS;
89347c478bd9Sstevel@tonic-gate 
89357c478bd9Sstevel@tonic-gate 	ret_key->ck_format = CRYPTO_KEY_ATTR_LIST;
89367c478bd9Sstevel@tonic-gate 
89377c478bd9Sstevel@tonic-gate 	switch (key->ck_format) {
89387c478bd9Sstevel@tonic-gate 
89397c478bd9Sstevel@tonic-gate 	case CRYPTO_KEY_ATTR_LIST:
89407c478bd9Sstevel@tonic-gate 		ret_key->ck_attrs = key->ck_attrs;
89417c478bd9Sstevel@tonic-gate 		ret_key->ck_count = key->ck_count;
89427c478bd9Sstevel@tonic-gate 		break;
89437c478bd9Sstevel@tonic-gate 
89447c478bd9Sstevel@tonic-gate 	case CRYPTO_KEY_REFERENCE: {
89457c478bd9Sstevel@tonic-gate 		dprov_object_t *object;
89467c478bd9Sstevel@tonic-gate 
89477c478bd9Sstevel@tonic-gate 		/* check session id */
89487c478bd9Sstevel@tonic-gate 		if (softc->ds_sessions[session_id] == NULL) {
89497c478bd9Sstevel@tonic-gate 			ret = CRYPTO_SESSION_HANDLE_INVALID;
89507c478bd9Sstevel@tonic-gate 			break;
89517c478bd9Sstevel@tonic-gate 		}
89527c478bd9Sstevel@tonic-gate 
89537c478bd9Sstevel@tonic-gate 		/* check if object id specified by key is valid */
89547c478bd9Sstevel@tonic-gate 		object = softc->ds_sessions[session_id]->
89557c478bd9Sstevel@tonic-gate 		    ds_objects[key->ck_obj_id];
89567c478bd9Sstevel@tonic-gate 		if (object == NULL) {
89577c478bd9Sstevel@tonic-gate 			ret = CRYPTO_KEY_HANDLE_INVALID;
89587c478bd9Sstevel@tonic-gate 			break;
89597c478bd9Sstevel@tonic-gate 		}
89607c478bd9Sstevel@tonic-gate 
89617c478bd9Sstevel@tonic-gate 		/* check if object can be used for operation */
89627c478bd9Sstevel@tonic-gate 		if ((ret = dprov_key_can_use(object, req_type)) !=
89637c478bd9Sstevel@tonic-gate 		    CRYPTO_SUCCESS)
89647c478bd9Sstevel@tonic-gate 			break;
89657c478bd9Sstevel@tonic-gate 
89667c478bd9Sstevel@tonic-gate 		ret_key->ck_attrs = object->do_attr;
89677c478bd9Sstevel@tonic-gate 		ret_key->ck_count = DPROV_MAX_ATTR;
89687c478bd9Sstevel@tonic-gate 		break;
89697c478bd9Sstevel@tonic-gate 	}
89707c478bd9Sstevel@tonic-gate 
89717c478bd9Sstevel@tonic-gate 	default:
89727c478bd9Sstevel@tonic-gate 		ret = CRYPTO_ARGUMENTS_BAD;
89737c478bd9Sstevel@tonic-gate 	}
89747c478bd9Sstevel@tonic-gate 
89757c478bd9Sstevel@tonic-gate 	return (ret);
89767c478bd9Sstevel@tonic-gate }
89777c478bd9Sstevel@tonic-gate 
89787c478bd9Sstevel@tonic-gate /*
89797c478bd9Sstevel@tonic-gate  * Return the index of an attribute of specified type found in
89807c478bd9Sstevel@tonic-gate  * the specified array of attributes. If the attribute cannot
89817c478bd9Sstevel@tonic-gate  * found, return -1.
89827c478bd9Sstevel@tonic-gate  */
89837c478bd9Sstevel@tonic-gate static int
89847c478bd9Sstevel@tonic-gate dprov_find_attr(crypto_object_attribute_t *attr, uint_t nattr,
89857c478bd9Sstevel@tonic-gate     uint64_t attr_type)
89867c478bd9Sstevel@tonic-gate {
89877c478bd9Sstevel@tonic-gate 	int i;
89887c478bd9Sstevel@tonic-gate 
89897c478bd9Sstevel@tonic-gate 	for (i = 0; i < nattr; i++)
89907c478bd9Sstevel@tonic-gate 		if (attr[i].oa_value != NULL &&
89917c478bd9Sstevel@tonic-gate 		    attr[i].oa_type == attr_type)
89927c478bd9Sstevel@tonic-gate 			return (i);
89937c478bd9Sstevel@tonic-gate 
89947c478bd9Sstevel@tonic-gate 	return (-1);
89957c478bd9Sstevel@tonic-gate }
89967c478bd9Sstevel@tonic-gate 
89977c478bd9Sstevel@tonic-gate /*
89987c478bd9Sstevel@tonic-gate  * Given the given object template and session, return whether
89997c478bd9Sstevel@tonic-gate  * an object can be created from that template according to the
90007c478bd9Sstevel@tonic-gate  * following rules:
90017c478bd9Sstevel@tonic-gate  * - private objects can be created only by a logged-in user
90027c478bd9Sstevel@tonic-gate  */
90037c478bd9Sstevel@tonic-gate static int
90047c478bd9Sstevel@tonic-gate dprov_template_can_create(dprov_session_t *session,
90057c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *template, uint_t nattr,
90067c478bd9Sstevel@tonic-gate     boolean_t check_for_secret)
90077c478bd9Sstevel@tonic-gate {
90087c478bd9Sstevel@tonic-gate 	boolean_t is_private = B_FALSE;
90097c478bd9Sstevel@tonic-gate 	ulong_t key_type, class;
90107c478bd9Sstevel@tonic-gate 	int error;
90117c478bd9Sstevel@tonic-gate 
90127c478bd9Sstevel@tonic-gate 	/* check CKA_PRIVATE attribute value */
90137c478bd9Sstevel@tonic-gate 	error = dprov_get_template_attr_boolean(template, nattr,
90147c478bd9Sstevel@tonic-gate 	    DPROV_CKA_PRIVATE, &is_private);
90157c478bd9Sstevel@tonic-gate 	if (error == CRYPTO_SUCCESS && is_private) {
90167c478bd9Sstevel@tonic-gate 		/* it's a private object */
90177c478bd9Sstevel@tonic-gate 		if (session->ds_state != DPROV_SESSION_STATE_USER) {
90187c478bd9Sstevel@tonic-gate 			/*
90197c478bd9Sstevel@tonic-gate 			 * Cannot create private object with SO or public
90207c478bd9Sstevel@tonic-gate 			 * sessions.
90217c478bd9Sstevel@tonic-gate 			 */
90227c478bd9Sstevel@tonic-gate 			return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
90237c478bd9Sstevel@tonic-gate 		}
90247c478bd9Sstevel@tonic-gate 	}
90257c478bd9Sstevel@tonic-gate 
90267c478bd9Sstevel@tonic-gate 	/* all objects must have an object class attribute */
90277c478bd9Sstevel@tonic-gate 	if (dprov_get_template_attr_ulong(template, nattr, DPROV_CKA_CLASS,
90287c478bd9Sstevel@tonic-gate 	    &class) != CRYPTO_SUCCESS) {
90297c478bd9Sstevel@tonic-gate 		return (CRYPTO_TEMPLATE_INCOMPLETE);
90307c478bd9Sstevel@tonic-gate 	}
90317c478bd9Sstevel@tonic-gate 
90327c478bd9Sstevel@tonic-gate 	/* key objects must have a key type attribute */
90337c478bd9Sstevel@tonic-gate 	if (class == DPROV_CKO_SECRET_KEY ||
90347c478bd9Sstevel@tonic-gate 	    class == DPROV_CKO_PUBLIC_KEY ||
90357c478bd9Sstevel@tonic-gate 	    class == DPROV_CKO_PRIVATE_KEY) {
90367c478bd9Sstevel@tonic-gate 		if (!dprov_template_attr_present(template, nattr,
90377c478bd9Sstevel@tonic-gate 		    DPROV_CKA_KEY_TYPE)) {
90387c478bd9Sstevel@tonic-gate 			return (CRYPTO_TEMPLATE_INCOMPLETE);
90397c478bd9Sstevel@tonic-gate 		}
90407c478bd9Sstevel@tonic-gate 	}
90417c478bd9Sstevel@tonic-gate 
90427c478bd9Sstevel@tonic-gate 	/* check for RSA public key attributes that must be present */
90437c478bd9Sstevel@tonic-gate 	if (class == DPROV_CKO_PUBLIC_KEY) {
90447c478bd9Sstevel@tonic-gate 		if (dprov_get_template_attr_ulong(template, nattr,
90457c478bd9Sstevel@tonic-gate 		    DPROV_CKA_KEY_TYPE, &key_type) == CRYPTO_SUCCESS) {
90467c478bd9Sstevel@tonic-gate 			if (key_type == DPROV_CKK_RSA) {
90477c478bd9Sstevel@tonic-gate 				if (!dprov_template_attr_present(template,
90487c478bd9Sstevel@tonic-gate 				    nattr, DPROV_CKA_MODULUS) ||
90497c478bd9Sstevel@tonic-gate 				    !dprov_template_attr_present(template,
90507c478bd9Sstevel@tonic-gate 				    nattr, DPROV_CKA_PUBLIC_EXPONENT)) {
90517c478bd9Sstevel@tonic-gate 					return (CRYPTO_TEMPLATE_INCOMPLETE);
90527c478bd9Sstevel@tonic-gate 				}
90537c478bd9Sstevel@tonic-gate 
90547c478bd9Sstevel@tonic-gate 				/* these attributes should not be present */
90557c478bd9Sstevel@tonic-gate 				if (dprov_template_attr_present(template, nattr,
90567c478bd9Sstevel@tonic-gate 				    DPROV_CKA_MODULUS_BITS)) {
90577c478bd9Sstevel@tonic-gate 					return (CRYPTO_TEMPLATE_INCONSISTENT);
90587c478bd9Sstevel@tonic-gate 				}
90597c478bd9Sstevel@tonic-gate 			}
90607c478bd9Sstevel@tonic-gate 		}
90617c478bd9Sstevel@tonic-gate 	}
90627c478bd9Sstevel@tonic-gate 
90637c478bd9Sstevel@tonic-gate 	/* check for RSA private key attributes that must be present */
90647c478bd9Sstevel@tonic-gate 	if (class == DPROV_CKO_PRIVATE_KEY) {
90657c478bd9Sstevel@tonic-gate 		if (dprov_get_template_attr_ulong(template, nattr,
90667c478bd9Sstevel@tonic-gate 		    DPROV_CKA_KEY_TYPE, &key_type) == CRYPTO_SUCCESS) {
90677c478bd9Sstevel@tonic-gate 			if (key_type == DPROV_CKK_RSA) {
90687c478bd9Sstevel@tonic-gate 				if (!dprov_template_attr_present(template,
90697c478bd9Sstevel@tonic-gate 				    nattr, DPROV_CKA_MODULUS))
90707c478bd9Sstevel@tonic-gate 					return (CRYPTO_TEMPLATE_INCOMPLETE);
90717c478bd9Sstevel@tonic-gate 
90727c478bd9Sstevel@tonic-gate 				if (check_for_secret) {
90737c478bd9Sstevel@tonic-gate 					if (!dprov_template_attr_present(
90747c478bd9Sstevel@tonic-gate 					    template, nattr,
90757c478bd9Sstevel@tonic-gate 					    DPROV_CKA_PRIVATE_EXPONENT))
90767c478bd9Sstevel@tonic-gate 						return (
90777c478bd9Sstevel@tonic-gate 						    CRYPTO_TEMPLATE_INCOMPLETE);
90787c478bd9Sstevel@tonic-gate 				}
90797c478bd9Sstevel@tonic-gate 			}
90807c478bd9Sstevel@tonic-gate 		}
90817c478bd9Sstevel@tonic-gate 	}
90827c478bd9Sstevel@tonic-gate 
90837c478bd9Sstevel@tonic-gate 	/* check for secret key attributes that must be present */
90847c478bd9Sstevel@tonic-gate 	if (class == DPROV_CKO_SECRET_KEY) {
90857c478bd9Sstevel@tonic-gate 		if (check_for_secret) {
90867c478bd9Sstevel@tonic-gate 			if (!dprov_template_attr_present(template, nattr,
90877c478bd9Sstevel@tonic-gate 			    DPROV_CKA_VALUE)) {
90887c478bd9Sstevel@tonic-gate 				return (CRYPTO_TEMPLATE_INCOMPLETE);
90897c478bd9Sstevel@tonic-gate 			}
90907c478bd9Sstevel@tonic-gate 		}
90917c478bd9Sstevel@tonic-gate 
90927c478bd9Sstevel@tonic-gate 		/* these attributes should not be present */
90937c478bd9Sstevel@tonic-gate 		if (dprov_template_attr_present(template, nattr,
90947c478bd9Sstevel@tonic-gate 		    DPROV_CKA_VALUE_LEN)) {
90957c478bd9Sstevel@tonic-gate 			return (CRYPTO_TEMPLATE_INCONSISTENT);
90967c478bd9Sstevel@tonic-gate 		}
90977c478bd9Sstevel@tonic-gate 	}
90987c478bd9Sstevel@tonic-gate 
90997c478bd9Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
91007c478bd9Sstevel@tonic-gate }
91017c478bd9Sstevel@tonic-gate 
91027c478bd9Sstevel@tonic-gate /*
91037c478bd9Sstevel@tonic-gate  * Create an object from the specified template. Checks whether the
91047c478bd9Sstevel@tonic-gate  * object can be created according to its attributes and the state
91057c478bd9Sstevel@tonic-gate  * of the session. The new session object id is returned. If the
91067c478bd9Sstevel@tonic-gate  * object is a token object, it is added to the per-instance object
91077c478bd9Sstevel@tonic-gate  * table as well.
91087c478bd9Sstevel@tonic-gate  */
91097c478bd9Sstevel@tonic-gate static int
91107c478bd9Sstevel@tonic-gate dprov_create_object_from_template(dprov_state_t *softc,
91117c478bd9Sstevel@tonic-gate     dprov_session_t *session, crypto_object_attribute_t *template,
91127c478bd9Sstevel@tonic-gate     uint_t nattr, crypto_object_id_t *object_id, boolean_t check_for_secret,
91137c478bd9Sstevel@tonic-gate     boolean_t force)
91147c478bd9Sstevel@tonic-gate {
91157c478bd9Sstevel@tonic-gate 	dprov_object_t *object;
91167c478bd9Sstevel@tonic-gate 	boolean_t is_token = B_FALSE;
91177c478bd9Sstevel@tonic-gate 	boolean_t extractable_attribute_present = B_FALSE;
9118034448feSmcpowers 	boolean_t sensitive_attribute_present = B_FALSE;
91197c478bd9Sstevel@tonic-gate 	boolean_t private_attribute_present = B_FALSE;
9120034448feSmcpowers 	boolean_t token_attribute_present = B_FALSE;
91217c478bd9Sstevel@tonic-gate 	uint_t i;
91227c478bd9Sstevel@tonic-gate 	int error;
91237c478bd9Sstevel@tonic-gate 	uint_t attr;
91247c478bd9Sstevel@tonic-gate 	uint_t oattr;
9125894b2776Smcpowers 	crypto_attr_type_t type;
9126894b2776Smcpowers 	size_t old_len, new_len;
9127894b2776Smcpowers 	offset_t offset;
91287c478bd9Sstevel@tonic-gate 
91297c478bd9Sstevel@tonic-gate 	if (nattr > DPROV_MAX_ATTR)
91307c478bd9Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
91317c478bd9Sstevel@tonic-gate 
91327c478bd9Sstevel@tonic-gate 	if (!force) {
91337c478bd9Sstevel@tonic-gate 		/* verify that object can be created */
91347c478bd9Sstevel@tonic-gate 		if ((error = dprov_template_can_create(session, template,
91357c478bd9Sstevel@tonic-gate 		    nattr, check_for_secret)) != CRYPTO_SUCCESS)
91367c478bd9Sstevel@tonic-gate 			return (error);
91377c478bd9Sstevel@tonic-gate 	}
91387c478bd9Sstevel@tonic-gate 
91397c478bd9Sstevel@tonic-gate 	/* allocate new object */
91407c478bd9Sstevel@tonic-gate 	object = kmem_zalloc(sizeof (dprov_object_t), KM_SLEEP);
91417c478bd9Sstevel@tonic-gate 	if (object == NULL)
91427c478bd9Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
91437c478bd9Sstevel@tonic-gate 
91447c478bd9Sstevel@tonic-gate 	/* is it a token object? */
91457c478bd9Sstevel@tonic-gate 	/* check CKA_TOKEN attribute value */
91467c478bd9Sstevel@tonic-gate 	error = dprov_get_template_attr_boolean(template, nattr,
91477c478bd9Sstevel@tonic-gate 	    DPROV_CKA_TOKEN, &is_token);
91487c478bd9Sstevel@tonic-gate 	if (error == CRYPTO_SUCCESS && is_token) {
91497c478bd9Sstevel@tonic-gate 		/* token object, add it to the per-instance object table */
91507c478bd9Sstevel@tonic-gate 		for (i = 0; i < DPROV_MAX_OBJECTS; i++)
91517c478bd9Sstevel@tonic-gate 			if (softc->ds_objects[i] == NULL)
91527c478bd9Sstevel@tonic-gate 				break;
91537c478bd9Sstevel@tonic-gate 		if (i == DPROV_MAX_OBJECTS)
91547c478bd9Sstevel@tonic-gate 			/* no free slot */
91557c478bd9Sstevel@tonic-gate 			return (CRYPTO_HOST_MEMORY);
91567c478bd9Sstevel@tonic-gate 		softc->ds_objects[i] = object;
91577c478bd9Sstevel@tonic-gate 		object->do_token_idx = i;
91587c478bd9Sstevel@tonic-gate 		DPROV_OBJECT_REFHOLD(object);
91597c478bd9Sstevel@tonic-gate 	}
91607c478bd9Sstevel@tonic-gate 
91617c478bd9Sstevel@tonic-gate 	/* add object to session object table */
91627c478bd9Sstevel@tonic-gate 	for (i = 0; i < DPROV_MAX_OBJECTS; i++)
91637c478bd9Sstevel@tonic-gate 		if (session->ds_objects[i] == NULL)
91647c478bd9Sstevel@tonic-gate 			break;
91657c478bd9Sstevel@tonic-gate 	if (i == DPROV_MAX_OBJECTS) {
91667c478bd9Sstevel@tonic-gate 		/* no more session object slots */
91677c478bd9Sstevel@tonic-gate 		DPROV_OBJECT_REFRELE(object);
91687c478bd9Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
91697c478bd9Sstevel@tonic-gate 	}
91707c478bd9Sstevel@tonic-gate 	session->ds_objects[i] = object;
91717c478bd9Sstevel@tonic-gate 	DPROV_OBJECT_REFHOLD(object);
91727c478bd9Sstevel@tonic-gate 	*object_id = i;
91737c478bd9Sstevel@tonic-gate 
91747c478bd9Sstevel@tonic-gate 	/* initialize object from template */
91757c478bd9Sstevel@tonic-gate 	for (attr = 0, oattr = 0; attr < nattr; attr++) {
91767c478bd9Sstevel@tonic-gate 		if (template[attr].oa_value == NULL)
91777c478bd9Sstevel@tonic-gate 			continue;
9178894b2776Smcpowers 		type = template[attr].oa_type;
9179894b2776Smcpowers 		old_len = template[attr].oa_value_len;
9180894b2776Smcpowers 		new_len = attribute_size(type, old_len);
9181894b2776Smcpowers 
9182894b2776Smcpowers 		if (type == DPROV_CKA_EXTRACTABLE) {
91837c478bd9Sstevel@tonic-gate 			extractable_attribute_present = B_TRUE;
9184894b2776Smcpowers 		} else if (type == DPROV_CKA_PRIVATE) {
91857c478bd9Sstevel@tonic-gate 			private_attribute_present = B_TRUE;
9186034448feSmcpowers 		} else if (type == DPROV_CKA_TOKEN) {
9187034448feSmcpowers 			token_attribute_present = B_TRUE;
91887c478bd9Sstevel@tonic-gate 		}
9189894b2776Smcpowers 		object->do_attr[oattr].oa_type = type;
9190894b2776Smcpowers 		object->do_attr[oattr].oa_value_len = new_len;
91917c478bd9Sstevel@tonic-gate 
9192894b2776Smcpowers 		object->do_attr[oattr].oa_value = kmem_zalloc(new_len,
9193894b2776Smcpowers 		    KM_SLEEP);
9194894b2776Smcpowers 
9195894b2776Smcpowers 		offset = 0;
9196894b2776Smcpowers #ifdef _BIG_ENDIAN
9197894b2776Smcpowers 		if (fixed_size_attribute(type)) {
9198894b2776Smcpowers 			offset = old_len - new_len;
9199894b2776Smcpowers 		}
9200894b2776Smcpowers #endif
9201894b2776Smcpowers 		bcopy(&template[attr].oa_value[offset],
9202894b2776Smcpowers 		    object->do_attr[oattr].oa_value, new_len);
92037c478bd9Sstevel@tonic-gate 		oattr++;
92047c478bd9Sstevel@tonic-gate 	}
92057c478bd9Sstevel@tonic-gate 
92067c478bd9Sstevel@tonic-gate 	/* add boolean attributes that must be present */
92077c478bd9Sstevel@tonic-gate 	if (extractable_attribute_present == B_FALSE) {
92087c478bd9Sstevel@tonic-gate 		object->do_attr[oattr].oa_type = DPROV_CKA_EXTRACTABLE;
92097c478bd9Sstevel@tonic-gate 		object->do_attr[oattr].oa_value_len = 1;
92107c478bd9Sstevel@tonic-gate 		object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP);
92117c478bd9Sstevel@tonic-gate 		object->do_attr[oattr].oa_value[0] = B_TRUE;
92127c478bd9Sstevel@tonic-gate 		oattr++;
92137c478bd9Sstevel@tonic-gate 	}
92147c478bd9Sstevel@tonic-gate 
92157c478bd9Sstevel@tonic-gate 	if (private_attribute_present == B_FALSE) {
92167c478bd9Sstevel@tonic-gate 		object->do_attr[oattr].oa_type = DPROV_CKA_PRIVATE;
92177c478bd9Sstevel@tonic-gate 		object->do_attr[oattr].oa_value_len = 1;
92187c478bd9Sstevel@tonic-gate 		object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP);
92197c478bd9Sstevel@tonic-gate 		object->do_attr[oattr].oa_value[0] = B_FALSE;
92207c478bd9Sstevel@tonic-gate 		oattr++;
92217c478bd9Sstevel@tonic-gate 	}
92227c478bd9Sstevel@tonic-gate 
9223034448feSmcpowers 	if (token_attribute_present == B_FALSE) {
9224034448feSmcpowers 		object->do_attr[oattr].oa_type = DPROV_CKA_TOKEN;
9225034448feSmcpowers 		object->do_attr[oattr].oa_value_len = 1;
9226034448feSmcpowers 		object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP);
9227034448feSmcpowers 		object->do_attr[oattr].oa_value[0] = B_FALSE;
9228034448feSmcpowers 		oattr++;
9229034448feSmcpowers 	}
9230034448feSmcpowers 
9231034448feSmcpowers 	if (sensitive_attribute_present == B_FALSE) {
9232034448feSmcpowers 		object->do_attr[oattr].oa_type = DPROV_CKA_SENSITIVE;
9233034448feSmcpowers 		object->do_attr[oattr].oa_value_len = 1;
9234034448feSmcpowers 		object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP);
9235034448feSmcpowers 		object->do_attr[oattr].oa_value[0] = B_FALSE;
9236034448feSmcpowers 		oattr++;
9237034448feSmcpowers 	}
92387c478bd9Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
92397c478bd9Sstevel@tonic-gate }
92407c478bd9Sstevel@tonic-gate 
92417c478bd9Sstevel@tonic-gate /*
92427c478bd9Sstevel@tonic-gate  * Checks whether or not the object matches the specified attributes.
9243894b2776Smcpowers  *
9244894b2776Smcpowers  * PKCS#11 attributes which are longs are stored in uint32_t containers
9245894b2776Smcpowers  * so they can be matched by both 32 and 64-bit applications.
92467c478bd9Sstevel@tonic-gate  */
92477c478bd9Sstevel@tonic-gate static boolean_t
92487c478bd9Sstevel@tonic-gate dprov_attributes_match(dprov_object_t *object,
92497c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *template, uint_t nattr)
92507c478bd9Sstevel@tonic-gate {
9251894b2776Smcpowers 	crypto_attr_type_t type;
9252894b2776Smcpowers 	size_t tlen, olen, diff;
92537c478bd9Sstevel@tonic-gate 	int ta_idx;	/* template attribute index */
92547c478bd9Sstevel@tonic-gate 	int oa_idx;	/* object attribute index */
92557c478bd9Sstevel@tonic-gate 
92567c478bd9Sstevel@tonic-gate 	for (ta_idx = 0; ta_idx < nattr; ta_idx++) {
92577c478bd9Sstevel@tonic-gate 		/* no value for template attribute */
92587c478bd9Sstevel@tonic-gate 		if (template[ta_idx].oa_value == NULL)
92597c478bd9Sstevel@tonic-gate 			continue;
92607c478bd9Sstevel@tonic-gate 
92617c478bd9Sstevel@tonic-gate 		/* find attribute in object */
9262894b2776Smcpowers 		type = template[ta_idx].oa_type;
9263894b2776Smcpowers 		oa_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR, type);
92647c478bd9Sstevel@tonic-gate 
92657c478bd9Sstevel@tonic-gate 		if (oa_idx == -1)
92667c478bd9Sstevel@tonic-gate 			/* attribute not found in object */
92677c478bd9Sstevel@tonic-gate 			return (B_FALSE);
92687c478bd9Sstevel@tonic-gate 
9269894b2776Smcpowers 		tlen = template[ta_idx].oa_value_len;
9270894b2776Smcpowers 		olen = object->do_attr[oa_idx].oa_value_len;
9271894b2776Smcpowers 		if (tlen < olen)
92727c478bd9Sstevel@tonic-gate 			return (B_FALSE);
92737c478bd9Sstevel@tonic-gate 
9274894b2776Smcpowers 		diff = 0;
9275894b2776Smcpowers #ifdef _BIG_ENDIAN
9276894b2776Smcpowers 		/* application may think attribute is 8 bytes */
9277894b2776Smcpowers 		if (fixed_size_attribute(type))
9278894b2776Smcpowers 			diff = tlen - olen;
9279894b2776Smcpowers #endif
9280894b2776Smcpowers 
9281894b2776Smcpowers 		if (bcmp(&template[ta_idx].oa_value[diff],
9282894b2776Smcpowers 		    object->do_attr[oa_idx].oa_value, olen) != 0)
92837c478bd9Sstevel@tonic-gate 			/* value mismatch */
92847c478bd9Sstevel@tonic-gate 			return (B_FALSE);
92857c478bd9Sstevel@tonic-gate 	}
92867c478bd9Sstevel@tonic-gate 
92877c478bd9Sstevel@tonic-gate 	return (B_TRUE);
92887c478bd9Sstevel@tonic-gate }
92897c478bd9Sstevel@tonic-gate 
92907c478bd9Sstevel@tonic-gate /*
92917c478bd9Sstevel@tonic-gate  * Destroy the object specified by its session and object id.
92927c478bd9Sstevel@tonic-gate  */
92937c478bd9Sstevel@tonic-gate static int
92947c478bd9Sstevel@tonic-gate dprov_destroy_object(dprov_state_t *softc, dprov_session_t *session,
92957c478bd9Sstevel@tonic-gate     crypto_object_id_t object_id)
92967c478bd9Sstevel@tonic-gate {
92977c478bd9Sstevel@tonic-gate 	dprov_object_t *object;
92987c478bd9Sstevel@tonic-gate 
92997c478bd9Sstevel@tonic-gate 	if ((object = session->ds_objects[object_id]) == NULL)
93007c478bd9Sstevel@tonic-gate 		return (CRYPTO_OBJECT_HANDLE_INVALID);
93017c478bd9Sstevel@tonic-gate 
93027c478bd9Sstevel@tonic-gate 	/* remove from session table */
93037c478bd9Sstevel@tonic-gate 	session->ds_objects[object_id] = NULL;
93041c02caffSmcpowers 
93051c02caffSmcpowers 	if (dprov_object_is_token(object)) {
93061c02caffSmcpowers 		if (!object->do_destroyed) {
93071c02caffSmcpowers 			object->do_destroyed = B_TRUE;
93081c02caffSmcpowers 			/* remove from per-instance token table */
93091c02caffSmcpowers 			softc->ds_objects[object->do_token_idx] = NULL;
93101c02caffSmcpowers 			DPROV_OBJECT_REFRELE(object);
93111c02caffSmcpowers 		} else {
93121c02caffSmcpowers 			DPROV_DEBUG(D_OBJECT, ("dprov_destroy_object: "
93131c02caffSmcpowers 			    "object %p already destroyed\n", (void *)object));
93141c02caffSmcpowers 		}
93151c02caffSmcpowers 	}
93161c02caffSmcpowers 
93177c478bd9Sstevel@tonic-gate 	DPROV_OBJECT_REFRELE(object);
93187c478bd9Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
93197c478bd9Sstevel@tonic-gate }
93207c478bd9Sstevel@tonic-gate 
93217c478bd9Sstevel@tonic-gate static int
93227c478bd9Sstevel@tonic-gate dprov_object_can_modify(dprov_object_t *object,
93237c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *template, uint_t nattr)
93247c478bd9Sstevel@tonic-gate {
93257c478bd9Sstevel@tonic-gate 	ulong_t object_class;
93267c478bd9Sstevel@tonic-gate 
93277c478bd9Sstevel@tonic-gate 	/* all objects should have an object class attribute */
93287c478bd9Sstevel@tonic-gate 	if (dprov_get_object_attr_ulong(object, DPROV_CKA_CLASS,
93297c478bd9Sstevel@tonic-gate 	    &object_class) != CRYPTO_SUCCESS) {
93307c478bd9Sstevel@tonic-gate 		return (CRYPTO_SUCCESS);
93317c478bd9Sstevel@tonic-gate 	}
93327c478bd9Sstevel@tonic-gate 
93337c478bd9Sstevel@tonic-gate 	if (object_class == DPROV_CKO_SECRET_KEY ||
93347c478bd9Sstevel@tonic-gate 	    object_class == DPROV_CKO_PUBLIC_KEY ||
93357c478bd9Sstevel@tonic-gate 	    object_class == DPROV_CKO_PRIVATE_KEY) {
93367c478bd9Sstevel@tonic-gate 		if (dprov_template_attr_present(template, nattr,
93377c478bd9Sstevel@tonic-gate 		    DPROV_CKA_CLASS) ||
93387c478bd9Sstevel@tonic-gate 		    dprov_template_attr_present(template, nattr,
93397c478bd9Sstevel@tonic-gate 		    DPROV_CKA_KEY_TYPE))
93407c478bd9Sstevel@tonic-gate 			return (CRYPTO_TEMPLATE_INCONSISTENT);
93417c478bd9Sstevel@tonic-gate 	}
93427c478bd9Sstevel@tonic-gate 
93437c478bd9Sstevel@tonic-gate 	switch (object_class) {
93447c478bd9Sstevel@tonic-gate 	case DPROV_CKO_SECRET_KEY:
93457c478bd9Sstevel@tonic-gate 		if (dprov_template_attr_present(template, nattr,
93467c478bd9Sstevel@tonic-gate 		    DPROV_CKA_VALUE))
93477c478bd9Sstevel@tonic-gate 			return (CRYPTO_TEMPLATE_INCONSISTENT);
93487c478bd9Sstevel@tonic-gate 		break;
93497c478bd9Sstevel@tonic-gate 
93507c478bd9Sstevel@tonic-gate 	case DPROV_CKO_PUBLIC_KEY:
93517c478bd9Sstevel@tonic-gate 		if (dprov_template_attr_present(template, nattr,
93527c478bd9Sstevel@tonic-gate 		    DPROV_CKA_MODULUS) ||
93537c478bd9Sstevel@tonic-gate 		    dprov_template_attr_present(template, nattr,
93547c478bd9Sstevel@tonic-gate 		    DPROV_CKA_PUBLIC_EXPONENT))
93557c478bd9Sstevel@tonic-gate 			return (CRYPTO_TEMPLATE_INCONSISTENT);
93567c478bd9Sstevel@tonic-gate 		break;
93577c478bd9Sstevel@tonic-gate 
93587c478bd9Sstevel@tonic-gate 	case DPROV_CKO_PRIVATE_KEY:
93597c478bd9Sstevel@tonic-gate 		if (dprov_template_attr_present(template, nattr,
93607c478bd9Sstevel@tonic-gate 		    DPROV_CKA_MODULUS) ||
93617c478bd9Sstevel@tonic-gate 		    dprov_template_attr_present(template, nattr,
93627c478bd9Sstevel@tonic-gate 		    DPROV_CKA_PRIVATE_EXPONENT))
93637c478bd9Sstevel@tonic-gate 			return (CRYPTO_TEMPLATE_INCONSISTENT);
93647c478bd9Sstevel@tonic-gate 		break;
93657c478bd9Sstevel@tonic-gate 
93667c478bd9Sstevel@tonic-gate 	default:
93677c478bd9Sstevel@tonic-gate 		return (CRYPTO_SUCCESS);
93687c478bd9Sstevel@tonic-gate 	}
93697c478bd9Sstevel@tonic-gate 
93707c478bd9Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
93717c478bd9Sstevel@tonic-gate }
93727c478bd9Sstevel@tonic-gate 
93737c478bd9Sstevel@tonic-gate /*
93747c478bd9Sstevel@tonic-gate  * Set the attributes specified by the template in the specified object,
93757c478bd9Sstevel@tonic-gate  * replacing existing ones if needed.
93767c478bd9Sstevel@tonic-gate  */
93777c478bd9Sstevel@tonic-gate static int
93787c478bd9Sstevel@tonic-gate dprov_object_set_attr(dprov_session_t *session, crypto_object_id_t object_id,
93797c478bd9Sstevel@tonic-gate     crypto_object_attribute_t *template, uint_t nattr,
93807c478bd9Sstevel@tonic-gate     boolean_t check_attributes)
93817c478bd9Sstevel@tonic-gate {
9382894b2776Smcpowers 	crypto_attr_type_t type;
93837c478bd9Sstevel@tonic-gate 	dprov_object_t *object;
9384894b2776Smcpowers 	size_t old_len, new_len;
93857c478bd9Sstevel@tonic-gate 	uint_t i, j;
93867c478bd9Sstevel@tonic-gate 	int error;
93877c478bd9Sstevel@tonic-gate 
93887c478bd9Sstevel@tonic-gate 	if ((object = session->ds_objects[object_id]) == NULL)
93897c478bd9Sstevel@tonic-gate 		return (CRYPTO_OBJECT_HANDLE_INVALID);
93907c478bd9Sstevel@tonic-gate 
93917c478bd9Sstevel@tonic-gate 	if (check_attributes) {
93927c478bd9Sstevel@tonic-gate 		/* verify that attributes in the template can be modified */
93937c478bd9Sstevel@tonic-gate 		if ((error = dprov_object_can_modify(object, template, nattr))
93947c478bd9Sstevel@tonic-gate 		    != CRYPTO_SUCCESS)
93957c478bd9Sstevel@tonic-gate 			return (error);
93967c478bd9Sstevel@tonic-gate 	}
93977c478bd9Sstevel@tonic-gate 
93987c478bd9Sstevel@tonic-gate 	/* go through the attributes specified in the template */
93997c478bd9Sstevel@tonic-gate 	for (i = 0; i < nattr; i++) {
94007c478bd9Sstevel@tonic-gate 		if (template[i].oa_value == NULL)
94017c478bd9Sstevel@tonic-gate 			continue;
94027c478bd9Sstevel@tonic-gate 
94037c478bd9Sstevel@tonic-gate 		/* find attribute in object */
9404894b2776Smcpowers 		type = template[i].oa_type;
9405894b2776Smcpowers 		j = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR, type);
94067c478bd9Sstevel@tonic-gate 
94077c478bd9Sstevel@tonic-gate 		if (j != -1) {
94087c478bd9Sstevel@tonic-gate 			/* attribute already exists, free old value */
94097c478bd9Sstevel@tonic-gate 			kmem_free(object->do_attr[j].oa_value,
94107c478bd9Sstevel@tonic-gate 			    object->do_attr[j].oa_value_len);
94117c478bd9Sstevel@tonic-gate 		} else {
94127c478bd9Sstevel@tonic-gate 			/* attribute does not exist, create it */
94137c478bd9Sstevel@tonic-gate 			for (j = 0; j < DPROV_MAX_ATTR; j++)
94147c478bd9Sstevel@tonic-gate 				if (object->do_attr[j].oa_value == NULL)
94157c478bd9Sstevel@tonic-gate 					break;
94167c478bd9Sstevel@tonic-gate 			if (j == DPROV_MAX_ATTR)
94177c478bd9Sstevel@tonic-gate 				/* ran out of attribute slots */
94187c478bd9Sstevel@tonic-gate 				return (CRYPTO_HOST_MEMORY);
94197c478bd9Sstevel@tonic-gate 		}
94207c478bd9Sstevel@tonic-gate 
9421894b2776Smcpowers 		old_len = template[i].oa_value_len;
9422894b2776Smcpowers 		new_len = attribute_size(type, old_len);
9423894b2776Smcpowers 
94247c478bd9Sstevel@tonic-gate 		/* set object attribute value */
9425894b2776Smcpowers 		object->do_attr[j].oa_value = kmem_alloc(new_len, KM_SLEEP);
9426894b2776Smcpowers 		bcopy(&template[i].oa_value[old_len - new_len],
9427894b2776Smcpowers 		    object->do_attr[j].oa_value, new_len);
9428894b2776Smcpowers 		object->do_attr[j].oa_value_len = new_len;
94297c478bd9Sstevel@tonic-gate 
94307c478bd9Sstevel@tonic-gate 		/* and the type */
9431894b2776Smcpowers 		object->do_attr[j].oa_type = type;
94327c478bd9Sstevel@tonic-gate 	}
94337c478bd9Sstevel@tonic-gate 
94347c478bd9Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
94357c478bd9Sstevel@tonic-gate }
94367c478bd9Sstevel@tonic-gate 
94377c478bd9Sstevel@tonic-gate 
94387c478bd9Sstevel@tonic-gate /*
94397c478bd9Sstevel@tonic-gate  * Free the specified object.
94407c478bd9Sstevel@tonic-gate  */
94417c478bd9Sstevel@tonic-gate static void
94427c478bd9Sstevel@tonic-gate dprov_free_object(dprov_object_t *object)
94437c478bd9Sstevel@tonic-gate {
94447c478bd9Sstevel@tonic-gate 	int i;
94457c478bd9Sstevel@tonic-gate 
94467c478bd9Sstevel@tonic-gate 	/* free the object attributes values */
94477c478bd9Sstevel@tonic-gate 	for (i = 0; i < DPROV_MAX_ATTR; i++)
94487c478bd9Sstevel@tonic-gate 		if (object->do_attr[i].oa_value != NULL)
94497c478bd9Sstevel@tonic-gate 			kmem_free(object->do_attr[i].oa_value,
94507c478bd9Sstevel@tonic-gate 			    object->do_attr[i].oa_value_len);
94517c478bd9Sstevel@tonic-gate 
94527c478bd9Sstevel@tonic-gate 	/* free the object */
94537c478bd9Sstevel@tonic-gate 	kmem_free(object, sizeof (dprov_object_t));
94547c478bd9Sstevel@tonic-gate }
94557c478bd9Sstevel@tonic-gate 
94567c478bd9Sstevel@tonic-gate /*
94577c478bd9Sstevel@tonic-gate  * Checks whether the specified object is a private or public object.
94587c478bd9Sstevel@tonic-gate  */
94597c478bd9Sstevel@tonic-gate static boolean_t
94607c478bd9Sstevel@tonic-gate dprov_object_is_private(dprov_object_t *object)
94617c478bd9Sstevel@tonic-gate {
94627c478bd9Sstevel@tonic-gate 	boolean_t ret;
94637c478bd9Sstevel@tonic-gate 	int err;
94647c478bd9Sstevel@tonic-gate 
94657c478bd9Sstevel@tonic-gate 	err = dprov_get_object_attr_boolean(object, DPROV_CKA_PRIVATE, &ret);
94667c478bd9Sstevel@tonic-gate 
94677c478bd9Sstevel@tonic-gate 	if (err != CRYPTO_SUCCESS)
94687c478bd9Sstevel@tonic-gate 		/* by default, CKA_PRIVATE is false */
94697c478bd9Sstevel@tonic-gate 		ret = B_FALSE;
94707c478bd9Sstevel@tonic-gate 
94717c478bd9Sstevel@tonic-gate 	return (ret);
94727c478bd9Sstevel@tonic-gate }
94737c478bd9Sstevel@tonic-gate 
94747c478bd9Sstevel@tonic-gate /*
94757c478bd9Sstevel@tonic-gate  * Checks whether the specified object is a token or session object.
94767c478bd9Sstevel@tonic-gate  */
94777c478bd9Sstevel@tonic-gate static boolean_t
94787c478bd9Sstevel@tonic-gate dprov_object_is_token(dprov_object_t *object)
94797c478bd9Sstevel@tonic-gate {
94807c478bd9Sstevel@tonic-gate 	boolean_t ret;
94817c478bd9Sstevel@tonic-gate 	int err;
94827c478bd9Sstevel@tonic-gate 
94837c478bd9Sstevel@tonic-gate 	err = dprov_get_object_attr_boolean(object, DPROV_CKA_TOKEN, &ret);
94847c478bd9Sstevel@tonic-gate 
94857c478bd9Sstevel@tonic-gate 	if (err != CRYPTO_SUCCESS)
94867c478bd9Sstevel@tonic-gate 		/* by default, CKA_TOKEN is false */
94877c478bd9Sstevel@tonic-gate 		ret = B_FALSE;
94887c478bd9Sstevel@tonic-gate 
94897c478bd9Sstevel@tonic-gate 	return (ret);
94907c478bd9Sstevel@tonic-gate }
94917c478bd9Sstevel@tonic-gate 
94927c478bd9Sstevel@tonic-gate /*
94937c478bd9Sstevel@tonic-gate  * Common function used by the dprov_get_object_attr_*() family of
94947c478bd9Sstevel@tonic-gate  * functions. Returns the value of the specified attribute of specified
94957c478bd9Sstevel@tonic-gate  * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID
94967c478bd9Sstevel@tonic-gate  * if the length of the attribute does not match the specified length,
94977c478bd9Sstevel@tonic-gate  * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found.
94987c478bd9Sstevel@tonic-gate  */
94997c478bd9Sstevel@tonic-gate static int
95007c478bd9Sstevel@tonic-gate dprov_get_object_attr_scalar_common(dprov_object_t *object, uint64_t attr_type,
95017c478bd9Sstevel@tonic-gate 				    void *value, size_t value_len)
95027c478bd9Sstevel@tonic-gate {
95037c478bd9Sstevel@tonic-gate 	int attr_idx;
95047c478bd9Sstevel@tonic-gate 	size_t oa_value_len;
95057c478bd9Sstevel@tonic-gate 	size_t offset = 0;
95067c478bd9Sstevel@tonic-gate 
95077c478bd9Sstevel@tonic-gate 	if ((attr_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR,
95087c478bd9Sstevel@tonic-gate 	    attr_type)) == -1)
95097c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
95107c478bd9Sstevel@tonic-gate 
95117c478bd9Sstevel@tonic-gate 	oa_value_len = object->do_attr[attr_idx].oa_value_len;
95127c478bd9Sstevel@tonic-gate 	if (oa_value_len != value_len) {
95137c478bd9Sstevel@tonic-gate 		/*
95147c478bd9Sstevel@tonic-gate 		 * For some attributes, it's okay to copy the value
95157c478bd9Sstevel@tonic-gate 		 * into a larger container, e.g. copy an unsigned
95167c478bd9Sstevel@tonic-gate 		 * 32-bit integer into a 64-bit container.
95177c478bd9Sstevel@tonic-gate 		 */
95187c478bd9Sstevel@tonic-gate 		if (attr_type == DPROV_CKA_VALUE_LEN ||
95197c478bd9Sstevel@tonic-gate 		    attr_type == DPROV_CKA_KEY_TYPE ||
95207c478bd9Sstevel@tonic-gate 		    attr_type == DPROV_CKA_CLASS) {
95217c478bd9Sstevel@tonic-gate 			if (oa_value_len < value_len) {
95227c478bd9Sstevel@tonic-gate #ifdef _BIG_ENDIAN
95237c478bd9Sstevel@tonic-gate 				offset = value_len - oa_value_len;
95247c478bd9Sstevel@tonic-gate #endif
95257c478bd9Sstevel@tonic-gate 				bzero(value, value_len);
95267c478bd9Sstevel@tonic-gate 				goto do_copy;
95277c478bd9Sstevel@tonic-gate 			}
95287c478bd9Sstevel@tonic-gate 		}
95297c478bd9Sstevel@tonic-gate 		/* incorrect attribute value length */
95307c478bd9Sstevel@tonic-gate 		return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
95317c478bd9Sstevel@tonic-gate 	}
95327c478bd9Sstevel@tonic-gate 
95337c478bd9Sstevel@tonic-gate do_copy:
95347c478bd9Sstevel@tonic-gate 	bcopy(object->do_attr[attr_idx].oa_value, (uchar_t *)value + offset,
95357c478bd9Sstevel@tonic-gate 	    oa_value_len);
95367c478bd9Sstevel@tonic-gate 
95377c478bd9Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
95387c478bd9Sstevel@tonic-gate }
95397c478bd9Sstevel@tonic-gate 
95407c478bd9Sstevel@tonic-gate /*
95417c478bd9Sstevel@tonic-gate  * Get the value of the a boolean attribute from the specified object.
95427c478bd9Sstevel@tonic-gate  */
95437c478bd9Sstevel@tonic-gate static int
95447c478bd9Sstevel@tonic-gate dprov_get_object_attr_boolean(dprov_object_t *object, uint64_t attr_type,
95457c478bd9Sstevel@tonic-gate     boolean_t *attr_value)
95467c478bd9Sstevel@tonic-gate {
95477c478bd9Sstevel@tonic-gate 	uchar_t val;
95487c478bd9Sstevel@tonic-gate 	int ret;
95497c478bd9Sstevel@tonic-gate 
95507c478bd9Sstevel@tonic-gate 	/* PKCS#11 defines a boolean as one byte */
95517c478bd9Sstevel@tonic-gate 	ret = dprov_get_object_attr_scalar_common(object, attr_type, &val, 1);
95527c478bd9Sstevel@tonic-gate 	if (ret == CRYPTO_SUCCESS) {
95537c478bd9Sstevel@tonic-gate 		*attr_value = (val == '\0') ? B_FALSE : B_TRUE;
95547c478bd9Sstevel@tonic-gate 	}
95557c478bd9Sstevel@tonic-gate 	return (ret);
95567c478bd9Sstevel@tonic-gate }
95577c478bd9Sstevel@tonic-gate 
95587c478bd9Sstevel@tonic-gate /*
95597c478bd9Sstevel@tonic-gate  * Get the value of a ulong_t attribute from the specified object.
95607c478bd9Sstevel@tonic-gate  */
95617c478bd9Sstevel@tonic-gate static int
95627c478bd9Sstevel@tonic-gate dprov_get_object_attr_ulong(dprov_object_t *object, uint64_t attr_type,
95637c478bd9Sstevel@tonic-gate     ulong_t *attr_value)
95647c478bd9Sstevel@tonic-gate {
95657c478bd9Sstevel@tonic-gate 	return (dprov_get_object_attr_scalar_common(object, attr_type,
95667c478bd9Sstevel@tonic-gate 	    attr_value, sizeof (ulong_t)));
95677c478bd9Sstevel@tonic-gate }
95687c478bd9Sstevel@tonic-gate 
95697c478bd9Sstevel@tonic-gate /*
95707c478bd9Sstevel@tonic-gate  * Find the specified byte array attribute of specified type in
95717c478bd9Sstevel@tonic-gate  * the specified object. Returns CRYPTO_SUCCESS
95727c478bd9Sstevel@tonic-gate  * on success or CRYPTO_ARGUMENTS_BAD if the specified
95737c478bd9Sstevel@tonic-gate  * attribute cannot be found.
95747c478bd9Sstevel@tonic-gate  */
95757c478bd9Sstevel@tonic-gate static int
95767c478bd9Sstevel@tonic-gate dprov_get_object_attr_array(dprov_object_t *object, uint64_t attr_type,
95777c478bd9Sstevel@tonic-gate     void **array, size_t *len)
95787c478bd9Sstevel@tonic-gate {
95797c478bd9Sstevel@tonic-gate 	int attr_idx;
95807c478bd9Sstevel@tonic-gate 
95817c478bd9Sstevel@tonic-gate 	if ((attr_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR,
95827c478bd9Sstevel@tonic-gate 	    attr_type)) == -1)
95837c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
95847c478bd9Sstevel@tonic-gate 
95857c478bd9Sstevel@tonic-gate 	*array = object->do_attr[attr_idx].oa_value;
95867c478bd9Sstevel@tonic-gate 	*len = object->do_attr[attr_idx].oa_value_len;
95877c478bd9Sstevel@tonic-gate 
95887c478bd9Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
95897c478bd9Sstevel@tonic-gate }
95907c478bd9Sstevel@tonic-gate 
95917c478bd9Sstevel@tonic-gate /*
95927c478bd9Sstevel@tonic-gate  * Common function used by the dprov_get_template_attr_*() family of
95937c478bd9Sstevel@tonic-gate  * functions. Returns the value of the specified attribute of specified
95947c478bd9Sstevel@tonic-gate  * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID
95957c478bd9Sstevel@tonic-gate  * if the length of the attribute does not match the specified length,
95967c478bd9Sstevel@tonic-gate  * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found.
95977c478bd9Sstevel@tonic-gate  */
95987c478bd9Sstevel@tonic-gate static int
95997c478bd9Sstevel@tonic-gate dprov_get_template_attr_scalar_common(crypto_object_attribute_t *template,
96007c478bd9Sstevel@tonic-gate     uint_t nattr, uint64_t attr_type, void *value, size_t value_len)
96017c478bd9Sstevel@tonic-gate {
96027c478bd9Sstevel@tonic-gate 	size_t oa_value_len;
96037c478bd9Sstevel@tonic-gate 	size_t offset = 0;
96047c478bd9Sstevel@tonic-gate 	int attr_idx;
96057c478bd9Sstevel@tonic-gate 
96067c478bd9Sstevel@tonic-gate 	if ((attr_idx = dprov_find_attr(template, nattr, attr_type)) == -1)
96077c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
96087c478bd9Sstevel@tonic-gate 
96097c478bd9Sstevel@tonic-gate 	oa_value_len = template[attr_idx].oa_value_len;
96107c478bd9Sstevel@tonic-gate 	if (oa_value_len != value_len) {
96117c478bd9Sstevel@tonic-gate 		/*
96127c478bd9Sstevel@tonic-gate 		 * For some attributes, it's okay to copy the value
96137c478bd9Sstevel@tonic-gate 		 * into a larger container, e.g. copy an unsigned
96147c478bd9Sstevel@tonic-gate 		 * 32-bit integer into a 64-bit container.
96157c478bd9Sstevel@tonic-gate 		 */
96167c478bd9Sstevel@tonic-gate 		if (attr_type == DPROV_CKA_VALUE_LEN ||
96177c478bd9Sstevel@tonic-gate 		    attr_type == DPROV_CKA_KEY_TYPE ||
96187c478bd9Sstevel@tonic-gate 		    attr_type == DPROV_CKA_CLASS) {
96197c478bd9Sstevel@tonic-gate 			if (oa_value_len < value_len) {
96207c478bd9Sstevel@tonic-gate #ifdef _BIG_ENDIAN
96217c478bd9Sstevel@tonic-gate 				offset = value_len - oa_value_len;
96227c478bd9Sstevel@tonic-gate #endif
96237c478bd9Sstevel@tonic-gate 				bzero(value, value_len);
96247c478bd9Sstevel@tonic-gate 				goto do_copy;
96257c478bd9Sstevel@tonic-gate 			}
96267c478bd9Sstevel@tonic-gate 		}
96277c478bd9Sstevel@tonic-gate 		/* incorrect attribute value length */
96287c478bd9Sstevel@tonic-gate 		return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
96297c478bd9Sstevel@tonic-gate 	}
96307c478bd9Sstevel@tonic-gate 
96317c478bd9Sstevel@tonic-gate do_copy:
96327c478bd9Sstevel@tonic-gate 	bcopy(template[attr_idx].oa_value, (uchar_t *)value + offset,
96337c478bd9Sstevel@tonic-gate 	    oa_value_len);
96347c478bd9Sstevel@tonic-gate 
96357c478bd9Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
96367c478bd9Sstevel@tonic-gate }
96377c478bd9Sstevel@tonic-gate 
96387c478bd9Sstevel@tonic-gate /*
96397c478bd9Sstevel@tonic-gate  * Get the value of the a boolean attribute from the specified template
96407c478bd9Sstevel@tonic-gate  */
96417c478bd9Sstevel@tonic-gate static int
96427c478bd9Sstevel@tonic-gate dprov_get_template_attr_boolean(crypto_object_attribute_t *template,
96437c478bd9Sstevel@tonic-gate     uint_t nattr, uint64_t attr_type, boolean_t *attr_value)
96447c478bd9Sstevel@tonic-gate {
96457c478bd9Sstevel@tonic-gate 	uchar_t val;
96467c478bd9Sstevel@tonic-gate 	int ret;
96477c478bd9Sstevel@tonic-gate 
96487c478bd9Sstevel@tonic-gate 	/* PKCS#11 defines a boolean as one byte */
96497c478bd9Sstevel@tonic-gate 	ret = dprov_get_template_attr_scalar_common(template, nattr,
96507c478bd9Sstevel@tonic-gate 	    attr_type, &val, 1);
96517c478bd9Sstevel@tonic-gate 	if (ret == CRYPTO_SUCCESS) {
96527c478bd9Sstevel@tonic-gate 		*attr_value = (val == '\0') ? B_FALSE : B_TRUE;
96537c478bd9Sstevel@tonic-gate 	}
96547c478bd9Sstevel@tonic-gate 	return (ret);
96557c478bd9Sstevel@tonic-gate }
96567c478bd9Sstevel@tonic-gate 
96577c478bd9Sstevel@tonic-gate /*
96587c478bd9Sstevel@tonic-gate  * Get the value of a ulong_t attribute from the specified template.
96597c478bd9Sstevel@tonic-gate  */
96607c478bd9Sstevel@tonic-gate static int
96617c478bd9Sstevel@tonic-gate dprov_get_template_attr_ulong(crypto_object_attribute_t *template,
96627c478bd9Sstevel@tonic-gate     uint_t nattr, uint64_t attr_type, ulong_t *attr_value)
96637c478bd9Sstevel@tonic-gate {
96647c478bd9Sstevel@tonic-gate 	return (dprov_get_template_attr_scalar_common(template, nattr,
96657c478bd9Sstevel@tonic-gate 	    attr_type, attr_value, sizeof (ulong_t)));
96667c478bd9Sstevel@tonic-gate }
96677c478bd9Sstevel@tonic-gate 
96687c478bd9Sstevel@tonic-gate static int
96697c478bd9Sstevel@tonic-gate dprov_template_attr_present(crypto_object_attribute_t *template,
96707c478bd9Sstevel@tonic-gate     uint_t nattr, uint64_t attr_type)
96717c478bd9Sstevel@tonic-gate {
96727c478bd9Sstevel@tonic-gate 	return (dprov_find_attr(template, nattr,
96737c478bd9Sstevel@tonic-gate 	    attr_type) == -1 ? B_FALSE : B_TRUE);
96747c478bd9Sstevel@tonic-gate }
96757c478bd9Sstevel@tonic-gate 
96767c478bd9Sstevel@tonic-gate /*
96777c478bd9Sstevel@tonic-gate  * Find the specified byte array attribute of specified type in
96787c478bd9Sstevel@tonic-gate  * the specified template. Returns CRYPTO_SUCCESS on success or
96797c478bd9Sstevel@tonic-gate  * CRYPTO_ARGUMENTS_BAD if the specified attribute cannot be found.
96807c478bd9Sstevel@tonic-gate  */
96817c478bd9Sstevel@tonic-gate static int
96827c478bd9Sstevel@tonic-gate dprov_get_template_attr_array(crypto_object_attribute_t *template,
96837c478bd9Sstevel@tonic-gate     uint_t nattr, uint64_t attr_type, void **array, size_t *len)
96847c478bd9Sstevel@tonic-gate {
96857c478bd9Sstevel@tonic-gate 	int attr_idx;
96867c478bd9Sstevel@tonic-gate 
96877c478bd9Sstevel@tonic-gate 	if ((attr_idx = dprov_find_attr(template, nattr, attr_type)) == -1)
96887c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
96897c478bd9Sstevel@tonic-gate 
96907c478bd9Sstevel@tonic-gate 	*array = template[attr_idx].oa_value;
96917c478bd9Sstevel@tonic-gate 	*len = template[attr_idx].oa_value_len;
96927c478bd9Sstevel@tonic-gate 
96937c478bd9Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
96947c478bd9Sstevel@tonic-gate }
96957c478bd9Sstevel@tonic-gate 
96967c478bd9Sstevel@tonic-gate /*
96977c478bd9Sstevel@tonic-gate  * Common function used by the dprov_get_key_attr_*() family of
96987c478bd9Sstevel@tonic-gate  * functions. Returns the value of the specified attribute of specified
96997c478bd9Sstevel@tonic-gate  * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID
97007c478bd9Sstevel@tonic-gate  * if the length of the attribute does not match the specified length,
97017c478bd9Sstevel@tonic-gate  * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found.
97027c478bd9Sstevel@tonic-gate  */
97037c478bd9Sstevel@tonic-gate static int
97047c478bd9Sstevel@tonic-gate dprov_get_key_attr_scalar_common(crypto_key_t *key, uint64_t attr_type,
97057c478bd9Sstevel@tonic-gate     void *value, size_t value_len)
97067c478bd9Sstevel@tonic-gate {
97077c478bd9Sstevel@tonic-gate 	int attr_idx;
97087c478bd9Sstevel@tonic-gate 
97097c478bd9Sstevel@tonic-gate 	ASSERT(key->ck_format == CRYPTO_KEY_ATTR_LIST);
97107c478bd9Sstevel@tonic-gate 
97117c478bd9Sstevel@tonic-gate 	if ((attr_idx = dprov_find_attr(key->ck_attrs, key->ck_count,
97127c478bd9Sstevel@tonic-gate 	    attr_type)) == -1)
97137c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
97147c478bd9Sstevel@tonic-gate 
97157c478bd9Sstevel@tonic-gate 	if (key->ck_attrs[attr_idx].oa_value_len != value_len)
97167c478bd9Sstevel@tonic-gate 		/* incorrect attribute value length */
97177c478bd9Sstevel@tonic-gate 		return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
97187c478bd9Sstevel@tonic-gate 
97197c478bd9Sstevel@tonic-gate 	bcopy(key->ck_attrs[attr_idx].oa_value, value, value_len);
97207c478bd9Sstevel@tonic-gate 
97217c478bd9Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
97227c478bd9Sstevel@tonic-gate }
97237c478bd9Sstevel@tonic-gate 
97247c478bd9Sstevel@tonic-gate /*
97257c478bd9Sstevel@tonic-gate  * Get the value of a ulong_t attribute from the specified key.
97267c478bd9Sstevel@tonic-gate  */
97277c478bd9Sstevel@tonic-gate static int
97287c478bd9Sstevel@tonic-gate dprov_get_key_attr_ulong(crypto_key_t *key, uint64_t attr_type,
97297c478bd9Sstevel@tonic-gate     ulong_t *attr_value)
97307c478bd9Sstevel@tonic-gate {
97317c478bd9Sstevel@tonic-gate 	return (dprov_get_key_attr_scalar_common(key, attr_type,
97327c478bd9Sstevel@tonic-gate 	    attr_value, sizeof (ulong_t)));
97337c478bd9Sstevel@tonic-gate }
97347c478bd9Sstevel@tonic-gate 
97357c478bd9Sstevel@tonic-gate /*
97367c478bd9Sstevel@tonic-gate  * Find the specified byte array attribute of specified type in
97377c478bd9Sstevel@tonic-gate  * the specified key by attributes. Returns CRYPTO_SUCCESS
97387c478bd9Sstevel@tonic-gate  * on success or CRYPTO_ARGUMENTS_BAD if the specified
97397c478bd9Sstevel@tonic-gate  * attribute cannot be found.
97407c478bd9Sstevel@tonic-gate  */
97417c478bd9Sstevel@tonic-gate static int
97427c478bd9Sstevel@tonic-gate dprov_get_key_attr_array(crypto_key_t *key, uint64_t attr_type,
97437c478bd9Sstevel@tonic-gate     void **array, size_t *len)
97447c478bd9Sstevel@tonic-gate {
97457c478bd9Sstevel@tonic-gate 	int attr_idx;
97467c478bd9Sstevel@tonic-gate 
97477c478bd9Sstevel@tonic-gate 	ASSERT(key->ck_format == CRYPTO_KEY_ATTR_LIST);
97487c478bd9Sstevel@tonic-gate 
97497c478bd9Sstevel@tonic-gate 	if ((attr_idx = dprov_find_attr(key->ck_attrs, key->ck_count,
97507c478bd9Sstevel@tonic-gate 	    attr_type)) == -1)
97517c478bd9Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
97527c478bd9Sstevel@tonic-gate 
97537c478bd9Sstevel@tonic-gate 	*array = key->ck_attrs[attr_idx].oa_value;
97547c478bd9Sstevel@tonic-gate 	*len = key->ck_attrs[attr_idx].oa_value_len;
97557c478bd9Sstevel@tonic-gate 
97567c478bd9Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
97577c478bd9Sstevel@tonic-gate }
97587c478bd9Sstevel@tonic-gate 
97597c478bd9Sstevel@tonic-gate static void
97607c478bd9Sstevel@tonic-gate dprov_release_session_objects(dprov_session_t *session)
97617c478bd9Sstevel@tonic-gate {
97627c478bd9Sstevel@tonic-gate 	dprov_object_t *object;
97637c478bd9Sstevel@tonic-gate 	int i;
97647c478bd9Sstevel@tonic-gate 
97657c478bd9Sstevel@tonic-gate 	for (i = 0; i < DPROV_MAX_OBJECTS; i++) {
97667c478bd9Sstevel@tonic-gate 		object = session->ds_objects[i];
97677c478bd9Sstevel@tonic-gate 		if (object != NULL) {
97687c478bd9Sstevel@tonic-gate 			DPROV_OBJECT_REFRELE(object);
97697c478bd9Sstevel@tonic-gate 		}
97707c478bd9Sstevel@tonic-gate 	}
97717c478bd9Sstevel@tonic-gate }
9772f9fbec18Smcpowers 
9773f9fbec18Smcpowers /*
9774f9fbec18Smcpowers  * Adjust an attribute list by turning 32-bit values into 64-bit values
9775f9fbec18Smcpowers  * for certain attributes like CKA_CLASS. Assumes that at least 8 bytes
9776f9fbec18Smcpowers  * of storage have been allocated for all attributes.
9777f9fbec18Smcpowers  */
9778f9fbec18Smcpowers static void
9779f9fbec18Smcpowers dprov_adjust_attrs(crypto_object_attribute_t *in, int in_count)
9780f9fbec18Smcpowers {
9781f9fbec18Smcpowers 	int i;
9782f9fbec18Smcpowers 	size_t offset = 0;
9783f9fbec18Smcpowers 	ulong_t tmp = 0;
9784f9fbec18Smcpowers 
9785f9fbec18Smcpowers 	for (i = 0; i < in_count; i++) {
9786f9fbec18Smcpowers 		/*
9787f9fbec18Smcpowers 		 * For some attributes, it's okay to copy the value
9788f9fbec18Smcpowers 		 * into a larger container, e.g. copy an unsigned
9789f9fbec18Smcpowers 		 * 32-bit integer into a 64-bit container.
9790f9fbec18Smcpowers 		 */
9791f9fbec18Smcpowers 		if (in[i].oa_type == CKA_VALUE_LEN ||
9792f9fbec18Smcpowers 		    in[i].oa_type == CKA_KEY_TYPE ||
9793f9fbec18Smcpowers 		    in[i].oa_type == CKA_CLASS) {
9794f9fbec18Smcpowers 			if (in[i].oa_value_len < sizeof (ulong_t)) {
9795f9fbec18Smcpowers #ifdef _BIG_ENDIAN
9796f9fbec18Smcpowers 				offset = sizeof (ulong_t) - in[i].oa_value_len;
9797f9fbec18Smcpowers #endif
9798f9fbec18Smcpowers 				bcopy(in[i].oa_value, (uchar_t *)&tmp + offset,
9799f9fbec18Smcpowers 				    in[i].oa_value_len);
9800f9fbec18Smcpowers 				bcopy(&tmp, in[i].oa_value, sizeof (ulong_t));
9801f9fbec18Smcpowers 				in[i].oa_value_len = sizeof (ulong_t);
9802f9fbec18Smcpowers 			}
9803f9fbec18Smcpowers 		}
9804f9fbec18Smcpowers 	}
9805f9fbec18Smcpowers }
9806