xref: /onnv-gate/usr/src/uts/common/crypto/io/dprov.c (revision 11413:21d4b1442799)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51920Smcpowers  * Common Development and Distribution License (the "License").
61920Smcpowers  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*11413Sopensolaris@drydog.com  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate 
270Sstevel@tonic-gate /*
280Sstevel@tonic-gate  * Dummy Cryptographic Provider:
290Sstevel@tonic-gate  *
300Sstevel@tonic-gate  * This file implements a "dummy" cryptographic provider. It is implemented
310Sstevel@tonic-gate  * as a pseudo device driver.
320Sstevel@tonic-gate  *
330Sstevel@tonic-gate  */
340Sstevel@tonic-gate 
350Sstevel@tonic-gate /*
360Sstevel@tonic-gate  * This driver implements a KEF provider with the following capabilities:
370Sstevel@tonic-gate  *
380Sstevel@tonic-gate  * - registration/unregistration with KEF
390Sstevel@tonic-gate  * - digest entry points
400Sstevel@tonic-gate  * - mac entry points
410Sstevel@tonic-gate  * - ctx management
420Sstevel@tonic-gate  * - support for async requests
430Sstevel@tonic-gate  * - cipher entry points
440Sstevel@tonic-gate  * - dual entry points
450Sstevel@tonic-gate  * - sign entry points
460Sstevel@tonic-gate  * - verify entry points
470Sstevel@tonic-gate  * - dual operations entry points
480Sstevel@tonic-gate  * - dual cipher/mac operation entry points
490Sstevel@tonic-gate  * - session management
500Sstevel@tonic-gate  * - object management
510Sstevel@tonic-gate  * - key management
520Sstevel@tonic-gate  * - provider management
530Sstevel@tonic-gate  *
540Sstevel@tonic-gate  * In order to avoid duplicating the implementation of algorithms
550Sstevel@tonic-gate  * provided by software providers, this pseudo driver acts as
560Sstevel@tonic-gate  * a consumer of the framework. When invoking one of the framework's
570Sstevel@tonic-gate  * entry points, the driver specifies the software provider to
580Sstevel@tonic-gate  * be used for the operation.
590Sstevel@tonic-gate  *
600Sstevel@tonic-gate  * User management: we implement a PKCS#11 style provider which supports:
610Sstevel@tonic-gate  * - one normal user with a PIN, and
620Sstevel@tonic-gate  * - one SO user with a PIN.
630Sstevel@tonic-gate  * These values are kept in the per-instance structure, and are initialized
640Sstevel@tonic-gate  * with the provider management entry points.
650Sstevel@tonic-gate  *
660Sstevel@tonic-gate  */
670Sstevel@tonic-gate 
680Sstevel@tonic-gate 
690Sstevel@tonic-gate #include <sys/types.h>
700Sstevel@tonic-gate #include <sys/modctl.h>
710Sstevel@tonic-gate #include <sys/conf.h>
720Sstevel@tonic-gate #include <sys/stat.h>
730Sstevel@tonic-gate #include <sys/ddi.h>
740Sstevel@tonic-gate #include <sys/sunddi.h>
750Sstevel@tonic-gate #include <sys/kmem.h>
760Sstevel@tonic-gate #include <sys/errno.h>
770Sstevel@tonic-gate #include <sys/ksynch.h>
780Sstevel@tonic-gate #include <sys/file.h>
790Sstevel@tonic-gate #include <sys/open.h>
800Sstevel@tonic-gate #include <sys/cred.h>
810Sstevel@tonic-gate #include <sys/model.h>
820Sstevel@tonic-gate #include <sys/note.h>
830Sstevel@tonic-gate #include <sys/random.h>
840Sstevel@tonic-gate #include <sys/byteorder.h>
850Sstevel@tonic-gate #include <sys/crypto/common.h>
860Sstevel@tonic-gate #include <sys/crypto/spi.h>
870Sstevel@tonic-gate 
880Sstevel@tonic-gate #include <sys/taskq.h>
890Sstevel@tonic-gate #include <sys/disp.h>
900Sstevel@tonic-gate #include <sys/sysmacros.h>
910Sstevel@tonic-gate #include <sys/crypto/impl.h>
920Sstevel@tonic-gate #include <sys/crypto/sched_impl.h>
93904Smcpowers 
94676Sizick #include <sys/sha2.h>
957188Smcpowers #include <modes/modes.h>
967188Smcpowers #include <aes/aes_impl.h>
97904Smcpowers #include <des/des_impl.h>
985697Smcpowers #include <ecc/ecc_impl.h>
99904Smcpowers #include <blowfish/blowfish_impl.h>
100904Smcpowers 
1010Sstevel@tonic-gate /*
1020Sstevel@tonic-gate  * Debugging macros.
1030Sstevel@tonic-gate  */
1040Sstevel@tonic-gate #ifdef DEBUG
1050Sstevel@tonic-gate #define	D_INIT		0x00000001	/* _init/_fini/_info */
1060Sstevel@tonic-gate #define	D_ATTACH	0x00000002	/* attach/detach */
1070Sstevel@tonic-gate #define	D_DIGEST	0x00000010	/* digest entry points */
1080Sstevel@tonic-gate #define	D_MAC		0x00000020	/* mac entry points */
1090Sstevel@tonic-gate #define	D_CONTEXT	0x00000040	/* context entry points */
1100Sstevel@tonic-gate #define	D_CIPHER	0x00000080	/* cipher entry points */
1110Sstevel@tonic-gate #define	D_SIGN		0x00000100	/* sign entry points */
1120Sstevel@tonic-gate #define	D_VERIFY	0x00000200	/* verify entry points */
1130Sstevel@tonic-gate #define	D_SESSION	0x00000400	/* session management entry points */
1140Sstevel@tonic-gate #define	D_MGMT		0x00000800	/* provider management entry points */
1150Sstevel@tonic-gate #define	D_DUAL		0x00001000	/* dual ops */
1160Sstevel@tonic-gate #define	D_CIPHER_MAC	0x00002000	/* cipher/mac dual ops */
1170Sstevel@tonic-gate #define	D_OBJECT	0x00004000	/* object management */
1180Sstevel@tonic-gate #define	D_RANDOM	0x00008000	/* random number generation */
1190Sstevel@tonic-gate #define	D_KEY		0x00010000	/* key management */
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate static uint32_t dprov_debug = 0;
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate #define	DPROV_DEBUG(f, x)	if (dprov_debug & (f)) { (void) printf x; }
1240Sstevel@tonic-gate #define	DPROV_CALL(f, r, x)	if (dprov_debug & (f)) { (void) r x; }
1250Sstevel@tonic-gate #else /* DEBUG */
1260Sstevel@tonic-gate #define	DPROV_DEBUG(f, x)
1270Sstevel@tonic-gate #define	DPROV_CALL(f, r, x)
1280Sstevel@tonic-gate #endif /* DEBUG */
1290Sstevel@tonic-gate 
1304219Smcpowers static int nostore_key_gen;
1314072Skrishna static boolean_t dprov_no_multipart = B_FALSE;
1324072Skrishna static int dprov_max_digestsz = INT_MAX;
1334072Skrishna 
1340Sstevel@tonic-gate /*
1350Sstevel@tonic-gate  * DDI entry points.
1360Sstevel@tonic-gate  */
1370Sstevel@tonic-gate static int dprov_attach(dev_info_t *, ddi_attach_cmd_t);
1380Sstevel@tonic-gate static int dprov_detach(dev_info_t *, ddi_detach_cmd_t);
1390Sstevel@tonic-gate static int dprov_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
1400Sstevel@tonic-gate 
1410Sstevel@tonic-gate /*
1420Sstevel@tonic-gate  * Module linkage.
1430Sstevel@tonic-gate  */
1440Sstevel@tonic-gate static struct cb_ops cbops = {
1450Sstevel@tonic-gate 	nodev,			/* cb_open */
1460Sstevel@tonic-gate 	nodev,			/* cb_close */
1470Sstevel@tonic-gate 	nodev,			/* cb_strategy */
1480Sstevel@tonic-gate 	nodev,			/* cb_print */
1490Sstevel@tonic-gate 	nodev,			/* cb_dump */
1500Sstevel@tonic-gate 	nodev,			/* cb_read */
1510Sstevel@tonic-gate 	nodev,			/* cb_write */
1520Sstevel@tonic-gate 	nodev,			/* cb_ioctl */
1530Sstevel@tonic-gate 	nodev,			/* cb_devmap */
1540Sstevel@tonic-gate 	nodev,			/* cb_mmap */
1550Sstevel@tonic-gate 	nodev,			/* cb_segmap */
1560Sstevel@tonic-gate 	nochpoll,		/* cb_chpoll */
1570Sstevel@tonic-gate 	ddi_prop_op,		/* cb_prop_op */
1580Sstevel@tonic-gate 	NULL,			/* cb_streamtab */
1590Sstevel@tonic-gate 	D_MP,			/* cb_flag */
1600Sstevel@tonic-gate 	CB_REV,			/* cb_rev */
1610Sstevel@tonic-gate 	nodev,			/* cb_aread */
1620Sstevel@tonic-gate 	nodev,			/* cb_awrite */
1630Sstevel@tonic-gate };
1640Sstevel@tonic-gate 
1650Sstevel@tonic-gate static struct dev_ops devops = {
1660Sstevel@tonic-gate 	DEVO_REV,		/* devo_rev */
1670Sstevel@tonic-gate 	0,			/* devo_refcnt */
1680Sstevel@tonic-gate 	dprov_getinfo,		/* devo_getinfo */
1690Sstevel@tonic-gate 	nulldev,		/* devo_identify */
1700Sstevel@tonic-gate 	nulldev,		/* devo_probe */
1710Sstevel@tonic-gate 	dprov_attach,		/* devo_attach */
1720Sstevel@tonic-gate 	dprov_detach,		/* devo_detach */
1730Sstevel@tonic-gate 	nodev,			/* devo_reset */
1740Sstevel@tonic-gate 	&cbops,			/* devo_cb_ops */
1750Sstevel@tonic-gate 	NULL,			/* devo_bus_ops */
1760Sstevel@tonic-gate 	NULL,			/* devo_power */
1777656SSherry.Moore@Sun.COM 	ddi_quiesce_not_needed,		/* devo_quiesce */
1780Sstevel@tonic-gate };
1790Sstevel@tonic-gate 
1800Sstevel@tonic-gate static struct modldrv modldrv = {
1810Sstevel@tonic-gate 	&mod_driverops,
1825072Smcpowers 	"Pseudo KCF Prov (drv)",
1830Sstevel@tonic-gate 	&devops
1840Sstevel@tonic-gate };
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate static struct modlcrypto modlcrypto = {
1870Sstevel@tonic-gate 	&mod_cryptoops,
1885072Smcpowers 	"Pseudo KCF Prov (crypto)"
1890Sstevel@tonic-gate };
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate static struct modlinkage modlinkage = {
1920Sstevel@tonic-gate 	MODREV_1,
1930Sstevel@tonic-gate 	&modldrv,
1940Sstevel@tonic-gate 	&modlcrypto,
1950Sstevel@tonic-gate 	NULL
1960Sstevel@tonic-gate };
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate /*
1990Sstevel@tonic-gate  * CSPI information (entry points, provider info, etc.)
2000Sstevel@tonic-gate  */
2010Sstevel@tonic-gate 
2020Sstevel@tonic-gate typedef enum dprov_mech_type {
2034002Sdarrenm 	MD4_MECH_INFO_TYPE,		/* SUN_CKM_MD4 */
2044002Sdarrenm 
2050Sstevel@tonic-gate 	MD5_MECH_INFO_TYPE,		/* SUN_CKM_MD5 */
2060Sstevel@tonic-gate 	MD5_HMAC_MECH_INFO_TYPE,	/* SUN_CKM_MD5_HMAC */
2070Sstevel@tonic-gate 	MD5_HMAC_GEN_MECH_INFO_TYPE,	/* SUN_CKM_MD5_HMAC_GENERAL */
2080Sstevel@tonic-gate 
2090Sstevel@tonic-gate 	SHA1_HMAC_MECH_INFO_TYPE,	/* SUN_CKM_SHA1_HMAC */
2100Sstevel@tonic-gate 	SHA1_HMAC_GEN_MECH_INFO_TYPE,	/* SUN_CKM_SHA1_HMAC_GENERAL */
2110Sstevel@tonic-gate 	SHA1_MECH_INFO_TYPE,		/* SUN_CKM_SHA1 */
2120Sstevel@tonic-gate 
2130Sstevel@tonic-gate 	SHA256_HMAC_MECH_INFO_TYPE,	/* SUN_CKM_SHA256_HMAC */
2140Sstevel@tonic-gate 	SHA256_HMAC_GEN_MECH_INFO_TYPE,	/* SUN_CKM_SHA256_HMAC_GENERAL */
2150Sstevel@tonic-gate 	SHA256_MECH_INFO_TYPE,		/* SUN_CKM_SHA256 */
2160Sstevel@tonic-gate 	SHA384_HMAC_MECH_INFO_TYPE,	/* SUN_CKM_SHA384_HMAC */
2170Sstevel@tonic-gate 	SHA384_HMAC_GEN_MECH_INFO_TYPE,	/* SUN_CKM_SHA384_HMAC_GENERAL */
2180Sstevel@tonic-gate 	SHA384_MECH_INFO_TYPE,		/* SUN_CKM_SHA384 */
2190Sstevel@tonic-gate 	SHA512_HMAC_MECH_INFO_TYPE,	/* SUN_CKM_SHA512_HMAC */
2200Sstevel@tonic-gate 	SHA512_HMAC_GEN_MECH_INFO_TYPE,	/* SUN_CKM_SHA512_HMAC_GENERAL */
2210Sstevel@tonic-gate 	SHA512_MECH_INFO_TYPE,		/* SUN_CKM_SHA512 */
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate 	DES_CBC_MECH_INFO_TYPE,		/* SUN_CKM_DES_CBC */
2240Sstevel@tonic-gate 	DES3_CBC_MECH_INFO_TYPE,	/* SUN_CKM_DES3_CBC */
2250Sstevel@tonic-gate 	DES_ECB_MECH_INFO_TYPE,		/* SUN_CKM_DES_ECB */
2260Sstevel@tonic-gate 	DES3_ECB_MECH_INFO_TYPE,	/* SUN_CKM_DES3_ECB */
2270Sstevel@tonic-gate 
228676Sizick 	BLOWFISH_CBC_MECH_INFO_TYPE,	/* SUN_CKM_BLOWFISH_CBC */
229676Sizick 	BLOWFISH_ECB_MECH_INFO_TYPE,	/* SUN_CKM_BLOWFISH_ECB */
2300Sstevel@tonic-gate 	AES_CBC_MECH_INFO_TYPE,		/* SUN_CKM_AES_CBC */
2310Sstevel@tonic-gate 	AES_ECB_MECH_INFO_TYPE,		/* SUN_CKM_AES_ECB */
232904Smcpowers 	AES_CTR_MECH_INFO_TYPE,		/* SUN_CKM_AES_CTR */
2335413Sdinak 	AES_CCM_MECH_INFO_TYPE,		/* SUN_CKM_AES_CCM */
2349339SMark.Powers@Sun.COM 	AES_GCM_MECH_INFO_TYPE,		/* SUN_CKM_AES_GCM */
2359339SMark.Powers@Sun.COM 	AES_GMAC_MECH_INFO_TYPE,	/* SUN_CKM_AES_GMAC */
2360Sstevel@tonic-gate 	RC4_MECH_INFO_TYPE,		/* SUN_CKM_RC4 */
2370Sstevel@tonic-gate 	RSA_PKCS_MECH_INFO_TYPE,	/* SUN_CKM_RSA_PKCS */
2380Sstevel@tonic-gate 	RSA_X_509_MECH_INFO_TYPE,	/* SUN_CKM_RSA_X_509 */
2390Sstevel@tonic-gate 	MD5_RSA_PKCS_MECH_INFO_TYPE,	/* SUN_CKM_MD5_RSA_PKCS */
2400Sstevel@tonic-gate 	SHA1_RSA_PKCS_MECH_INFO_TYPE,	/* SUN_CKM_SHA1_RSA_PKCS */
241676Sizick 	SHA256_RSA_PKCS_MECH_INFO_TYPE,	/* SUN_CKM_SHA256_RSA_PKCS */
242676Sizick 	SHA384_RSA_PKCS_MECH_INFO_TYPE,	/* SUN_CKM_SHA384_RSA_PKCS */
243676Sizick 	SHA512_RSA_PKCS_MECH_INFO_TYPE,	/* SUN_CKM_SHA512_RSA_PKCS */
2440Sstevel@tonic-gate 	MD5_KEY_DERIVATION_MECH_INFO_TYPE, /* SUN_CKM_MD5_KEY_DERIVATION */
2450Sstevel@tonic-gate 	SHA1_KEY_DERIVATION_MECH_INFO_TYPE, /* SUN_CKM_SHA1_KEY_DERIVATION */
246676Sizick 	/* SUN_CKM_SHA256_KEY_DERIVATION */
247676Sizick 	SHA256_KEY_DERIVATION_MECH_INFO_TYPE,
248676Sizick 	/* SUN_CKM_SHA384_KEY_DERIVATION */
249676Sizick 	SHA384_KEY_DERIVATION_MECH_INFO_TYPE,
250676Sizick 	/* SUN_CKM_SHA512_KEY_DERIVATION */
251676Sizick 	SHA512_KEY_DERIVATION_MECH_INFO_TYPE,
2520Sstevel@tonic-gate 	DES_KEY_GEN_MECH_INFO_TYPE,	/* SUN_CKM_DES_KEY_GEN */
2530Sstevel@tonic-gate 	DES3_KEY_GEN_MECH_INFO_TYPE,	/* SUN_CKM_DES3_KEY_GEN */
2540Sstevel@tonic-gate 	AES_KEY_GEN_MECH_INFO_TYPE,	/* SUN_CKM_AES_KEY_GEN */
255676Sizick 	BLOWFISH_KEY_GEN_MECH_INFO_TYPE,	/* SUN_CKM_BLOWFISH_KEY_GEN */
2560Sstevel@tonic-gate 	RC4_KEY_GEN_MECH_INFO_TYPE,	/* SUN_CKM_RC4_KEY_GEN */
2575697Smcpowers 	EC_KEY_PAIR_GEN_MECH_INFO_TYPE,	/* SUN_CKM_EC_KEY_PAIR_GEN */
2585697Smcpowers 	ECDSA_MECH_INFO_TYPE,		/* SUN_CKM_ECDSA */
2595697Smcpowers 	ECDSA_SHA1_MECH_INFO_TYPE,	/* SUN_CKM_ECDSA_SHA1 */
2605697Smcpowers 	ECDH1_DERIVE_MECH_INFO_TYPE,	/* SUN_CKM_ECDH1_DERIVE */
2614424Sizick 	DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE, /* SUN_CKM_DH_PKCS_KEY_PAIR_GEN */
2624424Sizick 	DH_PKCS_DERIVE_MECH_INFO_TYPE,	/* SUN_CKM_DH_PKCS_DERIVE */
2630Sstevel@tonic-gate 	RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE /* SUN_CKM_RSA_PKCS_KEY_PAIR_GEN */
2640Sstevel@tonic-gate } dprov_mech_type_t;
2650Sstevel@tonic-gate 
2660Sstevel@tonic-gate /*
2670Sstevel@tonic-gate  * Mechanism info structure passed to KCF during registration.
2680Sstevel@tonic-gate  */
2690Sstevel@tonic-gate #define	MD5_DIGEST_LEN		16	/* MD5 digest size */
2700Sstevel@tonic-gate #define	MD5_HMAC_BLOCK_SIZE	64	/* MD5-HMAC block size */
2719364SVladimir.Kotal@Sun.COM #define	MD5_HMAC_MIN_KEY_LEN	1	/* MD5-HMAC min key length in bytes */
2729364SVladimir.Kotal@Sun.COM #define	MD5_HMAC_MAX_KEY_LEN	INT_MAX	/* MD5-HMAC max key length in bytes */
2730Sstevel@tonic-gate 
2740Sstevel@tonic-gate #define	SHA1_DIGEST_LEN		20	/* SHA1 digest size */
2750Sstevel@tonic-gate #define	SHA1_HMAC_BLOCK_SIZE	64	/* SHA1-HMAC block size */
2769364SVladimir.Kotal@Sun.COM #define	SHA1_HMAC_MIN_KEY_LEN	1	/* SHA1-HMAC min key length in bytes */
2779364SVladimir.Kotal@Sun.COM #define	SHA1_HMAC_MAX_KEY_LEN	INT_MAX	/* SHA1-HMAC max key length in bytes */
2780Sstevel@tonic-gate 
2790Sstevel@tonic-gate #define	DES_KEY_LEN		8	/* DES key length in bytes */
2800Sstevel@tonic-gate #define	DES3_KEY_LEN		24	/* DES3 key length in bytes */
2810Sstevel@tonic-gate 
282676Sizick #define	BLOWFISH_MIN_KEY_LEN	32	/* Blowfish min key length in bits */
283676Sizick #define	BLOWFISH_MAX_KEY_LEN	448	/* Blowfish max key length in bits */
2840Sstevel@tonic-gate 
2850Sstevel@tonic-gate #define	AES_MIN_KEY_LEN		16	/* AES min key length in bytes */
2860Sstevel@tonic-gate #define	AES_MAX_KEY_LEN		32	/* AES max key length in bytes */
2870Sstevel@tonic-gate 
2880Sstevel@tonic-gate #define	ARCFOUR_MIN_KEY_BITS	40	/* RC4 min supported key size */
2890Sstevel@tonic-gate #define	ARCFOUR_MAX_KEY_BITS	2048	/* RC4 max supported key size */
2900Sstevel@tonic-gate 
2910Sstevel@tonic-gate #define	RSA_MIN_KEY_LEN		256	/* RSA min key length in bits */
2920Sstevel@tonic-gate #define	RSA_MAX_KEY_LEN		4096	/* RSA max key length in bits */
2930Sstevel@tonic-gate 
2944424Sizick #define	DH_MIN_KEY_LEN		64	/* DH min key length in bits */
2954424Sizick #define	DH_MAX_KEY_LEN		4096	/* DH max key length in bits */
2964424Sizick 
2970Sstevel@tonic-gate #define	DPROV_CKM_MD5_KEY_DERIVATION	"CKM_MD5_KEY_DERIVATION"
2980Sstevel@tonic-gate #define	DPROV_CKM_SHA1_KEY_DERIVATION	"CKM_SHA1_KEY_DERIVATION"
299676Sizick #define	DPROV_CKM_SHA256_KEY_DERIVATION	"CKM_SHA256_KEY_DERIVATION"
300676Sizick #define	DPROV_CKM_SHA384_KEY_DERIVATION	"CKM_SHA384_KEY_DERIVATION"
301676Sizick #define	DPROV_CKM_SHA512_KEY_DERIVATION	"CKM_SHA512_KEY_DERIVATION"
3020Sstevel@tonic-gate #define	DPROV_CKM_DES_KEY_GEN		"CKM_DES_KEY_GEN"
3030Sstevel@tonic-gate #define	DPROV_CKM_DES3_KEY_GEN		"CKM_DES3_KEY_GEN"
3040Sstevel@tonic-gate #define	DPROV_CKM_AES_KEY_GEN		"CKM_AES_KEY_GEN"
305676Sizick #define	DPROV_CKM_BLOWFISH_KEY_GEN	"CKM_BLOWFISH_KEY_GEN"
3060Sstevel@tonic-gate #define	DPROV_CKM_RC4_KEY_GEN		"CKM_RC4_KEY_GEN"
3070Sstevel@tonic-gate #define	DPROV_CKM_RSA_PKCS_KEY_PAIR_GEN	"CKM_RSA_PKCS_KEY_PAIR_GEN"
3085697Smcpowers #define	DPROV_CKM_EC_KEY_PAIR_GEN	"CKM_EC_KEY_PAIR_GEN"
3095697Smcpowers #define	DPROV_CKM_ECDSA			"CKM_ECDSA"
3105697Smcpowers #define	DPROV_CKM_ECDSA_SHA1		"CKM_ECDSA_SHA1"
3115697Smcpowers #define	DPROV_CKM_ECDH1_DERIVE		"CKM_ECDH1_DERIVE"
3124424Sizick #define	DPROV_CKM_DH_PKCS_KEY_PAIR_GEN	"CKM_DH_PKCS_KEY_PAIR_GEN"
3134424Sizick #define	DPROV_CKM_DH_PKCS_DERIVE	"CKM_DH_PKCS_DERIVE"
3140Sstevel@tonic-gate 
3150Sstevel@tonic-gate static crypto_mech_info_t dprov_mech_info_tab[] = {
3164002Sdarrenm 	/* MD4 */
3174002Sdarrenm 	{SUN_CKM_MD4, MD4_MECH_INFO_TYPE,
3184002Sdarrenm 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
3194002Sdarrenm 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
3200Sstevel@tonic-gate 	/* MD5 */
3210Sstevel@tonic-gate 	{SUN_CKM_MD5, MD5_MECH_INFO_TYPE,
3220Sstevel@tonic-gate 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
3230Sstevel@tonic-gate 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
3240Sstevel@tonic-gate 	/* MD5-HMAC */
3250Sstevel@tonic-gate 	{SUN_CKM_MD5_HMAC, MD5_HMAC_MECH_INFO_TYPE,
3260Sstevel@tonic-gate 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
3270Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
3280Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
3290Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
3300Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
3310Sstevel@tonic-gate 	    MD5_HMAC_MIN_KEY_LEN, MD5_HMAC_MAX_KEY_LEN,
3329364SVladimir.Kotal@Sun.COM 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
3330Sstevel@tonic-gate 	/* MD5-HMAC GENERAL */
3340Sstevel@tonic-gate 	{SUN_CKM_MD5_HMAC_GENERAL, MD5_HMAC_GEN_MECH_INFO_TYPE,
3350Sstevel@tonic-gate 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
3360Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
3370Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
3380Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
3390Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
3400Sstevel@tonic-gate 	    MD5_HMAC_MIN_KEY_LEN, MD5_HMAC_MAX_KEY_LEN,
3419364SVladimir.Kotal@Sun.COM 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
3420Sstevel@tonic-gate 	/* SHA1 */
3430Sstevel@tonic-gate 	{SUN_CKM_SHA1, SHA1_MECH_INFO_TYPE,
3440Sstevel@tonic-gate 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
3450Sstevel@tonic-gate 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
3460Sstevel@tonic-gate 	/* SHA1-HMAC */
3470Sstevel@tonic-gate 	{SUN_CKM_SHA1_HMAC, SHA1_HMAC_MECH_INFO_TYPE,
3480Sstevel@tonic-gate 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
3490Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
3500Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
3510Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
3520Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
3530Sstevel@tonic-gate 	    SHA1_HMAC_MIN_KEY_LEN, SHA1_HMAC_MAX_KEY_LEN,
3549364SVladimir.Kotal@Sun.COM 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
3550Sstevel@tonic-gate 	/* SHA1-HMAC GENERAL */
3560Sstevel@tonic-gate 	{SUN_CKM_SHA1_HMAC_GENERAL, SHA1_HMAC_GEN_MECH_INFO_TYPE,
3570Sstevel@tonic-gate 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
3580Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
3590Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
3600Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
3610Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
3620Sstevel@tonic-gate 	    SHA1_HMAC_MIN_KEY_LEN, SHA1_HMAC_MAX_KEY_LEN,
3639364SVladimir.Kotal@Sun.COM 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
3640Sstevel@tonic-gate 	/* SHA256 */
3650Sstevel@tonic-gate 	{SUN_CKM_SHA256, SHA256_MECH_INFO_TYPE,
3660Sstevel@tonic-gate 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
3670Sstevel@tonic-gate 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
3680Sstevel@tonic-gate 	/* SHA256-HMAC */
3690Sstevel@tonic-gate 	{SUN_CKM_SHA256_HMAC, SHA256_HMAC_MECH_INFO_TYPE,
3700Sstevel@tonic-gate 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
3710Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
3720Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
3730Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
3740Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
3750Sstevel@tonic-gate 	    SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
3769364SVladimir.Kotal@Sun.COM 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
3770Sstevel@tonic-gate 	/* SHA256-HMAC GENERAL */
3780Sstevel@tonic-gate 	{SUN_CKM_SHA256_HMAC_GENERAL, SHA256_HMAC_GEN_MECH_INFO_TYPE,
3790Sstevel@tonic-gate 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
3800Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
3810Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
3820Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
3830Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
3840Sstevel@tonic-gate 	    SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
3859364SVladimir.Kotal@Sun.COM 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
3860Sstevel@tonic-gate 	/* SHA384 */
3870Sstevel@tonic-gate 	{SUN_CKM_SHA384, SHA384_MECH_INFO_TYPE,
3880Sstevel@tonic-gate 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
3890Sstevel@tonic-gate 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
3900Sstevel@tonic-gate 	/* SHA384-HMAC */
3910Sstevel@tonic-gate 	{SUN_CKM_SHA384_HMAC, SHA384_HMAC_MECH_INFO_TYPE,
3920Sstevel@tonic-gate 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
3930Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
3940Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
3950Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
3960Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
3970Sstevel@tonic-gate 	    SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
3989364SVladimir.Kotal@Sun.COM 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
3990Sstevel@tonic-gate 	/* SHA384-HMAC GENERAL */
4000Sstevel@tonic-gate 	{SUN_CKM_SHA384_HMAC_GENERAL, SHA384_HMAC_GEN_MECH_INFO_TYPE,
4010Sstevel@tonic-gate 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
4020Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
4030Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
4040Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
4050Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4060Sstevel@tonic-gate 	    SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
4079364SVladimir.Kotal@Sun.COM 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4080Sstevel@tonic-gate 	/* SHA512 */
4090Sstevel@tonic-gate 	{SUN_CKM_SHA512, SHA512_MECH_INFO_TYPE,
4100Sstevel@tonic-gate 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
4110Sstevel@tonic-gate 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
4120Sstevel@tonic-gate 	/* SHA512-HMAC */
4130Sstevel@tonic-gate 	{SUN_CKM_SHA512_HMAC, SHA512_HMAC_MECH_INFO_TYPE,
4140Sstevel@tonic-gate 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
4150Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
4160Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
4170Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
4180Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4190Sstevel@tonic-gate 	    SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
4209364SVladimir.Kotal@Sun.COM 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4210Sstevel@tonic-gate 	/* SHA512-HMAC GENERAL */
4220Sstevel@tonic-gate 	{SUN_CKM_SHA512_HMAC_GENERAL, SHA512_HMAC_GEN_MECH_INFO_TYPE,
4230Sstevel@tonic-gate 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
4240Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
4250Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
4260Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
4270Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4280Sstevel@tonic-gate 	    SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
4299364SVladimir.Kotal@Sun.COM 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4300Sstevel@tonic-gate 	/* DES-CBC */
4310Sstevel@tonic-gate 	{SUN_CKM_DES_CBC, DES_CBC_MECH_INFO_TYPE,
4320Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4330Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4340Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
4350Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4360Sstevel@tonic-gate 	    DES_KEY_LEN, DES_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4370Sstevel@tonic-gate 	/* DES3-CBC */
4380Sstevel@tonic-gate 	{SUN_CKM_DES3_CBC, DES3_CBC_MECH_INFO_TYPE,
4390Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4400Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4410Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
4420Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4430Sstevel@tonic-gate 	    DES3_KEY_LEN, DES3_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4440Sstevel@tonic-gate 	/* DES-ECB */
4450Sstevel@tonic-gate 	{SUN_CKM_DES_ECB, DES_ECB_MECH_INFO_TYPE,
4460Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4470Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4480Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
4490Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4500Sstevel@tonic-gate 	    DES_KEY_LEN, DES_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4510Sstevel@tonic-gate 	/* DES3-ECB */
4520Sstevel@tonic-gate 	{SUN_CKM_DES3_ECB, DES3_ECB_MECH_INFO_TYPE,
4530Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4540Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4550Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
4560Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4570Sstevel@tonic-gate 	    DES3_KEY_LEN, DES3_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
458676Sizick 	/* BLOWFISH-CBC */
459676Sizick 	{SUN_CKM_BLOWFISH_CBC, BLOWFISH_CBC_MECH_INFO_TYPE,
4600Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4610Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4620Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
463676Sizick 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC, BLOWFISH_MIN_KEY_LEN,
464676Sizick 	    BLOWFISH_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
465676Sizick 	/* BLOWFISH-ECB */
466676Sizick 	{SUN_CKM_BLOWFISH_ECB, BLOWFISH_ECB_MECH_INFO_TYPE,
4670Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4680Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4690Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
470676Sizick 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC, BLOWFISH_MIN_KEY_LEN,
471676Sizick 	    BLOWFISH_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
4720Sstevel@tonic-gate 	/* AES-CBC */
4730Sstevel@tonic-gate 	{SUN_CKM_AES_CBC, AES_CBC_MECH_INFO_TYPE,
4740Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4750Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4760Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
4770Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4780Sstevel@tonic-gate 	    AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4790Sstevel@tonic-gate 	/* AES-ECB */
4800Sstevel@tonic-gate 	{SUN_CKM_AES_ECB, AES_ECB_MECH_INFO_TYPE,
4810Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4820Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4830Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
4840Sstevel@tonic-gate 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4850Sstevel@tonic-gate 	    AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
486904Smcpowers 	/* AES-CTR */
487904Smcpowers 	{SUN_CKM_AES_CTR, AES_CTR_MECH_INFO_TYPE,
488904Smcpowers 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
489904Smcpowers 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
490904Smcpowers 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
491904Smcpowers 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
492904Smcpowers 	    AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4935413Sdinak 	/* AES-CCM */
4945413Sdinak 	{SUN_CKM_AES_CCM, AES_CCM_MECH_INFO_TYPE,
4955413Sdinak 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4965413Sdinak 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4975413Sdinak 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
4985413Sdinak 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4995413Sdinak 	    AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
5008005SMark.Powers@Sun.COM 	/* AES-GCM */
5018005SMark.Powers@Sun.COM 	{SUN_CKM_AES_GCM, AES_GCM_MECH_INFO_TYPE,
5028005SMark.Powers@Sun.COM 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
5038005SMark.Powers@Sun.COM 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
5048005SMark.Powers@Sun.COM 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
5058005SMark.Powers@Sun.COM 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
5068005SMark.Powers@Sun.COM 	    AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
5079339SMark.Powers@Sun.COM 	/* AES-GMAC */
5089339SMark.Powers@Sun.COM 	{SUN_CKM_AES_GMAC, AES_GMAC_MECH_INFO_TYPE,
5099339SMark.Powers@Sun.COM 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
5109339SMark.Powers@Sun.COM 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
5119339SMark.Powers@Sun.COM 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
5129339SMark.Powers@Sun.COM 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC |
5139339SMark.Powers@Sun.COM 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
5149339SMark.Powers@Sun.COM 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
5159339SMark.Powers@Sun.COM 	    AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
5160Sstevel@tonic-gate 	/* RC4 */
5170Sstevel@tonic-gate 	{SUN_CKM_RC4, RC4_MECH_INFO_TYPE,
5180Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
5190Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
5200Sstevel@tonic-gate 	    ARCFOUR_MIN_KEY_BITS, ARCFOUR_MAX_KEY_BITS,
5213708Skrishna 	    CRYPTO_KEYSIZE_UNIT_IN_BITS | CRYPTO_CAN_SHARE_OPSTATE},
5220Sstevel@tonic-gate 	/* RSA_PKCS */
5230Sstevel@tonic-gate 	{SUN_CKM_RSA_PKCS, RSA_PKCS_MECH_INFO_TYPE,
5240Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
5250Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC |
5260Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
5270Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
5280Sstevel@tonic-gate 	    CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC |
5290Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC,
5300Sstevel@tonic-gate 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
5310Sstevel@tonic-gate 	/* RSA_X_509 */
5320Sstevel@tonic-gate 	{SUN_CKM_RSA_X_509, RSA_X_509_MECH_INFO_TYPE,
5330Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
5340Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC |
5350Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
5360Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
5370Sstevel@tonic-gate 	    CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC |
5380Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC,
5390Sstevel@tonic-gate 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
5400Sstevel@tonic-gate 	/* MD5_RSA_PKCS */
5410Sstevel@tonic-gate 	{SUN_CKM_MD5_RSA_PKCS, MD5_RSA_PKCS_MECH_INFO_TYPE,
5420Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
5430Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
5440Sstevel@tonic-gate 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
5450Sstevel@tonic-gate 	/* SHA1_RSA_PKCS */
5460Sstevel@tonic-gate 	{SUN_CKM_SHA1_RSA_PKCS, SHA1_RSA_PKCS_MECH_INFO_TYPE,
5470Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
5480Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
5490Sstevel@tonic-gate 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
550676Sizick 	/* SHA256_RSA_PKCS */
551676Sizick 	{SUN_CKM_SHA256_RSA_PKCS, SHA256_RSA_PKCS_MECH_INFO_TYPE,
552676Sizick 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
553676Sizick 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
554676Sizick 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
555676Sizick 	/* SHA384_RSA_PKCS */
556676Sizick 	{SUN_CKM_SHA384_RSA_PKCS, SHA384_RSA_PKCS_MECH_INFO_TYPE,
557676Sizick 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
558676Sizick 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
559676Sizick 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
560676Sizick 	/* SHA512_RSA_PKCS */
561676Sizick 	{SUN_CKM_SHA512_RSA_PKCS, SHA512_RSA_PKCS_MECH_INFO_TYPE,
562676Sizick 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
563676Sizick 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
564676Sizick 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
5650Sstevel@tonic-gate 	/* MD5_KEY_DERIVATION */
5660Sstevel@tonic-gate 	{DPROV_CKM_MD5_KEY_DERIVATION, MD5_KEY_DERIVATION_MECH_INFO_TYPE,
5670Sstevel@tonic-gate 	    CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
5680Sstevel@tonic-gate 	/* SHA1_KEY_DERIVATION */
5690Sstevel@tonic-gate 	{DPROV_CKM_SHA1_KEY_DERIVATION, SHA1_KEY_DERIVATION_MECH_INFO_TYPE,
5700Sstevel@tonic-gate 	    CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
571676Sizick 	/* SHA256_KEY_DERIVATION */
572676Sizick 	{DPROV_CKM_SHA256_KEY_DERIVATION, SHA256_KEY_DERIVATION_MECH_INFO_TYPE,
573676Sizick 	    CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
574676Sizick 	/* SHA384_KEY_DERIVATION */
575676Sizick 	{DPROV_CKM_SHA384_KEY_DERIVATION, SHA384_KEY_DERIVATION_MECH_INFO_TYPE,
576676Sizick 	    CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
577676Sizick 	/* SHA512_KEY_DERIVATION */
578676Sizick 	{DPROV_CKM_SHA512_KEY_DERIVATION, SHA512_KEY_DERIVATION_MECH_INFO_TYPE,
579676Sizick 	    CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
5800Sstevel@tonic-gate 	/* DES_KEY_GENERATION */
5810Sstevel@tonic-gate 	{DPROV_CKM_DES_KEY_GEN, DES_KEY_GEN_MECH_INFO_TYPE,
5820Sstevel@tonic-gate 	    CRYPTO_FG_GENERATE, DES_KEY_LEN, DES_KEY_LEN,
5830Sstevel@tonic-gate 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
5840Sstevel@tonic-gate 	/* DES3_KEY_GENERATION */
5850Sstevel@tonic-gate 	{DPROV_CKM_DES3_KEY_GEN, DES3_KEY_GEN_MECH_INFO_TYPE,
5860Sstevel@tonic-gate 	    CRYPTO_FG_GENERATE, DES3_KEY_LEN, DES3_KEY_LEN,
5870Sstevel@tonic-gate 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
5880Sstevel@tonic-gate 	/* AES_KEY_GENERATION */
5890Sstevel@tonic-gate 	{DPROV_CKM_AES_KEY_GEN, AES_KEY_GEN_MECH_INFO_TYPE,
5900Sstevel@tonic-gate 	    CRYPTO_FG_GENERATE, AES_MIN_KEY_LEN, AES_MAX_KEY_LEN,
5910Sstevel@tonic-gate 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
592676Sizick 	/* BLOWFISH_KEY_GENERATION */
593676Sizick 	{DPROV_CKM_BLOWFISH_KEY_GEN, BLOWFISH_KEY_GEN_MECH_INFO_TYPE,
594676Sizick 	    CRYPTO_FG_GENERATE, BLOWFISH_MIN_KEY_LEN, BLOWFISH_MAX_KEY_LEN,
595676Sizick 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
5960Sstevel@tonic-gate 	/* RC4_KEY_GENERATION */
5970Sstevel@tonic-gate 	{DPROV_CKM_RC4_KEY_GEN, RC4_KEY_GEN_MECH_INFO_TYPE,
5980Sstevel@tonic-gate 	    CRYPTO_FG_GENERATE, ARCFOUR_MIN_KEY_BITS, ARCFOUR_MAX_KEY_BITS,
5990Sstevel@tonic-gate 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
6004424Sizick 	/* DH_PKCS_KEY_PAIR_GEN */
6014424Sizick 	{DPROV_CKM_DH_PKCS_KEY_PAIR_GEN, DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE,
6024424Sizick 	    CRYPTO_FG_GENERATE_KEY_PAIR, DH_MIN_KEY_LEN, DH_MAX_KEY_LEN,
6034424Sizick 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
6044424Sizick 	/* DH_PKCS_DERIVE */
6054424Sizick 	{DPROV_CKM_DH_PKCS_DERIVE, DH_PKCS_DERIVE_MECH_INFO_TYPE,
6064424Sizick 	    CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
6070Sstevel@tonic-gate 	/* RSA_PKCS_KEY_PAIR_GEN */
6080Sstevel@tonic-gate 	{DPROV_CKM_RSA_PKCS_KEY_PAIR_GEN, RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE,
6090Sstevel@tonic-gate 	    CRYPTO_FG_GENERATE_KEY_PAIR, RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN,
6105697Smcpowers 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
6115697Smcpowers 	/* EC_KEY_PAIR_GEN */
6125697Smcpowers 	{DPROV_CKM_EC_KEY_PAIR_GEN, EC_KEY_PAIR_GEN_MECH_INFO_TYPE,
6135697Smcpowers 	    CRYPTO_FG_GENERATE_KEY_PAIR, EC_MIN_KEY_LEN, EC_MAX_KEY_LEN,
6145697Smcpowers 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
6155697Smcpowers 	/* ECDSA */
6165697Smcpowers 	{DPROV_CKM_ECDSA, ECDSA_MECH_INFO_TYPE,
6175697Smcpowers 	    CRYPTO_FG_SIGN | CRYPTO_FG_VERIFY |
6185697Smcpowers 	    CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC |
6195697Smcpowers 	    EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
6205697Smcpowers 	/* ECDSA_SHA1 */
6215697Smcpowers 	{DPROV_CKM_ECDSA_SHA1, ECDSA_SHA1_MECH_INFO_TYPE,
6225697Smcpowers 	    CRYPTO_FG_SIGN | CRYPTO_FG_VERIFY |
6235697Smcpowers 	    CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC |
6245697Smcpowers 	    EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
6255697Smcpowers 	/* ECDH1_DERIVE */
6265697Smcpowers 	{DPROV_CKM_ECDH1_DERIVE, ECDH1_DERIVE_MECH_INFO_TYPE,
6275697Smcpowers 	    CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}
6280Sstevel@tonic-gate };
6290Sstevel@tonic-gate 
6304424Sizick /*
6314424Sizick  * Crypto Values
6324424Sizick  *
6334424Sizick  * These values are the used in the STC ef test suite.  If they are changed
6344424Sizick  * the test suite needs to be changed.
6354424Sizick  */
6364424Sizick static uchar_t dh_value[8] = { 'd', 'h', 'd', 'h', 'd', 'h', 'd', '\0' };
6374424Sizick char public_exponent[3] = { 0x01, 0x00, 0x01 };
6384424Sizick static uchar_t private_exponent[128] = {
6394424Sizick 	0x8e, 0xc9, 0x70, 0x57, 0x6b, 0xcd, 0xfb, 0xa9,
6404424Sizick 	0x19, 0xad, 0xcd, 0x91, 0x69, 0xd5, 0x52, 0xec,
6414424Sizick 	0x72, 0x1e, 0x45, 0x15, 0x06, 0xdc, 0x65, 0x2d,
6424424Sizick 	0x98, 0xc4, 0xce, 0x33, 0x54, 0x15, 0x70, 0x8d,
6434424Sizick 	0xfa, 0x65, 0xea, 0x53, 0x44, 0xf3, 0x3e, 0x3f,
6444424Sizick 	0xb4, 0x4c, 0x60, 0xd5, 0x01, 0x2d, 0xa4, 0x12,
6454424Sizick 	0x99, 0xbf, 0x3f, 0x0b, 0xcd, 0xbb, 0x24, 0x10,
6464424Sizick 	0x60, 0x30, 0x5e, 0x58, 0xf8, 0x59, 0xaa, 0xd1,
6474424Sizick 	0x63, 0x3b, 0xbc, 0xcb, 0x94, 0x58, 0x38, 0x24,
6484424Sizick 	0xfc, 0x65, 0x25, 0xc5, 0xa6, 0x51, 0xa2, 0x2e,
6494424Sizick 	0xf1, 0x5e, 0xf5, 0xc1, 0xf5, 0x46, 0xf7, 0xbd,
6504424Sizick 	0xc7, 0x62, 0xa8, 0xe2, 0x27, 0xd6, 0x94, 0x5b,
6514424Sizick 	0xd3, 0xa2, 0xb5, 0x76, 0x42, 0x67, 0x6b, 0x86,
6524424Sizick 	0x91, 0x97, 0x4d, 0x07, 0x92, 0x00, 0x4a, 0xdf,
6534424Sizick 	0x0b, 0x65, 0x64, 0x05, 0x03, 0x48, 0x27, 0xeb,
6544424Sizick 	0xce, 0x9a, 0x49, 0x7f, 0x3e, 0x10, 0xe0, 0x01
6554424Sizick };
6564424Sizick 
6574424Sizick static uchar_t modulus[128] = {
6584424Sizick 	0x94, 0x32, 0xb9, 0x12, 0x1d, 0x68, 0x2c, 0xda,
6594424Sizick 	0x2b, 0xe0, 0xe4, 0x97, 0x1b, 0x4d, 0xdc, 0x43,
6604424Sizick 	0xdf, 0x38, 0x6e, 0x7b, 0x9f, 0x07, 0x58, 0xae,
6614424Sizick 	0x9d, 0x82, 0x1e, 0xc7, 0xbc, 0x92, 0xbf, 0xd3,
6624424Sizick 	0xce, 0x00, 0xbb, 0x91, 0xc9, 0x79, 0x06, 0x03,
6634424Sizick 	0x1f, 0xbc, 0x9f, 0x94, 0x75, 0x29, 0x5f, 0xd7,
6644424Sizick 	0xc5, 0xf3, 0x73, 0x8a, 0xa4, 0x35, 0x43, 0x7a,
6654424Sizick 	0x00, 0x32, 0x97, 0x3e, 0x86, 0xef, 0x70, 0x6f,
6664424Sizick 	0x18, 0x56, 0x15, 0xaa, 0x6a, 0x87, 0xe7, 0x8d,
6674424Sizick 	0x7d, 0xdd, 0x1f, 0xa4, 0xe4, 0x31, 0xd4, 0x7a,
6684424Sizick 	0x8c, 0x0e, 0x20, 0xd2, 0x23, 0xf5, 0x57, 0x3c,
6694424Sizick 	0x1b, 0xa8, 0x44, 0xa4, 0x57, 0x8f, 0x33, 0x52,
6704424Sizick 	0xad, 0x83, 0xae, 0x4a, 0x97, 0xa6, 0x1e, 0xa6,
6714424Sizick 	0x2b, 0xfa, 0xea, 0xeb, 0x6e, 0x71, 0xb8, 0xb6,
6724424Sizick 	0x0a, 0x36, 0xed, 0x83, 0xce, 0xb0, 0xdf, 0xc1,
6734424Sizick 	0xd4, 0x3a, 0xe9, 0x99, 0x6f, 0xf3, 0x96, 0xb7
6744424Sizick };
6754424Sizick 
6764424Sizick 
6770Sstevel@tonic-gate static void dprov_provider_status(crypto_provider_handle_t, uint_t *);
6780Sstevel@tonic-gate 
6790Sstevel@tonic-gate static crypto_control_ops_t dprov_control_ops = {
6800Sstevel@tonic-gate 	dprov_provider_status
6810Sstevel@tonic-gate };
6820Sstevel@tonic-gate 
6830Sstevel@tonic-gate #define	DPROV_MANUFACTURER	"SUNW                            "
6840Sstevel@tonic-gate #define	DPROV_MODEL		"dprov           "
6850Sstevel@tonic-gate #define	DPROV_ALLSPACES		"                "
6860Sstevel@tonic-gate 
6870Sstevel@tonic-gate static int dprov_digest_init(crypto_ctx_t *, crypto_mechanism_t *,
6880Sstevel@tonic-gate     crypto_req_handle_t);
6890Sstevel@tonic-gate static int dprov_digest(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
6900Sstevel@tonic-gate     crypto_req_handle_t);
6910Sstevel@tonic-gate static int dprov_digest_update(crypto_ctx_t *, crypto_data_t *,
6920Sstevel@tonic-gate     crypto_req_handle_t);
6930Sstevel@tonic-gate static int dprov_digest_key(crypto_ctx_t *, crypto_key_t *,
6940Sstevel@tonic-gate     crypto_req_handle_t);
6950Sstevel@tonic-gate static int dprov_digest_final(crypto_ctx_t *, crypto_data_t *,
6960Sstevel@tonic-gate     crypto_req_handle_t);
6970Sstevel@tonic-gate static int dprov_digest_atomic(crypto_provider_handle_t, crypto_session_id_t,
6980Sstevel@tonic-gate     crypto_mechanism_t *, crypto_data_t *, crypto_data_t *,
6990Sstevel@tonic-gate     crypto_req_handle_t);
7000Sstevel@tonic-gate 
7010Sstevel@tonic-gate static crypto_digest_ops_t dprov_digest_ops = {
7020Sstevel@tonic-gate 	dprov_digest_init,
7030Sstevel@tonic-gate 	dprov_digest,
7040Sstevel@tonic-gate 	dprov_digest_update,
7050Sstevel@tonic-gate 	dprov_digest_key,
7060Sstevel@tonic-gate 	dprov_digest_final,
7070Sstevel@tonic-gate 	dprov_digest_atomic
7080Sstevel@tonic-gate };
7090Sstevel@tonic-gate 
7100Sstevel@tonic-gate static int dprov_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
7110Sstevel@tonic-gate     crypto_spi_ctx_template_t, crypto_req_handle_t);
7120Sstevel@tonic-gate static int dprov_mac(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
7130Sstevel@tonic-gate     crypto_req_handle_t);
7140Sstevel@tonic-gate static int dprov_mac_update(crypto_ctx_t *, crypto_data_t *,
7150Sstevel@tonic-gate     crypto_req_handle_t);
7160Sstevel@tonic-gate static int dprov_mac_final(crypto_ctx_t *, crypto_data_t *,
7170Sstevel@tonic-gate     crypto_req_handle_t);
7180Sstevel@tonic-gate static int dprov_mac_atomic(crypto_provider_handle_t, crypto_session_id_t,
7190Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
7200Sstevel@tonic-gate     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
7210Sstevel@tonic-gate static int dprov_mac_verify_atomic(crypto_provider_handle_t,
7220Sstevel@tonic-gate     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
7230Sstevel@tonic-gate     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
7240Sstevel@tonic-gate 
7250Sstevel@tonic-gate static crypto_mac_ops_t dprov_mac_ops = {
7260Sstevel@tonic-gate 	dprov_mac_init,
7270Sstevel@tonic-gate 	dprov_mac,
7280Sstevel@tonic-gate 	dprov_mac_update,
7290Sstevel@tonic-gate 	dprov_mac_final,
7300Sstevel@tonic-gate 	dprov_mac_atomic,
7310Sstevel@tonic-gate 	dprov_mac_verify_atomic
7320Sstevel@tonic-gate };
7330Sstevel@tonic-gate 
7340Sstevel@tonic-gate static int dprov_encrypt_init(crypto_ctx_t *, crypto_mechanism_t *,
7350Sstevel@tonic-gate     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
7360Sstevel@tonic-gate static int dprov_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
7370Sstevel@tonic-gate     crypto_req_handle_t);
7380Sstevel@tonic-gate static int dprov_encrypt_update(crypto_ctx_t *, crypto_data_t *,
7390Sstevel@tonic-gate     crypto_data_t *, crypto_req_handle_t);
7400Sstevel@tonic-gate static int dprov_encrypt_final(crypto_ctx_t *, crypto_data_t *,
7410Sstevel@tonic-gate     crypto_req_handle_t);
7420Sstevel@tonic-gate static int dprov_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
7430Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
7440Sstevel@tonic-gate     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
7450Sstevel@tonic-gate 
7460Sstevel@tonic-gate static int dprov_decrypt_init(crypto_ctx_t *, crypto_mechanism_t *,
7470Sstevel@tonic-gate     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
7480Sstevel@tonic-gate static int dprov_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
7490Sstevel@tonic-gate     crypto_req_handle_t);
7500Sstevel@tonic-gate static int dprov_decrypt_update(crypto_ctx_t *, crypto_data_t *,
7510Sstevel@tonic-gate     crypto_data_t *, crypto_req_handle_t);
7520Sstevel@tonic-gate static int dprov_decrypt_final(crypto_ctx_t *, crypto_data_t *,
7530Sstevel@tonic-gate     crypto_req_handle_t);
7540Sstevel@tonic-gate static int dprov_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
7550Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
7560Sstevel@tonic-gate     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
7570Sstevel@tonic-gate 
7580Sstevel@tonic-gate static crypto_cipher_ops_t dprov_cipher_ops = {
7590Sstevel@tonic-gate 	dprov_encrypt_init,
7600Sstevel@tonic-gate 	dprov_encrypt,
7610Sstevel@tonic-gate 	dprov_encrypt_update,
7620Sstevel@tonic-gate 	dprov_encrypt_final,
7630Sstevel@tonic-gate 	dprov_encrypt_atomic,
7640Sstevel@tonic-gate 	dprov_decrypt_init,
7650Sstevel@tonic-gate 	dprov_decrypt,
7660Sstevel@tonic-gate 	dprov_decrypt_update,
7670Sstevel@tonic-gate 	dprov_decrypt_final,
7680Sstevel@tonic-gate 	dprov_decrypt_atomic
7690Sstevel@tonic-gate };
7700Sstevel@tonic-gate 
7710Sstevel@tonic-gate static int dprov_sign_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
7720Sstevel@tonic-gate     crypto_spi_ctx_template_t, crypto_req_handle_t);
7730Sstevel@tonic-gate static int dprov_sign(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
7740Sstevel@tonic-gate     crypto_req_handle_t);
7750Sstevel@tonic-gate static int dprov_sign_update(crypto_ctx_t *, crypto_data_t *,
7760Sstevel@tonic-gate     crypto_req_handle_t);
7770Sstevel@tonic-gate static int dprov_sign_final(crypto_ctx_t *, crypto_data_t *,
7780Sstevel@tonic-gate     crypto_req_handle_t);
7790Sstevel@tonic-gate static int dprov_sign_atomic(crypto_provider_handle_t, crypto_session_id_t,
7800Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
7810Sstevel@tonic-gate     crypto_spi_ctx_template_t, crypto_req_handle_t);
7820Sstevel@tonic-gate static int dprov_sign_recover_init(crypto_ctx_t *, crypto_mechanism_t *,
7830Sstevel@tonic-gate     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
7840Sstevel@tonic-gate static int dprov_sign_recover(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
7850Sstevel@tonic-gate     crypto_req_handle_t);
7860Sstevel@tonic-gate static int dprov_sign_recover_atomic(crypto_provider_handle_t,
7870Sstevel@tonic-gate     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
7880Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
7890Sstevel@tonic-gate     crypto_req_handle_t);
7900Sstevel@tonic-gate 
7910Sstevel@tonic-gate static crypto_sign_ops_t dprov_sign_ops = {
7920Sstevel@tonic-gate 	dprov_sign_init,
7930Sstevel@tonic-gate 	dprov_sign,
7940Sstevel@tonic-gate 	dprov_sign_update,
7950Sstevel@tonic-gate 	dprov_sign_final,
7960Sstevel@tonic-gate 	dprov_sign_atomic,
7970Sstevel@tonic-gate 	dprov_sign_recover_init,
7980Sstevel@tonic-gate 	dprov_sign_recover,
7990Sstevel@tonic-gate 	dprov_sign_recover_atomic
8000Sstevel@tonic-gate };
8010Sstevel@tonic-gate 
8020Sstevel@tonic-gate static int dprov_verify_init(crypto_ctx_t *, crypto_mechanism_t *,
8030Sstevel@tonic-gate     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
8040Sstevel@tonic-gate static int dprov_verify(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
8050Sstevel@tonic-gate     crypto_req_handle_t);
8060Sstevel@tonic-gate static int dprov_verify_update(crypto_ctx_t *, crypto_data_t *,
8070Sstevel@tonic-gate     crypto_req_handle_t);
8080Sstevel@tonic-gate static int dprov_verify_final(crypto_ctx_t *, crypto_data_t *,
8090Sstevel@tonic-gate     crypto_req_handle_t);
8100Sstevel@tonic-gate static int dprov_verify_atomic(crypto_provider_handle_t, crypto_session_id_t,
8110Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
8120Sstevel@tonic-gate     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
8130Sstevel@tonic-gate static int dprov_verify_recover_init(crypto_ctx_t *, crypto_mechanism_t *,
8140Sstevel@tonic-gate     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
8150Sstevel@tonic-gate static int dprov_verify_recover(crypto_ctx_t *, crypto_data_t *,
8160Sstevel@tonic-gate     crypto_data_t *, crypto_req_handle_t);
8170Sstevel@tonic-gate static int dprov_verify_recover_atomic(crypto_provider_handle_t,
8180Sstevel@tonic-gate     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
8190Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
8200Sstevel@tonic-gate     crypto_req_handle_t);
8210Sstevel@tonic-gate 
8220Sstevel@tonic-gate static crypto_verify_ops_t dprov_verify_ops = {
8230Sstevel@tonic-gate 	dprov_verify_init,
8240Sstevel@tonic-gate 	dprov_verify,
8250Sstevel@tonic-gate 	dprov_verify_update,
8260Sstevel@tonic-gate 	dprov_verify_final,
8270Sstevel@tonic-gate 	dprov_verify_atomic,
8280Sstevel@tonic-gate 	dprov_verify_recover_init,
8290Sstevel@tonic-gate 	dprov_verify_recover,
8300Sstevel@tonic-gate 	dprov_verify_recover_atomic
8310Sstevel@tonic-gate };
8320Sstevel@tonic-gate 
8330Sstevel@tonic-gate static int dprov_digest_encrypt_update(crypto_ctx_t *, crypto_ctx_t *,
8340Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
8350Sstevel@tonic-gate static int dprov_decrypt_digest_update(crypto_ctx_t *, crypto_ctx_t *,
8360Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
8370Sstevel@tonic-gate static int dprov_sign_encrypt_update(crypto_ctx_t *, crypto_ctx_t *,
8380Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
8390Sstevel@tonic-gate static int dprov_decrypt_verify_update(crypto_ctx_t *, crypto_ctx_t *,
8400Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
8410Sstevel@tonic-gate 
8420Sstevel@tonic-gate static crypto_dual_ops_t dprov_dual_ops = {
8430Sstevel@tonic-gate 	dprov_digest_encrypt_update,
8440Sstevel@tonic-gate 	dprov_decrypt_digest_update,
8450Sstevel@tonic-gate 	dprov_sign_encrypt_update,
8460Sstevel@tonic-gate 	dprov_decrypt_verify_update
8470Sstevel@tonic-gate };
8480Sstevel@tonic-gate 
8490Sstevel@tonic-gate static int dprov_encrypt_mac_init(crypto_ctx_t *,
8500Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *,
8510Sstevel@tonic-gate     crypto_key_t *, crypto_spi_ctx_template_t,
8520Sstevel@tonic-gate     crypto_spi_ctx_template_t, crypto_req_handle_t);
8530Sstevel@tonic-gate static int dprov_encrypt_mac(crypto_ctx_t *,
8540Sstevel@tonic-gate     crypto_data_t *, crypto_dual_data_t *, crypto_data_t *,
8550Sstevel@tonic-gate     crypto_req_handle_t);
8560Sstevel@tonic-gate static int dprov_encrypt_mac_update(crypto_ctx_t *,
8570Sstevel@tonic-gate     crypto_data_t *, crypto_dual_data_t *, crypto_req_handle_t);
8580Sstevel@tonic-gate static int dprov_encrypt_mac_final(crypto_ctx_t *,
8590Sstevel@tonic-gate     crypto_dual_data_t *, crypto_data_t *, crypto_req_handle_t);
8600Sstevel@tonic-gate static int dprov_encrypt_mac_atomic(crypto_provider_handle_t,
8610Sstevel@tonic-gate     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
8620Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
8630Sstevel@tonic-gate     crypto_dual_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
8640Sstevel@tonic-gate     crypto_spi_ctx_template_t, crypto_req_handle_t);
8650Sstevel@tonic-gate 
8660Sstevel@tonic-gate static int dprov_mac_decrypt_init(crypto_ctx_t *,
8670Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *,
8680Sstevel@tonic-gate     crypto_key_t *, crypto_spi_ctx_template_t,
8690Sstevel@tonic-gate     crypto_spi_ctx_template_t, crypto_req_handle_t);
8700Sstevel@tonic-gate static int dprov_mac_decrypt(crypto_ctx_t *,
8710Sstevel@tonic-gate     crypto_dual_data_t *, crypto_data_t *, crypto_data_t *,
8720Sstevel@tonic-gate     crypto_req_handle_t);
8730Sstevel@tonic-gate static int dprov_mac_decrypt_update(crypto_ctx_t *,
8740Sstevel@tonic-gate     crypto_dual_data_t *, crypto_data_t *, crypto_req_handle_t);
8750Sstevel@tonic-gate static int dprov_mac_decrypt_final(crypto_ctx_t *,
8760Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
8770Sstevel@tonic-gate static int dprov_mac_decrypt_atomic(crypto_provider_handle_t,
8780Sstevel@tonic-gate     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
8790Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_dual_data_t *,
8800Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
8810Sstevel@tonic-gate     crypto_spi_ctx_template_t, crypto_req_handle_t);
8820Sstevel@tonic-gate static int dprov_mac_verify_decrypt_atomic(crypto_provider_handle_t,
8830Sstevel@tonic-gate     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
8840Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_dual_data_t *,
8850Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
8860Sstevel@tonic-gate     crypto_spi_ctx_template_t, crypto_req_handle_t);
8870Sstevel@tonic-gate 
8880Sstevel@tonic-gate static crypto_dual_cipher_mac_ops_t dprov_cipher_mac_ops = {
8890Sstevel@tonic-gate 	dprov_encrypt_mac_init,
8900Sstevel@tonic-gate 	dprov_encrypt_mac,
8910Sstevel@tonic-gate 	dprov_encrypt_mac_update,
8920Sstevel@tonic-gate 	dprov_encrypt_mac_final,
8930Sstevel@tonic-gate 	dprov_encrypt_mac_atomic,
8940Sstevel@tonic-gate 	dprov_mac_decrypt_init,
8950Sstevel@tonic-gate 	dprov_mac_decrypt,
8960Sstevel@tonic-gate 	dprov_mac_decrypt_update,
8970Sstevel@tonic-gate 	dprov_mac_decrypt_final,
8980Sstevel@tonic-gate 	dprov_mac_decrypt_atomic,
8990Sstevel@tonic-gate 	dprov_mac_verify_decrypt_atomic
9000Sstevel@tonic-gate };
9010Sstevel@tonic-gate 
9020Sstevel@tonic-gate static int dprov_seed_random(crypto_provider_handle_t, crypto_session_id_t,
9031920Smcpowers     uchar_t *, size_t, uint_t, uint32_t, crypto_req_handle_t);
9040Sstevel@tonic-gate static int dprov_generate_random(crypto_provider_handle_t, crypto_session_id_t,
9050Sstevel@tonic-gate     uchar_t *, size_t, crypto_req_handle_t);
9060Sstevel@tonic-gate 
9070Sstevel@tonic-gate static crypto_random_number_ops_t dprov_random_number_ops = {
9080Sstevel@tonic-gate 	dprov_seed_random,
9090Sstevel@tonic-gate 	dprov_generate_random
9100Sstevel@tonic-gate };
9110Sstevel@tonic-gate 
9120Sstevel@tonic-gate static int dprov_session_open(crypto_provider_handle_t, crypto_session_id_t *,
9130Sstevel@tonic-gate     crypto_req_handle_t);
9140Sstevel@tonic-gate static int dprov_session_close(crypto_provider_handle_t, crypto_session_id_t,
9150Sstevel@tonic-gate     crypto_req_handle_t);
9160Sstevel@tonic-gate static int dprov_session_login(crypto_provider_handle_t, crypto_session_id_t,
9170Sstevel@tonic-gate     crypto_user_type_t, char *, size_t, crypto_req_handle_t);
9180Sstevel@tonic-gate static int dprov_session_logout(crypto_provider_handle_t, crypto_session_id_t,
9190Sstevel@tonic-gate     crypto_req_handle_t);
9200Sstevel@tonic-gate 
9210Sstevel@tonic-gate static crypto_session_ops_t dprov_session_ops = {
9220Sstevel@tonic-gate 	dprov_session_open,
9230Sstevel@tonic-gate 	dprov_session_close,
9240Sstevel@tonic-gate 	dprov_session_login,
9250Sstevel@tonic-gate 	dprov_session_logout
9260Sstevel@tonic-gate };
9270Sstevel@tonic-gate 
9280Sstevel@tonic-gate static int dprov_object_create(crypto_provider_handle_t, crypto_session_id_t,
9290Sstevel@tonic-gate     crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
9300Sstevel@tonic-gate     crypto_req_handle_t);
9310Sstevel@tonic-gate static int dprov_object_copy(crypto_provider_handle_t, crypto_session_id_t,
9320Sstevel@tonic-gate     crypto_object_id_t, crypto_object_attribute_t *, uint_t,
9330Sstevel@tonic-gate     crypto_object_id_t *, crypto_req_handle_t);
9340Sstevel@tonic-gate static int dprov_object_destroy(crypto_provider_handle_t, crypto_session_id_t,
9350Sstevel@tonic-gate     crypto_object_id_t, crypto_req_handle_t);
9360Sstevel@tonic-gate static int dprov_object_get_size(crypto_provider_handle_t, crypto_session_id_t,
9370Sstevel@tonic-gate     crypto_object_id_t, size_t *, crypto_req_handle_t);
9380Sstevel@tonic-gate static int dprov_object_get_attribute_value(crypto_provider_handle_t,
9390Sstevel@tonic-gate     crypto_session_id_t, crypto_object_id_t,
9400Sstevel@tonic-gate     crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
9410Sstevel@tonic-gate static int dprov_object_set_attribute_value(crypto_provider_handle_t,
9420Sstevel@tonic-gate     crypto_session_id_t, crypto_object_id_t,
9430Sstevel@tonic-gate     crypto_object_attribute_t *,  uint_t, crypto_req_handle_t);
9440Sstevel@tonic-gate static int dprov_object_find_init(crypto_provider_handle_t, crypto_session_id_t,
9450Sstevel@tonic-gate     crypto_object_attribute_t *, uint_t, void **,
9460Sstevel@tonic-gate     crypto_req_handle_t);
9470Sstevel@tonic-gate static int dprov_object_find(crypto_provider_handle_t, void *,
9480Sstevel@tonic-gate     crypto_object_id_t *, uint_t, uint_t *, crypto_req_handle_t);
9490Sstevel@tonic-gate static int dprov_object_find_final(crypto_provider_handle_t, void *,
9500Sstevel@tonic-gate     crypto_req_handle_t);
9510Sstevel@tonic-gate 
9520Sstevel@tonic-gate static crypto_object_ops_t dprov_object_ops = {
9530Sstevel@tonic-gate 	dprov_object_create,
9540Sstevel@tonic-gate 	dprov_object_copy,
9550Sstevel@tonic-gate 	dprov_object_destroy,
9560Sstevel@tonic-gate 	dprov_object_get_size,
9570Sstevel@tonic-gate 	dprov_object_get_attribute_value,
9580Sstevel@tonic-gate 	dprov_object_set_attribute_value,
9590Sstevel@tonic-gate 	dprov_object_find_init,
9600Sstevel@tonic-gate 	dprov_object_find,
9610Sstevel@tonic-gate 	dprov_object_find_final
9620Sstevel@tonic-gate };
9630Sstevel@tonic-gate 
9640Sstevel@tonic-gate static int dprov_key_generate(crypto_provider_handle_t, crypto_session_id_t,
9650Sstevel@tonic-gate     crypto_mechanism_t *, crypto_object_attribute_t *, uint_t,
9660Sstevel@tonic-gate     crypto_object_id_t *, crypto_req_handle_t);
9670Sstevel@tonic-gate static int dprov_key_generate_pair(crypto_provider_handle_t,
9680Sstevel@tonic-gate     crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *,
9690Sstevel@tonic-gate     uint_t, crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
9700Sstevel@tonic-gate     crypto_object_id_t *, crypto_req_handle_t);
9710Sstevel@tonic-gate static int dprov_key_wrap(crypto_provider_handle_t, crypto_session_id_t,
9720Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_object_id_t *,
9730Sstevel@tonic-gate     uchar_t *, size_t *, crypto_req_handle_t);
9740Sstevel@tonic-gate static int dprov_key_unwrap(crypto_provider_handle_t, crypto_session_id_t,
9750Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, uchar_t *, size_t *,
9760Sstevel@tonic-gate     crypto_object_attribute_t *, uint_t,
9770Sstevel@tonic-gate     crypto_object_id_t *, crypto_req_handle_t);
9780Sstevel@tonic-gate static int dprov_key_derive(crypto_provider_handle_t, crypto_session_id_t,
9790Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_object_attribute_t *,
9800Sstevel@tonic-gate     uint_t, crypto_object_id_t *, crypto_req_handle_t);
9810Sstevel@tonic-gate 
9820Sstevel@tonic-gate static crypto_key_ops_t dprov_key_ops = {
9830Sstevel@tonic-gate 	dprov_key_generate,
9840Sstevel@tonic-gate 	dprov_key_generate_pair,
9850Sstevel@tonic-gate 	dprov_key_wrap,
9860Sstevel@tonic-gate 	dprov_key_unwrap,
9870Sstevel@tonic-gate 	dprov_key_derive
9880Sstevel@tonic-gate };
9890Sstevel@tonic-gate 
9900Sstevel@tonic-gate static int dprov_ext_info(crypto_provider_handle_t,
9910Sstevel@tonic-gate     crypto_provider_ext_info_t *, crypto_req_handle_t);
9920Sstevel@tonic-gate static int dprov_init_token(crypto_provider_handle_t, char *, size_t,
9930Sstevel@tonic-gate     char *, crypto_req_handle_t);
9940Sstevel@tonic-gate static int dprov_init_pin(crypto_provider_handle_t, crypto_session_id_t,
9950Sstevel@tonic-gate     char *, size_t, crypto_req_handle_t);
9960Sstevel@tonic-gate static int dprov_set_pin(crypto_provider_handle_t, crypto_session_id_t,
9970Sstevel@tonic-gate     char *, size_t, char *, size_t, crypto_req_handle_t);
9980Sstevel@tonic-gate 
9990Sstevel@tonic-gate static crypto_provider_management_ops_t dprov_management_ops = {
10000Sstevel@tonic-gate 	dprov_ext_info,
10010Sstevel@tonic-gate 	dprov_init_token,
10020Sstevel@tonic-gate 	dprov_init_pin,
10030Sstevel@tonic-gate 	dprov_set_pin
10040Sstevel@tonic-gate };
10050Sstevel@tonic-gate 
10060Sstevel@tonic-gate static int dprov_free_context(crypto_ctx_t *);
1007904Smcpowers static int dprov_copyin_mechanism(crypto_provider_handle_t,
1008904Smcpowers     crypto_mechanism_t *, crypto_mechanism_t *, int *error, int);
1009904Smcpowers static int dprov_copyout_mechanism(crypto_provider_handle_t,
1010904Smcpowers     crypto_mechanism_t *, crypto_mechanism_t *, int *error, int);
1011904Smcpowers static int dprov_free_mechanism(crypto_provider_handle_t,
1012904Smcpowers     crypto_mechanism_t *);
10130Sstevel@tonic-gate 
10140Sstevel@tonic-gate static crypto_ctx_ops_t dprov_ctx_ops = {
10150Sstevel@tonic-gate 	NULL,
10160Sstevel@tonic-gate 	dprov_free_context
10170Sstevel@tonic-gate };
10180Sstevel@tonic-gate 
1019904Smcpowers static crypto_mech_ops_t dprov_mech_ops = {
1020904Smcpowers 	dprov_copyin_mechanism,
1021904Smcpowers 	dprov_copyout_mechanism,
1022904Smcpowers 	dprov_free_mechanism
1023904Smcpowers };
1024904Smcpowers 
10254219Smcpowers static int dprov_nostore_key_generate(crypto_provider_handle_t,
10264219Smcpowers     crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *,
10274219Smcpowers     uint_t, crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
10284424Sizick static int dprov_nostore_key_generate_pair(crypto_provider_handle_t,
10294424Sizick     crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *,
10304424Sizick     uint_t, crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *,
10314424Sizick     uint_t, crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
10324424Sizick static int dprov_nostore_key_derive(crypto_provider_handle_t,
10334424Sizick     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
10344424Sizick     crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *,
10354424Sizick     uint_t, crypto_req_handle_t);
10364219Smcpowers 
10374219Smcpowers static crypto_nostore_key_ops_t dprov_nostore_key_ops = {
10384219Smcpowers 	dprov_nostore_key_generate,
10394424Sizick 	dprov_nostore_key_generate_pair,
10404424Sizick 	dprov_nostore_key_derive
10414219Smcpowers };
10424219Smcpowers 
10430Sstevel@tonic-gate static crypto_ops_t dprov_crypto_ops = {
10440Sstevel@tonic-gate 	&dprov_control_ops,
10450Sstevel@tonic-gate 	&dprov_digest_ops,
10460Sstevel@tonic-gate 	&dprov_cipher_ops,
10470Sstevel@tonic-gate 	&dprov_mac_ops,
10480Sstevel@tonic-gate 	&dprov_sign_ops,
10490Sstevel@tonic-gate 	&dprov_verify_ops,
10500Sstevel@tonic-gate 	&dprov_dual_ops,
10510Sstevel@tonic-gate 	&dprov_cipher_mac_ops,
10520Sstevel@tonic-gate 	&dprov_random_number_ops,
10530Sstevel@tonic-gate 	&dprov_session_ops,
10540Sstevel@tonic-gate 	&dprov_object_ops,
10550Sstevel@tonic-gate 	&dprov_key_ops,
10560Sstevel@tonic-gate 	&dprov_management_ops,
1057904Smcpowers 	&dprov_ctx_ops,
1058904Smcpowers 	&dprov_mech_ops
10590Sstevel@tonic-gate };
10600Sstevel@tonic-gate 
10610Sstevel@tonic-gate 
10620Sstevel@tonic-gate /* maximum SO and user PIN lengths */
10630Sstevel@tonic-gate #define	DPROV_MAX_PIN_LEN	128
10640Sstevel@tonic-gate 
10650Sstevel@tonic-gate /*
10660Sstevel@tonic-gate  * Objects: each session is associated with an array of objects.
10670Sstevel@tonic-gate  * Unlike PKCS#11, the objects cannot be shared between sessions.
10680Sstevel@tonic-gate  * The ioctl driver multiplexes PKCS#11 sessions to providers
10690Sstevel@tonic-gate  * sessions in order to support this semantic. This simplifies
10700Sstevel@tonic-gate  * the CSPI greatly since the provider does not have to associate
10710Sstevel@tonic-gate  * sessions with a user space process.
10720Sstevel@tonic-gate  * There is also a per-instance array of objects, which correspond
10730Sstevel@tonic-gate  * to PKCS#11 token objects. These objects can be shared by multiple
10740Sstevel@tonic-gate  * sesions.
10750Sstevel@tonic-gate  *
10760Sstevel@tonic-gate  * Token objects are identified by having a CKA_TOKEN attribute B_TRUE.
10770Sstevel@tonic-gate  * Private objects are identified by having a CKA_PRIVATE attribute
10780Sstevel@tonic-gate  * set to B_TRUE.
10790Sstevel@tonic-gate  */
10800Sstevel@tonic-gate 
10810Sstevel@tonic-gate #define	DPROV_MAX_OBJECTS	128	/* max # of objects */
10820Sstevel@tonic-gate #define	DPROV_MAX_ATTR		64	/* max # of attributes per object */
10830Sstevel@tonic-gate 
10840Sstevel@tonic-gate /* object description */
10850Sstevel@tonic-gate typedef struct dprov_object {
10860Sstevel@tonic-gate 	crypto_object_attribute_t do_attr[DPROV_MAX_ATTR]; /* attributes */
10870Sstevel@tonic-gate 	uint_t do_token_idx;		/* index in per-instance table */
10880Sstevel@tonic-gate 					/* for token objects. */
10890Sstevel@tonic-gate 	boolean_t do_destroyed;		/* object has been destroyed. */
10900Sstevel@tonic-gate 					/* keep object around until all */
10910Sstevel@tonic-gate 					/* sessions that refer to it */
10920Sstevel@tonic-gate 					/* are closed, but mark it */
10930Sstevel@tonic-gate 					/* destroyed so that references */
10940Sstevel@tonic-gate 					/* to the object fail. */
10950Sstevel@tonic-gate 					/* used for token objects only */
10960Sstevel@tonic-gate 	uint_t do_refcnt;
10970Sstevel@tonic-gate } dprov_object_t;
10980Sstevel@tonic-gate 
10990Sstevel@tonic-gate /*
11000Sstevel@tonic-gate  * If a session has a reference to a dprov_object_t,
11010Sstevel@tonic-gate  * it REFHOLD()s.
11020Sstevel@tonic-gate  */
11030Sstevel@tonic-gate #define	DPROV_OBJECT_REFHOLD(object) {		\
11040Sstevel@tonic-gate 	atomic_add_32(&(object)->do_refcnt, 1);	\
11050Sstevel@tonic-gate 	ASSERT((object)->do_refcnt != 0);		\
11060Sstevel@tonic-gate }
11070Sstevel@tonic-gate 
11080Sstevel@tonic-gate /*
11090Sstevel@tonic-gate  * Releases a reference to an object. When the last
11100Sstevel@tonic-gate  * reference is released, the object is freed.
11110Sstevel@tonic-gate  */
11120Sstevel@tonic-gate #define	DPROV_OBJECT_REFRELE(object) {				\
11130Sstevel@tonic-gate 	ASSERT((object)->do_refcnt != 0);			\
11140Sstevel@tonic-gate 	membar_exit();						\
11150Sstevel@tonic-gate 	if (atomic_add_32_nv(&(object)->do_refcnt, -1) == 0)	\
11160Sstevel@tonic-gate 		dprov_free_object(object);			\
11170Sstevel@tonic-gate }
11180Sstevel@tonic-gate 
11190Sstevel@tonic-gate /*
11200Sstevel@tonic-gate  * Object attributes are passed to the provider using crypto_object_attribute
11210Sstevel@tonic-gate  * structures, which contain the type of the attribute, a pointer to
11220Sstevel@tonic-gate  * it's value, and the length of its value. The attribute types values
11230Sstevel@tonic-gate  * are defined by the PKCS#11 specification. This provider only cares
11240Sstevel@tonic-gate  * about a subset of these attributes. In order to avoid having to
11250Sstevel@tonic-gate  * include the PKCS#11 header files, we define here the attributes values
11260Sstevel@tonic-gate  * which are used by the provider.
11270Sstevel@tonic-gate  */
11280Sstevel@tonic-gate 
11290Sstevel@tonic-gate #define	DPROV_CKA_CLASS			0x00000000
11300Sstevel@tonic-gate #define	DPROV_CKA_TOKEN			0x00000001
11310Sstevel@tonic-gate #define	DPROV_CKA_PRIVATE		0x00000002
11320Sstevel@tonic-gate #define	DPROV_CKA_VALUE			0x00000011
1133904Smcpowers #define	DPROV_CKA_CERTIFICATE_TYPE	0x00000080
11340Sstevel@tonic-gate #define	DPROV_CKA_KEY_TYPE		0x00000100
11354219Smcpowers #define	DPROV_CKA_SENSITIVE		0x00000103
11360Sstevel@tonic-gate #define	DPROV_CKA_ENCRYPT		0x00000104
11370Sstevel@tonic-gate #define	DPROV_CKA_DECRYPT		0x00000105
11380Sstevel@tonic-gate #define	DPROV_CKA_WRAP			0x00000106
11390Sstevel@tonic-gate #define	DPROV_CKA_UNWRAP		0x00000107
11400Sstevel@tonic-gate #define	DPROV_CKA_SIGN			0x00000108
11410Sstevel@tonic-gate #define	DPROV_CKA_SIGN_RECOVER		0x00000109
11420Sstevel@tonic-gate #define	DPROV_CKA_VERIFY		0x0000010A
11430Sstevel@tonic-gate #define	DPROV_CKA_VERIFY_RECOVER	0x0000010B
11440Sstevel@tonic-gate #define	DPROV_CKA_DERIVE		0x0000010C
11450Sstevel@tonic-gate #define	DPROV_CKA_MODULUS		0x00000120
11460Sstevel@tonic-gate #define	DPROV_CKA_MODULUS_BITS		0x00000121
11470Sstevel@tonic-gate #define	DPROV_CKA_PUBLIC_EXPONENT	0x00000122
11480Sstevel@tonic-gate #define	DPROV_CKA_PRIVATE_EXPONENT	0x00000123
11494424Sizick #define	DPROV_CKA_PRIME			0x00000130
11504424Sizick #define	DPROV_CKA_BASE			0x00000132
11510Sstevel@tonic-gate #define	DPROV_CKA_VALUE_BITS		0x00000160
11520Sstevel@tonic-gate #define	DPROV_CKA_VALUE_LEN		0x00000161
11530Sstevel@tonic-gate #define	DPROV_CKA_EXTRACTABLE		0x00000162
11545697Smcpowers #define	DPROV_CKA_EC_PARAMS		0x00000180
11555697Smcpowers #define	DPROV_CKA_EC_POINT		0x00000181
1156904Smcpowers #define	DPROV_HW_FEATURE_TYPE		0x00000300
11570Sstevel@tonic-gate 
11580Sstevel@tonic-gate /*
11590Sstevel@tonic-gate  * Object classes from PKCS#11
11600Sstevel@tonic-gate  */
11610Sstevel@tonic-gate #define	DPROV_CKO_DATA			0x00000000
11620Sstevel@tonic-gate #define	DPROV_CKO_CERTIFICATE		0x00000001
11630Sstevel@tonic-gate #define	DPROV_CKO_PUBLIC_KEY		0x00000002
11640Sstevel@tonic-gate #define	DPROV_CKO_PRIVATE_KEY		0x00000003
11650Sstevel@tonic-gate #define	DPROV_CKO_SECRET_KEY		0x00000004
11660Sstevel@tonic-gate #define	DPROV_CKO_HW_FEATURE		0x00000005
11670Sstevel@tonic-gate #define	DPROV_CKO_DOMAIN_PARAMETERS	0x00000006
11680Sstevel@tonic-gate #define	DPROV_CKO_VENDOR_DEFINED	0x80000000
11690Sstevel@tonic-gate 
11700Sstevel@tonic-gate /*
11710Sstevel@tonic-gate  * A few key types from PKCS#11
11720Sstevel@tonic-gate  */
11730Sstevel@tonic-gate #define	DPROV_CKK_RSA			0x00000000
11740Sstevel@tonic-gate #define	DPROV_CKK_GENERIC_SECRET	0x00000010
11750Sstevel@tonic-gate #define	DPROV_CKK_RC4			0x00000012
11760Sstevel@tonic-gate #define	DPROV_CKK_DES			0x00000013
11770Sstevel@tonic-gate #define	DPROV_CKK_DES3			0x00000015
11780Sstevel@tonic-gate #define	DPROV_CKK_AES			0x0000001F
1179676Sizick #define	DPROV_CKK_BLOWFISH		0x00000020
11800Sstevel@tonic-gate 
11810Sstevel@tonic-gate /*
11820Sstevel@tonic-gate  * Find object context. Allows the find object init/find/final
11830Sstevel@tonic-gate  * to store data persistent across calls.
11840Sstevel@tonic-gate  */
11850Sstevel@tonic-gate typedef struct dprov_find_ctx {
11860Sstevel@tonic-gate 	crypto_object_id_t fc_ids[DPROV_MAX_OBJECTS];	/* object ids */
11870Sstevel@tonic-gate 	uint_t fc_nids;			/* number of ids in fc_ids */
11880Sstevel@tonic-gate 	uint_t fc_next;			/* next id to return */
11890Sstevel@tonic-gate } dprov_find_ctx_t;
11900Sstevel@tonic-gate 
11910Sstevel@tonic-gate /*
11920Sstevel@tonic-gate  * Session management: each instance is associated with an array
11930Sstevel@tonic-gate  * of sessions. KEF providers sessions are always R/W the library and
11940Sstevel@tonic-gate  * the ioctl maintain the PKCS#11 R/W attributes for the session.
11950Sstevel@tonic-gate  */
11960Sstevel@tonic-gate 
11970Sstevel@tonic-gate #define	DPROV_MIN_SESSIONS	32	/* # of sessions to start with */
11980Sstevel@tonic-gate 
11990Sstevel@tonic-gate typedef enum dprov_session_state {
12000Sstevel@tonic-gate 	DPROV_SESSION_STATE_PUBLIC,	/* public (default) */
12010Sstevel@tonic-gate 	DPROV_SESSION_STATE_SO,		/* SO logged in */
12020Sstevel@tonic-gate 	DPROV_SESSION_STATE_USER	/* user logged in */
12030Sstevel@tonic-gate } dprov_session_state_t;
12040Sstevel@tonic-gate 
12050Sstevel@tonic-gate /* session description */
12060Sstevel@tonic-gate typedef struct dprov_session {
12070Sstevel@tonic-gate 	dprov_session_state_t ds_state;	/* session state */
12080Sstevel@tonic-gate 	dprov_object_t *ds_objects[DPROV_MAX_OBJECTS];	/* session objects */
12090Sstevel@tonic-gate } dprov_session_t;
12100Sstevel@tonic-gate 
12110Sstevel@tonic-gate 
12120Sstevel@tonic-gate static crypto_provider_info_t dprov_prov_info = {
1213904Smcpowers 	CRYPTO_SPI_VERSION_2,
12140Sstevel@tonic-gate 	"Dummy Pseudo HW Provider",
12150Sstevel@tonic-gate 	CRYPTO_HW_PROVIDER,
12160Sstevel@tonic-gate 	NULL,				/* pi_provider_dev */
12170Sstevel@tonic-gate 	NULL,				/* pi_provider_handle */
12180Sstevel@tonic-gate 	&dprov_crypto_ops,
12190Sstevel@tonic-gate 	sizeof (dprov_mech_info_tab)/sizeof (crypto_mech_info_t),
12200Sstevel@tonic-gate 	dprov_mech_info_tab,
12210Sstevel@tonic-gate 	0,				/* pi_logical_provider_count */
12224072Skrishna 	NULL,				/* pi_logical_providers */
12234072Skrishna 	0				/* pi_flags */
12240Sstevel@tonic-gate };
12250Sstevel@tonic-gate 
12260Sstevel@tonic-gate /*
12270Sstevel@tonic-gate  * Per-instance info.
12280Sstevel@tonic-gate  */
12290Sstevel@tonic-gate typedef struct dprov_state {
12300Sstevel@tonic-gate 	kmutex_t ds_lock;		/* per-instance lock */
12310Sstevel@tonic-gate 	dev_info_t *ds_dip;		/* device info */
12320Sstevel@tonic-gate 	crypto_kcf_provider_handle_t ds_prov_handle;	/* framework handle */
12330Sstevel@tonic-gate 	taskq_t *ds_taskq;		/* taskq for async behavior */
12340Sstevel@tonic-gate 	char ds_user_pin[DPROV_MAX_PIN_LEN];	/* normal user PIN */
12350Sstevel@tonic-gate 	uint_t ds_user_pin_len;
12360Sstevel@tonic-gate 	char ds_so_pin[DPROV_MAX_PIN_LEN];	/* SO PIN */
12370Sstevel@tonic-gate 	uint_t ds_so_pin_len;
12380Sstevel@tonic-gate 	dprov_session_t **ds_sessions;	/* sessions for this instance */
12390Sstevel@tonic-gate 	uint_t ds_sessions_slots;	/* number of session slots */
12400Sstevel@tonic-gate 	uint_t ds_sessions_count;	/* number of open sessions */
12410Sstevel@tonic-gate 	boolean_t ds_token_initialized;	/* provider initialized? */
12420Sstevel@tonic-gate 	boolean_t ds_user_pin_set;	/* user pin set? */
12430Sstevel@tonic-gate 	char ds_label[CRYPTO_EXT_SIZE_LABEL];		/* "token" label */
12440Sstevel@tonic-gate 	dprov_object_t *ds_objects[DPROV_MAX_OBJECTS];	/* "token" objects */
12450Sstevel@tonic-gate } dprov_state_t;
12460Sstevel@tonic-gate 
12470Sstevel@tonic-gate 
12480Sstevel@tonic-gate /*
12490Sstevel@tonic-gate  * A taskq is associated with each instance of the pseudo driver in order
12500Sstevel@tonic-gate  * to simulate the asynchronous execution of requests.
12510Sstevel@tonic-gate  * The following defines the taskq request structures.
12520Sstevel@tonic-gate  */
12530Sstevel@tonic-gate 
12540Sstevel@tonic-gate /* request types */
12550Sstevel@tonic-gate typedef enum dprov_req_type {
12560Sstevel@tonic-gate 	/* digest requests */
12570Sstevel@tonic-gate 	DPROV_REQ_DIGEST_INIT = 1,
12580Sstevel@tonic-gate 	DPROV_REQ_DIGEST,
12590Sstevel@tonic-gate 	DPROV_REQ_DIGEST_UPDATE,
12600Sstevel@tonic-gate 	DPROV_REQ_DIGEST_KEY,
12610Sstevel@tonic-gate 	DPROV_REQ_DIGEST_FINAL,
12620Sstevel@tonic-gate 	DPROV_REQ_DIGEST_ATOMIC,
12630Sstevel@tonic-gate 	/* cipher requests */
12640Sstevel@tonic-gate 	DPROV_REQ_ENCRYPT_INIT,
12650Sstevel@tonic-gate 	DPROV_REQ_ENCRYPT,
12660Sstevel@tonic-gate 	DPROV_REQ_ENCRYPT_UPDATE,
12670Sstevel@tonic-gate 	DPROV_REQ_ENCRYPT_FINAL,
12680Sstevel@tonic-gate 	DPROV_REQ_ENCRYPT_ATOMIC,
12690Sstevel@tonic-gate 	DPROV_REQ_DECRYPT_INIT,
12700Sstevel@tonic-gate 	DPROV_REQ_DECRYPT,
12710Sstevel@tonic-gate 	DPROV_REQ_DECRYPT_UPDATE,
12720Sstevel@tonic-gate 	DPROV_REQ_DECRYPT_FINAL,
12730Sstevel@tonic-gate 	DPROV_REQ_DECRYPT_ATOMIC,
12740Sstevel@tonic-gate 	/* mac requests */
12750Sstevel@tonic-gate 	DPROV_REQ_MAC_INIT,
12760Sstevel@tonic-gate 	DPROV_REQ_MAC,
12770Sstevel@tonic-gate 	DPROV_REQ_MAC_UPDATE,
12780Sstevel@tonic-gate 	DPROV_REQ_MAC_FINAL,
12790Sstevel@tonic-gate 	DPROV_REQ_MAC_ATOMIC,
12800Sstevel@tonic-gate 	DPROV_REQ_MAC_VERIFY_ATOMIC,
12810Sstevel@tonic-gate 	/* sign requests */
12820Sstevel@tonic-gate 	DPROV_REQ_SIGN_INIT,
12830Sstevel@tonic-gate 	DPROV_REQ_SIGN,
12840Sstevel@tonic-gate 	DPROV_REQ_SIGN_UPDATE,
12850Sstevel@tonic-gate 	DPROV_REQ_SIGN_FINAL,
12860Sstevel@tonic-gate 	DPROV_REQ_SIGN_ATOMIC,
12870Sstevel@tonic-gate 	DPROV_REQ_SIGN_RECOVER_INIT,
12880Sstevel@tonic-gate 	DPROV_REQ_SIGN_RECOVER,
12890Sstevel@tonic-gate 	DPROV_REQ_SIGN_RECOVER_ATOMIC,
12900Sstevel@tonic-gate 	/* verify requests */
12910Sstevel@tonic-gate 	DPROV_REQ_VERIFY_INIT,
12920Sstevel@tonic-gate 	DPROV_REQ_VERIFY,
12930Sstevel@tonic-gate 	DPROV_REQ_VERIFY_UPDATE,
12940Sstevel@tonic-gate 	DPROV_REQ_VERIFY_FINAL,
12950Sstevel@tonic-gate 	DPROV_REQ_VERIFY_ATOMIC,
12960Sstevel@tonic-gate 	DPROV_REQ_VERIFY_RECOVER_INIT,
12970Sstevel@tonic-gate 	DPROV_REQ_VERIFY_RECOVER,
12980Sstevel@tonic-gate 	DPROV_REQ_VERIFY_RECOVER_ATOMIC,
12990Sstevel@tonic-gate 	/* dual ops requests */
13000Sstevel@tonic-gate 	DPROV_REQ_DIGEST_ENCRYPT_UPDATE,
13010Sstevel@tonic-gate 	DPROV_REQ_DECRYPT_DIGEST_UPDATE,
13020Sstevel@tonic-gate 	DPROV_REQ_SIGN_ENCRYPT_UPDATE,
13030Sstevel@tonic-gate 	DPROV_REQ_DECRYPT_VERIFY_UPDATE,
13040Sstevel@tonic-gate 	/* dual cipher/mac requests */
13050Sstevel@tonic-gate 	DPROV_REQ_ENCRYPT_MAC_INIT,
13060Sstevel@tonic-gate 	DPROV_REQ_ENCRYPT_MAC,
13070Sstevel@tonic-gate 	DPROV_REQ_ENCRYPT_MAC_UPDATE,
13080Sstevel@tonic-gate 	DPROV_REQ_ENCRYPT_MAC_FINAL,
13090Sstevel@tonic-gate 	DPROV_REQ_ENCRYPT_MAC_ATOMIC,
13100Sstevel@tonic-gate 	DPROV_REQ_MAC_DECRYPT_INIT,
13110Sstevel@tonic-gate 	DPROV_REQ_MAC_DECRYPT,
13120Sstevel@tonic-gate 	DPROV_REQ_MAC_DECRYPT_UPDATE,
13130Sstevel@tonic-gate 	DPROV_REQ_MAC_DECRYPT_FINAL,
13140Sstevel@tonic-gate 	DPROV_REQ_MAC_DECRYPT_ATOMIC,
13150Sstevel@tonic-gate 	DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC,
13160Sstevel@tonic-gate 	/* random number ops */
13170Sstevel@tonic-gate 	DPROV_REQ_RANDOM_SEED,
13180Sstevel@tonic-gate 	DPROV_REQ_RANDOM_GENERATE,
13190Sstevel@tonic-gate 	/* session management requests */
13200Sstevel@tonic-gate 	DPROV_REQ_SESSION_OPEN,
13210Sstevel@tonic-gate 	DPROV_REQ_SESSION_CLOSE,
13220Sstevel@tonic-gate 	DPROV_REQ_SESSION_LOGIN,
13230Sstevel@tonic-gate 	DPROV_REQ_SESSION_LOGOUT,
13240Sstevel@tonic-gate 	/* object management requests */
13250Sstevel@tonic-gate 	DPROV_REQ_OBJECT_CREATE,
13260Sstevel@tonic-gate 	DPROV_REQ_OBJECT_COPY,
13270Sstevel@tonic-gate 	DPROV_REQ_OBJECT_DESTROY,
13280Sstevel@tonic-gate 	DPROV_REQ_OBJECT_GET_SIZE,
13290Sstevel@tonic-gate 	DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE,
13300Sstevel@tonic-gate 	DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE,
13310Sstevel@tonic-gate 	DPROV_REQ_OBJECT_FIND_INIT,
13320Sstevel@tonic-gate 	DPROV_REQ_OBJECT_FIND,
13330Sstevel@tonic-gate 	DPROV_REQ_OBJECT_FIND_FINAL,
13340Sstevel@tonic-gate 	/* key management requests */
13350Sstevel@tonic-gate 	DPROV_REQ_KEY_GENERATE,
13360Sstevel@tonic-gate 	DPROV_REQ_KEY_GENERATE_PAIR,
13370Sstevel@tonic-gate 	DPROV_REQ_KEY_WRAP,
13380Sstevel@tonic-gate 	DPROV_REQ_KEY_UNWRAP,
13390Sstevel@tonic-gate 	DPROV_REQ_KEY_DERIVE,
13400Sstevel@tonic-gate 	/* provider management requests */
13410Sstevel@tonic-gate 	DPROV_REQ_MGMT_EXTINFO,
13420Sstevel@tonic-gate 	DPROV_REQ_MGMT_INITTOKEN,
13430Sstevel@tonic-gate 	DPROV_REQ_MGMT_INITPIN,
13444219Smcpowers 	DPROV_REQ_MGMT_SETPIN,
13454219Smcpowers 	/* no (key)store key management requests */
13464424Sizick 	DPROV_REQ_NOSTORE_KEY_GENERATE,
13474424Sizick 	DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR,
13484424Sizick 	DPROV_REQ_NOSTORE_KEY_DERIVE
13490Sstevel@tonic-gate } dprov_req_type_t;
13500Sstevel@tonic-gate 
13510Sstevel@tonic-gate /* for DPROV_REQ_DIGEST requests */
13520Sstevel@tonic-gate typedef struct dprov_digest_req {
13530Sstevel@tonic-gate 	crypto_mechanism_t *dr_mechanism;
13540Sstevel@tonic-gate 	crypto_ctx_t *dr_ctx;
13550Sstevel@tonic-gate 	crypto_data_t *dr_data;
13560Sstevel@tonic-gate 	crypto_key_t *dr_key;
13570Sstevel@tonic-gate 	crypto_data_t *dr_digest;
13580Sstevel@tonic-gate } dprov_digest_req_t;
13590Sstevel@tonic-gate 
13600Sstevel@tonic-gate /* for DPROV_REQ_MAC requests */
13610Sstevel@tonic-gate typedef struct dprov_mac_req {
13620Sstevel@tonic-gate 	crypto_mechanism_t *dr_mechanism;
13630Sstevel@tonic-gate 	crypto_ctx_t *dr_ctx;
13644072Skrishna 	crypto_key_t *dr_key;
13650Sstevel@tonic-gate 	crypto_data_t *dr_data;
13660Sstevel@tonic-gate 	crypto_data_t *dr_mac;
13670Sstevel@tonic-gate 	crypto_session_id_t dr_session_id;
13680Sstevel@tonic-gate } dprov_mac_req_t;
13690Sstevel@tonic-gate 
13700Sstevel@tonic-gate /* for DPROV_REQ_ENCRYPT and DPROV_REQ_DECRYPT requests */
13710Sstevel@tonic-gate typedef struct dprov_cipher_req {
13720Sstevel@tonic-gate 	crypto_mechanism_t *dr_mechanism;
13730Sstevel@tonic-gate 	crypto_ctx_t *dr_ctx;
13740Sstevel@tonic-gate 	crypto_key_t *dr_key;
13750Sstevel@tonic-gate 	crypto_data_t *dr_plaintext;
13760Sstevel@tonic-gate 	crypto_data_t *dr_ciphertext;
13770Sstevel@tonic-gate 	crypto_session_id_t dr_session_id;
13780Sstevel@tonic-gate } dprov_cipher_req_t;
13790Sstevel@tonic-gate 
13800Sstevel@tonic-gate /* for DPROV_REQ_SIGN requests */
13810Sstevel@tonic-gate typedef struct dprov_sign_req {
13820Sstevel@tonic-gate 	crypto_mechanism_t *sr_mechanism;
13830Sstevel@tonic-gate 	crypto_ctx_t *sr_ctx;
13840Sstevel@tonic-gate 	crypto_key_t *sr_key;
13850Sstevel@tonic-gate 	crypto_data_t *sr_data;
13860Sstevel@tonic-gate 	crypto_data_t *sr_signature;
13870Sstevel@tonic-gate 	crypto_session_id_t sr_session_id;
13880Sstevel@tonic-gate } dprov_sign_req_t;
13890Sstevel@tonic-gate 
13900Sstevel@tonic-gate /* for DPROV_REQ_VERIFY requests */
13910Sstevel@tonic-gate typedef struct dprov_verify_req {
13920Sstevel@tonic-gate 	crypto_mechanism_t *vr_mechanism;
13930Sstevel@tonic-gate 	crypto_ctx_t *vr_ctx;
13940Sstevel@tonic-gate 	crypto_key_t *vr_key;
13950Sstevel@tonic-gate 	crypto_data_t *vr_data;
13960Sstevel@tonic-gate 	crypto_data_t *vr_signature;
13970Sstevel@tonic-gate 	crypto_session_id_t vr_session_id;
13980Sstevel@tonic-gate } dprov_verify_req_t;
13990Sstevel@tonic-gate 
14000Sstevel@tonic-gate /* for dual ops requests */
14010Sstevel@tonic-gate typedef struct dprov_dual_req {
14020Sstevel@tonic-gate 	crypto_ctx_t *dr_signverify_ctx;
14030Sstevel@tonic-gate 	crypto_ctx_t *dr_cipher_ctx;
14040Sstevel@tonic-gate 	crypto_data_t *dr_plaintext;
14050Sstevel@tonic-gate 	crypto_data_t *dr_ciphertext;
14060Sstevel@tonic-gate } dprov_dual_req_t;
14070Sstevel@tonic-gate 
14080Sstevel@tonic-gate /* for cipher/mac dual ops requests */
14090Sstevel@tonic-gate typedef struct dprov_cipher_mac_req {
14100Sstevel@tonic-gate 	crypto_session_id_t mr_session_id;
14110Sstevel@tonic-gate 	crypto_ctx_t *mr_ctx;
14120Sstevel@tonic-gate 	crypto_mechanism_t *mr_cipher_mech;
14130Sstevel@tonic-gate 	crypto_key_t *mr_cipher_key;
14140Sstevel@tonic-gate 	crypto_mechanism_t *mr_mac_mech;
14150Sstevel@tonic-gate 	crypto_key_t *mr_mac_key;
14160Sstevel@tonic-gate 	crypto_dual_data_t *mr_dual_data;
14170Sstevel@tonic-gate 	crypto_data_t *mr_data;
14180Sstevel@tonic-gate 	crypto_data_t *mr_mac;
14190Sstevel@tonic-gate } dprov_cipher_mac_req_t;
14200Sstevel@tonic-gate 
14210Sstevel@tonic-gate /* for DPROV_REQ_RANDOM requests */
14220Sstevel@tonic-gate typedef struct dprov_random_req {
14230Sstevel@tonic-gate 	uchar_t *rr_buf;
14240Sstevel@tonic-gate 	size_t rr_len;
14250Sstevel@tonic-gate 	crypto_session_id_t rr_session_id;
14261920Smcpowers 	uint_t rr_entropy_est;
14271920Smcpowers 	uint32_t rr_flags;
14280Sstevel@tonic-gate } dprov_random_req_t;
14290Sstevel@tonic-gate 
14300Sstevel@tonic-gate /* for DPROV_REQ_SESSION requests */
14310Sstevel@tonic-gate typedef struct dprov_session_req {
14320Sstevel@tonic-gate 	crypto_session_id_t *sr_session_id_ptr;
14330Sstevel@tonic-gate 	crypto_session_id_t sr_session_id;
14340Sstevel@tonic-gate 	crypto_user_type_t sr_user_type;
14350Sstevel@tonic-gate 	char *sr_pin;
14360Sstevel@tonic-gate 	size_t sr_pin_len;
14370Sstevel@tonic-gate } dprov_session_req_t;
14380Sstevel@tonic-gate 
14390Sstevel@tonic-gate /* for DPROV_REQ_OBJECT requests */
14400Sstevel@tonic-gate typedef struct dprov_object_req {
14410Sstevel@tonic-gate 	crypto_session_id_t or_session_id;
14420Sstevel@tonic-gate 	crypto_object_id_t or_object_id;
14430Sstevel@tonic-gate 	crypto_object_attribute_t *or_template;
14440Sstevel@tonic-gate 	uint_t or_attribute_count;
14450Sstevel@tonic-gate 	crypto_object_id_t *or_object_id_ptr;
14460Sstevel@tonic-gate 	size_t *or_object_size;
14470Sstevel@tonic-gate 	void **or_find_pp;
14480Sstevel@tonic-gate 	void *or_find_p;
14490Sstevel@tonic-gate 	uint_t or_max_object_count;
14500Sstevel@tonic-gate 	uint_t *or_object_count_ptr;
14510Sstevel@tonic-gate } dprov_object_req_t;
14520Sstevel@tonic-gate 
14530Sstevel@tonic-gate /* for DPROV_REQ_KEY requests */
14540Sstevel@tonic-gate typedef struct dprov_key_req {
14550Sstevel@tonic-gate 	crypto_session_id_t kr_session_id;
14560Sstevel@tonic-gate 	crypto_mechanism_t *kr_mechanism;
14570Sstevel@tonic-gate 	crypto_object_attribute_t *kr_template;
14580Sstevel@tonic-gate 	uint_t kr_attribute_count;
14590Sstevel@tonic-gate 	crypto_object_id_t *kr_object_id_ptr;
14600Sstevel@tonic-gate 	crypto_object_attribute_t *kr_private_key_template;
14610Sstevel@tonic-gate 	uint_t kr_private_key_attribute_count;
14620Sstevel@tonic-gate 	crypto_object_id_t *kr_private_key_object_id_ptr;
14630Sstevel@tonic-gate 	crypto_key_t *kr_key;
14640Sstevel@tonic-gate 	uchar_t *kr_wrapped_key;
14650Sstevel@tonic-gate 	size_t *kr_wrapped_key_len_ptr;
14664219Smcpowers 	crypto_object_attribute_t *kr_out_template1;
14674219Smcpowers 	crypto_object_attribute_t *kr_out_template2;
14684219Smcpowers 	uint_t kr_out_attribute_count1;
14694219Smcpowers 	uint_t kr_out_attribute_count2;
14700Sstevel@tonic-gate } dprov_key_req_t;
14710Sstevel@tonic-gate 
14720Sstevel@tonic-gate /* for DPROV_REQ_MGMT requests */
14730Sstevel@tonic-gate typedef struct dprov_mgmt_req {
14740Sstevel@tonic-gate 	crypto_session_id_t mr_session_id;
14750Sstevel@tonic-gate 	char *mr_pin;
14760Sstevel@tonic-gate 	size_t mr_pin_len;
14770Sstevel@tonic-gate 	char *mr_old_pin;
14780Sstevel@tonic-gate 	size_t mr_old_pin_len;
14790Sstevel@tonic-gate 	char *mr_label;
14800Sstevel@tonic-gate 	crypto_provider_ext_info_t *mr_ext_info;
14810Sstevel@tonic-gate } dprov_mgmt_req_t;
14820Sstevel@tonic-gate 
14830Sstevel@tonic-gate /* request, as queued on taskq */
14840Sstevel@tonic-gate typedef struct dprov_req {
14850Sstevel@tonic-gate 	dprov_req_type_t dr_type;
14860Sstevel@tonic-gate 	dprov_state_t *dr_softc;
14870Sstevel@tonic-gate 	crypto_req_handle_t dr_kcf_req;
14880Sstevel@tonic-gate 	union {
14890Sstevel@tonic-gate 		dprov_digest_req_t dru_digest_req;
14900Sstevel@tonic-gate 		dprov_mac_req_t dru_mac_req;
14910Sstevel@tonic-gate 		dprov_cipher_req_t dru_cipher_req;
14920Sstevel@tonic-gate 		dprov_sign_req_t dru_sign_req;
14930Sstevel@tonic-gate 		dprov_verify_req_t dru_verify_req;
14940Sstevel@tonic-gate 		dprov_dual_req_t dru_dual_req;
14950Sstevel@tonic-gate 		dprov_cipher_mac_req_t dru_cipher_mac_req;
14960Sstevel@tonic-gate 		dprov_random_req_t dru_random_req;
14970Sstevel@tonic-gate 		dprov_session_req_t dru_session_req;
14980Sstevel@tonic-gate 		dprov_object_req_t dru_object_req;
14990Sstevel@tonic-gate 		dprov_key_req_t dru_key_req;
15000Sstevel@tonic-gate 		dprov_mgmt_req_t dru_mgmt_req;
15010Sstevel@tonic-gate 	} dr_req;
15020Sstevel@tonic-gate } dprov_req_t;
15030Sstevel@tonic-gate 
15040Sstevel@tonic-gate /* shortcuts for union fields */
15050Sstevel@tonic-gate #define	dr_digest_req		dr_req.dru_digest_req
15060Sstevel@tonic-gate #define	dr_mac_req		dr_req.dru_mac_req
15070Sstevel@tonic-gate #define	dr_cipher_req		dr_req.dru_cipher_req
15080Sstevel@tonic-gate #define	dr_sign_req		dr_req.dru_sign_req
15090Sstevel@tonic-gate #define	dr_verify_req		dr_req.dru_verify_req
15100Sstevel@tonic-gate #define	dr_dual_req		dr_req.dru_dual_req
15110Sstevel@tonic-gate #define	dr_cipher_mac_req	dr_req.dru_cipher_mac_req
15120Sstevel@tonic-gate #define	dr_random_req		dr_req.dru_random_req
15130Sstevel@tonic-gate #define	dr_session_req		dr_req.dru_session_req
15140Sstevel@tonic-gate #define	dr_object_req		dr_req.dru_object_req
15150Sstevel@tonic-gate #define	dr_key_req		dr_req.dru_key_req
15160Sstevel@tonic-gate #define	dr_mgmt_req		dr_req.dru_mgmt_req
15170Sstevel@tonic-gate 
15180Sstevel@tonic-gate /* prototypes for the tasq dispatcher functions */
15190Sstevel@tonic-gate static void dprov_digest_task(dprov_req_t *);
15200Sstevel@tonic-gate static void dprov_mac_task(dprov_req_t *);
15210Sstevel@tonic-gate static void dprov_sign_task(dprov_req_t *);
15220Sstevel@tonic-gate static void dprov_verify_task(dprov_req_t *);
15230Sstevel@tonic-gate static void dprov_dual_task(dprov_req_t *);
15240Sstevel@tonic-gate static void dprov_cipher_task(dprov_req_t *);
15250Sstevel@tonic-gate static void dprov_cipher_mac_task(dprov_req_t *);
15260Sstevel@tonic-gate static void dprov_random_task(dprov_req_t *);
15270Sstevel@tonic-gate static void dprov_session_task(dprov_req_t *);
15280Sstevel@tonic-gate static void dprov_object_task(dprov_req_t *);
15290Sstevel@tonic-gate static void dprov_key_task(dprov_req_t *);
15300Sstevel@tonic-gate static void dprov_mgmt_task(dprov_req_t *);
15310Sstevel@tonic-gate 
15320Sstevel@tonic-gate /* helper functions */
15330Sstevel@tonic-gate static int dprov_digest_submit_req(dprov_req_type_t, dprov_state_t *,
15340Sstevel@tonic-gate     crypto_req_handle_t, crypto_mechanism_t *, crypto_data_t *, crypto_key_t *,
15350Sstevel@tonic-gate     crypto_data_t *, crypto_ctx_t *, int);
15360Sstevel@tonic-gate static int dprov_cipher_submit_req(dprov_req_type_t, dprov_state_t *,
15370Sstevel@tonic-gate     crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
15380Sstevel@tonic-gate     crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
15390Sstevel@tonic-gate static int dprov_mac_submit_req(dprov_req_type_t, dprov_state_t *,
15400Sstevel@tonic-gate     crypto_req_handle_t, crypto_mechanism_t *, crypto_data_t *,
15410Sstevel@tonic-gate     crypto_key_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
15420Sstevel@tonic-gate static int dprov_sign_submit_req(dprov_req_type_t, dprov_state_t *,
15430Sstevel@tonic-gate     crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *,
15440Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
15450Sstevel@tonic-gate static int dprov_verify_submit_req(dprov_req_type_t, dprov_state_t *,
15460Sstevel@tonic-gate     crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *,
15470Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
15480Sstevel@tonic-gate static int dprov_dual_submit_req(dprov_req_type_t, dprov_state_t *,
15490Sstevel@tonic-gate     crypto_req_handle_t, crypto_ctx_t *, crypto_ctx_t *, crypto_data_t *,
15500Sstevel@tonic-gate     crypto_data_t *);
15510Sstevel@tonic-gate static int dprov_cipher_mac_submit_req(dprov_req_type_t, dprov_state_t *,
15520Sstevel@tonic-gate     crypto_req_handle_t, crypto_ctx_t *, crypto_session_id_t,
15530Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *, crypto_key_t *,
15540Sstevel@tonic-gate     crypto_dual_data_t *, crypto_data_t *, crypto_data_t *, int);
15550Sstevel@tonic-gate static int dprov_random_submit_req(dprov_req_type_t, dprov_state_t *,
15561920Smcpowers     crypto_req_handle_t, uchar_t *, size_t, crypto_session_id_t, uint_t,
15571920Smcpowers     uint32_t);
15580Sstevel@tonic-gate static int dprov_session_submit_req(dprov_req_type_t, dprov_state_t *,
15590Sstevel@tonic-gate     crypto_req_handle_t, crypto_session_id_t *, crypto_session_id_t,
15600Sstevel@tonic-gate     crypto_user_type_t, char *, size_t);
15610Sstevel@tonic-gate static int dprov_object_submit_req(dprov_req_type_t, dprov_state_t *,
15620Sstevel@tonic-gate     crypto_req_handle_t, crypto_session_id_t, crypto_object_id_t,
15630Sstevel@tonic-gate     crypto_object_attribute_t *, uint_t, crypto_object_id_t *, size_t *,
15640Sstevel@tonic-gate     void **, void *, uint_t, uint_t *, int);
15650Sstevel@tonic-gate static int dprov_key_submit_req(dprov_req_type_t, dprov_state_t *,
15660Sstevel@tonic-gate     crypto_req_handle_t, crypto_session_id_t, crypto_mechanism_t *,
15670Sstevel@tonic-gate     crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
15680Sstevel@tonic-gate     crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
15694219Smcpowers     crypto_key_t *, uchar_t *, size_t *, crypto_object_attribute_t *,
15704219Smcpowers     uint_t, crypto_object_attribute_t *, uint_t);
15710Sstevel@tonic-gate static int dprov_mgmt_submit_req(dprov_req_type_t, dprov_state_t *,
15720Sstevel@tonic-gate     crypto_req_handle_t, crypto_session_id_t, char *, size_t, char *, size_t,
15730Sstevel@tonic-gate     char *, crypto_provider_ext_info_t *);
15740Sstevel@tonic-gate static int dprov_get_sw_prov(crypto_mechanism_t *, kcf_provider_desc_t **,
15750Sstevel@tonic-gate     crypto_mech_type_t *);
15760Sstevel@tonic-gate 
15770Sstevel@tonic-gate /* object management helper functions */
15780Sstevel@tonic-gate static void dprov_free_object(dprov_object_t *);
15790Sstevel@tonic-gate static void dprov_release_session_objects(dprov_session_t *);
15805697Smcpowers static void dprov_adjust_attrs(crypto_object_attribute_t *, int);
15810Sstevel@tonic-gate static boolean_t dprov_object_is_private(dprov_object_t *);
15820Sstevel@tonic-gate static boolean_t dprov_object_is_token(dprov_object_t *);
15830Sstevel@tonic-gate static int dprov_key_value_secret(dprov_state_t *, crypto_session_id_t,
15840Sstevel@tonic-gate     dprov_req_type_t, crypto_key_t *, crypto_key_t *);
15850Sstevel@tonic-gate static int dprov_key_attr_asymmetric(dprov_state_t *, crypto_session_id_t,
15860Sstevel@tonic-gate     dprov_req_type_t, crypto_key_t *, crypto_key_t *);
15870Sstevel@tonic-gate static int dprov_get_object_attr_boolean(dprov_object_t *, uint64_t,
15880Sstevel@tonic-gate 	boolean_t *);
15890Sstevel@tonic-gate static int dprov_get_object_attr_ulong(dprov_object_t *, uint64_t, ulong_t *);
15900Sstevel@tonic-gate static int dprov_get_object_attr_array(dprov_object_t *, uint64_t, void **,
15910Sstevel@tonic-gate     size_t *);
15920Sstevel@tonic-gate static int dprov_get_key_attr_ulong(crypto_key_t *, uint64_t, ulong_t *);
15930Sstevel@tonic-gate static int dprov_get_key_attr_array(crypto_key_t *, uint64_t, void **,
15940Sstevel@tonic-gate     size_t *);
15950Sstevel@tonic-gate static int dprov_create_object_from_template(dprov_state_t *, dprov_session_t *,
15960Sstevel@tonic-gate     crypto_object_attribute_t *, uint_t, crypto_object_id_t *, boolean_t,
15970Sstevel@tonic-gate     boolean_t);
15980Sstevel@tonic-gate static int dprov_get_template_attr_scalar_common(crypto_object_attribute_t *,
15990Sstevel@tonic-gate     uint_t, uint64_t, void *, size_t);
16000Sstevel@tonic-gate static int dprov_get_template_attr_boolean(crypto_object_attribute_t *,
16010Sstevel@tonic-gate     uint_t, uint64_t, boolean_t *);
16020Sstevel@tonic-gate static int dprov_get_template_attr_ulong(crypto_object_attribute_t *, uint_t,
16030Sstevel@tonic-gate     uint64_t, ulong_t *);
16040Sstevel@tonic-gate static int dprov_template_attr_present(crypto_object_attribute_t *, uint_t,
16050Sstevel@tonic-gate     uint64_t);
16060Sstevel@tonic-gate static int dprov_get_template_attr_array(crypto_object_attribute_t *, uint_t,
16070Sstevel@tonic-gate     uint64_t, void **, size_t *);
16080Sstevel@tonic-gate static int dprov_destroy_object(dprov_state_t *, dprov_session_t *,
16090Sstevel@tonic-gate     crypto_object_id_t);
16100Sstevel@tonic-gate static int dprov_object_set_attr(dprov_session_t *, crypto_object_id_t,
16110Sstevel@tonic-gate     crypto_object_attribute_t *, uint_t, boolean_t);
16120Sstevel@tonic-gate static int dprov_find_attr(crypto_object_attribute_t *, uint_t, uint64_t);
16130Sstevel@tonic-gate static boolean_t dprov_attributes_match(dprov_object_t *,
16140Sstevel@tonic-gate     crypto_object_attribute_t *, uint_t);
16150Sstevel@tonic-gate 
16160Sstevel@tonic-gate /* retrieve the softc and instance number from a SPI crypto context */
16170Sstevel@tonic-gate #define	DPROV_SOFTC_FROM_CTX(ctx, softc, instance) {	\
16180Sstevel@tonic-gate 	(softc) = (dprov_state_t *)(ctx)->cc_provider;	\
16190Sstevel@tonic-gate 	(instance) = ddi_get_instance((softc)->ds_dip);	\
16200Sstevel@tonic-gate }
16210Sstevel@tonic-gate 
16220Sstevel@tonic-gate /* retrieve the softc and instance number from a taskq request */
16230Sstevel@tonic-gate #define	DPROV_SOFTC_FROM_REQ(req, softc, instance) {	\
16240Sstevel@tonic-gate 	(softc) = (req)->dr_softc;			\
16250Sstevel@tonic-gate 	(instance) = ddi_get_instance((softc)->ds_dip);	\
16260Sstevel@tonic-gate }
16270Sstevel@tonic-gate 
16280Sstevel@tonic-gate /*
16290Sstevel@tonic-gate  * The dprov private context most of the time contains a pointer to the
16300Sstevel@tonic-gate  * crypto_context_t that was allocated when calling a KCF function.
16310Sstevel@tonic-gate  * Dual cipher/mac operations however require the dprov driver
16320Sstevel@tonic-gate  * to maintain the contexts associated with the separate cipher
16330Sstevel@tonic-gate  * and mac operations. These two types of dprov contexts are
16340Sstevel@tonic-gate  * defined below.
16350Sstevel@tonic-gate  */
16360Sstevel@tonic-gate typedef enum dprov_ctx_type {
16370Sstevel@tonic-gate 	DPROV_CTX_SINGLE,
16380Sstevel@tonic-gate 	DPROV_CTX_DUAL
16390Sstevel@tonic-gate } dprov_ctx_type_t;
16400Sstevel@tonic-gate 
16410Sstevel@tonic-gate /*
16420Sstevel@tonic-gate  * When the context refers to a single KCF context, the
16430Sstevel@tonic-gate  * cc_provider field of a crypto_ctx_t points to a structure of
16440Sstevel@tonic-gate  * type dprov_ctx_single.
16450Sstevel@tonic-gate  */
16460Sstevel@tonic-gate typedef struct dprov_ctx_single {
16470Sstevel@tonic-gate 	dprov_ctx_type_t dc_type;
16480Sstevel@tonic-gate 	crypto_context_t dc_ctx;
16494072Skrishna 	boolean_t dc_svrfy_to_mac;
16500Sstevel@tonic-gate } dprov_ctx_single_t;
16510Sstevel@tonic-gate 
16520Sstevel@tonic-gate /*
16530Sstevel@tonic-gate  * When the context is used for cipher/mac operations, it contains
16540Sstevel@tonic-gate  * pointers to to KCF contexts, one for the cipher operation, the
16550Sstevel@tonic-gate  * other for the mac operation.
16560Sstevel@tonic-gate  */
16570Sstevel@tonic-gate typedef struct dprov_ctx_dual {
16580Sstevel@tonic-gate 	dprov_ctx_type_t cd_type;
16590Sstevel@tonic-gate 	crypto_context_t cd_cipher_ctx;
16600Sstevel@tonic-gate 	crypto_context_t cd_mac_ctx;
16610Sstevel@tonic-gate } dprov_ctx_dual_t;
16620Sstevel@tonic-gate 
16630Sstevel@tonic-gate /*
16640Sstevel@tonic-gate  * Helper macros for context accessors. These macros return the
16650Sstevel@tonic-gate  * k-API context corresponding to the given SPI context for
16660Sstevel@tonic-gate  * single and dual cipher/mac operations.
16670Sstevel@tonic-gate  */
16680Sstevel@tonic-gate 
16694072Skrishna #define	DPROV_CTX_P(_ctx) \
16704072Skrishna 	((dprov_ctx_single_t *)(_ctx)->cc_provider_private)
16714072Skrishna 
16724072Skrishna #define	DPROV_CTX_SINGLE(_ctx)	((DPROV_CTX_P(_ctx))->dc_ctx)
16730Sstevel@tonic-gate 
16740Sstevel@tonic-gate #define	DPROV_CTX_DUAL_CIPHER(_ctx) \
16750Sstevel@tonic-gate 	(((dprov_ctx_dual_t *)(_ctx)->cc_provider_private)->cd_cipher_ctx)
16760Sstevel@tonic-gate 
16770Sstevel@tonic-gate #define	DPROV_CTX_DUAL_MAC(_ctx) \
16780Sstevel@tonic-gate 	(((dprov_ctx_dual_t *)(_ctx)->cc_provider_private)->cd_mac_ctx)
16790Sstevel@tonic-gate 
16800Sstevel@tonic-gate static int dprov_alloc_context(dprov_req_type_t, crypto_ctx_t *);
16810Sstevel@tonic-gate 
16820Sstevel@tonic-gate 
16830Sstevel@tonic-gate 
16840Sstevel@tonic-gate static void *statep;	/* state pointer */
16850Sstevel@tonic-gate 
16860Sstevel@tonic-gate /*
16870Sstevel@tonic-gate  * DDI entry points.
16880Sstevel@tonic-gate  */
16890Sstevel@tonic-gate int
_init(void)16900Sstevel@tonic-gate _init(void)
16910Sstevel@tonic-gate {
16920Sstevel@tonic-gate 	int error;
16930Sstevel@tonic-gate 
16940Sstevel@tonic-gate 	DPROV_DEBUG(D_INIT, ("dprov: in _init\n"));
16950Sstevel@tonic-gate 
16960Sstevel@tonic-gate 	if ((error = ddi_soft_state_init(&statep, sizeof (dprov_state_t),
16970Sstevel@tonic-gate 	    0)) != 0)
16980Sstevel@tonic-gate 		return (error);
16990Sstevel@tonic-gate 
17000Sstevel@tonic-gate 	return (mod_install(&modlinkage));
17010Sstevel@tonic-gate }
17020Sstevel@tonic-gate 
17030Sstevel@tonic-gate int
_fini(void)17040Sstevel@tonic-gate _fini(void)
17050Sstevel@tonic-gate {
17060Sstevel@tonic-gate 	int error;
17070Sstevel@tonic-gate 
17080Sstevel@tonic-gate 	DPROV_DEBUG(D_INIT, ("dprov: in _fini\n"));
17090Sstevel@tonic-gate 
17100Sstevel@tonic-gate 	if ((error = mod_remove(&modlinkage)) != 0)
17110Sstevel@tonic-gate 		return (error);
17120Sstevel@tonic-gate 
17130Sstevel@tonic-gate 	ddi_soft_state_fini(&statep);
17140Sstevel@tonic-gate 
17150Sstevel@tonic-gate 	return (0);
17160Sstevel@tonic-gate }
17170Sstevel@tonic-gate 
17180Sstevel@tonic-gate int
_info(struct modinfo * modinfop)17190Sstevel@tonic-gate _info(struct modinfo *modinfop)
17200Sstevel@tonic-gate {
17210Sstevel@tonic-gate 	DPROV_DEBUG(D_INIT, ("dprov: in _info\n"));
17220Sstevel@tonic-gate 
17230Sstevel@tonic-gate 	return (mod_info(&modlinkage, modinfop));
17240Sstevel@tonic-gate }
17250Sstevel@tonic-gate 
17260Sstevel@tonic-gate /* ARGSUSED */
17270Sstevel@tonic-gate static int
dprov_getinfo(dev_info_t * dip,ddi_info_cmd_t cmd,void * arg,void ** result)17280Sstevel@tonic-gate dprov_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
17290Sstevel@tonic-gate {
17300Sstevel@tonic-gate 	int instance = getminor((dev_t)arg);
17310Sstevel@tonic-gate 	dprov_state_t *softc;
17320Sstevel@tonic-gate 
17330Sstevel@tonic-gate 	DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_getinfo() for %d\n",
17340Sstevel@tonic-gate 	    instance));
17350Sstevel@tonic-gate 
17360Sstevel@tonic-gate 	switch (cmd) {
17370Sstevel@tonic-gate 	case DDI_INFO_DEVT2DEVINFO:
17380Sstevel@tonic-gate 		softc = ddi_get_soft_state(statep, instance);
17390Sstevel@tonic-gate 		*result = softc->ds_dip;
17400Sstevel@tonic-gate 		return (DDI_SUCCESS);
17410Sstevel@tonic-gate 
17420Sstevel@tonic-gate 	case DDI_INFO_DEVT2INSTANCE:
17430Sstevel@tonic-gate 		*result = (void *)(uintptr_t)instance;
17440Sstevel@tonic-gate 		return (DDI_SUCCESS);
17450Sstevel@tonic-gate 	}
17460Sstevel@tonic-gate 	return (DDI_FAILURE);
17470Sstevel@tonic-gate }
17480Sstevel@tonic-gate 
17490Sstevel@tonic-gate static int
dprov_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)17500Sstevel@tonic-gate dprov_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
17510Sstevel@tonic-gate {
17520Sstevel@tonic-gate 	int instance = ddi_get_instance(dip);
17530Sstevel@tonic-gate 	dprov_state_t *softc;
17540Sstevel@tonic-gate 	char devname[256];
17550Sstevel@tonic-gate 	int ret;
17560Sstevel@tonic-gate 
17570Sstevel@tonic-gate 	DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_attach() for %d\n",
17580Sstevel@tonic-gate 	    instance));
17590Sstevel@tonic-gate 
17600Sstevel@tonic-gate 	if (cmd != DDI_ATTACH) {
17610Sstevel@tonic-gate 		return (DDI_FAILURE);
17620Sstevel@tonic-gate 	}
17630Sstevel@tonic-gate 
17640Sstevel@tonic-gate 	/* get new softc and initialize it */
17650Sstevel@tonic-gate 	if (ddi_soft_state_zalloc(statep, instance) != DDI_SUCCESS)
17660Sstevel@tonic-gate 		return (DDI_FAILURE);
17670Sstevel@tonic-gate 
17680Sstevel@tonic-gate 	softc = ddi_get_soft_state(statep, instance);
17690Sstevel@tonic-gate 	mutex_init(&softc->ds_lock, NULL, MUTEX_DRIVER, NULL);
17700Sstevel@tonic-gate 	softc->ds_dip = dip;
17710Sstevel@tonic-gate 	softc->ds_prov_handle = NULL;
17720Sstevel@tonic-gate 
17730Sstevel@tonic-gate 	/* create minor node */
17744427Sizick 	(void) sprintf(devname, "dprov%d", instance);
17750Sstevel@tonic-gate 	if (ddi_create_minor_node(dip, devname, S_IFCHR, instance,
17760Sstevel@tonic-gate 	    DDI_PSEUDO, 0) != DDI_SUCCESS) {
17770Sstevel@tonic-gate 		cmn_err(CE_WARN, "attach: failed creating minor node");
17780Sstevel@tonic-gate 		mutex_destroy(&softc->ds_lock);
17790Sstevel@tonic-gate 		ddi_soft_state_free(statep, instance);
17800Sstevel@tonic-gate 		return (DDI_FAILURE);
17810Sstevel@tonic-gate 	}
17820Sstevel@tonic-gate 
17834219Smcpowers 	nostore_key_gen = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
17844219Smcpowers 	    DDI_PROP_DONTPASS, "nostore_key_gen", 0);
17854219Smcpowers 	if (nostore_key_gen != 0) {
17864219Smcpowers 		dprov_prov_info.pi_interface_version = CRYPTO_SPI_VERSION_3;
17874219Smcpowers 		dprov_crypto_ops.co_object_ops = NULL;
17884219Smcpowers 		dprov_crypto_ops.co_nostore_key_ops = &dprov_nostore_key_ops;
17894219Smcpowers 	}
17904219Smcpowers 
17914072Skrishna 	dprov_max_digestsz = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
17924072Skrishna 	    DDI_PROP_DONTPASS, "max_digest_sz", INT_MAX);
17934072Skrishna 	if (dprov_max_digestsz != INT_MAX && dprov_max_digestsz != 0 &&
17944072Skrishna 	    dprov_max_digestsz != DDI_PROP_NOT_FOUND) {
17954072Skrishna 		dprov_no_multipart = B_TRUE;
179611304SJanie.Lu@Sun.COM 		dprov_prov_info.pi_flags |=
179711304SJanie.Lu@Sun.COM 		    (CRYPTO_HASH_NO_UPDATE | CRYPTO_HMAC_NO_UPDATE);
17984072Skrishna 	}
17994072Skrishna 
18000Sstevel@tonic-gate 	/* create taskq */
18010Sstevel@tonic-gate 	softc->ds_taskq = taskq_create(devname, 1, minclsyspri,
18020Sstevel@tonic-gate 	    crypto_taskq_minalloc, crypto_taskq_maxalloc, TASKQ_PREPOPULATE);
18030Sstevel@tonic-gate 
18040Sstevel@tonic-gate 	/* initialize table of sessions */
18050Sstevel@tonic-gate 	softc->ds_sessions = kmem_zalloc(DPROV_MIN_SESSIONS *
18060Sstevel@tonic-gate 	    sizeof (dprov_session_t *), KM_SLEEP);
18070Sstevel@tonic-gate 	softc->ds_sessions_slots = DPROV_MIN_SESSIONS;
18080Sstevel@tonic-gate 	softc->ds_sessions_count = 0;
18090Sstevel@tonic-gate 
18100Sstevel@tonic-gate 	/* initialized done by init_token entry point */
18110Sstevel@tonic-gate 	softc->ds_token_initialized = B_TRUE;
18120Sstevel@tonic-gate 
1813904Smcpowers 	(void) memset(softc->ds_label, ' ', CRYPTO_EXT_SIZE_LABEL);
1814904Smcpowers 	bcopy("Dummy Pseudo HW Provider", softc->ds_label, 24);
1815904Smcpowers 
18160Sstevel@tonic-gate 	bcopy("changeme", softc->ds_user_pin, 8);
18170Sstevel@tonic-gate 	softc->ds_user_pin_len = 8;
18180Sstevel@tonic-gate 	softc->ds_user_pin_set = B_TRUE;
18190Sstevel@tonic-gate 
18200Sstevel@tonic-gate 	/* register with the crypto framework */
18210Sstevel@tonic-gate 	dprov_prov_info.pi_provider_dev.pd_hw = dip;
18220Sstevel@tonic-gate 	dprov_prov_info.pi_provider_handle = softc;
18234072Skrishna 
18244072Skrishna 	if (dprov_no_multipart) { /* Export only single part */
18254072Skrishna 		dprov_digest_ops.digest_update = NULL;
18264072Skrishna 		dprov_digest_ops.digest_key = NULL;
18274072Skrishna 		dprov_digest_ops.digest_final = NULL;
18284072Skrishna 		dprov_object_ops.object_create = NULL;
18294072Skrishna 	}
18304072Skrishna 
18310Sstevel@tonic-gate 	if ((ret = crypto_register_provider(&dprov_prov_info,
18320Sstevel@tonic-gate 	    &softc->ds_prov_handle)) != CRYPTO_SUCCESS) {
18330Sstevel@tonic-gate 		cmn_err(CE_WARN,
18340Sstevel@tonic-gate 		    "dprov crypto_register_provider() failed (0x%x)", ret);
18350Sstevel@tonic-gate 		taskq_destroy(softc->ds_taskq);
18360Sstevel@tonic-gate 		kmem_free(softc->ds_sessions, softc->ds_sessions_slots *
18370Sstevel@tonic-gate 		    sizeof (dprov_session_t *));
18380Sstevel@tonic-gate 		mutex_destroy(&softc->ds_lock);
18390Sstevel@tonic-gate 		ddi_soft_state_free(statep, instance);
18400Sstevel@tonic-gate 		ddi_remove_minor_node(dip, NULL);
18410Sstevel@tonic-gate 		return (DDI_FAILURE);
18420Sstevel@tonic-gate 	}
18430Sstevel@tonic-gate 
18440Sstevel@tonic-gate 	/*
18450Sstevel@tonic-gate 	 * This call is for testing only; it is not required by the SPI.
18460Sstevel@tonic-gate 	 */
18470Sstevel@tonic-gate 	crypto_provider_notification(softc->ds_prov_handle,
18480Sstevel@tonic-gate 	    CRYPTO_PROVIDER_READY);
18490Sstevel@tonic-gate 
18500Sstevel@tonic-gate 	return (DDI_SUCCESS);
18510Sstevel@tonic-gate }
18520Sstevel@tonic-gate 
18530Sstevel@tonic-gate static int
dprov_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)18540Sstevel@tonic-gate dprov_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
18550Sstevel@tonic-gate {
18560Sstevel@tonic-gate 	int instance = ddi_get_instance(dip);
18570Sstevel@tonic-gate 	dprov_state_t *softc = ddi_get_soft_state(statep, instance);
18580Sstevel@tonic-gate 	dprov_session_t *session;
18590Sstevel@tonic-gate 	int i, ret;
18600Sstevel@tonic-gate 
18610Sstevel@tonic-gate 	DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_detach() for %d\n",
18620Sstevel@tonic-gate 	    instance));
18630Sstevel@tonic-gate 
18640Sstevel@tonic-gate 	if (cmd != DDI_DETACH)
18650Sstevel@tonic-gate 		return (DDI_FAILURE);
18660Sstevel@tonic-gate 
18670Sstevel@tonic-gate 	/* unregister from the crypto framework */
18680Sstevel@tonic-gate 	if (softc->ds_prov_handle != NULL)
18690Sstevel@tonic-gate 		if ((ret = crypto_unregister_provider(
18700Sstevel@tonic-gate 		    softc->ds_prov_handle)) != CRYPTO_SUCCESS) {
18710Sstevel@tonic-gate 			cmn_err(CE_WARN, "dprov_detach: "
18720Sstevel@tonic-gate 			    "crypto_unregister_provider() "
18730Sstevel@tonic-gate 			    "failed (0x%x)", ret);
18740Sstevel@tonic-gate 			return (DDI_FAILURE);
18750Sstevel@tonic-gate 		}
18760Sstevel@tonic-gate 
18770Sstevel@tonic-gate 
18780Sstevel@tonic-gate 	taskq_destroy(softc->ds_taskq);
18790Sstevel@tonic-gate 
18800Sstevel@tonic-gate 	for (i = 0; i < softc->ds_sessions_slots; i++) {
18810Sstevel@tonic-gate 		if ((session = softc->ds_sessions[i]) == NULL)
18820Sstevel@tonic-gate 			continue;
18830Sstevel@tonic-gate 
18840Sstevel@tonic-gate 		dprov_release_session_objects(session);
18850Sstevel@tonic-gate 
18860Sstevel@tonic-gate 		kmem_free(session, sizeof (dprov_session_t));
18870Sstevel@tonic-gate 		softc->ds_sessions_count--;
18880Sstevel@tonic-gate 
18890Sstevel@tonic-gate 	}
18900Sstevel@tonic-gate 
18910Sstevel@tonic-gate 	kmem_free(softc->ds_sessions, softc->ds_sessions_slots *
18920Sstevel@tonic-gate 	    sizeof (dprov_session_t *));
18930Sstevel@tonic-gate 	/* free token objects */
18940Sstevel@tonic-gate 	for (i = 0; i < DPROV_MAX_OBJECTS; i++)
18950Sstevel@tonic-gate 		if (softc->ds_objects[i] != NULL)
18960Sstevel@tonic-gate 			dprov_free_object(softc->ds_objects[i]);
18970Sstevel@tonic-gate 
18980Sstevel@tonic-gate 	mutex_destroy(&softc->ds_lock);
18990Sstevel@tonic-gate 	ddi_soft_state_free(statep, instance);
19000Sstevel@tonic-gate 
19010Sstevel@tonic-gate 	ddi_remove_minor_node(dip, NULL);
19020Sstevel@tonic-gate 
19030Sstevel@tonic-gate 	return (DDI_SUCCESS);
19040Sstevel@tonic-gate }
19050Sstevel@tonic-gate 
19060Sstevel@tonic-gate /*
19070Sstevel@tonic-gate  * Control entry points.
19080Sstevel@tonic-gate  */
19090Sstevel@tonic-gate static void
dprov_provider_status(crypto_provider_handle_t provider,uint_t * status)19100Sstevel@tonic-gate dprov_provider_status(crypto_provider_handle_t provider, uint_t *status)
19110Sstevel@tonic-gate {
19120Sstevel@tonic-gate 	_NOTE(ARGUNUSED(provider))
19130Sstevel@tonic-gate 
19140Sstevel@tonic-gate 	*status = CRYPTO_PROVIDER_READY;
19150Sstevel@tonic-gate }
19160Sstevel@tonic-gate 
19170Sstevel@tonic-gate /*
19180Sstevel@tonic-gate  * Digest entry points.
19190Sstevel@tonic-gate  */
19200Sstevel@tonic-gate 
19210Sstevel@tonic-gate static int
dprov_digest_init(crypto_ctx_t * ctx,crypto_mechanism_t * mechanism,crypto_req_handle_t req)19220Sstevel@tonic-gate dprov_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
19230Sstevel@tonic-gate     crypto_req_handle_t req)
19240Sstevel@tonic-gate {
19250Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
19260Sstevel@tonic-gate 	dprov_state_t *softc;
19270Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
19280Sstevel@tonic-gate 	int instance;
19290Sstevel@tonic-gate 
19300Sstevel@tonic-gate 	/* extract softc and instance number from context */
19310Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
19320Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_init: started\n", instance));
19330Sstevel@tonic-gate 
19340Sstevel@tonic-gate 	/* check mechanism */
19354002Sdarrenm 	if (mechanism->cm_type != MD4_MECH_INFO_TYPE &&
19364002Sdarrenm 	    mechanism->cm_type != MD5_MECH_INFO_TYPE &&
19370Sstevel@tonic-gate 	    mechanism->cm_type != SHA1_MECH_INFO_TYPE &&
19380Sstevel@tonic-gate 	    mechanism->cm_type != SHA256_MECH_INFO_TYPE &&
19390Sstevel@tonic-gate 	    mechanism->cm_type != SHA384_MECH_INFO_TYPE &&
19400Sstevel@tonic-gate 	    mechanism->cm_type != SHA512_MECH_INFO_TYPE) {
19410Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_digest_init: unexpected mech type "
19420Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
19430Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
19440Sstevel@tonic-gate 	}
19450Sstevel@tonic-gate 
19460Sstevel@tonic-gate 	/* submit request to the taskq */
19470Sstevel@tonic-gate 	error = dprov_digest_submit_req(DPROV_REQ_DIGEST_INIT, softc, req,
19480Sstevel@tonic-gate 	    mechanism, NULL, NULL, NULL, ctx, KM_SLEEP);
19490Sstevel@tonic-gate 
19500Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_init: done err = 0x%x\n",
19510Sstevel@tonic-gate 	    instance, error));
19520Sstevel@tonic-gate 
19530Sstevel@tonic-gate 	return (error);
19540Sstevel@tonic-gate }
19550Sstevel@tonic-gate 
19560Sstevel@tonic-gate static int
dprov_digest(crypto_ctx_t * ctx,crypto_data_t * data,crypto_data_t * digest,crypto_req_handle_t req)19570Sstevel@tonic-gate dprov_digest(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *digest,
19580Sstevel@tonic-gate     crypto_req_handle_t req)
19590Sstevel@tonic-gate {
19600Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
19610Sstevel@tonic-gate 	dprov_state_t *softc;
19620Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
19630Sstevel@tonic-gate 	int instance;
19640Sstevel@tonic-gate 
19654072Skrishna 	if (dprov_no_multipart && data->cd_length > dprov_max_digestsz)
19664072Skrishna 		return (CRYPTO_BUFFER_TOO_BIG);
19674072Skrishna 
19680Sstevel@tonic-gate 	/* extract softc and instance number from context */
19690Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
19700Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest: started\n", instance));
19710Sstevel@tonic-gate 
19720Sstevel@tonic-gate 	/* submit request to the taskq */
19730Sstevel@tonic-gate 	error = dprov_digest_submit_req(DPROV_REQ_DIGEST, softc, req,
19740Sstevel@tonic-gate 	    NULL, data, NULL, digest, ctx, KM_NOSLEEP);
19750Sstevel@tonic-gate 
19760Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest: done, err = 0x%x\n",
19770Sstevel@tonic-gate 	    instance, error));
19780Sstevel@tonic-gate 
19790Sstevel@tonic-gate 	return (error);
19800Sstevel@tonic-gate }
19810Sstevel@tonic-gate 
19820Sstevel@tonic-gate static int
dprov_digest_update(crypto_ctx_t * ctx,crypto_data_t * data,crypto_req_handle_t req)19830Sstevel@tonic-gate dprov_digest_update(crypto_ctx_t *ctx, crypto_data_t *data,
19840Sstevel@tonic-gate     crypto_req_handle_t req)
19850Sstevel@tonic-gate {
19860Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
19870Sstevel@tonic-gate 	dprov_state_t *softc;
19880Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
19890Sstevel@tonic-gate 	int instance;
19900Sstevel@tonic-gate 
19910Sstevel@tonic-gate 	/* extract softc and instance number from context */
19920Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
19930Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_update: started\n",
19940Sstevel@tonic-gate 	    instance));
19950Sstevel@tonic-gate 
19960Sstevel@tonic-gate 	/* submit request to the taskq */
19970Sstevel@tonic-gate 	error = dprov_digest_submit_req(DPROV_REQ_DIGEST_UPDATE, softc,
19980Sstevel@tonic-gate 	    req, NULL, data, NULL, NULL, ctx, KM_NOSLEEP);
19990Sstevel@tonic-gate 
20000Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_update: done err = 0x0%x\n",
20010Sstevel@tonic-gate 	    instance, error));
20020Sstevel@tonic-gate 
20030Sstevel@tonic-gate 	return (error);
20040Sstevel@tonic-gate }
20050Sstevel@tonic-gate 
20060Sstevel@tonic-gate static int
dprov_digest_key(crypto_ctx_t * ctx,crypto_key_t * key,crypto_req_handle_t req)20070Sstevel@tonic-gate dprov_digest_key(crypto_ctx_t *ctx, crypto_key_t *key, crypto_req_handle_t req)
20080Sstevel@tonic-gate {
20090Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
20100Sstevel@tonic-gate 	dprov_state_t *softc;
20110Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
20120Sstevel@tonic-gate 	int instance;
20130Sstevel@tonic-gate 
20140Sstevel@tonic-gate 	/* extract softc and instance number from context */
20150Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
20160Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_key: started\n", instance));
20170Sstevel@tonic-gate 
20180Sstevel@tonic-gate 	/* submit request to the taskq */
20190Sstevel@tonic-gate 	error = dprov_digest_submit_req(DPROV_REQ_DIGEST_KEY, softc, req, NULL,
20200Sstevel@tonic-gate 	    NULL, key, NULL, ctx, KM_NOSLEEP);
20210Sstevel@tonic-gate 
20220Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_key: done err = 0x0%x\n",
20230Sstevel@tonic-gate 	    instance, error));
20240Sstevel@tonic-gate 
20250Sstevel@tonic-gate 	return (error);
20260Sstevel@tonic-gate }
20270Sstevel@tonic-gate 
20280Sstevel@tonic-gate static int
dprov_digest_final(crypto_ctx_t * ctx,crypto_data_t * digest,crypto_req_handle_t req)20290Sstevel@tonic-gate dprov_digest_final(crypto_ctx_t *ctx, crypto_data_t *digest,
20300Sstevel@tonic-gate     crypto_req_handle_t req)
20310Sstevel@tonic-gate {
20320Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
20330Sstevel@tonic-gate 	dprov_state_t *softc;
20340Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
20350Sstevel@tonic-gate 	int instance;
20360Sstevel@tonic-gate 
20370Sstevel@tonic-gate 	/* extract softc and instance number from context */
20380Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
20390Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_final: started\n", instance));
20400Sstevel@tonic-gate 
20410Sstevel@tonic-gate 	/* submit request to the taskq */
20420Sstevel@tonic-gate 	error = dprov_digest_submit_req(DPROV_REQ_DIGEST_FINAL, softc, req,
20430Sstevel@tonic-gate 	    NULL, NULL, NULL, digest, ctx, KM_NOSLEEP);
20440Sstevel@tonic-gate 
20450Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_final: done err = 0x0%x\n",
20460Sstevel@tonic-gate 	    instance, error));
20470Sstevel@tonic-gate 
20480Sstevel@tonic-gate 	return (error);
20490Sstevel@tonic-gate }
20500Sstevel@tonic-gate 
20510Sstevel@tonic-gate /* ARGSUSED */
20520Sstevel@tonic-gate static int
dprov_digest_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_data_t * data,crypto_data_t * digest,crypto_req_handle_t req)20530Sstevel@tonic-gate dprov_digest_atomic(crypto_provider_handle_t provider,
20540Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
20550Sstevel@tonic-gate     crypto_data_t *data, crypto_data_t *digest,
20560Sstevel@tonic-gate     crypto_req_handle_t req)
20570Sstevel@tonic-gate {
20580Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
20590Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
20600Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
20610Sstevel@tonic-gate 	int instance;
20620Sstevel@tonic-gate 
20634072Skrishna 	if (dprov_no_multipart && data->cd_length > dprov_max_digestsz)
20644072Skrishna 		return (CRYPTO_BUFFER_TOO_BIG);
20654072Skrishna 
20660Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
20670Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_atomic: started\n",
20680Sstevel@tonic-gate 	    instance));
20690Sstevel@tonic-gate 
20700Sstevel@tonic-gate 	/* check mechanism */
20714002Sdarrenm 	if (mechanism->cm_type != MD4_MECH_INFO_TYPE &&
20724002Sdarrenm 	    mechanism->cm_type != MD5_MECH_INFO_TYPE &&
20730Sstevel@tonic-gate 	    mechanism->cm_type != SHA1_MECH_INFO_TYPE &&
20740Sstevel@tonic-gate 	    mechanism->cm_type != SHA256_MECH_INFO_TYPE &&
20750Sstevel@tonic-gate 	    mechanism->cm_type != SHA384_MECH_INFO_TYPE &&
20760Sstevel@tonic-gate 	    mechanism->cm_type != SHA512_MECH_INFO_TYPE) {
20770Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_digest_atomic: unexpected mech type "
20780Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
20790Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
20800Sstevel@tonic-gate 	}
20810Sstevel@tonic-gate 
20820Sstevel@tonic-gate 	/* submit request to the taskq */
20830Sstevel@tonic-gate 	error = dprov_digest_submit_req(DPROV_REQ_DIGEST_ATOMIC, softc, req,
20840Sstevel@tonic-gate 	    mechanism, data, NULL, digest, NULL, KM_SLEEP);
20850Sstevel@tonic-gate 
20860Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_atomic: done err = 0x0%x\n",
20870Sstevel@tonic-gate 	    instance, error));
20880Sstevel@tonic-gate 
20890Sstevel@tonic-gate 	return (error);
20900Sstevel@tonic-gate }
20910Sstevel@tonic-gate 
20920Sstevel@tonic-gate /*
20930Sstevel@tonic-gate  * MAC entry points.
20940Sstevel@tonic-gate  */
20950Sstevel@tonic-gate 
20960Sstevel@tonic-gate /*
20970Sstevel@tonic-gate  * Checks whether the specified mech_type is supported by mac
20980Sstevel@tonic-gate  * entry points.
20990Sstevel@tonic-gate  */
21000Sstevel@tonic-gate static boolean_t
dprov_valid_mac_mech(crypto_mech_type_t mech_type)21010Sstevel@tonic-gate dprov_valid_mac_mech(crypto_mech_type_t mech_type)
21020Sstevel@tonic-gate {
21030Sstevel@tonic-gate 	return (mech_type == MD5_HMAC_MECH_INFO_TYPE ||
21040Sstevel@tonic-gate 	    mech_type == MD5_HMAC_GEN_MECH_INFO_TYPE ||
21050Sstevel@tonic-gate 	    mech_type == SHA1_HMAC_MECH_INFO_TYPE ||
21060Sstevel@tonic-gate 	    mech_type == SHA1_HMAC_GEN_MECH_INFO_TYPE ||
21070Sstevel@tonic-gate 	    mech_type == SHA256_HMAC_MECH_INFO_TYPE ||
21080Sstevel@tonic-gate 	    mech_type == SHA256_HMAC_GEN_MECH_INFO_TYPE ||
21090Sstevel@tonic-gate 	    mech_type == SHA384_HMAC_MECH_INFO_TYPE ||
21100Sstevel@tonic-gate 	    mech_type == SHA384_HMAC_GEN_MECH_INFO_TYPE ||
21110Sstevel@tonic-gate 	    mech_type == SHA512_HMAC_MECH_INFO_TYPE ||
21129339SMark.Powers@Sun.COM 	    mech_type == SHA512_HMAC_GEN_MECH_INFO_TYPE ||
21139339SMark.Powers@Sun.COM 	    mech_type == AES_GMAC_MECH_INFO_TYPE);
21140Sstevel@tonic-gate }
21150Sstevel@tonic-gate 
21160Sstevel@tonic-gate static int
dprov_mac_init(crypto_ctx_t * ctx,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)21170Sstevel@tonic-gate dprov_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
21180Sstevel@tonic-gate     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
21190Sstevel@tonic-gate     crypto_req_handle_t req)
21200Sstevel@tonic-gate {
21210Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
21220Sstevel@tonic-gate 	dprov_state_t *softc;
21230Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
21240Sstevel@tonic-gate 	int instance;
21250Sstevel@tonic-gate 
21260Sstevel@tonic-gate 	/* extract softc and instance number from context */
21270Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
21280Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_init: started\n", instance));
21290Sstevel@tonic-gate 
21300Sstevel@tonic-gate 	/* check mechanism */
21310Sstevel@tonic-gate 	if (!dprov_valid_mac_mech(mechanism->cm_type)) {
21320Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_mac_init: unexpected mech type "
21330Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
21340Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
21350Sstevel@tonic-gate 	}
21360Sstevel@tonic-gate 
21370Sstevel@tonic-gate 	if (ctx_template != NULL)
21380Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
21390Sstevel@tonic-gate 
21400Sstevel@tonic-gate 	/* submit request to the taskq */
21410Sstevel@tonic-gate 	error = dprov_mac_submit_req(DPROV_REQ_MAC_INIT, softc, req,
21420Sstevel@tonic-gate 	    mechanism, NULL, key, NULL, ctx, 0, KM_SLEEP);
21430Sstevel@tonic-gate 
21440Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_init: done err = 0x%x\n",
21450Sstevel@tonic-gate 	    instance, error));
21460Sstevel@tonic-gate 
21470Sstevel@tonic-gate 	return (error);
21480Sstevel@tonic-gate }
21490Sstevel@tonic-gate 
21500Sstevel@tonic-gate static int
dprov_mac(crypto_ctx_t * ctx,crypto_data_t * data,crypto_data_t * mac,crypto_req_handle_t req)21510Sstevel@tonic-gate dprov_mac(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *mac,
21520Sstevel@tonic-gate     crypto_req_handle_t req)
21530Sstevel@tonic-gate {
21540Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
21550Sstevel@tonic-gate 	dprov_state_t *softc;
21560Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
21570Sstevel@tonic-gate 	int instance;
21580Sstevel@tonic-gate 
21590Sstevel@tonic-gate 	/* extract softc and instance number from context */
21600Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
21610Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac: started\n", instance));
21620Sstevel@tonic-gate 
21630Sstevel@tonic-gate 	/* submit request to the taskq */
21640Sstevel@tonic-gate 	error = dprov_mac_submit_req(DPROV_REQ_MAC, softc, req,
21650Sstevel@tonic-gate 	    NULL, data, NULL, mac, ctx, 0, KM_NOSLEEP);
21660Sstevel@tonic-gate 
21670Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac: done, err = 0x%x\n", instance,
21680Sstevel@tonic-gate 	    error));
21690Sstevel@tonic-gate 
21700Sstevel@tonic-gate 	return (error);
21710Sstevel@tonic-gate }
21720Sstevel@tonic-gate 
21730Sstevel@tonic-gate static int
dprov_mac_update(crypto_ctx_t * ctx,crypto_data_t * data,crypto_req_handle_t req)21740Sstevel@tonic-gate dprov_mac_update(crypto_ctx_t *ctx, crypto_data_t *data,
21750Sstevel@tonic-gate     crypto_req_handle_t req)
21760Sstevel@tonic-gate {
21770Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
21780Sstevel@tonic-gate 	dprov_state_t *softc;
21790Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
21800Sstevel@tonic-gate 	int instance;
21810Sstevel@tonic-gate 
21820Sstevel@tonic-gate 	/* extract softc and instance number from context */
21830Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
21840Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_update: started\n", instance));
21850Sstevel@tonic-gate 
21860Sstevel@tonic-gate 	/* submit request to the taskq */
21870Sstevel@tonic-gate 	error = dprov_mac_submit_req(DPROV_REQ_MAC_UPDATE, softc,
21880Sstevel@tonic-gate 	    req, NULL, data, NULL, NULL, ctx, 0, KM_NOSLEEP);
21890Sstevel@tonic-gate 
21900Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_update: done err = 0x0%x\n",
21910Sstevel@tonic-gate 	    instance, error));
21920Sstevel@tonic-gate 
21930Sstevel@tonic-gate 	return (error);
21940Sstevel@tonic-gate }
21950Sstevel@tonic-gate 
21960Sstevel@tonic-gate static int
dprov_mac_final(crypto_ctx_t * ctx,crypto_data_t * mac,crypto_req_handle_t req)21970Sstevel@tonic-gate dprov_mac_final(crypto_ctx_t *ctx, crypto_data_t *mac, crypto_req_handle_t req)
21980Sstevel@tonic-gate {
21990Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
22000Sstevel@tonic-gate 	dprov_state_t *softc;
22010Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
22020Sstevel@tonic-gate 	int instance;
22030Sstevel@tonic-gate 
22040Sstevel@tonic-gate 	/* extract softc and instance number from context */
22050Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
22060Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_final: started\n", instance));
22070Sstevel@tonic-gate 
22080Sstevel@tonic-gate 	/* submit request to the taskq */
22090Sstevel@tonic-gate 	error = dprov_mac_submit_req(DPROV_REQ_MAC_FINAL, softc, req,
22100Sstevel@tonic-gate 	    NULL, NULL, NULL, mac, ctx, 0, KM_NOSLEEP);
22110Sstevel@tonic-gate 
22120Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_final: done err = 0x0%x\n",
22130Sstevel@tonic-gate 	    instance, error));
22140Sstevel@tonic-gate 
22150Sstevel@tonic-gate 	return (error);
22160Sstevel@tonic-gate }
22170Sstevel@tonic-gate 
22180Sstevel@tonic-gate static int
dprov_mac_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * data,crypto_data_t * mac,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)22190Sstevel@tonic-gate dprov_mac_atomic(crypto_provider_handle_t provider,
22200Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
22210Sstevel@tonic-gate     crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
22220Sstevel@tonic-gate     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
22230Sstevel@tonic-gate {
22240Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
22250Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
22260Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
22270Sstevel@tonic-gate 	int instance;
22280Sstevel@tonic-gate 
22290Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
22300Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_atomic: started\n", instance));
22310Sstevel@tonic-gate 
22320Sstevel@tonic-gate 	if (ctx_template != NULL)
22330Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
22340Sstevel@tonic-gate 
22350Sstevel@tonic-gate 	/* check mechanism */
22360Sstevel@tonic-gate 	if (!dprov_valid_mac_mech(mechanism->cm_type)) {
22370Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_mac_atomic: unexpected mech type "
22380Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
22390Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
22400Sstevel@tonic-gate 	}
22410Sstevel@tonic-gate 
22420Sstevel@tonic-gate 	/* submit request to the taskq */
22430Sstevel@tonic-gate 	error = dprov_mac_submit_req(DPROV_REQ_MAC_ATOMIC, softc, req,
22440Sstevel@tonic-gate 	    mechanism, data, key, mac, NULL, session_id, KM_SLEEP);
22450Sstevel@tonic-gate 
22460Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_atomic: done err = 0x0%x\n",
22470Sstevel@tonic-gate 	    instance, error));
22480Sstevel@tonic-gate 
22490Sstevel@tonic-gate 	return (error);
22500Sstevel@tonic-gate }
22510Sstevel@tonic-gate 
22520Sstevel@tonic-gate static int
dprov_mac_verify_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * data,crypto_data_t * mac,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)22530Sstevel@tonic-gate dprov_mac_verify_atomic(crypto_provider_handle_t provider,
22540Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
22550Sstevel@tonic-gate     crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
22560Sstevel@tonic-gate     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
22570Sstevel@tonic-gate {
22580Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
22590Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
22600Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
22610Sstevel@tonic-gate 	int instance;
22620Sstevel@tonic-gate 
22630Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
22640Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_verify_atomic: started\n",
22650Sstevel@tonic-gate 	    instance));
22660Sstevel@tonic-gate 
22670Sstevel@tonic-gate 	if (ctx_template != NULL)
22680Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
22690Sstevel@tonic-gate 
22700Sstevel@tonic-gate 	/* check mechanism */
22710Sstevel@tonic-gate 	if (!dprov_valid_mac_mech(mechanism->cm_type)) {
22720Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_mac_verify_atomic: unexpected mech "
22730Sstevel@tonic-gate 		    "type 0x%llx\n", (unsigned long long)mechanism->cm_type);
22740Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
22750Sstevel@tonic-gate 	}
22760Sstevel@tonic-gate 
22770Sstevel@tonic-gate 	/* submit request to the taskq */
22780Sstevel@tonic-gate 	error = dprov_mac_submit_req(DPROV_REQ_MAC_VERIFY_ATOMIC, softc, req,
22790Sstevel@tonic-gate 	    mechanism, data, key, mac, NULL, session_id, KM_SLEEP);
22800Sstevel@tonic-gate 
22810Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_verify_atomic: done err = 0x0%x\n",
22820Sstevel@tonic-gate 	    instance, error));
22830Sstevel@tonic-gate 
22840Sstevel@tonic-gate 	return (error);
22850Sstevel@tonic-gate }
22860Sstevel@tonic-gate 
22870Sstevel@tonic-gate /*
22880Sstevel@tonic-gate  * Cipher (encrypt/decrypt) entry points.
22890Sstevel@tonic-gate  */
22900Sstevel@tonic-gate 
22910Sstevel@tonic-gate /*
22920Sstevel@tonic-gate  * Checks whether the specified mech_type is supported by cipher entry
22930Sstevel@tonic-gate  * points.
22940Sstevel@tonic-gate  */
22950Sstevel@tonic-gate static boolean_t
dprov_valid_cipher_mech(crypto_mech_type_t mech_type)22960Sstevel@tonic-gate dprov_valid_cipher_mech(crypto_mech_type_t mech_type)
22970Sstevel@tonic-gate {
22980Sstevel@tonic-gate 	return (mech_type == DES_CBC_MECH_INFO_TYPE ||
22994424Sizick 	    mech_type == DES3_CBC_MECH_INFO_TYPE ||
23004424Sizick 	    mech_type == DES_ECB_MECH_INFO_TYPE ||
23014424Sizick 	    mech_type == DES3_ECB_MECH_INFO_TYPE ||
23024424Sizick 	    mech_type == BLOWFISH_CBC_MECH_INFO_TYPE ||
23034424Sizick 	    mech_type == BLOWFISH_ECB_MECH_INFO_TYPE ||
23044424Sizick 	    mech_type == AES_CBC_MECH_INFO_TYPE ||
23054424Sizick 	    mech_type == AES_ECB_MECH_INFO_TYPE ||
23064424Sizick 	    mech_type == AES_CTR_MECH_INFO_TYPE ||
23075413Sdinak 	    mech_type == AES_CCM_MECH_INFO_TYPE ||
23088005SMark.Powers@Sun.COM 	    mech_type == AES_GCM_MECH_INFO_TYPE ||
23099339SMark.Powers@Sun.COM 	    mech_type == AES_GMAC_MECH_INFO_TYPE ||
23104424Sizick 	    mech_type == RC4_MECH_INFO_TYPE ||
23114424Sizick 	    mech_type == RSA_PKCS_MECH_INFO_TYPE ||
23124424Sizick 	    mech_type == RSA_X_509_MECH_INFO_TYPE ||
23134424Sizick 	    mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE ||
23144424Sizick 	    mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE ||
23154424Sizick 	    mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE ||
23164424Sizick 	    mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE ||
23174424Sizick 	    mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE);
23180Sstevel@tonic-gate }
23190Sstevel@tonic-gate 
23200Sstevel@tonic-gate static boolean_t
is_publickey_mech(crypto_mech_type_t mech_type)23210Sstevel@tonic-gate is_publickey_mech(crypto_mech_type_t mech_type)
23220Sstevel@tonic-gate {
23230Sstevel@tonic-gate 	return (mech_type == RSA_PKCS_MECH_INFO_TYPE ||
23244424Sizick 	    mech_type == RSA_X_509_MECH_INFO_TYPE ||
23254424Sizick 	    mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE ||
23264424Sizick 	    mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE ||
23274424Sizick 	    mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE ||
23284424Sizick 	    mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE ||
23295697Smcpowers 	    mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE ||
23305697Smcpowers 	    mech_type == ECDSA_SHA1_MECH_INFO_TYPE ||
23315697Smcpowers 	    mech_type == ECDSA_MECH_INFO_TYPE);
23320Sstevel@tonic-gate }
23330Sstevel@tonic-gate 
23340Sstevel@tonic-gate 
23350Sstevel@tonic-gate /* ARGSUSED */
23360Sstevel@tonic-gate static int
dprov_encrypt_init(crypto_ctx_t * ctx,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)23370Sstevel@tonic-gate dprov_encrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
23380Sstevel@tonic-gate     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
23390Sstevel@tonic-gate     crypto_req_handle_t req)
23400Sstevel@tonic-gate {
23410Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
23420Sstevel@tonic-gate 	dprov_state_t *softc;
23430Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
23440Sstevel@tonic-gate 	int instance;
23450Sstevel@tonic-gate 
23460Sstevel@tonic-gate 	/* extract softc and instance number from context */
23470Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
23480Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_init: started\n",
23490Sstevel@tonic-gate 	    instance));
23500Sstevel@tonic-gate 
23510Sstevel@tonic-gate 	/* check mechanism */
23520Sstevel@tonic-gate 	if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
23530Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_encrypt_init: unexpected mech type "
23540Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
23550Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
23560Sstevel@tonic-gate 	}
23570Sstevel@tonic-gate 
23580Sstevel@tonic-gate 	/* submit request to the taskq */
23590Sstevel@tonic-gate 	error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_INIT, softc,
23600Sstevel@tonic-gate 	    req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
23610Sstevel@tonic-gate 
23620Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_init: done err = 0x0%x\n",
23630Sstevel@tonic-gate 	    instance, error));
23640Sstevel@tonic-gate 
23650Sstevel@tonic-gate 	return (error);
23660Sstevel@tonic-gate }
23670Sstevel@tonic-gate 
23680Sstevel@tonic-gate /* ARGSUSED */
23690Sstevel@tonic-gate static int
dprov_encrypt(crypto_ctx_t * ctx,crypto_data_t * plaintext,crypto_data_t * ciphertext,crypto_req_handle_t req)23700Sstevel@tonic-gate dprov_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
23710Sstevel@tonic-gate     crypto_data_t *ciphertext, crypto_req_handle_t req)
23720Sstevel@tonic-gate {
23730Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
23740Sstevel@tonic-gate 	dprov_state_t *softc;
23750Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
23760Sstevel@tonic-gate 	int instance;
23770Sstevel@tonic-gate 
23780Sstevel@tonic-gate 	/* extract softc and instance number from context */
23790Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
23800Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt: started\n", instance));
23810Sstevel@tonic-gate 
23820Sstevel@tonic-gate 	/* submit request to the taskq */
23830Sstevel@tonic-gate 	error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT, softc,
23840Sstevel@tonic-gate 	    req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
23850Sstevel@tonic-gate 
23860Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt: done err = 0x0%x\n",
23870Sstevel@tonic-gate 	    instance, error));
23880Sstevel@tonic-gate 
23890Sstevel@tonic-gate 	return (error);
23900Sstevel@tonic-gate }
23910Sstevel@tonic-gate 
23920Sstevel@tonic-gate /* ARGSUSED */
23930Sstevel@tonic-gate static int
dprov_encrypt_update(crypto_ctx_t * ctx,crypto_data_t * plaintext,crypto_data_t * ciphertext,crypto_req_handle_t req)23940Sstevel@tonic-gate dprov_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
23950Sstevel@tonic-gate     crypto_data_t *ciphertext, crypto_req_handle_t req)
23960Sstevel@tonic-gate {
23970Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
23980Sstevel@tonic-gate 	dprov_state_t *softc;
23990Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
24000Sstevel@tonic-gate 	int instance;
24010Sstevel@tonic-gate 
24020Sstevel@tonic-gate 	/* extract softc and instance number from context */
24030Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
24040Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_update: started\n",
24050Sstevel@tonic-gate 	    instance));
24060Sstevel@tonic-gate 
24070Sstevel@tonic-gate 	/* submit request to the taskq */
24080Sstevel@tonic-gate 	error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_UPDATE, softc,
24090Sstevel@tonic-gate 	    req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
24100Sstevel@tonic-gate 
24110Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_update: done err = 0x0%x\n",
24120Sstevel@tonic-gate 	    instance, error));
24130Sstevel@tonic-gate 
24140Sstevel@tonic-gate 	return (error);
24150Sstevel@tonic-gate }
24160Sstevel@tonic-gate 
24170Sstevel@tonic-gate /* ARGSUSED */
24180Sstevel@tonic-gate static int
dprov_encrypt_final(crypto_ctx_t * ctx,crypto_data_t * ciphertext,crypto_req_handle_t req)24190Sstevel@tonic-gate dprov_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
24200Sstevel@tonic-gate     crypto_req_handle_t req)
24210Sstevel@tonic-gate {
24220Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
24230Sstevel@tonic-gate 	dprov_state_t *softc;
24240Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
24250Sstevel@tonic-gate 	int instance;
24260Sstevel@tonic-gate 
24270Sstevel@tonic-gate 	/* extract softc and instance number from context */
24280Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
24290Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_final: started\n",
24300Sstevel@tonic-gate 	    instance));
24310Sstevel@tonic-gate 
24320Sstevel@tonic-gate 	/* submit request to the taskq */
24330Sstevel@tonic-gate 	error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_FINAL, softc,
24340Sstevel@tonic-gate 	    req, NULL, NULL, NULL, ciphertext, ctx, 0, KM_NOSLEEP);
24350Sstevel@tonic-gate 
24360Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_final: done err = 0x0%x\n",
24370Sstevel@tonic-gate 	    instance, error));
24380Sstevel@tonic-gate 
24390Sstevel@tonic-gate 	return (error);
24400Sstevel@tonic-gate }
24410Sstevel@tonic-gate 
24420Sstevel@tonic-gate static int
dprov_encrypt_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * plaintext,crypto_data_t * ciphertext,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)24430Sstevel@tonic-gate dprov_encrypt_atomic(crypto_provider_handle_t provider,
24440Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
24450Sstevel@tonic-gate     crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext,
24460Sstevel@tonic-gate     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
24470Sstevel@tonic-gate {
24480Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
24490Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
24500Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
24510Sstevel@tonic-gate 	int instance;
24520Sstevel@tonic-gate 
24530Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
24540Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_encrypt_atomic: started\n", instance));
24550Sstevel@tonic-gate 
24560Sstevel@tonic-gate 	if (ctx_template != NULL)
24570Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
24580Sstevel@tonic-gate 
24590Sstevel@tonic-gate 	/* check mechanism */
24600Sstevel@tonic-gate 	if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
24610Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_encrypt_atomic: unexpected mech type "
24620Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
24630Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
24640Sstevel@tonic-gate 	}
24650Sstevel@tonic-gate 
24660Sstevel@tonic-gate 	error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_ATOMIC, softc,
24670Sstevel@tonic-gate 	    req, mechanism, key, plaintext, ciphertext, NULL, session_id,
24680Sstevel@tonic-gate 	    KM_SLEEP);
24690Sstevel@tonic-gate 
24700Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_encrypt_atomic: done err = 0x0%x\n",
24710Sstevel@tonic-gate 	    instance, error));
24720Sstevel@tonic-gate 
24730Sstevel@tonic-gate 	return (error);
24740Sstevel@tonic-gate }
24750Sstevel@tonic-gate 
24760Sstevel@tonic-gate /* ARGSUSED */
24770Sstevel@tonic-gate static int
dprov_decrypt_init(crypto_ctx_t * ctx,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)24780Sstevel@tonic-gate dprov_decrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
24790Sstevel@tonic-gate     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
24800Sstevel@tonic-gate     crypto_req_handle_t req)
24810Sstevel@tonic-gate {
24820Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
24830Sstevel@tonic-gate 	dprov_state_t *softc;
24840Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
24850Sstevel@tonic-gate 	int instance;
24860Sstevel@tonic-gate 
24870Sstevel@tonic-gate 	/* extract softc and instance number from context */
24880Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
24890Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_init: started\n",
24900Sstevel@tonic-gate 	    instance));
24910Sstevel@tonic-gate 
24920Sstevel@tonic-gate 	/* check mechanism */
24930Sstevel@tonic-gate 	if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
24940Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_decrypt_init: unexpected mech type "
24950Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
24960Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
24970Sstevel@tonic-gate 	}
24980Sstevel@tonic-gate 
24990Sstevel@tonic-gate 	/* submit request to the taskq */
25000Sstevel@tonic-gate 	error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_INIT, softc,
25010Sstevel@tonic-gate 	    req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
25020Sstevel@tonic-gate 
25030Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_init: done err = 0x0%x\n",
25040Sstevel@tonic-gate 	    instance, error));
25050Sstevel@tonic-gate 
25060Sstevel@tonic-gate 	return (error);
25070Sstevel@tonic-gate }
25080Sstevel@tonic-gate 
25090Sstevel@tonic-gate /* ARGSUSED */
25100Sstevel@tonic-gate static int
dprov_decrypt(crypto_ctx_t * ctx,crypto_data_t * ciphertext,crypto_data_t * plaintext,crypto_req_handle_t req)25110Sstevel@tonic-gate dprov_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
25120Sstevel@tonic-gate     crypto_data_t *plaintext, crypto_req_handle_t req)
25130Sstevel@tonic-gate {
25140Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
25150Sstevel@tonic-gate 
25160Sstevel@tonic-gate 	dprov_state_t *softc;
25170Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
25180Sstevel@tonic-gate 	int instance;
25190Sstevel@tonic-gate 
25200Sstevel@tonic-gate 	/* extract softc and instance number from context */
25210Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
25220Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt: started\n", instance));
25230Sstevel@tonic-gate 
25240Sstevel@tonic-gate 	/* submit request to the taskq */
25250Sstevel@tonic-gate 	error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT, softc,
25260Sstevel@tonic-gate 	    req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
25270Sstevel@tonic-gate 
25280Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt: done err = 0x0%x\n",
25290Sstevel@tonic-gate 	    instance, error));
25300Sstevel@tonic-gate 
25310Sstevel@tonic-gate 	return (error);
25320Sstevel@tonic-gate }
25330Sstevel@tonic-gate 
25340Sstevel@tonic-gate /* ARGSUSED */
25350Sstevel@tonic-gate static int
dprov_decrypt_update(crypto_ctx_t * ctx,crypto_data_t * ciphertext,crypto_data_t * plaintext,crypto_req_handle_t req)25360Sstevel@tonic-gate dprov_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
25370Sstevel@tonic-gate     crypto_data_t *plaintext, crypto_req_handle_t req)
25380Sstevel@tonic-gate {
25390Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
25400Sstevel@tonic-gate 	dprov_state_t *softc;
25410Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
25420Sstevel@tonic-gate 	int instance;
25430Sstevel@tonic-gate 
25440Sstevel@tonic-gate 	/* extract softc and instance number from context */
25450Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
25460Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_update: started\n",
25470Sstevel@tonic-gate 	    instance));
25480Sstevel@tonic-gate 
25490Sstevel@tonic-gate 	/* submit request to the taskq */
25500Sstevel@tonic-gate 	error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_UPDATE, softc,
25510Sstevel@tonic-gate 	    req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
25520Sstevel@tonic-gate 
25530Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_update: done err = 0x0%x\n",
25540Sstevel@tonic-gate 	    instance, error));
25550Sstevel@tonic-gate 
25560Sstevel@tonic-gate 	return (error);
25570Sstevel@tonic-gate }
25580Sstevel@tonic-gate 
25590Sstevel@tonic-gate /* ARGSUSED */
25600Sstevel@tonic-gate static int
dprov_decrypt_final(crypto_ctx_t * ctx,crypto_data_t * plaintext,crypto_req_handle_t req)25610Sstevel@tonic-gate dprov_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *plaintext,
25620Sstevel@tonic-gate     crypto_req_handle_t req)
25630Sstevel@tonic-gate {
25640Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
25650Sstevel@tonic-gate 	dprov_state_t *softc;
25660Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
25670Sstevel@tonic-gate 	int instance;
25680Sstevel@tonic-gate 
25690Sstevel@tonic-gate 	/* extract softc and instance number from context */
25700Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
25710Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_final: started\n",
25720Sstevel@tonic-gate 	    instance));
25730Sstevel@tonic-gate 
25740Sstevel@tonic-gate 	/* submit request to the taskq */
25750Sstevel@tonic-gate 	error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_FINAL, softc,
25760Sstevel@tonic-gate 	    req, NULL, NULL, plaintext, NULL, ctx, 0, KM_NOSLEEP);
25770Sstevel@tonic-gate 
25780Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_final: done err = 0x0%x\n",
25790Sstevel@tonic-gate 	    instance, error));
25800Sstevel@tonic-gate 
25810Sstevel@tonic-gate 	return (error);
25820Sstevel@tonic-gate }
25830Sstevel@tonic-gate 
25840Sstevel@tonic-gate static int
dprov_decrypt_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * ciphertext,crypto_data_t * plaintext,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)25850Sstevel@tonic-gate dprov_decrypt_atomic(crypto_provider_handle_t provider,
25860Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
25870Sstevel@tonic-gate     crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext,
25880Sstevel@tonic-gate     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
25890Sstevel@tonic-gate {
25900Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
25910Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
25920Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
25930Sstevel@tonic-gate 	int instance;
25940Sstevel@tonic-gate 
25950Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
25960Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_decrypt_atomic: started\n", instance));
25970Sstevel@tonic-gate 
25980Sstevel@tonic-gate 	if (ctx_template != NULL)
25990Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
26000Sstevel@tonic-gate 
26010Sstevel@tonic-gate 	/* check mechanism */
26020Sstevel@tonic-gate 	if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
26030Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_atomic_init: unexpected mech type "
26040Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
26050Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
26060Sstevel@tonic-gate 	}
26070Sstevel@tonic-gate 
26080Sstevel@tonic-gate 	error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_ATOMIC, softc,
26090Sstevel@tonic-gate 	    req, mechanism, key, plaintext, ciphertext, NULL, session_id,
26100Sstevel@tonic-gate 	    KM_SLEEP);
26110Sstevel@tonic-gate 
26120Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_decrypt_atomic: done err = 0x0%x\n",
26130Sstevel@tonic-gate 	    instance, error));
26140Sstevel@tonic-gate 
26150Sstevel@tonic-gate 	return (error);
26160Sstevel@tonic-gate }
26170Sstevel@tonic-gate 
26180Sstevel@tonic-gate /*
26190Sstevel@tonic-gate  * Sign entry points.
26200Sstevel@tonic-gate  */
26210Sstevel@tonic-gate 
26220Sstevel@tonic-gate /*
26230Sstevel@tonic-gate  * Checks whether the specified mech_type is supported by sign/verify
26240Sstevel@tonic-gate  * entry points.
26250Sstevel@tonic-gate  */
26260Sstevel@tonic-gate static boolean_t
dprov_valid_sign_verif_mech(crypto_mech_type_t mech_type)26270Sstevel@tonic-gate dprov_valid_sign_verif_mech(crypto_mech_type_t mech_type)
26280Sstevel@tonic-gate {
26290Sstevel@tonic-gate 	return (mech_type == MD5_HMAC_MECH_INFO_TYPE ||
26304424Sizick 	    mech_type == MD5_HMAC_GEN_MECH_INFO_TYPE ||
26314424Sizick 	    mech_type == SHA1_HMAC_MECH_INFO_TYPE ||
26324424Sizick 	    mech_type == SHA1_HMAC_GEN_MECH_INFO_TYPE ||
26334424Sizick 	    mech_type == SHA256_HMAC_MECH_INFO_TYPE ||
26344424Sizick 	    mech_type == SHA256_HMAC_GEN_MECH_INFO_TYPE ||
26354424Sizick 	    mech_type == SHA384_HMAC_MECH_INFO_TYPE ||
26364424Sizick 	    mech_type == SHA384_HMAC_GEN_MECH_INFO_TYPE ||
26374424Sizick 	    mech_type == SHA512_HMAC_MECH_INFO_TYPE ||
26384424Sizick 	    mech_type == SHA512_HMAC_GEN_MECH_INFO_TYPE ||
26394424Sizick 	    mech_type == RSA_PKCS_MECH_INFO_TYPE ||
26404424Sizick 	    mech_type == RSA_X_509_MECH_INFO_TYPE ||
26414424Sizick 	    mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE ||
26424424Sizick 	    mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE ||
26434424Sizick 	    mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE ||
26444424Sizick 	    mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE ||
26455697Smcpowers 	    mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE ||
26465697Smcpowers 	    mech_type == ECDSA_SHA1_MECH_INFO_TYPE ||
26475697Smcpowers 	    mech_type == ECDSA_MECH_INFO_TYPE);
26480Sstevel@tonic-gate }
26490Sstevel@tonic-gate 
26500Sstevel@tonic-gate static int
dprov_sign_init(crypto_ctx_t * ctx,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)26510Sstevel@tonic-gate dprov_sign_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
26520Sstevel@tonic-gate     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
26530Sstevel@tonic-gate     crypto_req_handle_t req)
26540Sstevel@tonic-gate {
26550Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
26560Sstevel@tonic-gate 	dprov_state_t *softc;
26570Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
26580Sstevel@tonic-gate 	int instance;
26590Sstevel@tonic-gate 
26600Sstevel@tonic-gate 	/* extract softc and instance number from context */
26610Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
26620Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_init: started\n", instance));
26630Sstevel@tonic-gate 
26640Sstevel@tonic-gate 	/* check mechanism */
26650Sstevel@tonic-gate 	if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
26660Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_sign_init: unexpected mech type "
26670Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
26680Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
26690Sstevel@tonic-gate 	}
26700Sstevel@tonic-gate 
26710Sstevel@tonic-gate 	if (ctx_template != NULL)
26720Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
26730Sstevel@tonic-gate 
26740Sstevel@tonic-gate 	/* submit request to the taskq */
26750Sstevel@tonic-gate 	error = dprov_sign_submit_req(DPROV_REQ_SIGN_INIT, softc, req,
26760Sstevel@tonic-gate 	    mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
26770Sstevel@tonic-gate 
26780Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_init: done err = 0x%x\n",
26790Sstevel@tonic-gate 	    instance, error));
26800Sstevel@tonic-gate 
26810Sstevel@tonic-gate 	return (error);
26820Sstevel@tonic-gate }
26830Sstevel@tonic-gate 
26840Sstevel@tonic-gate static int
dprov_sign(crypto_ctx_t * ctx,crypto_data_t * data,crypto_data_t * signature,crypto_req_handle_t req)26850Sstevel@tonic-gate dprov_sign(crypto_ctx_t *ctx, crypto_data_t *data,
26860Sstevel@tonic-gate     crypto_data_t *signature, crypto_req_handle_t req)
26870Sstevel@tonic-gate {
26880Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
26890Sstevel@tonic-gate 	dprov_state_t *softc;
26900Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
26910Sstevel@tonic-gate 	int instance;
26920Sstevel@tonic-gate 
26930Sstevel@tonic-gate 	/* extract softc and instance number from context */
26940Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
26950Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign: started\n", instance));
26960Sstevel@tonic-gate 
26970Sstevel@tonic-gate 	/* submit request to the taskq */
26980Sstevel@tonic-gate 	error = dprov_sign_submit_req(DPROV_REQ_SIGN, softc, req,
26990Sstevel@tonic-gate 	    NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
27000Sstevel@tonic-gate 
27010Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign: done err = 0x%x\n",
27020Sstevel@tonic-gate 	    instance, error));
27030Sstevel@tonic-gate 
27040Sstevel@tonic-gate 	return (error);
27050Sstevel@tonic-gate }
27060Sstevel@tonic-gate 
27070Sstevel@tonic-gate static int
dprov_sign_update(crypto_ctx_t * ctx,crypto_data_t * data,crypto_req_handle_t req)27080Sstevel@tonic-gate dprov_sign_update(crypto_ctx_t *ctx, crypto_data_t *data,
27090Sstevel@tonic-gate     crypto_req_handle_t req)
27100Sstevel@tonic-gate {
27110Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
27120Sstevel@tonic-gate 	dprov_state_t *softc;
27130Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
27140Sstevel@tonic-gate 	int instance;
27150Sstevel@tonic-gate 
27160Sstevel@tonic-gate 	/* extract softc and instance number from context */
27170Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
27180Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_update: started\n", instance));
27190Sstevel@tonic-gate 
27200Sstevel@tonic-gate 	/* submit request to the taskq */
27210Sstevel@tonic-gate 	error = dprov_sign_submit_req(DPROV_REQ_SIGN_UPDATE, softc, req,
27220Sstevel@tonic-gate 	    NULL, NULL, data, NULL, ctx, 0, KM_NOSLEEP);
27230Sstevel@tonic-gate 
27240Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_update: done err = 0x%x\n",
27250Sstevel@tonic-gate 	    instance, error));
27260Sstevel@tonic-gate 
27270Sstevel@tonic-gate 	return (error);
27280Sstevel@tonic-gate }
27290Sstevel@tonic-gate 
27300Sstevel@tonic-gate static int
dprov_sign_final(crypto_ctx_t * ctx,crypto_data_t * signature,crypto_req_handle_t req)27310Sstevel@tonic-gate dprov_sign_final(crypto_ctx_t *ctx, crypto_data_t *signature,
27320Sstevel@tonic-gate     crypto_req_handle_t req)
27330Sstevel@tonic-gate {
27340Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
27350Sstevel@tonic-gate 	dprov_state_t *softc;
27360Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
27370Sstevel@tonic-gate 	int instance;
27380Sstevel@tonic-gate 
27390Sstevel@tonic-gate 	/* extract softc and instance number from context */
27400Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
27410Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_final: started\n", instance));
27420Sstevel@tonic-gate 
27430Sstevel@tonic-gate 	/* submit request to the taskq */
27440Sstevel@tonic-gate 	error = dprov_sign_submit_req(DPROV_REQ_SIGN_FINAL, softc, req,
27450Sstevel@tonic-gate 	    NULL, NULL, NULL, signature, ctx, 0, KM_NOSLEEP);
27460Sstevel@tonic-gate 
27470Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_final: done err = 0x%x\n",
27480Sstevel@tonic-gate 	    instance, error));
27490Sstevel@tonic-gate 
27500Sstevel@tonic-gate 	return (error);
27510Sstevel@tonic-gate }
27520Sstevel@tonic-gate 
27530Sstevel@tonic-gate static int
dprov_sign_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * data,crypto_data_t * signature,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)27540Sstevel@tonic-gate dprov_sign_atomic(crypto_provider_handle_t provider,
27550Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
27560Sstevel@tonic-gate     crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature,
27570Sstevel@tonic-gate     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
27580Sstevel@tonic-gate {
27590Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
27600Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
27610Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
27620Sstevel@tonic-gate 	int instance;
27630Sstevel@tonic-gate 
27640Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
27650Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_atomic: started\n", instance));
27660Sstevel@tonic-gate 
27670Sstevel@tonic-gate 	/* check mechanism */
27680Sstevel@tonic-gate 	if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
27690Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_sign_atomic: unexpected mech type "
27700Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
27710Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
27720Sstevel@tonic-gate 	}
27730Sstevel@tonic-gate 
27740Sstevel@tonic-gate 	if (ctx_template != NULL)
27750Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
27760Sstevel@tonic-gate 
27770Sstevel@tonic-gate 	/* submit request to the taskq */
27780Sstevel@tonic-gate 	error = dprov_sign_submit_req(DPROV_REQ_SIGN_ATOMIC, softc, req,
27790Sstevel@tonic-gate 	    mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
27800Sstevel@tonic-gate 
27810Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_atomic: done err = 0x%x\n",
27820Sstevel@tonic-gate 	    instance, error));
27830Sstevel@tonic-gate 
27840Sstevel@tonic-gate 	return (error);
27850Sstevel@tonic-gate }
27860Sstevel@tonic-gate 
27870Sstevel@tonic-gate static int
dprov_sign_recover_init(crypto_ctx_t * ctx,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)27880Sstevel@tonic-gate dprov_sign_recover_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
27890Sstevel@tonic-gate     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
27900Sstevel@tonic-gate     crypto_req_handle_t req)
27910Sstevel@tonic-gate {
27920Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
27930Sstevel@tonic-gate 	dprov_state_t *softc;
27940Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
27950Sstevel@tonic-gate 	int instance;
27960Sstevel@tonic-gate 
27970Sstevel@tonic-gate 	/* extract softc and instance number from context */
27980Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
27990Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_init: started\n",
28000Sstevel@tonic-gate 	    instance));
28010Sstevel@tonic-gate 
28020Sstevel@tonic-gate 	if (ctx_template != NULL)
28030Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
28040Sstevel@tonic-gate 
28050Sstevel@tonic-gate 	/* submit request to the taskq */
28060Sstevel@tonic-gate 	error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER_INIT, softc, req,
28070Sstevel@tonic-gate 	    mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
28080Sstevel@tonic-gate 
28090Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_init: done err = 0x%x\n",
28100Sstevel@tonic-gate 	    instance, error));
28110Sstevel@tonic-gate 
28120Sstevel@tonic-gate 	return (error);
28130Sstevel@tonic-gate }
28140Sstevel@tonic-gate 
28150Sstevel@tonic-gate static int
dprov_sign_recover(crypto_ctx_t * ctx,crypto_data_t * data,crypto_data_t * signature,crypto_req_handle_t req)28160Sstevel@tonic-gate dprov_sign_recover(crypto_ctx_t *ctx, crypto_data_t *data,
28170Sstevel@tonic-gate     crypto_data_t *signature, crypto_req_handle_t req)
28180Sstevel@tonic-gate {
28190Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
28200Sstevel@tonic-gate 	dprov_state_t *softc;
28210Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
28220Sstevel@tonic-gate 	int instance;
28230Sstevel@tonic-gate 
28240Sstevel@tonic-gate 	/* extract softc and instance number from context */
28250Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
28260Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover: started\n", instance));
28270Sstevel@tonic-gate 
28280Sstevel@tonic-gate 	/* submit request to the taskq */
28290Sstevel@tonic-gate 	error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER, softc, req,
28300Sstevel@tonic-gate 	    NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
28310Sstevel@tonic-gate 
28320Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover: done err = 0x%x\n",
28330Sstevel@tonic-gate 	    instance, error));
28340Sstevel@tonic-gate 
28350Sstevel@tonic-gate 	return (error);
28360Sstevel@tonic-gate }
28370Sstevel@tonic-gate 
28380Sstevel@tonic-gate static int
dprov_sign_recover_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * data,crypto_data_t * signature,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)28390Sstevel@tonic-gate dprov_sign_recover_atomic(crypto_provider_handle_t provider,
28400Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
28410Sstevel@tonic-gate     crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature,
28420Sstevel@tonic-gate     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
28430Sstevel@tonic-gate {
28440Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
28450Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
28460Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
28470Sstevel@tonic-gate 	int instance;
28480Sstevel@tonic-gate 
28490Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
28500Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_atomic: started\n",
28510Sstevel@tonic-gate 	    instance));
28520Sstevel@tonic-gate 
28530Sstevel@tonic-gate 	if (ctx_template != NULL)
28540Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
28550Sstevel@tonic-gate 
28560Sstevel@tonic-gate 	/* submit request to the taskq */
28570Sstevel@tonic-gate 	error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER_ATOMIC, softc, req,
28580Sstevel@tonic-gate 	    mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
28590Sstevel@tonic-gate 
28600Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_atomic: done "
28610Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
28620Sstevel@tonic-gate 
28630Sstevel@tonic-gate 	return (error);
28640Sstevel@tonic-gate }
28650Sstevel@tonic-gate 
28660Sstevel@tonic-gate /*
28670Sstevel@tonic-gate  * Verify entry points.
28680Sstevel@tonic-gate  */
28690Sstevel@tonic-gate 
28700Sstevel@tonic-gate static int
dprov_verify_init(crypto_ctx_t * ctx,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)28710Sstevel@tonic-gate dprov_verify_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
28720Sstevel@tonic-gate     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
28730Sstevel@tonic-gate     crypto_req_handle_t req)
28740Sstevel@tonic-gate {
28750Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
28760Sstevel@tonic-gate 	dprov_state_t *softc;
28770Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
28780Sstevel@tonic-gate 	int instance;
28790Sstevel@tonic-gate 
28800Sstevel@tonic-gate 	/* extract softc and instance number from context */
28810Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
28820Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_init: started\n", instance));
28830Sstevel@tonic-gate 
28840Sstevel@tonic-gate 	/* check mechanism */
28850Sstevel@tonic-gate 	if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
28860Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_verify_init: unexpected mech type "
28870Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
28880Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
28890Sstevel@tonic-gate 	}
28900Sstevel@tonic-gate 
28910Sstevel@tonic-gate 	if (ctx_template != NULL)
28920Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
28930Sstevel@tonic-gate 
28940Sstevel@tonic-gate 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY_INIT, softc, req,
28950Sstevel@tonic-gate 	    mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
28960Sstevel@tonic-gate 
28970Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_init: done err = 0x%x\n",
28980Sstevel@tonic-gate 	    instance, error));
28990Sstevel@tonic-gate 
29000Sstevel@tonic-gate 	return (error);
29010Sstevel@tonic-gate }
29020Sstevel@tonic-gate 
29030Sstevel@tonic-gate static int
dprov_verify(crypto_ctx_t * ctx,crypto_data_t * data,crypto_data_t * signature,crypto_req_handle_t req)29040Sstevel@tonic-gate dprov_verify(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature,
29050Sstevel@tonic-gate     crypto_req_handle_t req)
29060Sstevel@tonic-gate {
29070Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
29080Sstevel@tonic-gate 	dprov_state_t *softc;
29090Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
29100Sstevel@tonic-gate 	int instance;
29110Sstevel@tonic-gate 
29120Sstevel@tonic-gate 	/* extract softc and instance number from context */
29130Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
29140Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify: started\n", instance));
29150Sstevel@tonic-gate 
29160Sstevel@tonic-gate 	/* submit request to the taskq */
29170Sstevel@tonic-gate 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY, softc, req,
29180Sstevel@tonic-gate 	    NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
29190Sstevel@tonic-gate 
29200Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify: done err = 0x%x\n",
29210Sstevel@tonic-gate 	    instance, error));
29220Sstevel@tonic-gate 
29230Sstevel@tonic-gate 	return (error);
29240Sstevel@tonic-gate }
29250Sstevel@tonic-gate 
29260Sstevel@tonic-gate static int
dprov_verify_update(crypto_ctx_t * ctx,crypto_data_t * data,crypto_req_handle_t req)29270Sstevel@tonic-gate dprov_verify_update(crypto_ctx_t *ctx, crypto_data_t *data,
29280Sstevel@tonic-gate     crypto_req_handle_t req)
29290Sstevel@tonic-gate {
29300Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
29310Sstevel@tonic-gate 	dprov_state_t *softc;
29320Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
29330Sstevel@tonic-gate 	int instance;
29340Sstevel@tonic-gate 
29350Sstevel@tonic-gate 	/* extract softc and instance number from context */
29360Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
29370Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_update: started\n",
29380Sstevel@tonic-gate 	    instance));
29390Sstevel@tonic-gate 
29400Sstevel@tonic-gate 	/* submit request to the taskq */
29410Sstevel@tonic-gate 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY_UPDATE, softc, req,
29420Sstevel@tonic-gate 	    NULL, NULL, data, NULL, ctx, 0, KM_NOSLEEP);
29430Sstevel@tonic-gate 
29440Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_update: done err = 0x%x\n",
29450Sstevel@tonic-gate 	    instance, error));
29460Sstevel@tonic-gate 
29470Sstevel@tonic-gate 	return (error);
29480Sstevel@tonic-gate }
29490Sstevel@tonic-gate 
29500Sstevel@tonic-gate static int
dprov_verify_final(crypto_ctx_t * ctx,crypto_data_t * signature,crypto_req_handle_t req)29510Sstevel@tonic-gate dprov_verify_final(crypto_ctx_t *ctx, crypto_data_t *signature,
29520Sstevel@tonic-gate     crypto_req_handle_t req)
29530Sstevel@tonic-gate {
29540Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
29550Sstevel@tonic-gate 	dprov_state_t *softc;
29560Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
29570Sstevel@tonic-gate 	int instance;
29580Sstevel@tonic-gate 
29590Sstevel@tonic-gate 	/* extract softc and instance number from context */
29600Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
29610Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_final: started\n", instance));
29620Sstevel@tonic-gate 
29630Sstevel@tonic-gate 	/* submit request to the taskq */
29640Sstevel@tonic-gate 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY_FINAL, softc, req,
29650Sstevel@tonic-gate 	    NULL, NULL, NULL, signature, ctx, 0, KM_NOSLEEP);
29660Sstevel@tonic-gate 
29670Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_final: done err = 0x%x\n",
29680Sstevel@tonic-gate 	    instance, error));
29690Sstevel@tonic-gate 
29700Sstevel@tonic-gate 	return (error);
29710Sstevel@tonic-gate }
29720Sstevel@tonic-gate 
29730Sstevel@tonic-gate static int
dprov_verify_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * data,crypto_data_t * signature,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)29740Sstevel@tonic-gate dprov_verify_atomic(crypto_provider_handle_t provider,
29750Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
29760Sstevel@tonic-gate     crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature,
29770Sstevel@tonic-gate     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
29780Sstevel@tonic-gate {
29790Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
29800Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
29810Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
29820Sstevel@tonic-gate 	int instance;
29830Sstevel@tonic-gate 
29840Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
29850Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_atomic: started\n",
29860Sstevel@tonic-gate 	    instance));
29870Sstevel@tonic-gate 
29880Sstevel@tonic-gate 	/* check mechanism */
29890Sstevel@tonic-gate 	if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
29900Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_verify_atomic: unexpected mech type "
29910Sstevel@tonic-gate 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
29920Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
29930Sstevel@tonic-gate 	}
29940Sstevel@tonic-gate 
29950Sstevel@tonic-gate 	if (ctx_template != NULL)
29960Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
29970Sstevel@tonic-gate 
29980Sstevel@tonic-gate 	/* submit request to the taskq */
29990Sstevel@tonic-gate 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY_ATOMIC, softc, req,
30000Sstevel@tonic-gate 	    mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
30010Sstevel@tonic-gate 
30020Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_atomic: done err = 0x%x\n",
30030Sstevel@tonic-gate 	    instance, error));
30040Sstevel@tonic-gate 
30050Sstevel@tonic-gate 	return (error);
30060Sstevel@tonic-gate }
30070Sstevel@tonic-gate 
30080Sstevel@tonic-gate static int
dprov_verify_recover_init(crypto_ctx_t * ctx,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)30090Sstevel@tonic-gate dprov_verify_recover_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
30100Sstevel@tonic-gate     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
30110Sstevel@tonic-gate     crypto_req_handle_t req)
30120Sstevel@tonic-gate {
30130Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
30140Sstevel@tonic-gate 	dprov_state_t *softc;
30150Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
30160Sstevel@tonic-gate 	int instance;
30170Sstevel@tonic-gate 
30180Sstevel@tonic-gate 	/* extract softc and instance number from context */
30190Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
30200Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_init: started\n",
30210Sstevel@tonic-gate 	    instance));
30220Sstevel@tonic-gate 
30230Sstevel@tonic-gate 	if (ctx_template != NULL)
30240Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
30250Sstevel@tonic-gate 
30260Sstevel@tonic-gate 	/* submit request to the taskq */
30270Sstevel@tonic-gate 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER_INIT, softc,
30280Sstevel@tonic-gate 	    req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
30290Sstevel@tonic-gate 
30300Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_init: done "
30310Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
30320Sstevel@tonic-gate 
30330Sstevel@tonic-gate 	return (error);
30340Sstevel@tonic-gate }
30350Sstevel@tonic-gate 
30360Sstevel@tonic-gate static int
dprov_verify_recover(crypto_ctx_t * ctx,crypto_data_t * signature,crypto_data_t * data,crypto_req_handle_t req)30370Sstevel@tonic-gate dprov_verify_recover(crypto_ctx_t *ctx, crypto_data_t *signature,
30380Sstevel@tonic-gate     crypto_data_t *data, crypto_req_handle_t req)
30390Sstevel@tonic-gate {
30400Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
30410Sstevel@tonic-gate 	dprov_state_t *softc;
30420Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
30430Sstevel@tonic-gate 	int instance;
30440Sstevel@tonic-gate 
30450Sstevel@tonic-gate 	/* extract softc and instance number from context */
30460Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
30470Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover: started\n",
30480Sstevel@tonic-gate 	    instance));
30490Sstevel@tonic-gate 
30500Sstevel@tonic-gate 	/* submit request to the taskq */
30510Sstevel@tonic-gate 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER, softc, req,
30520Sstevel@tonic-gate 	    NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
30530Sstevel@tonic-gate 
30540Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover: done err = 0x%x\n",
30550Sstevel@tonic-gate 	    instance, error));
30560Sstevel@tonic-gate 
30570Sstevel@tonic-gate 	return (error);
30580Sstevel@tonic-gate }
30590Sstevel@tonic-gate 
30600Sstevel@tonic-gate static int
dprov_verify_recover_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * signature,crypto_data_t * data,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)30610Sstevel@tonic-gate dprov_verify_recover_atomic(crypto_provider_handle_t provider,
30620Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
30630Sstevel@tonic-gate     crypto_key_t *key, crypto_data_t *signature, crypto_data_t *data,
30640Sstevel@tonic-gate     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
30650Sstevel@tonic-gate {
30660Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
30670Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
30680Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
30690Sstevel@tonic-gate 	int instance;
30700Sstevel@tonic-gate 
30710Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
30720Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_atomic: started\n",
30730Sstevel@tonic-gate 	    instance));
30740Sstevel@tonic-gate 
30750Sstevel@tonic-gate 	if (ctx_template != NULL)
30760Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
30770Sstevel@tonic-gate 
30780Sstevel@tonic-gate 	/* submit request to the taskq */
30790Sstevel@tonic-gate 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER_ATOMIC, softc,
30800Sstevel@tonic-gate 	    req, mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
30810Sstevel@tonic-gate 
30820Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_atomic: done "
30830Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
30840Sstevel@tonic-gate 
30850Sstevel@tonic-gate 	return (error);
30860Sstevel@tonic-gate }
30870Sstevel@tonic-gate 
30880Sstevel@tonic-gate /*
30890Sstevel@tonic-gate  * Dual operations entry points.
30900Sstevel@tonic-gate  */
30910Sstevel@tonic-gate 
30920Sstevel@tonic-gate static int
dprov_digest_encrypt_update(crypto_ctx_t * digest_ctx,crypto_ctx_t * encrypt_ctx,crypto_data_t * plaintext,crypto_data_t * ciphertext,crypto_req_handle_t req)30930Sstevel@tonic-gate dprov_digest_encrypt_update(crypto_ctx_t *digest_ctx,
30940Sstevel@tonic-gate     crypto_ctx_t *encrypt_ctx, crypto_data_t *plaintext,
30950Sstevel@tonic-gate     crypto_data_t *ciphertext, crypto_req_handle_t req)
30960Sstevel@tonic-gate {
30970Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
30980Sstevel@tonic-gate 	dprov_state_t *softc;
30990Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
31000Sstevel@tonic-gate 	int instance;
31010Sstevel@tonic-gate 
31020Sstevel@tonic-gate 	/* extract softc and instance number from context */
31030Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(digest_ctx, softc, instance);
31040Sstevel@tonic-gate 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_digest_encrypt_update: started\n",
31050Sstevel@tonic-gate 	    instance));
31060Sstevel@tonic-gate 
31070Sstevel@tonic-gate 	if (digest_ctx->cc_provider != encrypt_ctx->cc_provider)
31080Sstevel@tonic-gate 		return (CRYPTO_INVALID_CONTEXT);
31090Sstevel@tonic-gate 
31100Sstevel@tonic-gate 	/* submit request to the taskq */
31110Sstevel@tonic-gate 	error = dprov_dual_submit_req(DPROV_REQ_DIGEST_ENCRYPT_UPDATE,
31120Sstevel@tonic-gate 	    softc, req, digest_ctx, encrypt_ctx, plaintext, ciphertext);
31130Sstevel@tonic-gate 
31140Sstevel@tonic-gate 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_digest_encrypt_update: done "
31150Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
31160Sstevel@tonic-gate 
31170Sstevel@tonic-gate 	return (error);
31180Sstevel@tonic-gate }
31190Sstevel@tonic-gate 
31200Sstevel@tonic-gate static int
dprov_decrypt_digest_update(crypto_ctx_t * decrypt_ctx,crypto_ctx_t * digest_ctx,crypto_data_t * ciphertext,crypto_data_t * plaintext,crypto_req_handle_t req)31210Sstevel@tonic-gate dprov_decrypt_digest_update(crypto_ctx_t *decrypt_ctx, crypto_ctx_t *digest_ctx,
31220Sstevel@tonic-gate     crypto_data_t *ciphertext, crypto_data_t *plaintext,
31230Sstevel@tonic-gate     crypto_req_handle_t req)
31240Sstevel@tonic-gate {
31250Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
31260Sstevel@tonic-gate 	dprov_state_t *softc;
31270Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
31280Sstevel@tonic-gate 	int instance;
31290Sstevel@tonic-gate 
31300Sstevel@tonic-gate 	/* extract softc and instance number from context */
31310Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(decrypt_ctx, softc, instance);
31320Sstevel@tonic-gate 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_digest_update: started\n",
31330Sstevel@tonic-gate 	    instance));
31340Sstevel@tonic-gate 
31350Sstevel@tonic-gate 	if (decrypt_ctx->cc_provider != digest_ctx->cc_provider)
31360Sstevel@tonic-gate 		return (CRYPTO_INVALID_CONTEXT);
31370Sstevel@tonic-gate 
31380Sstevel@tonic-gate 	/* submit request to the taskq */
31390Sstevel@tonic-gate 	error = dprov_dual_submit_req(DPROV_REQ_DECRYPT_DIGEST_UPDATE,
31400Sstevel@tonic-gate 	    softc, req, digest_ctx, decrypt_ctx, plaintext, ciphertext);
31410Sstevel@tonic-gate 
31420Sstevel@tonic-gate 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_digest_update: done "
31430Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
31440Sstevel@tonic-gate 
31450Sstevel@tonic-gate 	return (error);
31460Sstevel@tonic-gate }
31470Sstevel@tonic-gate 
31480Sstevel@tonic-gate static int
dprov_sign_encrypt_update(crypto_ctx_t * sign_ctx,crypto_ctx_t * encrypt_ctx,crypto_data_t * plaintext,crypto_data_t * ciphertext,crypto_req_handle_t req)31490Sstevel@tonic-gate dprov_sign_encrypt_update(crypto_ctx_t *sign_ctx, crypto_ctx_t *encrypt_ctx,
31500Sstevel@tonic-gate     crypto_data_t *plaintext, crypto_data_t *ciphertext,
31510Sstevel@tonic-gate     crypto_req_handle_t req)
31520Sstevel@tonic-gate {
31530Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
31540Sstevel@tonic-gate 	dprov_state_t *softc;
31550Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
31560Sstevel@tonic-gate 	int instance;
31570Sstevel@tonic-gate 
31580Sstevel@tonic-gate 	/* extract softc and instance number from context */
31590Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(sign_ctx, softc, instance);
31600Sstevel@tonic-gate 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_sign_encrypt_update: started\n",
31610Sstevel@tonic-gate 	    instance));
31620Sstevel@tonic-gate 
31630Sstevel@tonic-gate 	if (sign_ctx->cc_provider != encrypt_ctx->cc_provider)
31640Sstevel@tonic-gate 		return (CRYPTO_INVALID_CONTEXT);
31650Sstevel@tonic-gate 
31660Sstevel@tonic-gate 	/* submit request to the taskq */
31670Sstevel@tonic-gate 	error = dprov_dual_submit_req(DPROV_REQ_SIGN_ENCRYPT_UPDATE,
31680Sstevel@tonic-gate 	    softc, req, sign_ctx, encrypt_ctx, plaintext, ciphertext);
31690Sstevel@tonic-gate 
31700Sstevel@tonic-gate 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_sign_encrypt_update: done "
31710Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
31720Sstevel@tonic-gate 
31730Sstevel@tonic-gate 	return (error);
31740Sstevel@tonic-gate }
31750Sstevel@tonic-gate 
31760Sstevel@tonic-gate static int
dprov_decrypt_verify_update(crypto_ctx_t * decrypt_ctx,crypto_ctx_t * verify_ctx,crypto_data_t * ciphertext,crypto_data_t * plaintext,crypto_req_handle_t req)31770Sstevel@tonic-gate dprov_decrypt_verify_update(crypto_ctx_t *decrypt_ctx, crypto_ctx_t *verify_ctx,
31780Sstevel@tonic-gate     crypto_data_t *ciphertext, crypto_data_t *plaintext,
31790Sstevel@tonic-gate     crypto_req_handle_t req)
31800Sstevel@tonic-gate {
31810Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
31820Sstevel@tonic-gate 	dprov_state_t *softc;
31830Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
31840Sstevel@tonic-gate 	int instance;
31850Sstevel@tonic-gate 
31860Sstevel@tonic-gate 	/* extract softc and instance number from context */
31870Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(decrypt_ctx, softc, instance);
31880Sstevel@tonic-gate 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_verify_update: started\n",
31890Sstevel@tonic-gate 	    instance));
31900Sstevel@tonic-gate 
31910Sstevel@tonic-gate 	if (decrypt_ctx->cc_provider != verify_ctx->cc_provider)
31920Sstevel@tonic-gate 		return (CRYPTO_INVALID_CONTEXT);
31930Sstevel@tonic-gate 
31940Sstevel@tonic-gate 	/* submit request to the taskq */
31950Sstevel@tonic-gate 	error = dprov_dual_submit_req(DPROV_REQ_DECRYPT_VERIFY_UPDATE,
31960Sstevel@tonic-gate 	    softc, req, verify_ctx, decrypt_ctx, plaintext, ciphertext);
31970Sstevel@tonic-gate 
31980Sstevel@tonic-gate 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_verify_update: done "
31990Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
32000Sstevel@tonic-gate 
32010Sstevel@tonic-gate 	return (error);
32020Sstevel@tonic-gate }
32030Sstevel@tonic-gate 
32040Sstevel@tonic-gate /*
32050Sstevel@tonic-gate  * Dual cipher-mac entry points.
32060Sstevel@tonic-gate  */
32070Sstevel@tonic-gate 
32080Sstevel@tonic-gate static int
dprov_encrypt_mac_init(crypto_ctx_t * ctx,crypto_mechanism_t * encrypt_mech,crypto_key_t * encrypt_key,crypto_mechanism_t * mac_mech,crypto_key_t * mac_key,crypto_spi_ctx_template_t encr_ctx_template,crypto_spi_ctx_template_t mac_ctx_template,crypto_req_handle_t req)32090Sstevel@tonic-gate dprov_encrypt_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *encrypt_mech,
32100Sstevel@tonic-gate     crypto_key_t *encrypt_key, crypto_mechanism_t *mac_mech,
32110Sstevel@tonic-gate     crypto_key_t *mac_key, crypto_spi_ctx_template_t encr_ctx_template,
32120Sstevel@tonic-gate     crypto_spi_ctx_template_t mac_ctx_template,
32130Sstevel@tonic-gate     crypto_req_handle_t req)
32140Sstevel@tonic-gate {
32150Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
32160Sstevel@tonic-gate 	dprov_state_t *softc;
32170Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
32180Sstevel@tonic-gate 	int instance;
32190Sstevel@tonic-gate 
32200Sstevel@tonic-gate 	/* extract softc and instance number from context */
32210Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
32220Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_init: started\n",
32230Sstevel@tonic-gate 	    instance));
32240Sstevel@tonic-gate 
32250Sstevel@tonic-gate 	/* check mechanisms */
32260Sstevel@tonic-gate 	if (!dprov_valid_cipher_mech(encrypt_mech->cm_type)) {
32270Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_encrypt_mac_init: unexpected encrypt "
32280Sstevel@tonic-gate 		    "mech type 0x%llx\n",
32290Sstevel@tonic-gate 		    (unsigned long long)encrypt_mech->cm_type);
32300Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
32310Sstevel@tonic-gate 	}
32320Sstevel@tonic-gate 	if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
32330Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_encrypt_mac_init: unexpected mac "
32340Sstevel@tonic-gate 		    "mech type 0x%llx\n",
32350Sstevel@tonic-gate 		    (unsigned long long)mac_mech->cm_type);
32360Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
32370Sstevel@tonic-gate 	}
32380Sstevel@tonic-gate 
32390Sstevel@tonic-gate 	if (encr_ctx_template != NULL || mac_ctx_template != NULL)
32400Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
32410Sstevel@tonic-gate 
32420Sstevel@tonic-gate 	/* submit request to the taskq */
32430Sstevel@tonic-gate 	error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_INIT,
32440Sstevel@tonic-gate 	    softc, req, ctx, 0, encrypt_mech, encrypt_key, mac_mech, mac_key,
32450Sstevel@tonic-gate 	    NULL, NULL, NULL, KM_SLEEP);
32460Sstevel@tonic-gate 
32470Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_init: done "
32480Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
32490Sstevel@tonic-gate 
32500Sstevel@tonic-gate 	return (error);
32510Sstevel@tonic-gate }
32520Sstevel@tonic-gate 
32530Sstevel@tonic-gate static int
dprov_encrypt_mac(crypto_ctx_t * ctx,crypto_data_t * plaintext,crypto_dual_data_t * ciphertext,crypto_data_t * mac,crypto_req_handle_t req)32540Sstevel@tonic-gate dprov_encrypt_mac(crypto_ctx_t *ctx, crypto_data_t *plaintext,
32550Sstevel@tonic-gate     crypto_dual_data_t *ciphertext, crypto_data_t *mac, crypto_req_handle_t req)
32560Sstevel@tonic-gate {
32570Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
32580Sstevel@tonic-gate 	dprov_state_t *softc;
32590Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
32600Sstevel@tonic-gate 	int instance;
32610Sstevel@tonic-gate 
32620Sstevel@tonic-gate 	/* extract softc and instance number from context */
32630Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
32640Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac: started\n",
32650Sstevel@tonic-gate 	    instance));
32660Sstevel@tonic-gate 
32670Sstevel@tonic-gate 	/*
32680Sstevel@tonic-gate 	 * submit request to the taskq
32690Sstevel@tonic-gate 	 * Careful! cihertext/plaintext order inversion
32700Sstevel@tonic-gate 	 */
32710Sstevel@tonic-gate 	error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC,
32720Sstevel@tonic-gate 	    softc, req, ctx, 0, NULL, NULL, NULL, NULL,
32730Sstevel@tonic-gate 	    ciphertext, plaintext, mac, KM_NOSLEEP);
32740Sstevel@tonic-gate 
32750Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac: done "
32760Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
32770Sstevel@tonic-gate 
32780Sstevel@tonic-gate 	return (error);
32790Sstevel@tonic-gate }
32800Sstevel@tonic-gate 
32810Sstevel@tonic-gate static int
dprov_encrypt_mac_update(crypto_ctx_t * ctx,crypto_data_t * plaintext,crypto_dual_data_t * ciphertext,crypto_req_handle_t req)32820Sstevel@tonic-gate dprov_encrypt_mac_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
32830Sstevel@tonic-gate     crypto_dual_data_t *ciphertext, crypto_req_handle_t req)
32840Sstevel@tonic-gate {
32850Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
32860Sstevel@tonic-gate 	dprov_state_t *softc;
32870Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
32880Sstevel@tonic-gate 	int instance;
32890Sstevel@tonic-gate 
32900Sstevel@tonic-gate 	/* extract softc and instance number from context */
32910Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
32920Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_update: started\n",
32930Sstevel@tonic-gate 	    instance));
32940Sstevel@tonic-gate 
32950Sstevel@tonic-gate 	/* submit request to the taskq */
32960Sstevel@tonic-gate 	error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_UPDATE,
32970Sstevel@tonic-gate 	    softc, req, ctx, 0, NULL, NULL, NULL, NULL,
32980Sstevel@tonic-gate 	    ciphertext, plaintext, NULL, KM_NOSLEEP);
32990Sstevel@tonic-gate 
33000Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_update: done "
33010Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
33020Sstevel@tonic-gate 
33030Sstevel@tonic-gate 	return (error);
33040Sstevel@tonic-gate }
33050Sstevel@tonic-gate 
33060Sstevel@tonic-gate static int
dprov_encrypt_mac_final(crypto_ctx_t * ctx,crypto_dual_data_t * ciphertext,crypto_data_t * mac,crypto_req_handle_t req)33070Sstevel@tonic-gate dprov_encrypt_mac_final(crypto_ctx_t *ctx,
33080Sstevel@tonic-gate     crypto_dual_data_t *ciphertext, crypto_data_t *mac,
33090Sstevel@tonic-gate     crypto_req_handle_t req)
33100Sstevel@tonic-gate {
33110Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
33120Sstevel@tonic-gate 	dprov_state_t *softc;
33130Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
33140Sstevel@tonic-gate 	int instance;
33150Sstevel@tonic-gate 
33160Sstevel@tonic-gate 	/* extract softc and instance number from context */
33170Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
33180Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_final: started\n",
33190Sstevel@tonic-gate 	    instance));
33200Sstevel@tonic-gate 
33210Sstevel@tonic-gate 	/* submit request to the taskq */
33220Sstevel@tonic-gate 	error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_FINAL,
33230Sstevel@tonic-gate 	    softc, req, ctx, 0, NULL, NULL, NULL, NULL,
33240Sstevel@tonic-gate 	    ciphertext, NULL, mac, KM_NOSLEEP);
33250Sstevel@tonic-gate 
33260Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_final: done "
33270Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
33280Sstevel@tonic-gate 
33290Sstevel@tonic-gate 	return (error);
33300Sstevel@tonic-gate }
33310Sstevel@tonic-gate 
33320Sstevel@tonic-gate static int
dprov_encrypt_mac_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * encrypt_mech,crypto_key_t * encrypt_key,crypto_mechanism_t * mac_mech,crypto_key_t * mac_key,crypto_data_t * plaintext,crypto_dual_data_t * ciphertext,crypto_data_t * mac,crypto_spi_ctx_template_t encr_ctx_template,crypto_spi_ctx_template_t mac_ctx_template,crypto_req_handle_t req)33330Sstevel@tonic-gate dprov_encrypt_mac_atomic(crypto_provider_handle_t provider,
33340Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *encrypt_mech,
33350Sstevel@tonic-gate     crypto_key_t *encrypt_key, crypto_mechanism_t *mac_mech,
33360Sstevel@tonic-gate     crypto_key_t *mac_key, crypto_data_t *plaintext,
33370Sstevel@tonic-gate     crypto_dual_data_t *ciphertext, crypto_data_t *mac,
33380Sstevel@tonic-gate     crypto_spi_ctx_template_t encr_ctx_template,
33390Sstevel@tonic-gate     crypto_spi_ctx_template_t mac_ctx_template,
33400Sstevel@tonic-gate     crypto_req_handle_t req)
33410Sstevel@tonic-gate {
33420Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
33430Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
33440Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
33450Sstevel@tonic-gate 	int instance;
33460Sstevel@tonic-gate 
33470Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
33480Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_atomic: started\n",
33490Sstevel@tonic-gate 	    instance));
33500Sstevel@tonic-gate 
33510Sstevel@tonic-gate 	/* check mechanisms */
33520Sstevel@tonic-gate 	if (!dprov_valid_cipher_mech(encrypt_mech->cm_type)) {
33530Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_encrypt_mac_atomic: unexpected encrypt "
33540Sstevel@tonic-gate 		    "mech type 0x%llx\n",
33550Sstevel@tonic-gate 		    (unsigned long long)encrypt_mech->cm_type);
33560Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
33570Sstevel@tonic-gate 	}
33580Sstevel@tonic-gate 	if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
33590Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_encrypt_mac_atomic: unexpected mac "
33600Sstevel@tonic-gate 		    "mech type 0x%llx\n",
33610Sstevel@tonic-gate 		    (unsigned long long)mac_mech->cm_type);
33620Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
33630Sstevel@tonic-gate 	}
33640Sstevel@tonic-gate 
33650Sstevel@tonic-gate 	if (encr_ctx_template != NULL || mac_ctx_template != NULL)
33660Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
33670Sstevel@tonic-gate 
33680Sstevel@tonic-gate 	/* submit request to the taskq */
33690Sstevel@tonic-gate 	error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_ATOMIC,
33700Sstevel@tonic-gate 	    softc, req, NULL, session_id, encrypt_mech, encrypt_key, mac_mech,
33710Sstevel@tonic-gate 	    mac_key, ciphertext, plaintext, mac, KM_SLEEP);
33720Sstevel@tonic-gate 
33730Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_atomic: done "
33740Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
33750Sstevel@tonic-gate 
33760Sstevel@tonic-gate 	return (error);
33770Sstevel@tonic-gate }
33780Sstevel@tonic-gate 
33790Sstevel@tonic-gate static int
dprov_mac_decrypt_init(crypto_ctx_t * ctx,crypto_mechanism_t * mac_mech,crypto_key_t * mac_key,crypto_mechanism_t * decrypt_mech,crypto_key_t * decrypt_key,crypto_spi_ctx_template_t mac_ctx_template,crypto_spi_ctx_template_t decr_ctx_template,crypto_req_handle_t req)33800Sstevel@tonic-gate dprov_mac_decrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mac_mech,
33810Sstevel@tonic-gate     crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech,
33820Sstevel@tonic-gate     crypto_key_t *decrypt_key, crypto_spi_ctx_template_t mac_ctx_template,
33830Sstevel@tonic-gate     crypto_spi_ctx_template_t decr_ctx_template,
33840Sstevel@tonic-gate     crypto_req_handle_t req)
33850Sstevel@tonic-gate {
33860Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
33870Sstevel@tonic-gate 	dprov_state_t *softc;
33880Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
33890Sstevel@tonic-gate 	int instance;
33900Sstevel@tonic-gate 
33910Sstevel@tonic-gate 	/* extract softc and instance number from context */
33920Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
33930Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_init: started\n",
33940Sstevel@tonic-gate 	    instance));
33950Sstevel@tonic-gate 
33960Sstevel@tonic-gate 	/* check mechanisms */
33970Sstevel@tonic-gate 	if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) {
33980Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_mac_decrypt_init: unexpected decrypt "
33990Sstevel@tonic-gate 		    "mech type 0x%llx\n",
34000Sstevel@tonic-gate 		    (unsigned long long)decrypt_mech->cm_type);
34010Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
34020Sstevel@tonic-gate 	}
34030Sstevel@tonic-gate 	if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
34040Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_mac_decrypt_init: unexpected mac "
34050Sstevel@tonic-gate 		    "mech type 0x%llx\n",
34060Sstevel@tonic-gate 		    (unsigned long long)mac_mech->cm_type);
34070Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
34080Sstevel@tonic-gate 	}
34090Sstevel@tonic-gate 
34100Sstevel@tonic-gate 	if (decr_ctx_template != NULL || mac_ctx_template != NULL)
34110Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
34120Sstevel@tonic-gate 
34130Sstevel@tonic-gate 	/* submit request to the taskq */
34140Sstevel@tonic-gate 	error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_INIT,
34150Sstevel@tonic-gate 	    softc, req, ctx, 0, decrypt_mech, decrypt_key, mac_mech, mac_key,
34160Sstevel@tonic-gate 	    NULL, NULL, NULL, KM_SLEEP);
34170Sstevel@tonic-gate 
34180Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_init: done "
34190Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
34200Sstevel@tonic-gate 
34210Sstevel@tonic-gate 	return (error);
34220Sstevel@tonic-gate }
34230Sstevel@tonic-gate 
34240Sstevel@tonic-gate static int
dprov_mac_decrypt(crypto_ctx_t * ctx,crypto_dual_data_t * ciphertext,crypto_data_t * mac,crypto_data_t * plaintext,crypto_req_handle_t req)34250Sstevel@tonic-gate dprov_mac_decrypt(crypto_ctx_t *ctx, crypto_dual_data_t *ciphertext,
34260Sstevel@tonic-gate     crypto_data_t *mac, crypto_data_t *plaintext, crypto_req_handle_t req)
34270Sstevel@tonic-gate {
34280Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
34290Sstevel@tonic-gate 	dprov_state_t *softc;
34300Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
34310Sstevel@tonic-gate 	int instance;
34320Sstevel@tonic-gate 
34330Sstevel@tonic-gate 	/* extract softc and instance number from context */
34340Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
34350Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt: started\n",
34360Sstevel@tonic-gate 	    instance));
34370Sstevel@tonic-gate 
34380Sstevel@tonic-gate 	/* submit request to the taskq */
34390Sstevel@tonic-gate 	error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT,
34400Sstevel@tonic-gate 	    softc, req, ctx, 0, NULL, NULL, NULL, NULL,
34410Sstevel@tonic-gate 	    ciphertext, plaintext, mac, KM_NOSLEEP);
34420Sstevel@tonic-gate 
34430Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt: done "
34440Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
34450Sstevel@tonic-gate 
34460Sstevel@tonic-gate 	return (error);
34470Sstevel@tonic-gate }
34480Sstevel@tonic-gate 
34490Sstevel@tonic-gate static int
dprov_mac_decrypt_update(crypto_ctx_t * ctx,crypto_dual_data_t * ciphertext,crypto_data_t * plaintext,crypto_req_handle_t req)34500Sstevel@tonic-gate dprov_mac_decrypt_update(crypto_ctx_t *ctx, crypto_dual_data_t *ciphertext,
34510Sstevel@tonic-gate     crypto_data_t *plaintext, crypto_req_handle_t req)
34520Sstevel@tonic-gate {
34530Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
34540Sstevel@tonic-gate 	dprov_state_t *softc;
34550Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
34560Sstevel@tonic-gate 	int instance;
34570Sstevel@tonic-gate 
34580Sstevel@tonic-gate 	/* extract softc and instance number from context */
34590Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
34600Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_update: started\n",
34610Sstevel@tonic-gate 	    instance));
34620Sstevel@tonic-gate 
34630Sstevel@tonic-gate 	/* submit request to the taskq */
34640Sstevel@tonic-gate 	error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_UPDATE,
34650Sstevel@tonic-gate 	    softc, req, ctx, 0, NULL, NULL, NULL, NULL,
34660Sstevel@tonic-gate 	    ciphertext, plaintext, NULL, KM_NOSLEEP);
34670Sstevel@tonic-gate 
34680Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_update: done "
34690Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
34700Sstevel@tonic-gate 
34710Sstevel@tonic-gate 	return (error);
34720Sstevel@tonic-gate }
34730Sstevel@tonic-gate 
34740Sstevel@tonic-gate static int
dprov_mac_decrypt_final(crypto_ctx_t * ctx,crypto_data_t * mac,crypto_data_t * plaintext,crypto_req_handle_t req)34750Sstevel@tonic-gate dprov_mac_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *mac,
34760Sstevel@tonic-gate     crypto_data_t *plaintext, crypto_req_handle_t req)
34770Sstevel@tonic-gate {
34780Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
34790Sstevel@tonic-gate 	dprov_state_t *softc;
34800Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
34810Sstevel@tonic-gate 	int instance;
34820Sstevel@tonic-gate 
34830Sstevel@tonic-gate 	/* extract softc and instance number from context */
34840Sstevel@tonic-gate 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
34850Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_final: started\n",
34860Sstevel@tonic-gate 	    instance));
34870Sstevel@tonic-gate 
34880Sstevel@tonic-gate 	/* submit request to the taskq */
34890Sstevel@tonic-gate 	error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_FINAL,
34900Sstevel@tonic-gate 	    softc, req, ctx, 0, NULL, NULL, NULL, NULL,
34910Sstevel@tonic-gate 	    NULL, plaintext, mac, KM_NOSLEEP);
34920Sstevel@tonic-gate 
34930Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_final: done "
34940Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
34950Sstevel@tonic-gate 
34960Sstevel@tonic-gate 	return (error);
34970Sstevel@tonic-gate }
34980Sstevel@tonic-gate 
34990Sstevel@tonic-gate static int
dprov_mac_decrypt_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mac_mech,crypto_key_t * mac_key,crypto_mechanism_t * decrypt_mech,crypto_key_t * decrypt_key,crypto_dual_data_t * ciphertext,crypto_data_t * mac,crypto_data_t * plaintext,crypto_spi_ctx_template_t mac_ctx_template,crypto_spi_ctx_template_t decr_ctx_template,crypto_req_handle_t req)35000Sstevel@tonic-gate dprov_mac_decrypt_atomic(crypto_provider_handle_t provider,
35010Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mac_mech,
35020Sstevel@tonic-gate     crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech,
35030Sstevel@tonic-gate     crypto_key_t *decrypt_key, crypto_dual_data_t *ciphertext,
35040Sstevel@tonic-gate     crypto_data_t *mac, crypto_data_t *plaintext,
35050Sstevel@tonic-gate     crypto_spi_ctx_template_t mac_ctx_template,
35060Sstevel@tonic-gate     crypto_spi_ctx_template_t decr_ctx_template,
35070Sstevel@tonic-gate     crypto_req_handle_t req)
35080Sstevel@tonic-gate {
35090Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
35100Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
35110Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
35120Sstevel@tonic-gate 	int instance;
35130Sstevel@tonic-gate 
35140Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
35150Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_atomic: started\n",
35160Sstevel@tonic-gate 	    instance));
35170Sstevel@tonic-gate 
35180Sstevel@tonic-gate 	/* check mechanisms */
35190Sstevel@tonic-gate 	if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) {
35200Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_mac_decrypt_atomic: unexpected encrypt "
35210Sstevel@tonic-gate 		    "mech type 0x%llx\n",
35220Sstevel@tonic-gate 		    (unsigned long long)decrypt_mech->cm_type);
35230Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
35240Sstevel@tonic-gate 	}
35250Sstevel@tonic-gate 	if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
35260Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_mac_decrypt_atomic: unexpected mac "
35270Sstevel@tonic-gate 		    "mech type 0x%llx\n",
35280Sstevel@tonic-gate 		    (unsigned long long)mac_mech->cm_type);
35290Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
35300Sstevel@tonic-gate 	}
35310Sstevel@tonic-gate 
35320Sstevel@tonic-gate 	if (decr_ctx_template != NULL || mac_ctx_template != NULL)
35330Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
35340Sstevel@tonic-gate 
35350Sstevel@tonic-gate 	/* submit request to the taskq */
35360Sstevel@tonic-gate 	error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_ATOMIC,
35370Sstevel@tonic-gate 	    softc, req, NULL, session_id, decrypt_mech, decrypt_key, mac_mech,
35380Sstevel@tonic-gate 	    mac_key, ciphertext, plaintext, mac, KM_SLEEP);
35390Sstevel@tonic-gate 
35400Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_atomic: done "
35410Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
35420Sstevel@tonic-gate 
35430Sstevel@tonic-gate 	return (error);
35440Sstevel@tonic-gate }
35450Sstevel@tonic-gate 
35460Sstevel@tonic-gate static int
dprov_mac_verify_decrypt_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mac_mech,crypto_key_t * mac_key,crypto_mechanism_t * decrypt_mech,crypto_key_t * decrypt_key,crypto_dual_data_t * ciphertext,crypto_data_t * mac,crypto_data_t * plaintext,crypto_spi_ctx_template_t mac_ctx_template,crypto_spi_ctx_template_t decr_ctx_template,crypto_req_handle_t req)35470Sstevel@tonic-gate dprov_mac_verify_decrypt_atomic(crypto_provider_handle_t provider,
35480Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mac_mech,
35490Sstevel@tonic-gate     crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech,
35500Sstevel@tonic-gate     crypto_key_t *decrypt_key, crypto_dual_data_t *ciphertext,
35510Sstevel@tonic-gate     crypto_data_t *mac, crypto_data_t *plaintext,
35520Sstevel@tonic-gate     crypto_spi_ctx_template_t mac_ctx_template,
35530Sstevel@tonic-gate     crypto_spi_ctx_template_t decr_ctx_template,
35540Sstevel@tonic-gate     crypto_req_handle_t req)
35550Sstevel@tonic-gate {
35560Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
35570Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
35580Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
35590Sstevel@tonic-gate 	int instance;
35600Sstevel@tonic-gate 
35610Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
35620Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_verify_decrypt_atomic:"
35630Sstevel@tonic-gate 	    "started\n", instance));
35640Sstevel@tonic-gate 
35650Sstevel@tonic-gate 	/* check mechanisms */
35660Sstevel@tonic-gate 	if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) {
35670Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_mac_verify_decrypt_atomic: "
35680Sstevel@tonic-gate 		    "unexpected encrypt mech type 0x%llx\n",
35690Sstevel@tonic-gate 		    (unsigned long long)decrypt_mech->cm_type);
35700Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
35710Sstevel@tonic-gate 	}
35720Sstevel@tonic-gate 	if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
35730Sstevel@tonic-gate 		cmn_err(CE_WARN, "dprov_mac_verify_decrypt_atomic: "
35740Sstevel@tonic-gate 		    "unexpected mac mech type 0x%llx\n",
35750Sstevel@tonic-gate 		    (unsigned long long)mac_mech->cm_type);
35760Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
35770Sstevel@tonic-gate 	}
35780Sstevel@tonic-gate 
35790Sstevel@tonic-gate 	if (decr_ctx_template != NULL || mac_ctx_template != NULL)
35800Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
35810Sstevel@tonic-gate 
35820Sstevel@tonic-gate 	/* submit request to the taskq */
35830Sstevel@tonic-gate 	error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC,
35840Sstevel@tonic-gate 	    softc, req, NULL, session_id, decrypt_mech, decrypt_key, mac_mech,
35850Sstevel@tonic-gate 	    mac_key, ciphertext, plaintext, mac, KM_SLEEP);
35860Sstevel@tonic-gate 
35870Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_verify_decrypt_atomic: done "
35880Sstevel@tonic-gate 	    "err = 0x%x\n", instance, error));
35890Sstevel@tonic-gate 
35900Sstevel@tonic-gate 	return (error);
35910Sstevel@tonic-gate }
35920Sstevel@tonic-gate 
35930Sstevel@tonic-gate /*
35940Sstevel@tonic-gate  * Random number entry points.
35950Sstevel@tonic-gate  */
35960Sstevel@tonic-gate 
35970Sstevel@tonic-gate static int
dprov_seed_random(crypto_provider_handle_t provider,crypto_session_id_t sid,uchar_t * buf,size_t len,uint_t entropy_est,uint32_t flags,crypto_req_handle_t req)35980Sstevel@tonic-gate dprov_seed_random(crypto_provider_handle_t provider,  crypto_session_id_t sid,
35991920Smcpowers     uchar_t *buf, size_t len, uint_t entropy_est, uint32_t flags,
36001920Smcpowers     crypto_req_handle_t req)
36010Sstevel@tonic-gate {
36020Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
36030Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
36040Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
36050Sstevel@tonic-gate 	int instance;
36060Sstevel@tonic-gate 
36070Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
36080Sstevel@tonic-gate 	DPROV_DEBUG(D_RANDOM, ("(%d) dprov_seed_random: started\n",
36090Sstevel@tonic-gate 	    instance));
36100Sstevel@tonic-gate 
36110Sstevel@tonic-gate 	error = dprov_random_submit_req(DPROV_REQ_RANDOM_SEED, softc,
36121920Smcpowers 	    req, buf, len, sid, entropy_est, flags);
36130Sstevel@tonic-gate 
36140Sstevel@tonic-gate 	DPROV_DEBUG(D_RANDOM, ("(%d) dprov_seed_random: done err = 0x0%x\n",
36150Sstevel@tonic-gate 	    instance, error));
36160Sstevel@tonic-gate 
36170Sstevel@tonic-gate 	return (error);
36180Sstevel@tonic-gate }
36190Sstevel@tonic-gate 
36200Sstevel@tonic-gate static int
dprov_generate_random(crypto_provider_handle_t provider,crypto_session_id_t sid,uchar_t * buf,size_t len,crypto_req_handle_t req)36210Sstevel@tonic-gate dprov_generate_random(crypto_provider_handle_t provider,
36220Sstevel@tonic-gate     crypto_session_id_t sid, uchar_t *buf, size_t len, crypto_req_handle_t req)
36230Sstevel@tonic-gate {
36240Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
36250Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
36260Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
36270Sstevel@tonic-gate 	int instance;
36280Sstevel@tonic-gate 
36290Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
36300Sstevel@tonic-gate 	DPROV_DEBUG(D_RANDOM, ("(%d) dprov_generate_random: started\n",
36310Sstevel@tonic-gate 	    instance));
36320Sstevel@tonic-gate 
36330Sstevel@tonic-gate 	error = dprov_random_submit_req(DPROV_REQ_RANDOM_GENERATE, softc,
36341920Smcpowers 	    req, buf, len, sid, 0, 0);
36350Sstevel@tonic-gate 
36360Sstevel@tonic-gate 	DPROV_DEBUG(D_RANDOM, ("(%d) dprov_generate_random: done "
36370Sstevel@tonic-gate 	    "err = 0x0%x\n", instance, error));
36380Sstevel@tonic-gate 
36390Sstevel@tonic-gate 	return (error);
36400Sstevel@tonic-gate }
36410Sstevel@tonic-gate 
36420Sstevel@tonic-gate /*
36430Sstevel@tonic-gate  * Session Management entry points.
36440Sstevel@tonic-gate  */
36450Sstevel@tonic-gate 
36460Sstevel@tonic-gate static int
dprov_session_open(crypto_provider_handle_t provider,crypto_session_id_t * session_id,crypto_req_handle_t req)36470Sstevel@tonic-gate dprov_session_open(crypto_provider_handle_t provider,
36480Sstevel@tonic-gate     crypto_session_id_t *session_id, crypto_req_handle_t req)
36490Sstevel@tonic-gate {
36500Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
36510Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
36520Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
36530Sstevel@tonic-gate 	int instance;
36540Sstevel@tonic-gate 
36550Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
36560Sstevel@tonic-gate 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_open: started\n",
36570Sstevel@tonic-gate 	    instance));
36580Sstevel@tonic-gate 
36590Sstevel@tonic-gate 	error = dprov_session_submit_req(DPROV_REQ_SESSION_OPEN, softc,
36600Sstevel@tonic-gate 	    req, session_id, 0, 0, NULL, 0);
36610Sstevel@tonic-gate 
36620Sstevel@tonic-gate 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_open: done err = 0x0%x\n",
36630Sstevel@tonic-gate 	    instance, error));
36640Sstevel@tonic-gate 
36650Sstevel@tonic-gate 	return (error);
36660Sstevel@tonic-gate }
36670Sstevel@tonic-gate 
36680Sstevel@tonic-gate static int
dprov_session_close(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_req_handle_t req)36690Sstevel@tonic-gate dprov_session_close(crypto_provider_handle_t provider,
36700Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_req_handle_t req)
36710Sstevel@tonic-gate {
36720Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
36730Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
36740Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
36750Sstevel@tonic-gate 	int instance;
36760Sstevel@tonic-gate 
36770Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
36780Sstevel@tonic-gate 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_close: started\n",
36790Sstevel@tonic-gate 	    instance));
36800Sstevel@tonic-gate 
36810Sstevel@tonic-gate 	error = dprov_session_submit_req(DPROV_REQ_SESSION_CLOSE, softc,
36820Sstevel@tonic-gate 	    req, 0, session_id, 0, NULL, 0);
36830Sstevel@tonic-gate 
36840Sstevel@tonic-gate 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_close: done err = 0x0%x\n",
36850Sstevel@tonic-gate 	    instance, error));
36860Sstevel@tonic-gate 
36870Sstevel@tonic-gate 	return (error);
36880Sstevel@tonic-gate }
36890Sstevel@tonic-gate 
36900Sstevel@tonic-gate static int
dprov_session_login(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_user_type_t user_type,char * pin,size_t pin_len,crypto_req_handle_t req)36910Sstevel@tonic-gate dprov_session_login(crypto_provider_handle_t provider,
36920Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_user_type_t user_type,
36930Sstevel@tonic-gate     char *pin, size_t pin_len, crypto_req_handle_t req)
36940Sstevel@tonic-gate {
36950Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
36960Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
36970Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
36980Sstevel@tonic-gate 	int instance;
36990Sstevel@tonic-gate 
37000Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
37010Sstevel@tonic-gate 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_login: started\n",
37020Sstevel@tonic-gate 	    instance));
37030Sstevel@tonic-gate 
37040Sstevel@tonic-gate 	error = dprov_session_submit_req(DPROV_REQ_SESSION_LOGIN, softc,
37050Sstevel@tonic-gate 	    req, 0, session_id, user_type, pin, pin_len);
37060Sstevel@tonic-gate 
37070Sstevel@tonic-gate 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_login: done err = 0x0%x\n",
37080Sstevel@tonic-gate 	    instance, error));
37090Sstevel@tonic-gate 
37100Sstevel@tonic-gate 	return (error);
37110Sstevel@tonic-gate }
37120Sstevel@tonic-gate 
37130Sstevel@tonic-gate static int
dprov_session_logout(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_req_handle_t req)37140Sstevel@tonic-gate dprov_session_logout(crypto_provider_handle_t provider,
37150Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_req_handle_t req)
37160Sstevel@tonic-gate {
37170Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
37180Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
37190Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
37200Sstevel@tonic-gate 	int instance;
37210Sstevel@tonic-gate 
37220Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
37230Sstevel@tonic-gate 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_logout: started\n",
37240Sstevel@tonic-gate 	    instance));
37250Sstevel@tonic-gate 
37260Sstevel@tonic-gate 	error = dprov_session_submit_req(DPROV_REQ_SESSION_LOGOUT, softc,
37270Sstevel@tonic-gate 	    req, 0, session_id, 0, NULL, 0);
37280Sstevel@tonic-gate 
37290Sstevel@tonic-gate 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_logout: done err = 0x0%x\n",
37300Sstevel@tonic-gate 	    instance, error));
37310Sstevel@tonic-gate 
37320Sstevel@tonic-gate 	return (error);
37330Sstevel@tonic-gate }
37340Sstevel@tonic-gate 
37350Sstevel@tonic-gate /*
37360Sstevel@tonic-gate  * Object management entry points.
37370Sstevel@tonic-gate  */
37380Sstevel@tonic-gate 
37390Sstevel@tonic-gate static int
dprov_object_create(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_object_attribute_t * template,uint_t attribute_count,crypto_object_id_t * object,crypto_req_handle_t req)37400Sstevel@tonic-gate dprov_object_create(crypto_provider_handle_t provider,
37410Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_object_attribute_t *template,
37420Sstevel@tonic-gate     uint_t attribute_count, crypto_object_id_t *object,
37430Sstevel@tonic-gate     crypto_req_handle_t req)
37440Sstevel@tonic-gate {
37450Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
37460Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
37470Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
37480Sstevel@tonic-gate 	int instance;
37490Sstevel@tonic-gate 
37500Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
37510Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_create: started\n",
37520Sstevel@tonic-gate 	    instance));
37530Sstevel@tonic-gate 
37540Sstevel@tonic-gate 	/* submit request to the taskq */
37550Sstevel@tonic-gate 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_CREATE, softc, req,
37560Sstevel@tonic-gate 	    session_id, 0, template, attribute_count, object, NULL, NULL,
37570Sstevel@tonic-gate 	    NULL, 0, NULL, KM_NOSLEEP);
37580Sstevel@tonic-gate 
37590Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_create: done err = 0x0%x\n",
37600Sstevel@tonic-gate 	    instance, error));
37610Sstevel@tonic-gate 
37620Sstevel@tonic-gate 	return (error);
37630Sstevel@tonic-gate }
37640Sstevel@tonic-gate 
37650Sstevel@tonic-gate static int
dprov_object_copy(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_object_id_t object,crypto_object_attribute_t * template,uint_t attribute_count,crypto_object_id_t * new_object,crypto_req_handle_t req)37660Sstevel@tonic-gate dprov_object_copy(crypto_provider_handle_t provider,
37670Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_object_id_t object,
37680Sstevel@tonic-gate     crypto_object_attribute_t *template, uint_t attribute_count,
37690Sstevel@tonic-gate     crypto_object_id_t *new_object, crypto_req_handle_t req)
37700Sstevel@tonic-gate {
37710Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
37720Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
37730Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
37740Sstevel@tonic-gate 	int instance;
37750Sstevel@tonic-gate 
37760Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
37770Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_copy: started\n",
37780Sstevel@tonic-gate 	    instance));
37790Sstevel@tonic-gate 
37800Sstevel@tonic-gate 	/* submit request to the taskq */
37810Sstevel@tonic-gate 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_COPY, softc, req,
37820Sstevel@tonic-gate 	    session_id, object, template, attribute_count, new_object,
37830Sstevel@tonic-gate 	    NULL, NULL, NULL, 0, NULL, KM_NOSLEEP);
37840Sstevel@tonic-gate 
37850Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_copy: done err = 0x0%x\n",
37860Sstevel@tonic-gate 	    instance, error));
37870Sstevel@tonic-gate 
37880Sstevel@tonic-gate 	return (error);
37890Sstevel@tonic-gate }
37900Sstevel@tonic-gate 
37910Sstevel@tonic-gate static int
dprov_object_destroy(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_object_id_t object,crypto_req_handle_t req)37920Sstevel@tonic-gate dprov_object_destroy(crypto_provider_handle_t provider,
37930Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_object_id_t object,
37940Sstevel@tonic-gate     crypto_req_handle_t req)
37950Sstevel@tonic-gate {
37960Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
37970Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
37980Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
37990Sstevel@tonic-gate 	int instance;
38000Sstevel@tonic-gate 
38010Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
38020Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_destroy: started\n",
38030Sstevel@tonic-gate 	    instance));
38040Sstevel@tonic-gate 
38050Sstevel@tonic-gate 	/* submit request to the taskq */
38060Sstevel@tonic-gate 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_DESTROY, softc, req,
38070Sstevel@tonic-gate 	    session_id, object, NULL, 0, NULL, NULL, NULL, NULL, 0, NULL,
38080Sstevel@tonic-gate 	    KM_NOSLEEP);
38090Sstevel@tonic-gate 
38100Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_destroy: done err = 0x0%x\n",
38110Sstevel@tonic-gate 	    instance, error));
38120Sstevel@tonic-gate 
38130Sstevel@tonic-gate 	return (error);
38140Sstevel@tonic-gate }
38150Sstevel@tonic-gate 
38160Sstevel@tonic-gate static int
dprov_object_get_size(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_object_id_t object,size_t * size,crypto_req_handle_t req)38170Sstevel@tonic-gate dprov_object_get_size(crypto_provider_handle_t provider,
38180Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_object_id_t object,
38190Sstevel@tonic-gate     size_t *size, crypto_req_handle_t req)
38200Sstevel@tonic-gate {
38210Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
38220Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
38230Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
38240Sstevel@tonic-gate 	int instance;
38250Sstevel@tonic-gate 
38260Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
38270Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_size: started\n",
38280Sstevel@tonic-gate 	    instance));
38290Sstevel@tonic-gate 
38300Sstevel@tonic-gate 	/* submit request to the taskq */
38310Sstevel@tonic-gate 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_GET_SIZE, softc, req,
38320Sstevel@tonic-gate 	    session_id, object, NULL, 0, NULL, size, NULL, NULL, 0, NULL,
38330Sstevel@tonic-gate 	    KM_NOSLEEP);
38340Sstevel@tonic-gate 
38350Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_size: done err = 0x0%x\n",
38360Sstevel@tonic-gate 	    instance, error));
38370Sstevel@tonic-gate 
38380Sstevel@tonic-gate 	return (error);
38390Sstevel@tonic-gate }
38400Sstevel@tonic-gate 
38410Sstevel@tonic-gate static int
dprov_object_get_attribute_value(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_object_id_t object,crypto_object_attribute_t * template,uint_t attribute_count,crypto_req_handle_t req)38420Sstevel@tonic-gate dprov_object_get_attribute_value(crypto_provider_handle_t provider,
38430Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_object_id_t object,
38440Sstevel@tonic-gate     crypto_object_attribute_t *template, uint_t attribute_count,
38450Sstevel@tonic-gate     crypto_req_handle_t req)
38460Sstevel@tonic-gate {
38470Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
38480Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
38490Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
38500Sstevel@tonic-gate 	int instance;
38510Sstevel@tonic-gate 
38520Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
38530Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_attribute_value: "
38540Sstevel@tonic-gate 	    "started\n", instance));
38550Sstevel@tonic-gate 
38560Sstevel@tonic-gate 	/* submit request to the taskq */
38570Sstevel@tonic-gate 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE,
38580Sstevel@tonic-gate 	    softc, req, session_id, object, template, attribute_count,
38590Sstevel@tonic-gate 	    NULL, NULL, NULL, NULL, 0, NULL, KM_NOSLEEP);
38600Sstevel@tonic-gate 
38610Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_attribute_value: "
38620Sstevel@tonic-gate 	    "done err = 0x0%x\n", instance, error));
38630Sstevel@tonic-gate 
38640Sstevel@tonic-gate 	return (error);
38650Sstevel@tonic-gate }
38660Sstevel@tonic-gate 
38670Sstevel@tonic-gate static int
dprov_object_set_attribute_value(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_object_id_t object,crypto_object_attribute_t * template,uint_t attribute_count,crypto_req_handle_t req)38680Sstevel@tonic-gate dprov_object_set_attribute_value(crypto_provider_handle_t provider,
38690Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_object_id_t object,
38700Sstevel@tonic-gate     crypto_object_attribute_t *template, uint_t attribute_count,
38710Sstevel@tonic-gate     crypto_req_handle_t req)
38720Sstevel@tonic-gate {
38730Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
38740Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
38750Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
38760Sstevel@tonic-gate 	int instance;
38770Sstevel@tonic-gate 
38780Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
38790Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_set_attribute_value: "
38800Sstevel@tonic-gate 	    "started\n", instance));
38810Sstevel@tonic-gate 
38820Sstevel@tonic-gate 	/* submit request to the taskq */
38830Sstevel@tonic-gate 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE,
38840Sstevel@tonic-gate 	    softc, req, session_id, object, template, attribute_count,
38850Sstevel@tonic-gate 	    NULL, NULL, NULL, NULL, 0, NULL, KM_NOSLEEP);
38860Sstevel@tonic-gate 
38870Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_set_attribute_value: "
38880Sstevel@tonic-gate 	    "done err = 0x0%x\n", instance, error));
38890Sstevel@tonic-gate 
38900Sstevel@tonic-gate 	return (error);
38910Sstevel@tonic-gate }
38920Sstevel@tonic-gate 
38930Sstevel@tonic-gate static int
dprov_object_find_init(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_object_attribute_t * template,uint_t attribute_count,void ** provider_private,crypto_req_handle_t req)38940Sstevel@tonic-gate dprov_object_find_init(crypto_provider_handle_t provider,
38950Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_object_attribute_t *template,
38960Sstevel@tonic-gate     uint_t attribute_count, void **provider_private,
38970Sstevel@tonic-gate     crypto_req_handle_t req)
38980Sstevel@tonic-gate {
38990Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
39000Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
39010Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
39020Sstevel@tonic-gate 	int instance;
39030Sstevel@tonic-gate 
39040Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
39050Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_init: started\n",
39060Sstevel@tonic-gate 	    instance));
39070Sstevel@tonic-gate 
39080Sstevel@tonic-gate 	/* submit request to the taskq */
39090Sstevel@tonic-gate 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND_INIT, softc, req,
39100Sstevel@tonic-gate 	    session_id, 0, template, attribute_count, NULL, NULL,
39110Sstevel@tonic-gate 	    provider_private, NULL, 0, NULL, KM_SLEEP);
39120Sstevel@tonic-gate 
39130Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_init: done "
39140Sstevel@tonic-gate 	    "err = 0x0%x\n", instance, error));
39150Sstevel@tonic-gate 
39160Sstevel@tonic-gate 	return (error);
39170Sstevel@tonic-gate }
39180Sstevel@tonic-gate 
39190Sstevel@tonic-gate static int
dprov_object_find(crypto_provider_handle_t provider,void * provider_private,crypto_object_id_t * objects,uint_t max_object_count,uint_t * object_count,crypto_req_handle_t req)39200Sstevel@tonic-gate dprov_object_find(crypto_provider_handle_t provider, void *provider_private,
39210Sstevel@tonic-gate     crypto_object_id_t *objects, uint_t max_object_count,
39220Sstevel@tonic-gate     uint_t *object_count, crypto_req_handle_t req)
39230Sstevel@tonic-gate {
39240Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
39250Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
39260Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
39270Sstevel@tonic-gate 	int instance;
39280Sstevel@tonic-gate 
39290Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
39300Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find: started\n",
39310Sstevel@tonic-gate 	    instance));
39320Sstevel@tonic-gate 
39330Sstevel@tonic-gate 	/* submit request to the taskq */
39340Sstevel@tonic-gate 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND, softc, req,
39350Sstevel@tonic-gate 	    0, 0, NULL, 0, objects, NULL, NULL, provider_private,
39360Sstevel@tonic-gate 	    max_object_count, object_count, KM_NOSLEEP);
39370Sstevel@tonic-gate 
39380Sstevel@tonic-gate 
39390Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find: done err = 0x0%x\n",
39400Sstevel@tonic-gate 	    instance, error));
39410Sstevel@tonic-gate 
39420Sstevel@tonic-gate 	return (error);
39430Sstevel@tonic-gate }
39440Sstevel@tonic-gate 
39450Sstevel@tonic-gate static int
dprov_object_find_final(crypto_provider_handle_t provider,void * provider_private,crypto_req_handle_t req)39460Sstevel@tonic-gate dprov_object_find_final(crypto_provider_handle_t provider,
39470Sstevel@tonic-gate     void *provider_private, crypto_req_handle_t req)
39480Sstevel@tonic-gate {
39490Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
39500Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
39510Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
39520Sstevel@tonic-gate 	int instance;
39530Sstevel@tonic-gate 
39540Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
39550Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_final: started\n",
39560Sstevel@tonic-gate 	    instance));
39570Sstevel@tonic-gate 
39580Sstevel@tonic-gate 	/* submit request to the taskq */
39590Sstevel@tonic-gate 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND_FINAL, softc, req,
39600Sstevel@tonic-gate 	    0, 0, NULL, 0, NULL, NULL, NULL, provider_private,
39610Sstevel@tonic-gate 	    0, NULL, KM_NOSLEEP);
39620Sstevel@tonic-gate 
39630Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_final: done "
39640Sstevel@tonic-gate 	    "err = 0x0%x\n", instance, error));
39650Sstevel@tonic-gate 
39660Sstevel@tonic-gate 	return (error);
39670Sstevel@tonic-gate }
39680Sstevel@tonic-gate 
39690Sstevel@tonic-gate /*
39700Sstevel@tonic-gate  * Key management entry points.
39710Sstevel@tonic-gate  */
39720Sstevel@tonic-gate 
39730Sstevel@tonic-gate static int
dprov_key_generate(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_object_attribute_t * template,uint_t attribute_count,crypto_object_id_t * object,crypto_req_handle_t req)39740Sstevel@tonic-gate dprov_key_generate(crypto_provider_handle_t provider,
39750Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
39760Sstevel@tonic-gate     crypto_object_attribute_t *template, uint_t attribute_count,
39770Sstevel@tonic-gate     crypto_object_id_t *object, crypto_req_handle_t req)
39780Sstevel@tonic-gate {
39790Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
39800Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
39810Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
39820Sstevel@tonic-gate 	int instance;
39830Sstevel@tonic-gate 
39840Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
39850Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate: started\n",
39860Sstevel@tonic-gate 	    instance));
39870Sstevel@tonic-gate 
39880Sstevel@tonic-gate 	/* submit request to the taskq */
39890Sstevel@tonic-gate 	error = dprov_key_submit_req(DPROV_REQ_KEY_GENERATE, softc, req,
39900Sstevel@tonic-gate 	    session_id, mechanism, template, attribute_count, object, NULL,
39914219Smcpowers 	    0, NULL, NULL, NULL, 0, NULL, 0, NULL, 0);
39920Sstevel@tonic-gate 
39930Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate: done err = 0x0%x\n",
39940Sstevel@tonic-gate 	    instance, error));
39950Sstevel@tonic-gate 
39960Sstevel@tonic-gate 	return (error);
39970Sstevel@tonic-gate }
39980Sstevel@tonic-gate 
39990Sstevel@tonic-gate static int
dprov_key_generate_pair(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_object_attribute_t * public_key_template,uint_t public_key_attribute_count,crypto_object_attribute_t * private_key_template,uint_t private_key_attribute_count,crypto_object_id_t * public_key,crypto_object_id_t * private_key,crypto_req_handle_t req)40000Sstevel@tonic-gate dprov_key_generate_pair(crypto_provider_handle_t provider,
40010Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
40020Sstevel@tonic-gate     crypto_object_attribute_t *public_key_template,
40030Sstevel@tonic-gate     uint_t public_key_attribute_count,
40040Sstevel@tonic-gate     crypto_object_attribute_t *private_key_template,
40050Sstevel@tonic-gate     uint_t private_key_attribute_count,
40060Sstevel@tonic-gate     crypto_object_id_t *public_key, crypto_object_id_t *private_key,
40070Sstevel@tonic-gate     crypto_req_handle_t req)
40080Sstevel@tonic-gate {
40090Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
40100Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
40110Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
40120Sstevel@tonic-gate 	int instance;
40130Sstevel@tonic-gate 
40140Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
40150Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate_pair: started\n",
40160Sstevel@tonic-gate 	    instance));
40170Sstevel@tonic-gate 
40180Sstevel@tonic-gate 	/* submit request to the taskq */
40190Sstevel@tonic-gate 	error = dprov_key_submit_req(DPROV_REQ_KEY_GENERATE_PAIR, softc, req,
40200Sstevel@tonic-gate 	    session_id, mechanism, public_key_template,
40210Sstevel@tonic-gate 	    public_key_attribute_count, public_key, private_key_template,
40224219Smcpowers 	    private_key_attribute_count, private_key, NULL, NULL, 0, NULL, 0,
40234219Smcpowers 	    NULL, 0);
40240Sstevel@tonic-gate 
40250Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate_pair: done err = 0x0%x\n",
40260Sstevel@tonic-gate 	    instance, error));
40270Sstevel@tonic-gate 
40280Sstevel@tonic-gate 	return (error);
40290Sstevel@tonic-gate }
40300Sstevel@tonic-gate 
40310Sstevel@tonic-gate static int
dprov_key_wrap(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * wrapping_key,crypto_object_id_t * key,uchar_t * wrapped_key,size_t * wrapped_key_len_ptr,crypto_req_handle_t req)40320Sstevel@tonic-gate dprov_key_wrap(crypto_provider_handle_t provider,
40330Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
40340Sstevel@tonic-gate     crypto_key_t *wrapping_key, crypto_object_id_t *key,
40350Sstevel@tonic-gate     uchar_t *wrapped_key, size_t *wrapped_key_len_ptr, crypto_req_handle_t req)
40360Sstevel@tonic-gate {
40370Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
40380Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
40390Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
40400Sstevel@tonic-gate 	int instance;
40410Sstevel@tonic-gate 
40420Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
40430Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_wrap: started\n",
40440Sstevel@tonic-gate 	    instance));
40450Sstevel@tonic-gate 
40460Sstevel@tonic-gate 	/* submit request to the taskq */
40470Sstevel@tonic-gate 	error = dprov_key_submit_req(DPROV_REQ_KEY_WRAP, softc, req,
40480Sstevel@tonic-gate 	    session_id, mechanism, NULL, 0, key, NULL,
40494219Smcpowers 	    0, NULL, wrapping_key, wrapped_key, wrapped_key_len_ptr,
40504219Smcpowers 	    NULL, 0, NULL, 0);
40510Sstevel@tonic-gate 
40520Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_wrap: done err = 0x0%x\n",
40530Sstevel@tonic-gate 	    instance, error));
40540Sstevel@tonic-gate 
40550Sstevel@tonic-gate 	return (error);
40560Sstevel@tonic-gate }
40570Sstevel@tonic-gate 
40580Sstevel@tonic-gate static int
dprov_key_unwrap(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * unwrapping_key,uchar_t * wrapped_key,size_t * wrapped_key_len_ptr,crypto_object_attribute_t * template,uint_t attribute_count,crypto_object_id_t * key,crypto_req_handle_t req)40590Sstevel@tonic-gate dprov_key_unwrap(crypto_provider_handle_t provider,
40600Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
40610Sstevel@tonic-gate     crypto_key_t *unwrapping_key, uchar_t *wrapped_key,
40620Sstevel@tonic-gate     size_t *wrapped_key_len_ptr, crypto_object_attribute_t *template,
40630Sstevel@tonic-gate     uint_t attribute_count, crypto_object_id_t *key, crypto_req_handle_t req)
40640Sstevel@tonic-gate {
40650Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
40660Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
40670Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
40680Sstevel@tonic-gate 	int instance;
40690Sstevel@tonic-gate 
40700Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
40710Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_unwrap: started\n",
40720Sstevel@tonic-gate 	    instance));
40730Sstevel@tonic-gate 
40740Sstevel@tonic-gate 	/* submit request to the taskq */
40750Sstevel@tonic-gate 	error = dprov_key_submit_req(DPROV_REQ_KEY_UNWRAP, softc, req,
40760Sstevel@tonic-gate 	    session_id, mechanism, template, attribute_count, key, NULL,
40774219Smcpowers 	    0, NULL, unwrapping_key, wrapped_key, wrapped_key_len_ptr,
40784219Smcpowers 	    NULL, 0, NULL, 0);
40790Sstevel@tonic-gate 
40800Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_unwrap: done err = 0x0%x\n",
40810Sstevel@tonic-gate 	    instance, error));
40820Sstevel@tonic-gate 
40830Sstevel@tonic-gate 	return (error);
40840Sstevel@tonic-gate }
40850Sstevel@tonic-gate 
40860Sstevel@tonic-gate static int
dprov_key_derive(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * base_key,crypto_object_attribute_t * template,uint_t attribute_count,crypto_object_id_t * key,crypto_req_handle_t req)40870Sstevel@tonic-gate dprov_key_derive(crypto_provider_handle_t provider,
40880Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
40890Sstevel@tonic-gate     crypto_key_t *base_key, crypto_object_attribute_t *template,
40900Sstevel@tonic-gate     uint_t attribute_count, crypto_object_id_t *key, crypto_req_handle_t req)
40910Sstevel@tonic-gate {
40920Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
40930Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
40940Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
40950Sstevel@tonic-gate 	int instance;
40960Sstevel@tonic-gate 
40970Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
40980Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_derive: started\n",
40990Sstevel@tonic-gate 	    instance));
41000Sstevel@tonic-gate 
41010Sstevel@tonic-gate 	/* submit request to the taskq */
41020Sstevel@tonic-gate 	error = dprov_key_submit_req(DPROV_REQ_KEY_DERIVE, softc, req,
41030Sstevel@tonic-gate 	    session_id, mechanism, template, attribute_count, key, NULL,
41044219Smcpowers 	    0, NULL, base_key, NULL, 0, NULL, 0, NULL, 0);
41050Sstevel@tonic-gate 
41060Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_derive: done err = 0x0%x\n",
41070Sstevel@tonic-gate 	    instance, error));
41080Sstevel@tonic-gate 
41090Sstevel@tonic-gate 	return (error);
41100Sstevel@tonic-gate }
41110Sstevel@tonic-gate 
41120Sstevel@tonic-gate /*
41130Sstevel@tonic-gate  * Provider management entry points.
41140Sstevel@tonic-gate  */
41150Sstevel@tonic-gate 
41160Sstevel@tonic-gate static int
dprov_ext_info(crypto_provider_handle_t provider,crypto_provider_ext_info_t * ext_info,crypto_req_handle_t req)41170Sstevel@tonic-gate dprov_ext_info(crypto_provider_handle_t provider,
41180Sstevel@tonic-gate     crypto_provider_ext_info_t *ext_info, crypto_req_handle_t req)
41190Sstevel@tonic-gate {
41200Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
41210Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
41220Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
41230Sstevel@tonic-gate 	int instance;
41240Sstevel@tonic-gate 
41250Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
41260Sstevel@tonic-gate 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_ext_info: started\n",
41270Sstevel@tonic-gate 	    instance));
41280Sstevel@tonic-gate 
41290Sstevel@tonic-gate 	error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_EXTINFO, softc, req,
41300Sstevel@tonic-gate 	    0, NULL, 0, NULL, 0, NULL, ext_info);
41310Sstevel@tonic-gate 
41320Sstevel@tonic-gate 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_ext_info: done err = 0x0%x\n",
41330Sstevel@tonic-gate 	    instance, error));
41340Sstevel@tonic-gate 
41350Sstevel@tonic-gate 	return (error);
41360Sstevel@tonic-gate }
41370Sstevel@tonic-gate 
41380Sstevel@tonic-gate static int
dprov_init_token(crypto_provider_handle_t provider,char * pin,size_t pin_len,char * label,crypto_req_handle_t req)41390Sstevel@tonic-gate dprov_init_token(crypto_provider_handle_t provider, char *pin, size_t pin_len,
41400Sstevel@tonic-gate     char *label, crypto_req_handle_t req)
41410Sstevel@tonic-gate {
41420Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
41430Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
41440Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
41450Sstevel@tonic-gate 	int instance;
41460Sstevel@tonic-gate 
41470Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
41480Sstevel@tonic-gate 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_token: started\n",
41490Sstevel@tonic-gate 	    instance));
41500Sstevel@tonic-gate 
41510Sstevel@tonic-gate 	error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_INITTOKEN, softc, req,
41520Sstevel@tonic-gate 	    0, pin, pin_len, NULL, 0, label, NULL);
41530Sstevel@tonic-gate 
41540Sstevel@tonic-gate 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_token: done err = 0x0%x\n",
41550Sstevel@tonic-gate 	    instance, error));
41560Sstevel@tonic-gate 
41570Sstevel@tonic-gate 	return (error);
41580Sstevel@tonic-gate }
41590Sstevel@tonic-gate 
41600Sstevel@tonic-gate static int
dprov_init_pin(crypto_provider_handle_t provider,crypto_session_id_t session_id,char * pin,size_t pin_len,crypto_req_handle_t req)41610Sstevel@tonic-gate dprov_init_pin(crypto_provider_handle_t provider,
41620Sstevel@tonic-gate     crypto_session_id_t session_id, char *pin, size_t pin_len,
41630Sstevel@tonic-gate     crypto_req_handle_t req)
41640Sstevel@tonic-gate {
41650Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
41660Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
41670Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
41680Sstevel@tonic-gate 	int instance;
41690Sstevel@tonic-gate 
41700Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
41710Sstevel@tonic-gate 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_pin: started\n",
41720Sstevel@tonic-gate 	    instance));
41730Sstevel@tonic-gate 
41740Sstevel@tonic-gate 	error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_INITPIN, softc, req,
41750Sstevel@tonic-gate 	    session_id, pin, pin_len, NULL, 0, NULL, NULL);
41760Sstevel@tonic-gate 
41770Sstevel@tonic-gate 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_pin: done err = 0x0%x\n",
41780Sstevel@tonic-gate 	    instance, error));
41790Sstevel@tonic-gate 
41800Sstevel@tonic-gate 	return (error);
41810Sstevel@tonic-gate }
41820Sstevel@tonic-gate 
41830Sstevel@tonic-gate static int
dprov_set_pin(crypto_provider_handle_t provider,crypto_session_id_t session_id,char * old_pin,size_t old_pin_len,char * new_pin,size_t new_pin_len,crypto_req_handle_t req)41840Sstevel@tonic-gate dprov_set_pin(crypto_provider_handle_t provider, crypto_session_id_t session_id,
41850Sstevel@tonic-gate     char *old_pin, size_t old_pin_len, char *new_pin, size_t new_pin_len,
41860Sstevel@tonic-gate     crypto_req_handle_t req)
41870Sstevel@tonic-gate {
41880Sstevel@tonic-gate 	int error = CRYPTO_FAILED;
41890Sstevel@tonic-gate 	dprov_state_t *softc = (dprov_state_t *)provider;
41900Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
41910Sstevel@tonic-gate 	int instance;
41920Sstevel@tonic-gate 
41930Sstevel@tonic-gate 	instance = ddi_get_instance(softc->ds_dip);
41940Sstevel@tonic-gate 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_set_pin: started\n",
41950Sstevel@tonic-gate 	    instance));
41960Sstevel@tonic-gate 
41970Sstevel@tonic-gate 	error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_SETPIN, softc, req,
41980Sstevel@tonic-gate 	    session_id, new_pin, new_pin_len, old_pin, old_pin_len, NULL, NULL);
41990Sstevel@tonic-gate 
42000Sstevel@tonic-gate 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_set_pin: done err = 0x0%x\n",
42010Sstevel@tonic-gate 	    instance, error));
42020Sstevel@tonic-gate 
42030Sstevel@tonic-gate 	return (error);
42040Sstevel@tonic-gate }
42050Sstevel@tonic-gate 
42060Sstevel@tonic-gate 
42070Sstevel@tonic-gate /*
42080Sstevel@tonic-gate  * Context management entry points.
42090Sstevel@tonic-gate  */
42100Sstevel@tonic-gate 
42110Sstevel@tonic-gate /*
42120Sstevel@tonic-gate  * Allocate a dprov-private context based on the specified dprov request.
42130Sstevel@tonic-gate  * For dual cipher/mac requests, the allocated context will
42140Sstevel@tonic-gate  * contain a structure dprov_ctx_dual_t, for other request types,
42150Sstevel@tonic-gate  * it will contain a dprov_ctx_single.
42160Sstevel@tonic-gate  * Returns one of the CRYPTO_ status codes.
42170Sstevel@tonic-gate  */
42180Sstevel@tonic-gate static int
dprov_alloc_context(dprov_req_type_t req_type,crypto_ctx_t * spi_ctx)42190Sstevel@tonic-gate dprov_alloc_context(dprov_req_type_t req_type, crypto_ctx_t *spi_ctx)
42200Sstevel@tonic-gate {
42210Sstevel@tonic-gate 	dprov_ctx_single_t *dprov_private;
42220Sstevel@tonic-gate 
42230Sstevel@tonic-gate 	switch (req_type) {
42240Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_MAC_INIT:
42250Sstevel@tonic-gate 	case DPROV_REQ_MAC_DECRYPT_INIT:
42260Sstevel@tonic-gate 		dprov_private = kmem_zalloc(sizeof (dprov_ctx_dual_t),
42270Sstevel@tonic-gate 		    KM_NOSLEEP);
42280Sstevel@tonic-gate 		if (dprov_private == NULL)
42290Sstevel@tonic-gate 			return (CRYPTO_HOST_MEMORY);
42300Sstevel@tonic-gate 		dprov_private->dc_type = DPROV_CTX_DUAL;
42310Sstevel@tonic-gate 		break;
42320Sstevel@tonic-gate 	default:
42330Sstevel@tonic-gate 		dprov_private = kmem_zalloc(sizeof (dprov_ctx_single_t),
42340Sstevel@tonic-gate 		    KM_NOSLEEP);
42350Sstevel@tonic-gate 		if (dprov_private == NULL)
42360Sstevel@tonic-gate 			return (CRYPTO_HOST_MEMORY);
42370Sstevel@tonic-gate 		dprov_private->dc_type = DPROV_CTX_SINGLE;
42384072Skrishna 		dprov_private->dc_svrfy_to_mac = B_FALSE;
42390Sstevel@tonic-gate 		break;
42400Sstevel@tonic-gate 	}
42410Sstevel@tonic-gate 
42420Sstevel@tonic-gate 	spi_ctx->cc_provider_private = (void *)dprov_private;
42430Sstevel@tonic-gate 
42440Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
42450Sstevel@tonic-gate }
42460Sstevel@tonic-gate 
42470Sstevel@tonic-gate static int
dprov_free_context(crypto_ctx_t * ctx)42480Sstevel@tonic-gate dprov_free_context(crypto_ctx_t *ctx)
42490Sstevel@tonic-gate {
42500Sstevel@tonic-gate 	if (ctx->cc_provider_private == NULL)
42510Sstevel@tonic-gate 		return (CRYPTO_SUCCESS);
42520Sstevel@tonic-gate 
42530Sstevel@tonic-gate 	DPROV_DEBUG(D_CONTEXT, ("dprov_free_context\n"));
42540Sstevel@tonic-gate 
42550Sstevel@tonic-gate 	{
42560Sstevel@tonic-gate 		/*
42570Sstevel@tonic-gate 		 * The dprov private context could contain either
42580Sstevel@tonic-gate 		 * a dprov_ctx_single_t or a dprov_ctx_dual_t. Free
42590Sstevel@tonic-gate 		 * the context based on its type. The k-API contexts
42600Sstevel@tonic-gate 		 * that were attached to the dprov private context
42610Sstevel@tonic-gate 		 * are freed by the framework.
42620Sstevel@tonic-gate 		 */
42630Sstevel@tonic-gate 		dprov_ctx_single_t *ctx_single =
42640Sstevel@tonic-gate 		    (dprov_ctx_single_t *)(ctx->cc_provider_private);
42650Sstevel@tonic-gate 
42660Sstevel@tonic-gate 		if (ctx_single->dc_type == DPROV_CTX_SINGLE) {
42670Sstevel@tonic-gate 			crypto_context_t context = DPROV_CTX_SINGLE(ctx);
42680Sstevel@tonic-gate 
42690Sstevel@tonic-gate 			/*
42700Sstevel@tonic-gate 			 * This case happens for the crypto_cancel_ctx() case.
42710Sstevel@tonic-gate 			 * We have to cancel the SW provider context also.
42720Sstevel@tonic-gate 			 */
42730Sstevel@tonic-gate 			if (context != NULL)
42740Sstevel@tonic-gate 				crypto_cancel_ctx(context);
42750Sstevel@tonic-gate 
42760Sstevel@tonic-gate 			kmem_free(ctx_single, sizeof (dprov_ctx_single_t));
42770Sstevel@tonic-gate 		} else {
42780Sstevel@tonic-gate 			crypto_context_t cipher_context =
42790Sstevel@tonic-gate 			    DPROV_CTX_DUAL_CIPHER(ctx);
42800Sstevel@tonic-gate 			crypto_context_t mac_context = DPROV_CTX_DUAL_MAC(ctx);
42810Sstevel@tonic-gate 
42820Sstevel@tonic-gate 			/* See comments above. */
42830Sstevel@tonic-gate 			if (cipher_context != NULL)
42840Sstevel@tonic-gate 				crypto_cancel_ctx(cipher_context);
42850Sstevel@tonic-gate 			if (mac_context != NULL)
42860Sstevel@tonic-gate 				crypto_cancel_ctx(mac_context);
42870Sstevel@tonic-gate 
42880Sstevel@tonic-gate 			ASSERT(ctx_single->dc_type == DPROV_CTX_DUAL);
42890Sstevel@tonic-gate 			kmem_free(ctx_single, sizeof (dprov_ctx_dual_t));
42900Sstevel@tonic-gate 		}
42910Sstevel@tonic-gate 		ctx->cc_provider_private = NULL;
42920Sstevel@tonic-gate 	}
42930Sstevel@tonic-gate 
42940Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
42950Sstevel@tonic-gate }
42960Sstevel@tonic-gate 
4297904Smcpowers /*
4298904Smcpowers  * Resource control checks don't need to be done. Why? Because this routine
4299904Smcpowers  * knows the size of the structure, and it can't be overridden by a user.
4300904Smcpowers  * This is different from the crypto module, which has no knowledge of
4301904Smcpowers  * specific mechanisms, and therefore has to trust specified size of the
4302904Smcpowers  * parameter.  This trust, or lack of trust, is why the size of the
4303904Smcpowers  * parameter has to be charged against the project resource control.
4304904Smcpowers  */
4305904Smcpowers static int
copyin_aes_ccm_mech(crypto_mechanism_t * in_mech,crypto_mechanism_t * out_mech,int * out_error,int mode)43065413Sdinak copyin_aes_ccm_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
43075413Sdinak     int *out_error, int mode)
43085413Sdinak {
43095413Sdinak 	STRUCT_DECL(crypto_mechanism, mech);
43105413Sdinak 	STRUCT_DECL(CK_AES_CCM_PARAMS, params);
43115413Sdinak 	CK_AES_CCM_PARAMS *aes_ccm_params;
43125413Sdinak 	caddr_t pp;
43135413Sdinak 	size_t param_len;
43145413Sdinak 	int error = 0;
43155413Sdinak 	int rv = 0;
43165413Sdinak 
43175413Sdinak 	STRUCT_INIT(mech, mode);
43185413Sdinak 	STRUCT_INIT(params, mode);
43195413Sdinak 	bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
43205413Sdinak 	pp = STRUCT_FGETP(mech, cm_param);
43215413Sdinak 	param_len = STRUCT_FGET(mech, cm_param_len);
43225413Sdinak 
43235413Sdinak 	if (param_len != STRUCT_SIZE(params)) {
43245413Sdinak 		rv = CRYPTO_ARGUMENTS_BAD;
43255413Sdinak 		goto out;
43265413Sdinak 	}
43275413Sdinak 
43285413Sdinak 	out_mech->cm_type = STRUCT_FGET(mech, cm_type);
43295413Sdinak 	out_mech->cm_param = NULL;
43305413Sdinak 	out_mech->cm_param_len = 0;
43315413Sdinak 	if (pp != NULL) {
43325413Sdinak 		size_t nonce_len, auth_data_len, total_param_len;
43335413Sdinak 
43345413Sdinak 		if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
43355413Sdinak 			out_mech->cm_param = NULL;
43365413Sdinak 			error = EFAULT;
43375413Sdinak 			goto out;
43385413Sdinak 		}
43395413Sdinak 
43405413Sdinak 		nonce_len = STRUCT_FGET(params, ulNonceSize);
43415413Sdinak 		auth_data_len = STRUCT_FGET(params, ulAuthDataSize);
43425413Sdinak 
43435413Sdinak 		/* allocate param structure */
43445413Sdinak 		total_param_len =
43455413Sdinak 		    sizeof (CK_AES_CCM_PARAMS) + nonce_len + auth_data_len;
43465413Sdinak 		aes_ccm_params = kmem_alloc(total_param_len, KM_NOSLEEP);
43475413Sdinak 		if (aes_ccm_params == NULL) {
43485413Sdinak 			rv = CRYPTO_HOST_MEMORY;
43495413Sdinak 			goto out;
43505413Sdinak 		}
43515413Sdinak 		aes_ccm_params->ulMACSize = STRUCT_FGET(params, ulMACSize);
43525413Sdinak 		aes_ccm_params->ulNonceSize = nonce_len;
43535413Sdinak 		aes_ccm_params->ulAuthDataSize = auth_data_len;
43545413Sdinak 		aes_ccm_params->ulDataSize
43555413Sdinak 		    = STRUCT_FGET(params, ulDataSize);
43565413Sdinak 		aes_ccm_params->nonce
43575413Sdinak 		    = (uchar_t *)aes_ccm_params + sizeof (CK_AES_CCM_PARAMS);
43585413Sdinak 		aes_ccm_params->authData
43595413Sdinak 		    = aes_ccm_params->nonce + nonce_len;
43605413Sdinak 
43615413Sdinak 		if (copyin((char *)STRUCT_FGETP(params, nonce),
43625413Sdinak 		    aes_ccm_params->nonce, nonce_len) != 0) {
43635413Sdinak 			kmem_free(aes_ccm_params, total_param_len);
43645413Sdinak 			out_mech->cm_param = NULL;
43655413Sdinak 			error = EFAULT;
43665413Sdinak 			goto out;
43675413Sdinak 		}
43685413Sdinak 		if (copyin((char *)STRUCT_FGETP(params, authData),
43695413Sdinak 		    aes_ccm_params->authData, auth_data_len) != 0) {
43705413Sdinak 			kmem_free(aes_ccm_params, total_param_len);
43715413Sdinak 			out_mech->cm_param = NULL;
43725413Sdinak 			error = EFAULT;
43735413Sdinak 			goto out;
43745413Sdinak 		}
43755413Sdinak 		out_mech->cm_param = (char *)aes_ccm_params;
43765413Sdinak 		out_mech->cm_param_len = sizeof (CK_AES_CCM_PARAMS);
43775413Sdinak 	}
43785413Sdinak out:
43795413Sdinak 	*out_error = error;
43805413Sdinak 	return (rv);
43815413Sdinak }
43825413Sdinak 
43838005SMark.Powers@Sun.COM /*
43848005SMark.Powers@Sun.COM  * Resource control checks don't need to be done. Why? Because this routine
43858005SMark.Powers@Sun.COM  * knows the size of the structure, and it can't be overridden by a user.
43868005SMark.Powers@Sun.COM  * This is different from the crypto module, which has no knowledge of
43878005SMark.Powers@Sun.COM  * specific mechanisms, and therefore has to trust specified size of the
43888005SMark.Powers@Sun.COM  * parameter.  This trust, or lack of trust, is why the size of the
43898005SMark.Powers@Sun.COM  * parameter has to be charged against the project resource control.
43908005SMark.Powers@Sun.COM  */
43918005SMark.Powers@Sun.COM static int
copyin_aes_gcm_mech(crypto_mechanism_t * in_mech,crypto_mechanism_t * out_mech,int * out_error,int mode)43928005SMark.Powers@Sun.COM copyin_aes_gcm_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
43938005SMark.Powers@Sun.COM     int *out_error, int mode)
43948005SMark.Powers@Sun.COM {
43958005SMark.Powers@Sun.COM 	STRUCT_DECL(crypto_mechanism, mech);
43968005SMark.Powers@Sun.COM 	STRUCT_DECL(CK_AES_GCM_PARAMS, params);
43978005SMark.Powers@Sun.COM 	CK_AES_GCM_PARAMS *aes_gcm_params;
43988005SMark.Powers@Sun.COM 	caddr_t pp;
43998005SMark.Powers@Sun.COM 	size_t param_len;
44008005SMark.Powers@Sun.COM 	int error = 0;
44018005SMark.Powers@Sun.COM 	int rv = 0;
44028005SMark.Powers@Sun.COM 
44038005SMark.Powers@Sun.COM 	STRUCT_INIT(mech, mode);
44048005SMark.Powers@Sun.COM 	STRUCT_INIT(params, mode);
44058005SMark.Powers@Sun.COM 	bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
44068005SMark.Powers@Sun.COM 	pp = STRUCT_FGETP(mech, cm_param);
44078005SMark.Powers@Sun.COM 	param_len = STRUCT_FGET(mech, cm_param_len);
44088005SMark.Powers@Sun.COM 
44098005SMark.Powers@Sun.COM 	if (param_len != STRUCT_SIZE(params)) {
44108005SMark.Powers@Sun.COM 		rv = CRYPTO_ARGUMENTS_BAD;
44118005SMark.Powers@Sun.COM 		goto out;
44128005SMark.Powers@Sun.COM 	}
44138005SMark.Powers@Sun.COM 
44148005SMark.Powers@Sun.COM 	out_mech->cm_type = STRUCT_FGET(mech, cm_type);
44158005SMark.Powers@Sun.COM 	out_mech->cm_param = NULL;
44168005SMark.Powers@Sun.COM 	out_mech->cm_param_len = 0;
44178005SMark.Powers@Sun.COM 	if (pp != NULL) {
44188005SMark.Powers@Sun.COM 		size_t nonce_len, auth_data_len, total_param_len;
44198005SMark.Powers@Sun.COM 
44208005SMark.Powers@Sun.COM 		if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
44218005SMark.Powers@Sun.COM 			out_mech->cm_param = NULL;
44228005SMark.Powers@Sun.COM 			error = EFAULT;
44238005SMark.Powers@Sun.COM 			goto out;
44248005SMark.Powers@Sun.COM 		}
44258005SMark.Powers@Sun.COM 
44268005SMark.Powers@Sun.COM 		nonce_len = STRUCT_FGET(params, ulIvLen);
44278005SMark.Powers@Sun.COM 		auth_data_len = STRUCT_FGET(params, ulAADLen);
44288005SMark.Powers@Sun.COM 
44298005SMark.Powers@Sun.COM 		/* allocate param structure */
44308005SMark.Powers@Sun.COM 		total_param_len =
44318005SMark.Powers@Sun.COM 		    sizeof (CK_AES_GCM_PARAMS) + nonce_len + auth_data_len;
44328005SMark.Powers@Sun.COM 		aes_gcm_params = kmem_alloc(total_param_len, KM_NOSLEEP);
44338005SMark.Powers@Sun.COM 		if (aes_gcm_params == NULL) {
44348005SMark.Powers@Sun.COM 			rv = CRYPTO_HOST_MEMORY;
44358005SMark.Powers@Sun.COM 			goto out;
44368005SMark.Powers@Sun.COM 		}
44378005SMark.Powers@Sun.COM 		aes_gcm_params->ulTagBits = STRUCT_FGET(params, ulTagBits);
44388005SMark.Powers@Sun.COM 		aes_gcm_params->ulIvLen = nonce_len;
44398005SMark.Powers@Sun.COM 		aes_gcm_params->ulAADLen = auth_data_len;
44408005SMark.Powers@Sun.COM 		aes_gcm_params->pIv
44418005SMark.Powers@Sun.COM 		    = (uchar_t *)aes_gcm_params + sizeof (CK_AES_GCM_PARAMS);
44428005SMark.Powers@Sun.COM 		aes_gcm_params->pAAD = aes_gcm_params->pIv + nonce_len;
44438005SMark.Powers@Sun.COM 
44448005SMark.Powers@Sun.COM 		if (copyin((char *)STRUCT_FGETP(params, pIv),
44458005SMark.Powers@Sun.COM 		    aes_gcm_params->pIv, nonce_len) != 0) {
44468005SMark.Powers@Sun.COM 			kmem_free(aes_gcm_params, total_param_len);
44478005SMark.Powers@Sun.COM 			out_mech->cm_param = NULL;
44488005SMark.Powers@Sun.COM 			error = EFAULT;
44498005SMark.Powers@Sun.COM 			goto out;
44508005SMark.Powers@Sun.COM 		}
44518005SMark.Powers@Sun.COM 		if (copyin((char *)STRUCT_FGETP(params, pAAD),
44528005SMark.Powers@Sun.COM 		    aes_gcm_params->pAAD, auth_data_len) != 0) {
44538005SMark.Powers@Sun.COM 			kmem_free(aes_gcm_params, total_param_len);
44548005SMark.Powers@Sun.COM 			out_mech->cm_param = NULL;
44558005SMark.Powers@Sun.COM 			error = EFAULT;
44568005SMark.Powers@Sun.COM 			goto out;
44578005SMark.Powers@Sun.COM 		}
44588005SMark.Powers@Sun.COM 		out_mech->cm_param = (char *)aes_gcm_params;
44598005SMark.Powers@Sun.COM 		out_mech->cm_param_len = sizeof (CK_AES_GCM_PARAMS);
44608005SMark.Powers@Sun.COM 	}
44618005SMark.Powers@Sun.COM out:
44628005SMark.Powers@Sun.COM 	*out_error = error;
44638005SMark.Powers@Sun.COM 	return (rv);
44648005SMark.Powers@Sun.COM }
44655413Sdinak 
44669339SMark.Powers@Sun.COM static int
copyin_aes_gmac_mech(crypto_mechanism_t * in_mech,crypto_mechanism_t * out_mech,int * out_error,int mode)44679339SMark.Powers@Sun.COM copyin_aes_gmac_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
44689339SMark.Powers@Sun.COM     int *out_error, int mode)
44699339SMark.Powers@Sun.COM {
44709339SMark.Powers@Sun.COM 	STRUCT_DECL(crypto_mechanism, mech);
44719339SMark.Powers@Sun.COM 	STRUCT_DECL(CK_AES_GMAC_PARAMS, params);
44729339SMark.Powers@Sun.COM 	CK_AES_GMAC_PARAMS *aes_gmac_params;
44739339SMark.Powers@Sun.COM 	caddr_t pp;
44749339SMark.Powers@Sun.COM 	size_t param_len;
44759339SMark.Powers@Sun.COM 	int error = 0;
44769339SMark.Powers@Sun.COM 	int rv = 0;
44779339SMark.Powers@Sun.COM 
44789339SMark.Powers@Sun.COM 	STRUCT_INIT(mech, mode);
44799339SMark.Powers@Sun.COM 	STRUCT_INIT(params, mode);
44809339SMark.Powers@Sun.COM 	bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
44819339SMark.Powers@Sun.COM 	pp = STRUCT_FGETP(mech, cm_param);
44829339SMark.Powers@Sun.COM 	param_len = STRUCT_FGET(mech, cm_param_len);
44839339SMark.Powers@Sun.COM 
44849339SMark.Powers@Sun.COM 	if (param_len != STRUCT_SIZE(params)) {
44859339SMark.Powers@Sun.COM 		rv = CRYPTO_ARGUMENTS_BAD;
44869339SMark.Powers@Sun.COM 		goto out;
44879339SMark.Powers@Sun.COM 	}
44889339SMark.Powers@Sun.COM 
44899339SMark.Powers@Sun.COM 	out_mech->cm_type = STRUCT_FGET(mech, cm_type);
44909339SMark.Powers@Sun.COM 	out_mech->cm_param = NULL;
44919339SMark.Powers@Sun.COM 	out_mech->cm_param_len = 0;
44929339SMark.Powers@Sun.COM 	if (pp != NULL) {
44939339SMark.Powers@Sun.COM 		size_t auth_data_len, total_param_len;
44949339SMark.Powers@Sun.COM 
44959339SMark.Powers@Sun.COM 		if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
44969339SMark.Powers@Sun.COM 			out_mech->cm_param = NULL;
44979339SMark.Powers@Sun.COM 			error = EFAULT;
44989339SMark.Powers@Sun.COM 			goto out;
44999339SMark.Powers@Sun.COM 		}
45009339SMark.Powers@Sun.COM 
45019339SMark.Powers@Sun.COM 		auth_data_len = STRUCT_FGET(params, ulAADLen);
45029339SMark.Powers@Sun.COM 
45039339SMark.Powers@Sun.COM 		/* allocate param structure */
45049339SMark.Powers@Sun.COM 		total_param_len = sizeof (CK_AES_GMAC_PARAMS) +
45059339SMark.Powers@Sun.COM 		    AES_GMAC_IV_LEN + auth_data_len;
45069339SMark.Powers@Sun.COM 		aes_gmac_params = kmem_alloc(total_param_len, KM_NOSLEEP);
45079339SMark.Powers@Sun.COM 		if (aes_gmac_params == NULL) {
45089339SMark.Powers@Sun.COM 			rv = CRYPTO_HOST_MEMORY;
45099339SMark.Powers@Sun.COM 			goto out;
45109339SMark.Powers@Sun.COM 		}
45119339SMark.Powers@Sun.COM 		aes_gmac_params->ulAADLen = auth_data_len;
45129339SMark.Powers@Sun.COM 		aes_gmac_params->pIv
45139339SMark.Powers@Sun.COM 		    = (uchar_t *)aes_gmac_params + sizeof (CK_AES_GMAC_PARAMS);
45149339SMark.Powers@Sun.COM 		aes_gmac_params->pAAD = aes_gmac_params->pIv + AES_GMAC_IV_LEN;
45159339SMark.Powers@Sun.COM 
45169339SMark.Powers@Sun.COM 		if (copyin((char *)STRUCT_FGETP(params, pIv),
45179339SMark.Powers@Sun.COM 		    aes_gmac_params->pIv, AES_GMAC_IV_LEN) != 0) {
45189339SMark.Powers@Sun.COM 			kmem_free(aes_gmac_params, total_param_len);
45199339SMark.Powers@Sun.COM 			out_mech->cm_param = NULL;
45209339SMark.Powers@Sun.COM 			error = EFAULT;
45219339SMark.Powers@Sun.COM 			goto out;
45229339SMark.Powers@Sun.COM 		}
45239339SMark.Powers@Sun.COM 		if (copyin((char *)STRUCT_FGETP(params, pAAD),
45249339SMark.Powers@Sun.COM 		    aes_gmac_params->pAAD, auth_data_len) != 0) {
45259339SMark.Powers@Sun.COM 			kmem_free(aes_gmac_params, total_param_len);
45269339SMark.Powers@Sun.COM 			out_mech->cm_param = NULL;
45279339SMark.Powers@Sun.COM 			error = EFAULT;
45289339SMark.Powers@Sun.COM 			goto out;
45299339SMark.Powers@Sun.COM 		}
45309339SMark.Powers@Sun.COM 		out_mech->cm_param = (char *)aes_gmac_params;
45319339SMark.Powers@Sun.COM 		out_mech->cm_param_len = sizeof (CK_AES_GMAC_PARAMS);
45329339SMark.Powers@Sun.COM 	}
45339339SMark.Powers@Sun.COM out:
45349339SMark.Powers@Sun.COM 	*out_error = error;
45359339SMark.Powers@Sun.COM 	return (rv);
45369339SMark.Powers@Sun.COM }
45379339SMark.Powers@Sun.COM 
45385413Sdinak /*
45395413Sdinak  * Resource control checks don't need to be done. Why? Because this routine
45405413Sdinak  * knows the size of the structure, and it can't be overridden by a user.
45415413Sdinak  * This is different from the crypto module, which has no knowledge of
45425413Sdinak  * specific mechanisms, and therefore has to trust specified size of the
45435413Sdinak  * parameter.  This trust, or lack of trust, is why the size of the
45445413Sdinak  * parameter has to be charged against the project resource control.
45455413Sdinak  */
45465413Sdinak static int
copyin_aes_ctr_mech(crypto_mechanism_t * in_mech,crypto_mechanism_t * out_mech,int * out_error,int mode)4547904Smcpowers copyin_aes_ctr_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
4548904Smcpowers     int *out_error, int mode)
4549904Smcpowers {
4550904Smcpowers 	STRUCT_DECL(crypto_mechanism, mech);
4551904Smcpowers 	STRUCT_DECL(CK_AES_CTR_PARAMS, params);
4552904Smcpowers 	CK_AES_CTR_PARAMS *aes_ctr_params;
4553904Smcpowers 	caddr_t pp;
4554904Smcpowers 	size_t param_len;
4555904Smcpowers 	int error = 0;
4556904Smcpowers 	int rv = 0;
4557904Smcpowers 
4558904Smcpowers 	STRUCT_INIT(mech, mode);
4559904Smcpowers 	STRUCT_INIT(params, mode);
4560904Smcpowers 	bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4561904Smcpowers 	pp = STRUCT_FGETP(mech, cm_param);
4562904Smcpowers 	param_len = STRUCT_FGET(mech, cm_param_len);
4563904Smcpowers 
4564904Smcpowers 	if (param_len != STRUCT_SIZE(params)) {
4565904Smcpowers 		rv = CRYPTO_ARGUMENTS_BAD;
4566904Smcpowers 		goto out;
4567904Smcpowers 	}
4568904Smcpowers 
4569904Smcpowers 	out_mech->cm_type = STRUCT_FGET(mech, cm_type);
4570904Smcpowers 	out_mech->cm_param = NULL;
4571904Smcpowers 	out_mech->cm_param_len = 0;
4572904Smcpowers 	if (pp != NULL) {
4573904Smcpowers 		if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
4574904Smcpowers 			out_mech->cm_param = NULL;
4575904Smcpowers 			error = EFAULT;
4576904Smcpowers 			goto out;
4577904Smcpowers 		}
4578904Smcpowers 		/* allocate param structure and counter block */
45795072Smcpowers 		aes_ctr_params = kmem_alloc(sizeof (CK_AES_CTR_PARAMS),
4580904Smcpowers 		    KM_NOSLEEP);
4581904Smcpowers 		if (aes_ctr_params == NULL) {
4582904Smcpowers 			rv = CRYPTO_HOST_MEMORY;
4583904Smcpowers 			goto out;
4584904Smcpowers 		}
4585904Smcpowers 		aes_ctr_params->ulCounterBits = STRUCT_FGET(params,
4586904Smcpowers 		    ulCounterBits);
45875072Smcpowers 		bcopy(STRUCT_FGETP(params, cb), aes_ctr_params->cb, 16);
4588904Smcpowers 		out_mech->cm_param = (char *)aes_ctr_params;
4589904Smcpowers 		out_mech->cm_param_len = sizeof (CK_AES_CTR_PARAMS);
4590904Smcpowers 	}
4591904Smcpowers out:
4592904Smcpowers 	*out_error = error;
4593904Smcpowers 	return (rv);
4594904Smcpowers }
4595904Smcpowers 
45965697Smcpowers static int
copyin_ecc_mech(crypto_mechanism_t * in_mech,crypto_mechanism_t * out_mech,int * out_error,int mode)45975697Smcpowers copyin_ecc_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
45985697Smcpowers     int *out_error, int mode)
45995697Smcpowers {
46005697Smcpowers 	STRUCT_DECL(crypto_mechanism, mech);
46015697Smcpowers 	STRUCT_DECL(CK_ECDH1_DERIVE_PARAMS, params);
46025697Smcpowers 	CK_ECDH1_DERIVE_PARAMS *ecc_params;
46035697Smcpowers 	caddr_t pp;
46045697Smcpowers 	size_t param_len, shared_data_len, public_data_len;
46055697Smcpowers 	int error = 0;
46065697Smcpowers 	int rv = 0;
46075697Smcpowers 
46085697Smcpowers 	STRUCT_INIT(mech, mode);
46095697Smcpowers 	STRUCT_INIT(params, mode);
46105697Smcpowers 	bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
46115697Smcpowers 	pp = STRUCT_FGETP(mech, cm_param);
46125697Smcpowers 	param_len = STRUCT_FGET(mech, cm_param_len);
46135697Smcpowers 
46145697Smcpowers 	if (param_len != STRUCT_SIZE(params)) {
46155697Smcpowers 		rv = CRYPTO_ARGUMENTS_BAD;
46165697Smcpowers 		goto out;
46175697Smcpowers 	}
46185697Smcpowers 
46195697Smcpowers 	out_mech->cm_type = STRUCT_FGET(mech, cm_type);
46205697Smcpowers 	out_mech->cm_param = NULL;
46215697Smcpowers 	out_mech->cm_param_len = 0;
46225697Smcpowers 	if (pp != NULL) {
46235697Smcpowers 		if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
46245697Smcpowers 			out_mech->cm_param = NULL;
46255697Smcpowers 			error = EFAULT;
46265697Smcpowers 			goto out;
46275697Smcpowers 		}
46285697Smcpowers 		shared_data_len = STRUCT_FGET(params, ulSharedDataLen);
46295697Smcpowers 		public_data_len = STRUCT_FGET(params, ulPublicDataLen);
46305697Smcpowers 		/* allocate param structure and buffers */
46315697Smcpowers 		ecc_params = kmem_alloc(sizeof (CK_ECDH1_DERIVE_PARAMS) +
46325697Smcpowers 		    roundup(shared_data_len, sizeof (caddr_t)) +
46335697Smcpowers 		    roundup(public_data_len, sizeof (caddr_t)), KM_NOSLEEP);
46345697Smcpowers 		if (ecc_params == NULL) {
46355697Smcpowers 			rv = CRYPTO_HOST_MEMORY;
46365697Smcpowers 			goto out;
46375697Smcpowers 		}
46385697Smcpowers 		ecc_params->pSharedData = (uchar_t *)ecc_params +
46395697Smcpowers 		    sizeof (CK_ECDH1_DERIVE_PARAMS);
46405697Smcpowers 		ecc_params->pPublicData = (uchar_t *)ecc_params->pSharedData +
46415697Smcpowers 		    roundup(shared_data_len, sizeof (caddr_t));
46425697Smcpowers 		if (copyin((char *)STRUCT_FGETP(params, pSharedData),
46435697Smcpowers 		    ecc_params->pSharedData, shared_data_len) != 0) {
46445697Smcpowers 			kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) +
46455697Smcpowers 			    roundup(shared_data_len, sizeof (caddr_t)) +
46465697Smcpowers 			    roundup(public_data_len, sizeof (caddr_t)));
46475697Smcpowers 			out_mech->cm_param = NULL;
46485697Smcpowers 			error = EFAULT;
46495697Smcpowers 			goto out;
46505697Smcpowers 		}
46515697Smcpowers 		ecc_params->ulSharedDataLen = shared_data_len;
46525697Smcpowers 
46535697Smcpowers 		if (copyin((char *)STRUCT_FGETP(params, pPublicData),
46545697Smcpowers 		    ecc_params->pPublicData, public_data_len) != 0) {
46555697Smcpowers 			kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) +
46565697Smcpowers 			    roundup(shared_data_len, sizeof (caddr_t)) +
46575697Smcpowers 			    roundup(public_data_len, sizeof (caddr_t)));
46585697Smcpowers 			out_mech->cm_param = NULL;
46595697Smcpowers 			error = EFAULT;
46605697Smcpowers 			goto out;
46615697Smcpowers 		}
46625697Smcpowers 		ecc_params->ulPublicDataLen = public_data_len;
46635697Smcpowers 		ecc_params->kdf = STRUCT_FGET(params, kdf);
46645697Smcpowers 		out_mech->cm_param = (char *)ecc_params;
46655697Smcpowers 		out_mech->cm_param_len = sizeof (CK_ECDH1_DERIVE_PARAMS);
46665697Smcpowers 	}
46675697Smcpowers out:
46685697Smcpowers 	*out_error = error;
46695697Smcpowers 	return (rv);
46705697Smcpowers }
46715697Smcpowers 
4672904Smcpowers /* ARGSUSED */
4673904Smcpowers static int
copyout_aes_ctr_mech(crypto_mechanism_t * in_mech,crypto_mechanism_t * out_mech,int * out_error,int mode)4674904Smcpowers copyout_aes_ctr_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
4675904Smcpowers     int *out_error, int mode)
4676904Smcpowers {
4677904Smcpowers 	STRUCT_DECL(crypto_mechanism, mech);
4678904Smcpowers 	STRUCT_DECL(CK_AES_CTR_PARAMS, params);
4679904Smcpowers 	caddr_t pp;
4680904Smcpowers 	size_t param_len;
4681904Smcpowers 	int error = 0;
4682904Smcpowers 	int rv = 0;
4683904Smcpowers 
4684904Smcpowers 	STRUCT_INIT(mech, mode);
4685904Smcpowers 	STRUCT_INIT(params, mode);
4686904Smcpowers 	bcopy(out_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4687904Smcpowers 	pp = STRUCT_FGETP(mech, cm_param);
4688904Smcpowers 	param_len = STRUCT_FGET(mech, cm_param_len);
4689904Smcpowers 	if (param_len != STRUCT_SIZE(params)) {
4690904Smcpowers 		rv = CRYPTO_ARGUMENTS_BAD;
4691904Smcpowers 		goto out;
4692904Smcpowers 	}
4693904Smcpowers 
4694904Smcpowers 	if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
4695904Smcpowers 		error = EFAULT;
4696904Smcpowers 		goto out;
4697904Smcpowers 	}
4698904Smcpowers 
4699904Smcpowers 	/* for testing, overwrite the iv with 16 X 'A' */
47005072Smcpowers 	(void) memset(STRUCT_FGETP(params, cb), 'A', 16);
47015413Sdinak 	if (copyout((char *)pp, STRUCT_BUF(params),  param_len) != 0) {
47025072Smcpowers 		error = EFAULT;
47035072Smcpowers 		goto out;
4704904Smcpowers 	}
4705904Smcpowers out:
4706904Smcpowers 	*out_error = error;
4707904Smcpowers 	return (rv);
4708904Smcpowers }
4709904Smcpowers 
4710904Smcpowers /* ARGSUSED */
4711904Smcpowers static int
dprov_copyin_mechanism(crypto_provider_handle_t provider,crypto_mechanism_t * umech,crypto_mechanism_t * kmech,int * out_error,int mode)4712904Smcpowers dprov_copyin_mechanism(crypto_provider_handle_t provider,
4713904Smcpowers     crypto_mechanism_t *umech, crypto_mechanism_t *kmech,
4714904Smcpowers     int *out_error, int mode)
4715904Smcpowers {
4716904Smcpowers 	STRUCT_DECL(crypto_mechanism, mech);
4717904Smcpowers 	size_t param_len, expected_param_len;
4718904Smcpowers 	caddr_t pp;
4719904Smcpowers 	char *param;
4720904Smcpowers 	int rv;
4721904Smcpowers 	int error = 0;
4722904Smcpowers 
4723904Smcpowers 	ASSERT(!servicing_interrupt());
4724904Smcpowers 
4725904Smcpowers 	STRUCT_INIT(mech, mode);
4726904Smcpowers 	bcopy(umech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4727904Smcpowers 	pp = STRUCT_FGETP(mech, cm_param);
4728904Smcpowers 	param_len = STRUCT_FGET(mech, cm_param_len);
4729904Smcpowers 
4730904Smcpowers 	kmech->cm_param = NULL;
4731904Smcpowers 	kmech->cm_param_len = 0;
4732904Smcpowers 
4733904Smcpowers 	switch (kmech->cm_type) {
4734904Smcpowers 	case DES_CBC_MECH_INFO_TYPE:
4735904Smcpowers 	case DES3_CBC_MECH_INFO_TYPE:
4736904Smcpowers 		expected_param_len = DES_BLOCK_LEN;
4737904Smcpowers 		break;
4738904Smcpowers 
4739904Smcpowers 	case BLOWFISH_CBC_MECH_INFO_TYPE:
4740904Smcpowers 		expected_param_len = BLOWFISH_BLOCK_LEN;
4741904Smcpowers 		break;
4742904Smcpowers 
4743904Smcpowers 	case AES_CBC_MECH_INFO_TYPE:
4744904Smcpowers 		expected_param_len = AES_BLOCK_LEN;
4745904Smcpowers 		break;
4746904Smcpowers 
4747904Smcpowers 	case AES_CTR_MECH_INFO_TYPE:
4748904Smcpowers 	case SHA1_KEY_DERIVATION_MECH_INFO_TYPE:	/* for testing only */
4749904Smcpowers 		rv = copyin_aes_ctr_mech(umech, kmech, &error, mode);
4750904Smcpowers 		goto out;
4751904Smcpowers 
47525697Smcpowers 	case ECDH1_DERIVE_MECH_INFO_TYPE:
47535697Smcpowers 		rv = copyin_ecc_mech(umech, kmech, &error, mode);
47545697Smcpowers 		goto out;
47555697Smcpowers 
47565413Sdinak 	case AES_CCM_MECH_INFO_TYPE:
47575413Sdinak 		rv = copyin_aes_ccm_mech(umech, kmech, &error, mode);
47585413Sdinak 		goto out;
47595413Sdinak 
47608005SMark.Powers@Sun.COM 	case AES_GCM_MECH_INFO_TYPE:
47618005SMark.Powers@Sun.COM 		rv = copyin_aes_gcm_mech(umech, kmech, &error, mode);
47628005SMark.Powers@Sun.COM 		goto out;
47638005SMark.Powers@Sun.COM 
47649339SMark.Powers@Sun.COM 	case AES_GMAC_MECH_INFO_TYPE:
47659339SMark.Powers@Sun.COM 		rv = copyin_aes_gmac_mech(umech, kmech, &error, mode);
47669339SMark.Powers@Sun.COM 		goto out;
47679339SMark.Powers@Sun.COM 
47684424Sizick 	case DH_PKCS_DERIVE_MECH_INFO_TYPE:
47694424Sizick 		expected_param_len = param_len;
47704424Sizick 		break;
47714424Sizick 
47722938Smcpowers 	default:
47732938Smcpowers 		/* nothing to do - mechanism has no parameters */
4774904Smcpowers 		rv = CRYPTO_SUCCESS;
4775904Smcpowers 		goto out;
4776904Smcpowers 	}
4777904Smcpowers 
4778904Smcpowers 	if (param_len != expected_param_len) {
4779904Smcpowers 		rv = CRYPTO_MECHANISM_PARAM_INVALID;
4780904Smcpowers 		goto out;
4781904Smcpowers 	}
4782904Smcpowers 	if (pp == NULL) {
4783904Smcpowers 		rv = CRYPTO_MECHANISM_PARAM_INVALID;
4784904Smcpowers 		goto out;
4785904Smcpowers 	}
4786904Smcpowers 	if ((param = kmem_alloc(param_len, KM_NOSLEEP)) == NULL) {
4787904Smcpowers 		rv = CRYPTO_HOST_MEMORY;
4788904Smcpowers 		goto out;
4789904Smcpowers 	}
4790904Smcpowers 	if (copyin((char *)pp, param, param_len) != 0) {
4791904Smcpowers 		kmem_free(param, param_len);
4792904Smcpowers 		error = EFAULT;
4793904Smcpowers 		rv = CRYPTO_FAILED;
4794904Smcpowers 		goto out;
4795904Smcpowers 	}
4796904Smcpowers 	kmech->cm_param = (char *)param;
4797904Smcpowers 	kmech->cm_param_len = param_len;
4798904Smcpowers 	rv = CRYPTO_SUCCESS;
4799904Smcpowers out:
4800904Smcpowers 	*out_error = error;
4801904Smcpowers 	return (rv);
4802904Smcpowers }
4803904Smcpowers 
4804904Smcpowers /* ARGSUSED */
4805904Smcpowers static int
dprov_copyout_mechanism(crypto_provider_handle_t provider,crypto_mechanism_t * kmech,crypto_mechanism_t * umech,int * out_error,int mode)4806904Smcpowers dprov_copyout_mechanism(crypto_provider_handle_t provider,
4807904Smcpowers     crypto_mechanism_t *kmech, crypto_mechanism_t *umech,
4808904Smcpowers     int *out_error, int mode)
4809904Smcpowers {
4810904Smcpowers 	ASSERT(!servicing_interrupt());
4811904Smcpowers 
4812904Smcpowers 	switch (kmech->cm_type) {
4813904Smcpowers 	case AES_CTR_MECH_INFO_TYPE:
4814904Smcpowers 	case SHA1_KEY_DERIVATION_MECH_INFO_TYPE:	/* for testing only */
4815904Smcpowers 		return (copyout_aes_ctr_mech(kmech, umech, out_error, mode));
48165697Smcpowers 	case ECDH1_DERIVE_MECH_INFO_TYPE:
48175697Smcpowers 		return (CRYPTO_SUCCESS);
4818904Smcpowers 	default:
4819904Smcpowers 		return (CRYPTO_MECHANISM_INVALID);
4820904Smcpowers 	}
4821904Smcpowers }
4822904Smcpowers 
4823904Smcpowers /*
4824904Smcpowers  * Free mechanism parameter that was allocated by the provider.
4825904Smcpowers  */
4826904Smcpowers /* ARGSUSED */
4827904Smcpowers static int
dprov_free_mechanism(crypto_provider_handle_t provider,crypto_mechanism_t * mech)4828904Smcpowers dprov_free_mechanism(crypto_provider_handle_t provider,
4829904Smcpowers     crypto_mechanism_t *mech)
4830904Smcpowers {
4831904Smcpowers 	size_t len;
4832904Smcpowers 
4833904Smcpowers 	if (mech->cm_param == NULL || mech->cm_param_len == 0)
4834904Smcpowers 		return (CRYPTO_SUCCESS);
4835904Smcpowers 
48365697Smcpowers 	switch (mech->cm_type) {
48375697Smcpowers 	case AES_CTR_MECH_INFO_TYPE:
48385697Smcpowers 	case SHA1_KEY_DERIVATION_MECH_INFO_TYPE:
48395072Smcpowers 		len = sizeof (CK_AES_CTR_PARAMS);
48405697Smcpowers 		break;
48415697Smcpowers 	case ECDH1_DERIVE_MECH_INFO_TYPE: {
48425697Smcpowers 		CK_ECDH1_DERIVE_PARAMS *ecc_params;
48435697Smcpowers 
48445697Smcpowers 		/* LINTED: pointer alignment */
48455697Smcpowers 		ecc_params = (CK_ECDH1_DERIVE_PARAMS *)mech->cm_param;
48465697Smcpowers 		kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) +
48475697Smcpowers 		    roundup(ecc_params->ulSharedDataLen, sizeof (caddr_t)) +
48485697Smcpowers 		    roundup(ecc_params->ulPublicDataLen, sizeof (caddr_t)));
48495697Smcpowers 		return (CRYPTO_SUCCESS);
48505697Smcpowers 	}
48517188Smcpowers 	case AES_CCM_MECH_INFO_TYPE: {
48527188Smcpowers 		CK_AES_CCM_PARAMS *params;
48537188Smcpowers 		size_t total_param_len;
48547188Smcpowers 
48557188Smcpowers 		if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) {
48567188Smcpowers 			/* LINTED: pointer alignment */
48577188Smcpowers 			params = (CK_AES_CCM_PARAMS *)mech->cm_param;
48587188Smcpowers 			total_param_len = mech->cm_param_len +
48597188Smcpowers 			    params->ulNonceSize + params->ulAuthDataSize;
48607188Smcpowers 			kmem_free(params, total_param_len);
48617188Smcpowers 			mech->cm_param = NULL;
48627188Smcpowers 			mech->cm_param_len = 0;
48637188Smcpowers 		}
48648005SMark.Powers@Sun.COM 		return (CRYPTO_SUCCESS);
48658005SMark.Powers@Sun.COM 	}
48669339SMark.Powers@Sun.COM 	case AES_GMAC_MECH_INFO_TYPE: {
48679339SMark.Powers@Sun.COM 		CK_AES_GMAC_PARAMS *params;
48689339SMark.Powers@Sun.COM 		size_t total_param_len;
48699339SMark.Powers@Sun.COM 
48709339SMark.Powers@Sun.COM 		if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) {
48719339SMark.Powers@Sun.COM 			/* LINTED: pointer alignment */
48729339SMark.Powers@Sun.COM 			params = (CK_AES_GMAC_PARAMS *)mech->cm_param;
48739339SMark.Powers@Sun.COM 			total_param_len = mech->cm_param_len +
48749339SMark.Powers@Sun.COM 			    AES_GMAC_IV_LEN + params->ulAADLen;
48759339SMark.Powers@Sun.COM 			kmem_free(params, total_param_len);
48769339SMark.Powers@Sun.COM 			mech->cm_param = NULL;
48779339SMark.Powers@Sun.COM 			mech->cm_param_len = 0;
48789339SMark.Powers@Sun.COM 		}
48799339SMark.Powers@Sun.COM 		return (CRYPTO_SUCCESS);
48809339SMark.Powers@Sun.COM 	}
48818005SMark.Powers@Sun.COM 	case AES_GCM_MECH_INFO_TYPE: {
48828005SMark.Powers@Sun.COM 		CK_AES_GCM_PARAMS *params;
48838005SMark.Powers@Sun.COM 		size_t total_param_len;
48848005SMark.Powers@Sun.COM 
48858005SMark.Powers@Sun.COM 		if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) {
48868005SMark.Powers@Sun.COM 			/* LINTED: pointer alignment */
48878005SMark.Powers@Sun.COM 			params = (CK_AES_GCM_PARAMS *)mech->cm_param;
48888005SMark.Powers@Sun.COM 			total_param_len = mech->cm_param_len +
48898005SMark.Powers@Sun.COM 			    params->ulIvLen + params->ulAADLen;
48908005SMark.Powers@Sun.COM 			kmem_free(params, total_param_len);
48918005SMark.Powers@Sun.COM 			mech->cm_param = NULL;
48928005SMark.Powers@Sun.COM 			mech->cm_param_len = 0;
48938005SMark.Powers@Sun.COM 		}
48948005SMark.Powers@Sun.COM 		return (CRYPTO_SUCCESS);
48957188Smcpowers 	}
48967188Smcpowers 
48975697Smcpowers 	default:
4898904Smcpowers 		len = mech->cm_param_len;
4899904Smcpowers 	}
4900904Smcpowers 	kmem_free(mech->cm_param, len);
4901904Smcpowers 	return (CRYPTO_SUCCESS);
4902904Smcpowers }
49030Sstevel@tonic-gate 
49040Sstevel@tonic-gate /*
49054219Smcpowers  * No (Key)Store Key management entry point.
49064219Smcpowers  */
49074219Smcpowers static int
dprov_nostore_key_generate(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_object_attribute_t * template,uint_t attribute_count,crypto_object_attribute_t * out_template,uint_t out_attribute_count,crypto_req_handle_t req)49084219Smcpowers dprov_nostore_key_generate(crypto_provider_handle_t provider,
49094219Smcpowers     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
49104219Smcpowers     crypto_object_attribute_t *template, uint_t attribute_count,
49114219Smcpowers     crypto_object_attribute_t *out_template, uint_t out_attribute_count,
49124219Smcpowers     crypto_req_handle_t req)
49134219Smcpowers {
49144219Smcpowers 	int error = CRYPTO_FAILED;
49154219Smcpowers 	dprov_state_t *softc = (dprov_state_t *)provider;
49164219Smcpowers 	/* LINTED E_FUNC_SET_NOT_USED */
49174219Smcpowers 	int instance;
49184219Smcpowers 
49194219Smcpowers 	instance = ddi_get_instance(softc->ds_dip);
49204219Smcpowers 	DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate: started\n",
49214219Smcpowers 	    instance));
49224219Smcpowers 
49234219Smcpowers 	/* submit request to the taskq */
49244219Smcpowers 	error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_GENERATE,
49254219Smcpowers 	    softc, req, session_id, mechanism, template, attribute_count,
49264219Smcpowers 	    NULL, NULL, 0, NULL, NULL, NULL, 0, out_template,
49274219Smcpowers 	    out_attribute_count, NULL, 0);
49284219Smcpowers 
49294219Smcpowers 	DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate: "
49304219Smcpowers 	    "done err = 0x0%x\n", instance, error));
49314219Smcpowers 
49324219Smcpowers 	return (error);
49334219Smcpowers }
49344219Smcpowers 
49354424Sizick static int
dprov_nostore_key_generate_pair(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_object_attribute_t * public_key_template,uint_t public_key_attribute_count,crypto_object_attribute_t * private_key_template,uint_t private_key_attribute_count,crypto_object_attribute_t * out_public_key_template,uint_t out_public_key_attribute_count,crypto_object_attribute_t * out_private_key_template,uint_t out_private_key_attribute_count,crypto_req_handle_t req)49364424Sizick dprov_nostore_key_generate_pair(crypto_provider_handle_t provider,
49374424Sizick     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
49384424Sizick     crypto_object_attribute_t *public_key_template,
49394424Sizick     uint_t public_key_attribute_count,
49404424Sizick     crypto_object_attribute_t *private_key_template,
49414424Sizick     uint_t private_key_attribute_count,
49424424Sizick     crypto_object_attribute_t *out_public_key_template,
49434424Sizick     uint_t out_public_key_attribute_count,
49444424Sizick     crypto_object_attribute_t *out_private_key_template,
49454424Sizick     uint_t out_private_key_attribute_count,
49464424Sizick     crypto_req_handle_t req)
49474424Sizick {
49484424Sizick 	int error = CRYPTO_FAILED;
49494424Sizick 	dprov_state_t *softc = (dprov_state_t *)provider;
49504424Sizick 	/* LINTED E_FUNC_SET_NOT_USED */
49514424Sizick 	int instance;
49524424Sizick 
49534424Sizick 	instance = ddi_get_instance(softc->ds_dip);
49544424Sizick 	DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate_pair: started\n",
49554424Sizick 	    instance));
49564424Sizick 
49574424Sizick 	/* submit request to the taskq */
49584424Sizick 	error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR,
49594424Sizick 	    softc, req, session_id, mechanism, public_key_template,
49604424Sizick 	    public_key_attribute_count, NULL, private_key_template,
49614424Sizick 	    private_key_attribute_count, NULL, NULL, NULL, 0,
49624424Sizick 	    out_public_key_template, out_public_key_attribute_count,
49634424Sizick 	    out_private_key_template, out_private_key_attribute_count);
49644424Sizick 
49654424Sizick 	DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate_pair: "
49664424Sizick 	    "done err = 0x0%x\n", instance, error));
49674424Sizick 
49684424Sizick 	return (error);
49694424Sizick }
49704424Sizick 
49714424Sizick static int
dprov_nostore_key_derive(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * base_key,crypto_object_attribute_t * template,uint_t attribute_count,crypto_object_attribute_t * out_template,uint_t out_attribute_count,crypto_req_handle_t req)49724424Sizick dprov_nostore_key_derive(crypto_provider_handle_t provider,
49734424Sizick     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
49744424Sizick     crypto_key_t *base_key, crypto_object_attribute_t *template,
49754424Sizick     uint_t attribute_count, crypto_object_attribute_t *out_template,
49764424Sizick     uint_t out_attribute_count, crypto_req_handle_t req)
49774424Sizick {
49784424Sizick 	int error = CRYPTO_FAILED;
49794424Sizick 	dprov_state_t *softc = (dprov_state_t *)provider;
49804424Sizick 	/* LINTED E_FUNC_SET_NOT_USED */
49814424Sizick 	int instance;
49824424Sizick 
49834424Sizick 	instance = ddi_get_instance(softc->ds_dip);
49844424Sizick 	DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_derive: started\n",
49854424Sizick 	    instance));
49864424Sizick 
49874424Sizick 	/* submit request to the taskq */
49884424Sizick 	error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_DERIVE, softc, req,
49894424Sizick 	    session_id, mechanism, template, attribute_count, NULL, NULL,
49904424Sizick 	    0, NULL, base_key, NULL, 0, out_template, out_attribute_count,
49914424Sizick 	    NULL, 0);
49924424Sizick 
49934424Sizick 	DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_derive: "
49944424Sizick 	    "done err = 0x0%x\n", instance, error));
49954424Sizick 
49964424Sizick 	return (error);
49974424Sizick }
49984424Sizick 
49994219Smcpowers /*
50000Sstevel@tonic-gate  * Allocate a dprov taskq request and initialize the common fields.
50010Sstevel@tonic-gate  * Return NULL if the memory allocation failed.
50020Sstevel@tonic-gate  */
50030Sstevel@tonic-gate static dprov_req_t *
dprov_alloc_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t kcf_req,int kmflag)50040Sstevel@tonic-gate dprov_alloc_req(dprov_req_type_t req_type, dprov_state_t *softc,
50050Sstevel@tonic-gate     crypto_req_handle_t kcf_req, int kmflag)
50060Sstevel@tonic-gate {
50070Sstevel@tonic-gate 	dprov_req_t *taskq_req;
50080Sstevel@tonic-gate 
50090Sstevel@tonic-gate 	if ((taskq_req = kmem_alloc(sizeof (dprov_req_t), kmflag)) == NULL)
50100Sstevel@tonic-gate 		return (NULL);
50110Sstevel@tonic-gate 
50120Sstevel@tonic-gate 	taskq_req->dr_type = req_type;
50130Sstevel@tonic-gate 	taskq_req->dr_softc = softc;
50140Sstevel@tonic-gate 	taskq_req->dr_kcf_req = kcf_req;
50150Sstevel@tonic-gate 
50160Sstevel@tonic-gate 	return (taskq_req);
50170Sstevel@tonic-gate }
50180Sstevel@tonic-gate 
50190Sstevel@tonic-gate /*
50200Sstevel@tonic-gate  * Dispatch a dprov request on the taskq associated with a softc.
50210Sstevel@tonic-gate  * Returns CRYPTO_HOST_MEMORY if the request cannot be queued,
50220Sstevel@tonic-gate  * CRYPTO_QUEUED on success.
50230Sstevel@tonic-gate  */
50240Sstevel@tonic-gate static int
dprov_taskq_dispatch(dprov_state_t * softc,dprov_req_t * taskq_req,task_func_t * func,int kmflag)50250Sstevel@tonic-gate dprov_taskq_dispatch(dprov_state_t *softc, dprov_req_t *taskq_req,
50260Sstevel@tonic-gate     task_func_t *func, int kmflag)
50270Sstevel@tonic-gate {
50280Sstevel@tonic-gate 	if (taskq_dispatch(softc->ds_taskq, func, taskq_req,
50290Sstevel@tonic-gate 	    kmflag == KM_NOSLEEP ? TQ_NOSLEEP : TQ_SLEEP) == (taskqid_t)0) {
50300Sstevel@tonic-gate 		kmem_free(taskq_req, sizeof (dprov_req_t));
50310Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
50320Sstevel@tonic-gate 	} else
50330Sstevel@tonic-gate 		return (CRYPTO_QUEUED);
50340Sstevel@tonic-gate }
50350Sstevel@tonic-gate 
50360Sstevel@tonic-gate /*
50370Sstevel@tonic-gate  * Helper function to submit digest operations to the taskq.
50380Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
50390Sstevel@tonic-gate  */
50400Sstevel@tonic-gate static int
dprov_digest_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,crypto_mechanism_t * mechanism,crypto_data_t * data,crypto_key_t * key,crypto_data_t * digest,crypto_ctx_t * ctx,int kmflag)50410Sstevel@tonic-gate dprov_digest_submit_req(dprov_req_type_t req_type,
50420Sstevel@tonic-gate     dprov_state_t *softc, crypto_req_handle_t req,
50430Sstevel@tonic-gate     crypto_mechanism_t *mechanism, crypto_data_t *data, crypto_key_t *key,
50440Sstevel@tonic-gate     crypto_data_t *digest, crypto_ctx_t *ctx, int kmflag)
50450Sstevel@tonic-gate {
50460Sstevel@tonic-gate 	dprov_req_t *taskq_req;
50470Sstevel@tonic-gate 
50480Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
50490Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
50500Sstevel@tonic-gate 
50510Sstevel@tonic-gate 	taskq_req->dr_digest_req.dr_mechanism = mechanism;
50520Sstevel@tonic-gate 	taskq_req->dr_digest_req.dr_ctx = ctx;
50530Sstevel@tonic-gate 	taskq_req->dr_digest_req.dr_data = data;
50540Sstevel@tonic-gate 	taskq_req->dr_digest_req.dr_key = key;
50550Sstevel@tonic-gate 	taskq_req->dr_digest_req.dr_digest = digest;
50560Sstevel@tonic-gate 
50570Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
50580Sstevel@tonic-gate 	    (task_func_t *)dprov_digest_task, kmflag));
50590Sstevel@tonic-gate }
50600Sstevel@tonic-gate 
50610Sstevel@tonic-gate /*
50620Sstevel@tonic-gate  * Helper function to submit mac operations to the taskq.
50630Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
50640Sstevel@tonic-gate  */
50650Sstevel@tonic-gate static int
dprov_mac_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,crypto_mechanism_t * mechanism,crypto_data_t * data,crypto_key_t * key,crypto_data_t * mac,crypto_ctx_t * ctx,crypto_session_id_t sid,int kmflag)50660Sstevel@tonic-gate dprov_mac_submit_req(dprov_req_type_t req_type,
50670Sstevel@tonic-gate     dprov_state_t *softc, crypto_req_handle_t req,
50680Sstevel@tonic-gate     crypto_mechanism_t *mechanism, crypto_data_t *data, crypto_key_t *key,
50690Sstevel@tonic-gate     crypto_data_t *mac, crypto_ctx_t *ctx, crypto_session_id_t sid, int kmflag)
50700Sstevel@tonic-gate {
50710Sstevel@tonic-gate 	dprov_req_t *taskq_req;
50720Sstevel@tonic-gate 
50730Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
50740Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
50750Sstevel@tonic-gate 
50760Sstevel@tonic-gate 	taskq_req->dr_mac_req.dr_mechanism = mechanism;
50770Sstevel@tonic-gate 	taskq_req->dr_mac_req.dr_ctx = ctx;
50780Sstevel@tonic-gate 	taskq_req->dr_mac_req.dr_data = data;
50790Sstevel@tonic-gate 	taskq_req->dr_mac_req.dr_key = key;
50800Sstevel@tonic-gate 	taskq_req->dr_mac_req.dr_mac = mac;
50810Sstevel@tonic-gate 	taskq_req->dr_mac_req.dr_session_id = sid;
50820Sstevel@tonic-gate 
50830Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
50840Sstevel@tonic-gate 	    (task_func_t *)dprov_mac_task, kmflag));
50850Sstevel@tonic-gate }
50860Sstevel@tonic-gate 
50870Sstevel@tonic-gate /*
50880Sstevel@tonic-gate  * Helper function to submit sign operations to the taskq.
50890Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
50900Sstevel@tonic-gate  */
50910Sstevel@tonic-gate static int
dprov_sign_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * data,crypto_data_t * signature,crypto_ctx_t * ctx,crypto_session_id_t sid,int kmflag)50920Sstevel@tonic-gate dprov_sign_submit_req(dprov_req_type_t req_type,
50930Sstevel@tonic-gate     dprov_state_t *softc, crypto_req_handle_t req,
50940Sstevel@tonic-gate     crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data,
50950Sstevel@tonic-gate     crypto_data_t *signature, crypto_ctx_t *ctx, crypto_session_id_t sid,
50960Sstevel@tonic-gate     int kmflag)
50970Sstevel@tonic-gate {
50980Sstevel@tonic-gate 	dprov_req_t *taskq_req;
50990Sstevel@tonic-gate 
51000Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
51010Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
51020Sstevel@tonic-gate 
51030Sstevel@tonic-gate 	taskq_req->dr_sign_req.sr_mechanism = mechanism;
51040Sstevel@tonic-gate 	taskq_req->dr_sign_req.sr_ctx = ctx;
51050Sstevel@tonic-gate 	taskq_req->dr_sign_req.sr_key = key;
51060Sstevel@tonic-gate 	taskq_req->dr_sign_req.sr_data = data;
51070Sstevel@tonic-gate 	taskq_req->dr_sign_req.sr_signature = signature;
51080Sstevel@tonic-gate 	taskq_req->dr_sign_req.sr_session_id = sid;
51090Sstevel@tonic-gate 
51100Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
51110Sstevel@tonic-gate 	    (task_func_t *)dprov_sign_task, kmflag));
51120Sstevel@tonic-gate }
51130Sstevel@tonic-gate 
51140Sstevel@tonic-gate /*
51150Sstevel@tonic-gate  * Helper function to submit verify operations to the taskq.
51160Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
51170Sstevel@tonic-gate  */
51180Sstevel@tonic-gate static int
dprov_verify_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * data,crypto_data_t * signature,crypto_ctx_t * ctx,crypto_session_id_t sid,int kmflag)51190Sstevel@tonic-gate dprov_verify_submit_req(dprov_req_type_t req_type,
51200Sstevel@tonic-gate     dprov_state_t *softc, crypto_req_handle_t req,
51210Sstevel@tonic-gate     crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data,
51220Sstevel@tonic-gate     crypto_data_t *signature, crypto_ctx_t *ctx, crypto_session_id_t sid,
51230Sstevel@tonic-gate     int kmflag)
51240Sstevel@tonic-gate {
51250Sstevel@tonic-gate 	dprov_req_t *taskq_req;
51260Sstevel@tonic-gate 
51270Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
51280Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
51290Sstevel@tonic-gate 
51300Sstevel@tonic-gate 	taskq_req->dr_verify_req.vr_mechanism = mechanism;
51310Sstevel@tonic-gate 	taskq_req->dr_verify_req.vr_ctx = ctx;
51320Sstevel@tonic-gate 	taskq_req->dr_verify_req.vr_key = key;
51330Sstevel@tonic-gate 	taskq_req->dr_verify_req.vr_data = data;
51340Sstevel@tonic-gate 	taskq_req->dr_verify_req.vr_signature = signature;
51350Sstevel@tonic-gate 	taskq_req->dr_verify_req.vr_session_id = sid;
51360Sstevel@tonic-gate 
51370Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
51380Sstevel@tonic-gate 	    (task_func_t *)dprov_verify_task, kmflag));
51390Sstevel@tonic-gate }
51400Sstevel@tonic-gate 
51410Sstevel@tonic-gate /*
51420Sstevel@tonic-gate  * Helper function to submit dual operations to the taskq.
51430Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
51440Sstevel@tonic-gate  */
51450Sstevel@tonic-gate static int
dprov_dual_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,crypto_ctx_t * signverify_ctx,crypto_ctx_t * cipher_ctx,crypto_data_t * plaintext,crypto_data_t * ciphertext)51460Sstevel@tonic-gate dprov_dual_submit_req(dprov_req_type_t req_type, dprov_state_t *softc,
51470Sstevel@tonic-gate     crypto_req_handle_t req, crypto_ctx_t *signverify_ctx,
51480Sstevel@tonic-gate     crypto_ctx_t *cipher_ctx, crypto_data_t *plaintext,
51490Sstevel@tonic-gate     crypto_data_t *ciphertext)
51500Sstevel@tonic-gate {
51510Sstevel@tonic-gate 	dprov_req_t *taskq_req;
51520Sstevel@tonic-gate 
51530Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req,
51540Sstevel@tonic-gate 	    KM_NOSLEEP)) == NULL)
51550Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
51560Sstevel@tonic-gate 
51570Sstevel@tonic-gate 	taskq_req->dr_dual_req.dr_signverify_ctx = signverify_ctx;
51580Sstevel@tonic-gate 	taskq_req->dr_dual_req.dr_cipher_ctx = cipher_ctx;
51590Sstevel@tonic-gate 	taskq_req->dr_dual_req.dr_plaintext = plaintext;
51600Sstevel@tonic-gate 	taskq_req->dr_dual_req.dr_ciphertext = ciphertext;
51610Sstevel@tonic-gate 
51620Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
51630Sstevel@tonic-gate 	    (task_func_t *)dprov_dual_task, KM_NOSLEEP));
51640Sstevel@tonic-gate }
51650Sstevel@tonic-gate 
51660Sstevel@tonic-gate /*
51670Sstevel@tonic-gate  * Helper function to submit dual cipher/mac operations to the taskq.
51680Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
51690Sstevel@tonic-gate  */
51700Sstevel@tonic-gate static int
dprov_cipher_mac_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,crypto_ctx_t * ctx,crypto_session_id_t sid,crypto_mechanism_t * cipher_mech,crypto_key_t * cipher_key,crypto_mechanism_t * mac_mech,crypto_key_t * mac_key,crypto_dual_data_t * dual_data,crypto_data_t * data,crypto_data_t * mac,int kmflag)51710Sstevel@tonic-gate dprov_cipher_mac_submit_req(dprov_req_type_t req_type,
51720Sstevel@tonic-gate     dprov_state_t *softc, crypto_req_handle_t req, crypto_ctx_t *ctx,
51730Sstevel@tonic-gate     crypto_session_id_t sid, crypto_mechanism_t *cipher_mech,
51740Sstevel@tonic-gate     crypto_key_t *cipher_key, crypto_mechanism_t *mac_mech,
51750Sstevel@tonic-gate     crypto_key_t *mac_key, crypto_dual_data_t *dual_data,
51760Sstevel@tonic-gate     crypto_data_t *data, crypto_data_t *mac, int kmflag)
51770Sstevel@tonic-gate {
51780Sstevel@tonic-gate 	dprov_req_t *taskq_req;
51790Sstevel@tonic-gate 
51800Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
51810Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
51820Sstevel@tonic-gate 
51830Sstevel@tonic-gate 	taskq_req->dr_cipher_mac_req.mr_session_id = sid;
51840Sstevel@tonic-gate 	taskq_req->dr_cipher_mac_req.mr_ctx = ctx;
51850Sstevel@tonic-gate 	taskq_req->dr_cipher_mac_req.mr_cipher_mech = cipher_mech;
51860Sstevel@tonic-gate 	taskq_req->dr_cipher_mac_req.mr_cipher_key = cipher_key;
51870Sstevel@tonic-gate 	taskq_req->dr_cipher_mac_req.mr_mac_mech = mac_mech;
51880Sstevel@tonic-gate 	taskq_req->dr_cipher_mac_req.mr_mac_key = mac_key;
51890Sstevel@tonic-gate 	taskq_req->dr_cipher_mac_req.mr_dual_data = dual_data;
51900Sstevel@tonic-gate 	taskq_req->dr_cipher_mac_req.mr_data = data;
51910Sstevel@tonic-gate 	taskq_req->dr_cipher_mac_req.mr_mac = mac;
51920Sstevel@tonic-gate 
51930Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
51940Sstevel@tonic-gate 	    (task_func_t *)dprov_cipher_mac_task, kmflag));
51950Sstevel@tonic-gate }
51960Sstevel@tonic-gate 
51970Sstevel@tonic-gate /*
51980Sstevel@tonic-gate  * Helper function to submit cipher operations to the taskq.
51990Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
52000Sstevel@tonic-gate  */
52010Sstevel@tonic-gate static int
dprov_cipher_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * plaintext,crypto_data_t * ciphertext,crypto_ctx_t * ctx,crypto_session_id_t sid,int kmflag)52020Sstevel@tonic-gate dprov_cipher_submit_req(dprov_req_type_t req_type,
52030Sstevel@tonic-gate     dprov_state_t *softc, crypto_req_handle_t req,
52040Sstevel@tonic-gate     crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *plaintext,
52050Sstevel@tonic-gate     crypto_data_t *ciphertext, crypto_ctx_t *ctx, crypto_session_id_t sid,
52060Sstevel@tonic-gate     int kmflag)
52070Sstevel@tonic-gate {
52080Sstevel@tonic-gate 	dprov_req_t *taskq_req;
52090Sstevel@tonic-gate 
52100Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
52110Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
52120Sstevel@tonic-gate 
52130Sstevel@tonic-gate 	taskq_req->dr_cipher_req.dr_mechanism = mechanism;
52140Sstevel@tonic-gate 	taskq_req->dr_cipher_req.dr_ctx = ctx;
52150Sstevel@tonic-gate 	taskq_req->dr_cipher_req.dr_key = key;
52160Sstevel@tonic-gate 	taskq_req->dr_cipher_req.dr_plaintext = plaintext;
52170Sstevel@tonic-gate 	taskq_req->dr_cipher_req.dr_ciphertext = ciphertext;
52180Sstevel@tonic-gate 	taskq_req->dr_cipher_req.dr_session_id = sid;
52190Sstevel@tonic-gate 
52200Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
52210Sstevel@tonic-gate 	    (task_func_t *)dprov_cipher_task, kmflag));
52220Sstevel@tonic-gate }
52230Sstevel@tonic-gate 
52240Sstevel@tonic-gate /*
52250Sstevel@tonic-gate  * Helper function to submit random number operations to the taskq.
52260Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
52270Sstevel@tonic-gate  */
52280Sstevel@tonic-gate static int
dprov_random_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,uchar_t * buf,size_t len,crypto_session_id_t sid,uint_t entropy_est,uint32_t flags)52290Sstevel@tonic-gate dprov_random_submit_req(dprov_req_type_t req_type,
52300Sstevel@tonic-gate     dprov_state_t *softc, crypto_req_handle_t req, uchar_t *buf, size_t len,
52311920Smcpowers     crypto_session_id_t sid, uint_t entropy_est, uint32_t flags)
52320Sstevel@tonic-gate {
52330Sstevel@tonic-gate 	dprov_req_t *taskq_req;
52340Sstevel@tonic-gate 
52350Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req,
52360Sstevel@tonic-gate 	    KM_NOSLEEP)) == NULL)
52370Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
52380Sstevel@tonic-gate 
52390Sstevel@tonic-gate 	taskq_req->dr_random_req.rr_buf = buf;
52400Sstevel@tonic-gate 	taskq_req->dr_random_req.rr_len = len;
52410Sstevel@tonic-gate 	taskq_req->dr_random_req.rr_session_id = sid;
52421920Smcpowers 	taskq_req->dr_random_req.rr_entropy_est = entropy_est;
52431920Smcpowers 	taskq_req->dr_random_req.rr_flags = flags;
52440Sstevel@tonic-gate 
52450Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
52460Sstevel@tonic-gate 	    (task_func_t *)dprov_random_task, KM_NOSLEEP));
52470Sstevel@tonic-gate }
52480Sstevel@tonic-gate 
52490Sstevel@tonic-gate 
52500Sstevel@tonic-gate /*
52510Sstevel@tonic-gate  * Helper function to submit session management operations to the taskq.
52520Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
52530Sstevel@tonic-gate  */
52540Sstevel@tonic-gate static int
dprov_session_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,crypto_session_id_t * session_id_ptr,crypto_session_id_t session_id,crypto_user_type_t user_type,char * pin,size_t pin_len)52550Sstevel@tonic-gate dprov_session_submit_req(dprov_req_type_t req_type,
52560Sstevel@tonic-gate     dprov_state_t *softc, crypto_req_handle_t req,
52570Sstevel@tonic-gate     crypto_session_id_t *session_id_ptr, crypto_session_id_t session_id,
52580Sstevel@tonic-gate     crypto_user_type_t user_type, char *pin, size_t pin_len)
52590Sstevel@tonic-gate {
52600Sstevel@tonic-gate 	dprov_req_t *taskq_req;
52610Sstevel@tonic-gate 
52620Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req,
52630Sstevel@tonic-gate 	    KM_NOSLEEP)) == NULL)
52640Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
52650Sstevel@tonic-gate 
52660Sstevel@tonic-gate 	taskq_req->dr_session_req.sr_session_id_ptr = session_id_ptr;
52670Sstevel@tonic-gate 	taskq_req->dr_session_req.sr_session_id = session_id;
52680Sstevel@tonic-gate 	taskq_req->dr_session_req.sr_user_type = user_type;
52690Sstevel@tonic-gate 	taskq_req->dr_session_req.sr_pin = pin;
52700Sstevel@tonic-gate 	taskq_req->dr_session_req.sr_pin_len = pin_len;
52710Sstevel@tonic-gate 
52720Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
52730Sstevel@tonic-gate 	    (task_func_t *)dprov_session_task, KM_NOSLEEP));
52740Sstevel@tonic-gate }
52750Sstevel@tonic-gate 
52760Sstevel@tonic-gate /*
52770Sstevel@tonic-gate  * Helper function to submit object management operations to the taskq.
52780Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
52790Sstevel@tonic-gate  */
52800Sstevel@tonic-gate static int
dprov_object_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,crypto_session_id_t session_id,crypto_object_id_t object_id,crypto_object_attribute_t * template,uint_t attribute_count,crypto_object_id_t * object_id_ptr,size_t * object_size,void ** find_pp,void * find_p,uint_t max_object_count,uint_t * object_count_ptr,int kmflag)52810Sstevel@tonic-gate dprov_object_submit_req(dprov_req_type_t req_type,
52820Sstevel@tonic-gate     dprov_state_t *softc, crypto_req_handle_t req,
52830Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_object_id_t object_id,
52840Sstevel@tonic-gate     crypto_object_attribute_t *template, uint_t attribute_count,
52850Sstevel@tonic-gate     crypto_object_id_t *object_id_ptr, size_t *object_size,
52860Sstevel@tonic-gate     void **find_pp, void *find_p, uint_t max_object_count,
52870Sstevel@tonic-gate     uint_t *object_count_ptr, int kmflag)
52880Sstevel@tonic-gate {
52890Sstevel@tonic-gate 	dprov_req_t *taskq_req;
52900Sstevel@tonic-gate 
52910Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req,
52920Sstevel@tonic-gate 	    kmflag)) == NULL)
52930Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
52940Sstevel@tonic-gate 
52950Sstevel@tonic-gate 	taskq_req->dr_object_req.or_session_id = session_id;
52960Sstevel@tonic-gate 	taskq_req->dr_object_req.or_object_id = object_id;
52970Sstevel@tonic-gate 	taskq_req->dr_object_req.or_template = template;
52980Sstevel@tonic-gate 	taskq_req->dr_object_req.or_attribute_count = attribute_count;
52990Sstevel@tonic-gate 	taskq_req->dr_object_req.or_object_id_ptr = object_id_ptr;
53000Sstevel@tonic-gate 	taskq_req->dr_object_req.or_object_size = object_size;
53010Sstevel@tonic-gate 	taskq_req->dr_object_req.or_find_pp = find_pp;
53020Sstevel@tonic-gate 	taskq_req->dr_object_req.or_find_p = find_p;
53030Sstevel@tonic-gate 	taskq_req->dr_object_req.or_max_object_count = max_object_count;
53040Sstevel@tonic-gate 	taskq_req->dr_object_req.or_object_count_ptr = object_count_ptr;
53050Sstevel@tonic-gate 
53060Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
53070Sstevel@tonic-gate 	    (task_func_t *)dprov_object_task, KM_NOSLEEP));
53080Sstevel@tonic-gate }
53090Sstevel@tonic-gate 
53100Sstevel@tonic-gate /*
53110Sstevel@tonic-gate  * Helper function to submit key management operations to the taskq.
53120Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
53130Sstevel@tonic-gate  */
53140Sstevel@tonic-gate static int
dprov_key_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_object_attribute_t * template,uint_t attribute_count,crypto_object_id_t * object_id_ptr,crypto_object_attribute_t * private_key_template,uint_t private_key_attribute_count,crypto_object_id_t * private_key_object_id_ptr,crypto_key_t * key,uchar_t * wrapped_key,size_t * wrapped_key_len_ptr,crypto_object_attribute_t * out_template1,uint_t out_attribute_count1,crypto_object_attribute_t * out_template2,uint_t out_attribute_count2)53150Sstevel@tonic-gate dprov_key_submit_req(dprov_req_type_t req_type,
53160Sstevel@tonic-gate     dprov_state_t *softc, crypto_req_handle_t req,
53170Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
53180Sstevel@tonic-gate     crypto_object_attribute_t *template, uint_t attribute_count,
53190Sstevel@tonic-gate     crypto_object_id_t *object_id_ptr,
53200Sstevel@tonic-gate     crypto_object_attribute_t *private_key_template,
53210Sstevel@tonic-gate     uint_t private_key_attribute_count,
53220Sstevel@tonic-gate     crypto_object_id_t *private_key_object_id_ptr, crypto_key_t *key,
53234219Smcpowers     uchar_t *wrapped_key, size_t *wrapped_key_len_ptr,
53244219Smcpowers     crypto_object_attribute_t *out_template1, uint_t out_attribute_count1,
53254219Smcpowers     crypto_object_attribute_t *out_template2, uint_t out_attribute_count2)
53260Sstevel@tonic-gate {
53270Sstevel@tonic-gate 	dprov_req_t *taskq_req;
53280Sstevel@tonic-gate 
53290Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req,
53300Sstevel@tonic-gate 	    KM_NOSLEEP)) == NULL)
53310Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
53320Sstevel@tonic-gate 
53330Sstevel@tonic-gate 	taskq_req->dr_key_req.kr_session_id = session_id;
53340Sstevel@tonic-gate 	taskq_req->dr_key_req.kr_mechanism = mechanism;
53350Sstevel@tonic-gate 	taskq_req->dr_key_req.kr_template = template;
53360Sstevel@tonic-gate 	taskq_req->dr_key_req.kr_attribute_count = attribute_count;
53370Sstevel@tonic-gate 	taskq_req->dr_key_req.kr_object_id_ptr = object_id_ptr;
53380Sstevel@tonic-gate 	taskq_req->dr_key_req.kr_private_key_template = private_key_template;
53390Sstevel@tonic-gate 	taskq_req->dr_key_req.kr_private_key_attribute_count =
53400Sstevel@tonic-gate 	    private_key_attribute_count;
53410Sstevel@tonic-gate 	taskq_req->dr_key_req.kr_private_key_object_id_ptr =
53420Sstevel@tonic-gate 	    private_key_object_id_ptr;
53430Sstevel@tonic-gate 	taskq_req->dr_key_req.kr_key = key;
53440Sstevel@tonic-gate 	taskq_req->dr_key_req.kr_wrapped_key = wrapped_key;
53450Sstevel@tonic-gate 	taskq_req->dr_key_req.kr_wrapped_key_len_ptr = wrapped_key_len_ptr;
53464219Smcpowers 	taskq_req->dr_key_req.kr_out_template1 = out_template1;
53474219Smcpowers 	taskq_req->dr_key_req.kr_out_attribute_count1 = out_attribute_count1;
53484219Smcpowers 	taskq_req->dr_key_req.kr_out_template2 = out_template2;
53494219Smcpowers 	taskq_req->dr_key_req.kr_out_attribute_count2 = out_attribute_count2;
53500Sstevel@tonic-gate 
53510Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
53520Sstevel@tonic-gate 	    (task_func_t *)dprov_key_task, KM_NOSLEEP));
53530Sstevel@tonic-gate }
53540Sstevel@tonic-gate 
53550Sstevel@tonic-gate /*
53560Sstevel@tonic-gate  * Helper function to submit provider management operations to the taskq.
53570Sstevel@tonic-gate  * Returns one of the CRYPTO_ errors.
53580Sstevel@tonic-gate  */
53590Sstevel@tonic-gate static int
dprov_mgmt_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,crypto_session_id_t session_id,char * pin,size_t pin_len,char * old_pin,size_t old_pin_len,char * label,crypto_provider_ext_info_t * ext_info)53600Sstevel@tonic-gate dprov_mgmt_submit_req(dprov_req_type_t req_type,
53610Sstevel@tonic-gate     dprov_state_t *softc, crypto_req_handle_t req,
53620Sstevel@tonic-gate     crypto_session_id_t session_id, char *pin, size_t pin_len,
53630Sstevel@tonic-gate     char *old_pin, size_t old_pin_len, char *label,
53640Sstevel@tonic-gate     crypto_provider_ext_info_t *ext_info)
53650Sstevel@tonic-gate {
53660Sstevel@tonic-gate 	dprov_req_t *taskq_req;
53670Sstevel@tonic-gate 
53680Sstevel@tonic-gate 	if ((taskq_req = dprov_alloc_req(req_type, softc, req,
53690Sstevel@tonic-gate 	    KM_NOSLEEP)) == NULL)
53700Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
53710Sstevel@tonic-gate 
53720Sstevel@tonic-gate 	taskq_req->dr_mgmt_req.mr_session_id = session_id;
53730Sstevel@tonic-gate 	taskq_req->dr_mgmt_req.mr_pin = pin;
53740Sstevel@tonic-gate 	taskq_req->dr_mgmt_req.mr_pin_len = pin_len;
53750Sstevel@tonic-gate 	taskq_req->dr_mgmt_req.mr_old_pin = old_pin;
53760Sstevel@tonic-gate 	taskq_req->dr_mgmt_req.mr_old_pin_len = old_pin_len;
53770Sstevel@tonic-gate 	taskq_req->dr_mgmt_req.mr_label = label;
53780Sstevel@tonic-gate 	taskq_req->dr_mgmt_req.mr_ext_info = ext_info;
53790Sstevel@tonic-gate 
53800Sstevel@tonic-gate 	return (dprov_taskq_dispatch(softc, taskq_req,
53810Sstevel@tonic-gate 	    (task_func_t *)dprov_mgmt_task, KM_NOSLEEP));
53820Sstevel@tonic-gate }
53830Sstevel@tonic-gate 
53840Sstevel@tonic-gate /*
53850Sstevel@tonic-gate  * Helper function for taskq dispatcher routines. Notify the framework
53860Sstevel@tonic-gate  * that the operation corresponding to the specified request is done,
53870Sstevel@tonic-gate  * and pass it the error code. Finally, free the taskq_req.
53880Sstevel@tonic-gate  */
53890Sstevel@tonic-gate static void
dprov_op_done(dprov_req_t * taskq_req,int error)53900Sstevel@tonic-gate dprov_op_done(dprov_req_t *taskq_req, int error)
53910Sstevel@tonic-gate {
53920Sstevel@tonic-gate 	/* notify framework that request is completed */
53930Sstevel@tonic-gate 	crypto_op_notification(taskq_req->dr_kcf_req, error);
53940Sstevel@tonic-gate 
53950Sstevel@tonic-gate 	/* free taskq request structure */
53960Sstevel@tonic-gate 	kmem_free(taskq_req, sizeof (dprov_req_t));
53970Sstevel@tonic-gate }
53980Sstevel@tonic-gate 
53990Sstevel@tonic-gate /*
54000Sstevel@tonic-gate  * taskq dispatcher function for digest operations.
54010Sstevel@tonic-gate  */
54020Sstevel@tonic-gate static void
dprov_digest_task(dprov_req_t * taskq_req)54030Sstevel@tonic-gate dprov_digest_task(dprov_req_t *taskq_req)
54040Sstevel@tonic-gate {
54050Sstevel@tonic-gate 	kcf_provider_desc_t *pd;
54060Sstevel@tonic-gate 	dprov_state_t *softc;
54070Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
54080Sstevel@tonic-gate 	int instance;
54090Sstevel@tonic-gate 	int error = CRYPTO_NOT_SUPPORTED;
54100Sstevel@tonic-gate 	crypto_ctx_t *ctx = taskq_req->dr_digest_req.dr_ctx;
54110Sstevel@tonic-gate 	crypto_mechanism_t mech;
54120Sstevel@tonic-gate 
54130Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
54140Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_task: started\n", instance));
54150Sstevel@tonic-gate 
54160Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
54170Sstevel@tonic-gate 
54180Sstevel@tonic-gate 	case DPROV_REQ_DIGEST_INIT:
54190Sstevel@tonic-gate 		/* allocate a dprov-private context */
54200Sstevel@tonic-gate 		if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
54210Sstevel@tonic-gate 		    CRYPTO_SUCCESS)
54220Sstevel@tonic-gate 			break;
54230Sstevel@tonic-gate 
54240Sstevel@tonic-gate 		/* structure assignment */
54250Sstevel@tonic-gate 		mech = *taskq_req->dr_digest_req.dr_mechanism;
54260Sstevel@tonic-gate 
54270Sstevel@tonic-gate 		/* get the software provider for this mechanism */
54280Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(
54290Sstevel@tonic-gate 		    taskq_req->dr_digest_req.dr_mechanism, &pd,
54300Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
54310Sstevel@tonic-gate 			break;
54320Sstevel@tonic-gate 
54330Sstevel@tonic-gate 		/* Use a session id of zero since we use a software provider */
54340Sstevel@tonic-gate 		error = crypto_digest_init_prov(pd, 0, &mech,
54350Sstevel@tonic-gate 		    &DPROV_CTX_SINGLE(ctx), NULL);
54360Sstevel@tonic-gate 
54370Sstevel@tonic-gate 		/* release provider reference */
54380Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
54390Sstevel@tonic-gate 		break;
54400Sstevel@tonic-gate 
54410Sstevel@tonic-gate 	case DPROV_REQ_DIGEST:
54420Sstevel@tonic-gate 		error = crypto_digest_single(DPROV_CTX_SINGLE(ctx),
54430Sstevel@tonic-gate 		    taskq_req->dr_digest_req.dr_data,
54440Sstevel@tonic-gate 		    taskq_req->dr_digest_req.dr_digest, NULL);
54450Sstevel@tonic-gate 
54460Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
54470Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
54480Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
54490Sstevel@tonic-gate 		}
54500Sstevel@tonic-gate 		break;
54510Sstevel@tonic-gate 
54520Sstevel@tonic-gate 	case DPROV_REQ_DIGEST_UPDATE:
54530Sstevel@tonic-gate 		error = crypto_digest_update(DPROV_CTX_SINGLE(ctx),
54540Sstevel@tonic-gate 		    taskq_req->dr_digest_req.dr_data, NULL);
54550Sstevel@tonic-gate 		break;
54560Sstevel@tonic-gate 
54570Sstevel@tonic-gate 	case DPROV_REQ_DIGEST_KEY: {
54580Sstevel@tonic-gate 		crypto_data_t data;
54590Sstevel@tonic-gate 		crypto_key_t key;
54600Sstevel@tonic-gate 		size_t len;
54610Sstevel@tonic-gate 
54620Sstevel@tonic-gate 		mutex_enter(&softc->ds_lock);
54630Sstevel@tonic-gate 		error = dprov_key_value_secret(softc, ctx->cc_session,
54640Sstevel@tonic-gate 		    taskq_req->dr_type, taskq_req->dr_digest_req.dr_key, &key);
54650Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
54660Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
54670Sstevel@tonic-gate 			break;
54680Sstevel@tonic-gate 
54690Sstevel@tonic-gate 		/* key lengths are specified in bits */
54700Sstevel@tonic-gate 		len = CRYPTO_BITS2BYTES(key.ck_length);
54710Sstevel@tonic-gate 		data.cd_format = CRYPTO_DATA_RAW;
54720Sstevel@tonic-gate 		data.cd_offset = 0;
54730Sstevel@tonic-gate 		data.cd_length = len;
54740Sstevel@tonic-gate 		data.cd_raw.iov_base = key.ck_data;
54750Sstevel@tonic-gate 		data.cd_raw.iov_len = len;
54760Sstevel@tonic-gate 		error = crypto_digest_update(DPROV_CTX_SINGLE(ctx),
54770Sstevel@tonic-gate 		    &data, NULL);
54780Sstevel@tonic-gate 		break;
54790Sstevel@tonic-gate 	}
54800Sstevel@tonic-gate 
54810Sstevel@tonic-gate 	case DPROV_REQ_DIGEST_FINAL:
54820Sstevel@tonic-gate 		error = crypto_digest_final(DPROV_CTX_SINGLE(ctx),
54830Sstevel@tonic-gate 		    taskq_req->dr_digest_req.dr_digest, NULL);
54840Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
54850Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
54860Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
54870Sstevel@tonic-gate 		}
54880Sstevel@tonic-gate 		break;
54890Sstevel@tonic-gate 
54900Sstevel@tonic-gate 	case DPROV_REQ_DIGEST_ATOMIC:
54910Sstevel@tonic-gate 		/* structure assignment */
54920Sstevel@tonic-gate 		mech = *taskq_req->dr_digest_req.dr_mechanism;
54930Sstevel@tonic-gate 
54940Sstevel@tonic-gate 		/* get the software provider for this mechanism */
54950Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(
54960Sstevel@tonic-gate 		    taskq_req->dr_digest_req.dr_mechanism, &pd,
54970Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
54980Sstevel@tonic-gate 			break;
54990Sstevel@tonic-gate 
55000Sstevel@tonic-gate 		/* use a session id of zero since we use a software provider */
5501904Smcpowers 		error = crypto_digest_prov(pd, 0, &mech,
55020Sstevel@tonic-gate 		    taskq_req->dr_digest_req.dr_data,
5503904Smcpowers 		    taskq_req->dr_digest_req.dr_digest, NULL);
55040Sstevel@tonic-gate 
55050Sstevel@tonic-gate 		/* release provider reference */
55060Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
55070Sstevel@tonic-gate 
55080Sstevel@tonic-gate 		break;
55090Sstevel@tonic-gate 	}
55100Sstevel@tonic-gate 
55110Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
55120Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_task: end\n", instance));
55130Sstevel@tonic-gate }
55140Sstevel@tonic-gate 
55150Sstevel@tonic-gate /*
55160Sstevel@tonic-gate  * taskq dispatcher function for mac operations.
55170Sstevel@tonic-gate  */
55180Sstevel@tonic-gate static void
dprov_mac_task(dprov_req_t * taskq_req)55190Sstevel@tonic-gate dprov_mac_task(dprov_req_t *taskq_req)
55200Sstevel@tonic-gate {
55210Sstevel@tonic-gate 	kcf_provider_desc_t *pd;
55220Sstevel@tonic-gate 	dprov_state_t *softc;
55230Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
55240Sstevel@tonic-gate 	int instance;
55250Sstevel@tonic-gate 	int error = CRYPTO_NOT_SUPPORTED;
55260Sstevel@tonic-gate 	crypto_ctx_t *ctx = taskq_req->dr_mac_req.dr_ctx;
55270Sstevel@tonic-gate 	crypto_key_t key;
55280Sstevel@tonic-gate 	crypto_mechanism_t mech;
55290Sstevel@tonic-gate 
55300Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
55310Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: started\n", instance));
55320Sstevel@tonic-gate 
55330Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
55340Sstevel@tonic-gate 
55350Sstevel@tonic-gate 	case DPROV_REQ_MAC_INIT:
55360Sstevel@tonic-gate 		/* allocate a dprov-private context */
55370Sstevel@tonic-gate 		if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
55380Sstevel@tonic-gate 		    CRYPTO_SUCCESS)
55390Sstevel@tonic-gate 			break;
55400Sstevel@tonic-gate 
55410Sstevel@tonic-gate 		/* get key value */
55420Sstevel@tonic-gate 		mutex_enter(&softc->ds_lock);
55430Sstevel@tonic-gate 		error = dprov_key_value_secret(softc, ctx->cc_session,
55440Sstevel@tonic-gate 		    taskq_req->dr_type, taskq_req->dr_mac_req.dr_key, &key);
55450Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
55460Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
55470Sstevel@tonic-gate 			break;
55480Sstevel@tonic-gate 
55490Sstevel@tonic-gate 		/* structure assignment */
55500Sstevel@tonic-gate 		mech = *taskq_req->dr_mac_req.dr_mechanism;
55510Sstevel@tonic-gate 
55520Sstevel@tonic-gate 		/* get the software provider for this mechanism */
55530Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(
55540Sstevel@tonic-gate 		    taskq_req->dr_mac_req.dr_mechanism, &pd,
55550Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
55560Sstevel@tonic-gate 			break;
55570Sstevel@tonic-gate 
55580Sstevel@tonic-gate 		/* Use a session id of zero since we use a software provider */
55590Sstevel@tonic-gate 		error = crypto_mac_init_prov(pd, 0, &mech, &key, NULL,
55600Sstevel@tonic-gate 		    &DPROV_CTX_SINGLE(ctx), NULL);
55610Sstevel@tonic-gate 
55620Sstevel@tonic-gate 		/* release provider reference */
55630Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
55640Sstevel@tonic-gate 		break;
55650Sstevel@tonic-gate 
55660Sstevel@tonic-gate 	case DPROV_REQ_MAC:
55670Sstevel@tonic-gate 		error = crypto_mac_single(DPROV_CTX_SINGLE(ctx),
55680Sstevel@tonic-gate 		    taskq_req->dr_mac_req.dr_data,
55690Sstevel@tonic-gate 		    taskq_req->dr_mac_req.dr_mac, NULL);
55700Sstevel@tonic-gate 
55710Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
55720Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
55730Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
55740Sstevel@tonic-gate 		}
55750Sstevel@tonic-gate 		break;
55760Sstevel@tonic-gate 
55770Sstevel@tonic-gate 	case DPROV_REQ_MAC_UPDATE:
55780Sstevel@tonic-gate 		error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
55790Sstevel@tonic-gate 		    taskq_req->dr_mac_req.dr_data, NULL);
55800Sstevel@tonic-gate 		break;
55810Sstevel@tonic-gate 
55820Sstevel@tonic-gate 	case DPROV_REQ_MAC_FINAL:
55830Sstevel@tonic-gate 		error = crypto_mac_final(DPROV_CTX_SINGLE(ctx),
55840Sstevel@tonic-gate 		    taskq_req->dr_mac_req.dr_mac, NULL);
55850Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
55860Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
55870Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
55880Sstevel@tonic-gate 		}
55890Sstevel@tonic-gate 		break;
55900Sstevel@tonic-gate 
55910Sstevel@tonic-gate 	case DPROV_REQ_MAC_ATOMIC:
55920Sstevel@tonic-gate 	case DPROV_REQ_MAC_VERIFY_ATOMIC:
55930Sstevel@tonic-gate 		/* get key value */
55940Sstevel@tonic-gate 		mutex_enter(&softc->ds_lock);
55950Sstevel@tonic-gate 		error = dprov_key_value_secret(softc,
55960Sstevel@tonic-gate 		    taskq_req->dr_mac_req.dr_session_id,
55970Sstevel@tonic-gate 		    taskq_req->dr_type, taskq_req->dr_mac_req.dr_key, &key);
55980Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
55990Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
56000Sstevel@tonic-gate 			break;
56010Sstevel@tonic-gate 
56020Sstevel@tonic-gate 		/* structure assignment */
56030Sstevel@tonic-gate 		mech = *taskq_req->dr_mac_req.dr_mechanism;
56040Sstevel@tonic-gate 
56050Sstevel@tonic-gate 		/* get the software provider for this mechanism */
56060Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(
56070Sstevel@tonic-gate 		    taskq_req->dr_mac_req.dr_mechanism, &pd,
56080Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
56090Sstevel@tonic-gate 			break;
56100Sstevel@tonic-gate 
56110Sstevel@tonic-gate 		/* use a session id of zero since we use a software provider */
56120Sstevel@tonic-gate 		if (taskq_req->dr_type == DPROV_REQ_MAC_ATOMIC)
5613904Smcpowers 			error = crypto_mac_prov(pd, 0, &mech,
56140Sstevel@tonic-gate 			    taskq_req->dr_mac_req.dr_data,
5615904Smcpowers 			    &key, NULL, taskq_req->dr_mac_req.dr_mac, NULL);
56160Sstevel@tonic-gate 		else
5617904Smcpowers 			error = crypto_mac_verify_prov(pd, 0, &mech,
56180Sstevel@tonic-gate 			    taskq_req->dr_mac_req.dr_data,
5619904Smcpowers 			    &key, NULL, taskq_req->dr_mac_req.dr_mac, NULL);
56200Sstevel@tonic-gate 
56210Sstevel@tonic-gate 		/* release provider reference */
56220Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
56230Sstevel@tonic-gate 
56240Sstevel@tonic-gate 		break;
56250Sstevel@tonic-gate 	}
56260Sstevel@tonic-gate 
56270Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
56280Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: end\n", instance));
56290Sstevel@tonic-gate }
56300Sstevel@tonic-gate 
56310Sstevel@tonic-gate /*
56320Sstevel@tonic-gate  * taskq dispatcher function for sign operations.
56330Sstevel@tonic-gate  */
56340Sstevel@tonic-gate static void
dprov_sign_task(dprov_req_t * taskq_req)56350Sstevel@tonic-gate dprov_sign_task(dprov_req_t *taskq_req)
56360Sstevel@tonic-gate {
56370Sstevel@tonic-gate 	kcf_provider_desc_t *pd;
56380Sstevel@tonic-gate 	dprov_state_t *softc;
56390Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
56400Sstevel@tonic-gate 	int instance;
56410Sstevel@tonic-gate 	int error = CRYPTO_NOT_SUPPORTED;
56424072Skrishna 	crypto_ctx_t *ctx = taskq_req->dr_sign_req.sr_ctx;
56430Sstevel@tonic-gate 	crypto_key_t key, *keyp;
56440Sstevel@tonic-gate 	crypto_mechanism_t mech;
56450Sstevel@tonic-gate 
56460Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
56470Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_task: started\n", instance));
56480Sstevel@tonic-gate 
56490Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
56500Sstevel@tonic-gate 
56510Sstevel@tonic-gate 	case DPROV_REQ_SIGN_INIT:
56520Sstevel@tonic-gate 	case DPROV_REQ_SIGN_RECOVER_INIT:
56530Sstevel@tonic-gate 		/* allocate a dprov-private context */
56540Sstevel@tonic-gate 		if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
56550Sstevel@tonic-gate 		    CRYPTO_SUCCESS)
56560Sstevel@tonic-gate 			break;
56570Sstevel@tonic-gate 
56580Sstevel@tonic-gate 		/* structure assignment */
56590Sstevel@tonic-gate 		mech = *taskq_req->dr_sign_req.sr_mechanism;
56604072Skrishna 		if (dprov_valid_mac_mech(mech.cm_type)) {
56614072Skrishna 			DPROV_CTX_P(ctx)->dc_svrfy_to_mac = B_TRUE;
56624072Skrishna 		}
56630Sstevel@tonic-gate 
56640Sstevel@tonic-gate 		mutex_enter(&softc->ds_lock);
56650Sstevel@tonic-gate 		if (is_publickey_mech(mech.cm_type)) {
56660Sstevel@tonic-gate 			if ((error = dprov_key_attr_asymmetric(softc,
56670Sstevel@tonic-gate 			    ctx->cc_session, taskq_req->dr_type,
56680Sstevel@tonic-gate 			    taskq_req->dr_sign_req.sr_key, &key))
56690Sstevel@tonic-gate 			    != CRYPTO_SUCCESS) {
56700Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
56710Sstevel@tonic-gate 				break;
56720Sstevel@tonic-gate 			}
56730Sstevel@tonic-gate 			keyp = &key;
56740Sstevel@tonic-gate 		} else {
56750Sstevel@tonic-gate 			if ((error = dprov_key_value_secret(softc,
56760Sstevel@tonic-gate 			    ctx->cc_session, taskq_req->dr_type,
56770Sstevel@tonic-gate 			    taskq_req->dr_sign_req.sr_key, &key))
56780Sstevel@tonic-gate 			    != CRYPTO_SUCCESS) {
56790Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
56800Sstevel@tonic-gate 				break;
56810Sstevel@tonic-gate 			}
56820Sstevel@tonic-gate 			keyp = &key;
56830Sstevel@tonic-gate 		}
56840Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
56850Sstevel@tonic-gate 
56860Sstevel@tonic-gate 		/* get the software provider for this mechanism */
56870Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(
56880Sstevel@tonic-gate 		    taskq_req->dr_sign_req.sr_mechanism, &pd,
56890Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
56900Sstevel@tonic-gate 			break;
56910Sstevel@tonic-gate 
56924072Skrishna 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
56934072Skrishna 			error = crypto_mac_init_prov(pd, 0, &mech, keyp, NULL,
56944072Skrishna 			    &DPROV_CTX_SINGLE(ctx), NULL);
56954072Skrishna 
56964072Skrishna 			/* release provider reference */
56974072Skrishna 			KCF_PROV_REFRELE(pd);
56984072Skrishna 			break;
56994072Skrishna 		}
57004072Skrishna 
57010Sstevel@tonic-gate 		/* Use a session id of zero since we use a software provider */
57020Sstevel@tonic-gate 		if (taskq_req->dr_type == DPROV_REQ_SIGN_INIT)
57030Sstevel@tonic-gate 			error = crypto_sign_init_prov(pd, 0, &mech, keyp,
57040Sstevel@tonic-gate 			    NULL, &DPROV_CTX_SINGLE(ctx), NULL);
57050Sstevel@tonic-gate 		else
57060Sstevel@tonic-gate 			error = crypto_sign_recover_init_prov(pd, 0, &mech,
57070Sstevel@tonic-gate 			    keyp, NULL, &DPROV_CTX_SINGLE(ctx), NULL);
57080Sstevel@tonic-gate 
57090Sstevel@tonic-gate 		/* release provider reference */
57100Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
57110Sstevel@tonic-gate 
57120Sstevel@tonic-gate 		break;
57130Sstevel@tonic-gate 
57140Sstevel@tonic-gate 	case DPROV_REQ_SIGN:
57154072Skrishna 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
57164072Skrishna 			/* Emulate using update and final */
57174072Skrishna 			error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
57184072Skrishna 			    taskq_req->dr_mac_req.dr_data, NULL);
57194072Skrishna 			if (error == CRYPTO_SUCCESS) {
57204072Skrishna 				error = crypto_mac_final(DPROV_CTX_SINGLE(ctx),
57214072Skrishna 				    taskq_req->dr_mac_req.dr_mac, NULL);
57224072Skrishna 			}
57234072Skrishna 		} else {
57244072Skrishna 			error = crypto_sign_single(DPROV_CTX_SINGLE(ctx),
57254072Skrishna 			    taskq_req->dr_sign_req.sr_data,
57264072Skrishna 			    taskq_req->dr_sign_req.sr_signature, NULL);
57274072Skrishna 		}
57280Sstevel@tonic-gate 
57290Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
57300Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
57310Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
57320Sstevel@tonic-gate 		}
57330Sstevel@tonic-gate 		break;
57340Sstevel@tonic-gate 
57350Sstevel@tonic-gate 	case DPROV_REQ_SIGN_UPDATE:
57364072Skrishna 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
57374072Skrishna 			error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
57384072Skrishna 			    taskq_req->dr_mac_req.dr_data, NULL);
57394072Skrishna 		} else {
57404072Skrishna 			error = crypto_sign_update(DPROV_CTX_SINGLE(ctx),
57414072Skrishna 			    taskq_req->dr_sign_req.sr_data, NULL);
57424072Skrishna 		}
57430Sstevel@tonic-gate 		break;
57440Sstevel@tonic-gate 
57450Sstevel@tonic-gate 	case DPROV_REQ_SIGN_FINAL:
57464072Skrishna 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
57474072Skrishna 			error = crypto_mac_final(DPROV_CTX_SINGLE(ctx),
57484072Skrishna 			    taskq_req->dr_mac_req.dr_mac, NULL);
57494072Skrishna 		} else {
57504072Skrishna 			error = crypto_sign_final(DPROV_CTX_SINGLE(ctx),
57514072Skrishna 			    taskq_req->dr_sign_req.sr_signature, NULL);
57524072Skrishna 		}
57530Sstevel@tonic-gate 
57540Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
57550Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
57560Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
57570Sstevel@tonic-gate 		}
57580Sstevel@tonic-gate 		break;
57590Sstevel@tonic-gate 
57600Sstevel@tonic-gate 	case DPROV_REQ_SIGN_ATOMIC:
57610Sstevel@tonic-gate 	case DPROV_REQ_SIGN_RECOVER_ATOMIC:
57620Sstevel@tonic-gate 		/* structure assignment */
57630Sstevel@tonic-gate 		mech = *taskq_req->dr_sign_req.sr_mechanism;
57640Sstevel@tonic-gate 
57650Sstevel@tonic-gate 		mutex_enter(&softc->ds_lock);
57660Sstevel@tonic-gate 		/* get key value for secret key algorithms */
57670Sstevel@tonic-gate 		if (is_publickey_mech(mech.cm_type)) {
57680Sstevel@tonic-gate 			if ((error = dprov_key_attr_asymmetric(softc,
57690Sstevel@tonic-gate 			    taskq_req->dr_sign_req.sr_session_id,
57700Sstevel@tonic-gate 			    taskq_req->dr_type,
57710Sstevel@tonic-gate 			    taskq_req->dr_sign_req.sr_key, &key))
57720Sstevel@tonic-gate 			    != CRYPTO_SUCCESS) {
57730Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
57740Sstevel@tonic-gate 				break;
57750Sstevel@tonic-gate 			}
57760Sstevel@tonic-gate 			keyp = &key;
57770Sstevel@tonic-gate 		} else {
57780Sstevel@tonic-gate 			if ((error = dprov_key_value_secret(softc,
57790Sstevel@tonic-gate 			    taskq_req->dr_sign_req.sr_session_id,
57800Sstevel@tonic-gate 			    taskq_req->dr_type,
57810Sstevel@tonic-gate 			    taskq_req->dr_sign_req.sr_key, &key))
57820Sstevel@tonic-gate 			    != CRYPTO_SUCCESS) {
57830Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
57840Sstevel@tonic-gate 				break;
57850Sstevel@tonic-gate 			}
57860Sstevel@tonic-gate 			keyp = &key;
57870Sstevel@tonic-gate 		}
57880Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
57890Sstevel@tonic-gate 
57900Sstevel@tonic-gate 		/* get the software provider for this mechanism */
57910Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(
57920Sstevel@tonic-gate 		    taskq_req->dr_sign_req.sr_mechanism, &pd,
57930Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
57940Sstevel@tonic-gate 			break;
57950Sstevel@tonic-gate 
57960Sstevel@tonic-gate 		/* Use a session id of zero since we use a software provider */
57970Sstevel@tonic-gate 		if (taskq_req->dr_type == DPROV_REQ_SIGN_ATOMIC)
57980Sstevel@tonic-gate 			error = crypto_sign_prov(pd, 0, &mech, keyp,
57990Sstevel@tonic-gate 			    taskq_req->dr_sign_req.sr_data,
58000Sstevel@tonic-gate 			    NULL, taskq_req->dr_sign_req.sr_signature, NULL);
58010Sstevel@tonic-gate 		else
58020Sstevel@tonic-gate 			error = crypto_sign_recover_prov(pd, 0, &mech, keyp,
58030Sstevel@tonic-gate 			    taskq_req->dr_sign_req.sr_data,
58040Sstevel@tonic-gate 			    NULL, taskq_req->dr_sign_req.sr_signature, NULL);
58050Sstevel@tonic-gate 
58060Sstevel@tonic-gate 		/* release provider reference */
58070Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
58080Sstevel@tonic-gate 		break;
58090Sstevel@tonic-gate 
58100Sstevel@tonic-gate 	case DPROV_REQ_SIGN_RECOVER:
58110Sstevel@tonic-gate 		error = crypto_sign_recover_single(DPROV_CTX_SINGLE(ctx),
58120Sstevel@tonic-gate 		    taskq_req->dr_sign_req.sr_data,
58130Sstevel@tonic-gate 		    taskq_req->dr_sign_req.sr_signature, NULL);
58140Sstevel@tonic-gate 
58150Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
58160Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
58170Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
58180Sstevel@tonic-gate 		}
58190Sstevel@tonic-gate 		break;
58200Sstevel@tonic-gate 	}
58210Sstevel@tonic-gate 
58220Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
58230Sstevel@tonic-gate 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_task: end\n", instance));
58240Sstevel@tonic-gate }
58250Sstevel@tonic-gate 
58264072Skrishna static int
emulate_verify_with_mac(crypto_ctx_t * ctx,crypto_data_t * in_mac)58274072Skrishna emulate_verify_with_mac(crypto_ctx_t *ctx, crypto_data_t *in_mac)
58284072Skrishna {
58294072Skrishna 	int error;
58304072Skrishna 	crypto_data_t tmpd;
58314072Skrishna 	crypto_data_t *out_mac;
58324072Skrishna 	char digest[SHA512_DIGEST_LENGTH];
58334072Skrishna 
58344072Skrishna 	bzero(&tmpd, sizeof (crypto_data_t));
58354072Skrishna 	tmpd.cd_format = CRYPTO_DATA_RAW;
58364072Skrishna 	tmpd.cd_length = SHA512_DIGEST_LENGTH;
58374072Skrishna 	tmpd.cd_raw.iov_base = digest;
58384072Skrishna 	tmpd.cd_raw.iov_len = SHA512_DIGEST_LENGTH;
58394072Skrishna 	out_mac = &tmpd;
58404072Skrishna 
58414072Skrishna 	error = crypto_mac_final(DPROV_CTX_SINGLE(ctx), out_mac, NULL);
58424072Skrishna 	if (in_mac->cd_length != out_mac->cd_length ||
58434072Skrishna 	    (bcmp(digest, (unsigned char *)in_mac->cd_raw.iov_base +
58444072Skrishna 	    in_mac->cd_offset, out_mac->cd_length) != 0)) {
58454072Skrishna 		error = CRYPTO_INVALID_MAC;
58464072Skrishna 	}
58474072Skrishna 
58484072Skrishna 	return (error);
58494072Skrishna }
58504072Skrishna 
58510Sstevel@tonic-gate /*
58520Sstevel@tonic-gate  * taskq dispatcher function for verify operations.
58530Sstevel@tonic-gate  */
58540Sstevel@tonic-gate static void
dprov_verify_task(dprov_req_t * taskq_req)58550Sstevel@tonic-gate dprov_verify_task(dprov_req_t *taskq_req)
58560Sstevel@tonic-gate {
58570Sstevel@tonic-gate 	kcf_provider_desc_t *pd;
58580Sstevel@tonic-gate 	dprov_state_t *softc;
58590Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
58600Sstevel@tonic-gate 	int instance;
58610Sstevel@tonic-gate 	int error = CRYPTO_NOT_SUPPORTED;
58620Sstevel@tonic-gate 	crypto_ctx_t *ctx = taskq_req->dr_verify_req.vr_ctx;
58630Sstevel@tonic-gate 	crypto_key_t key, *keyp;
58640Sstevel@tonic-gate 	crypto_mechanism_t mech;
58650Sstevel@tonic-gate 
58660Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
58670Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_task: started\n", instance));
58680Sstevel@tonic-gate 
58690Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
58700Sstevel@tonic-gate 
58710Sstevel@tonic-gate 	case DPROV_REQ_VERIFY_INIT:
58720Sstevel@tonic-gate 	case DPROV_REQ_VERIFY_RECOVER_INIT:
58730Sstevel@tonic-gate 		/* allocate a dprov-private context */
58740Sstevel@tonic-gate 		if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
58750Sstevel@tonic-gate 		    CRYPTO_SUCCESS)
58760Sstevel@tonic-gate 			break;
58770Sstevel@tonic-gate 
58780Sstevel@tonic-gate 		/* structure assignment */
58790Sstevel@tonic-gate 		mech = *taskq_req->dr_verify_req.vr_mechanism;
58804072Skrishna 		if (dprov_valid_mac_mech(mech.cm_type)) {
58814072Skrishna 			DPROV_CTX_P(ctx)->dc_svrfy_to_mac = B_TRUE;
58824072Skrishna 		}
58830Sstevel@tonic-gate 
58840Sstevel@tonic-gate 		mutex_enter(&softc->ds_lock);
58850Sstevel@tonic-gate 		/* get key value for secret key algorithms */
58860Sstevel@tonic-gate 		if (is_publickey_mech(mech.cm_type)) {
58870Sstevel@tonic-gate 			if ((error = dprov_key_attr_asymmetric(softc,
58880Sstevel@tonic-gate 			    ctx->cc_session, taskq_req->dr_type,
58890Sstevel@tonic-gate 			    taskq_req->dr_verify_req.vr_key, &key))
58900Sstevel@tonic-gate 			    != CRYPTO_SUCCESS) {
58910Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
58920Sstevel@tonic-gate 				break;
58930Sstevel@tonic-gate 			}
58940Sstevel@tonic-gate 			keyp = &key;
58950Sstevel@tonic-gate 		} else {
58960Sstevel@tonic-gate 			if ((error = dprov_key_value_secret(softc,
58970Sstevel@tonic-gate 			    ctx->cc_session, taskq_req->dr_type,
58980Sstevel@tonic-gate 			    taskq_req->dr_verify_req.vr_key, &key))
58990Sstevel@tonic-gate 			    != CRYPTO_SUCCESS) {
59000Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
59010Sstevel@tonic-gate 				break;
59020Sstevel@tonic-gate 			}
59030Sstevel@tonic-gate 			keyp = &key;
59040Sstevel@tonic-gate 		}
59050Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
59060Sstevel@tonic-gate 
59070Sstevel@tonic-gate 		/* get the software provider for this mechanism */
59080Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(
59090Sstevel@tonic-gate 		    taskq_req->dr_verify_req.vr_mechanism, &pd,
59100Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
59110Sstevel@tonic-gate 			break;
59120Sstevel@tonic-gate 
59134072Skrishna 
59144072Skrishna 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
59154072Skrishna 			error = crypto_mac_init_prov(pd, 0, &mech, keyp, NULL,
59164072Skrishna 			    &DPROV_CTX_SINGLE(ctx), NULL);
59174072Skrishna 
59184072Skrishna 			/* release provider reference */
59194072Skrishna 			KCF_PROV_REFRELE(pd);
59204072Skrishna 			break;
59214072Skrishna 		}
59224072Skrishna 
59230Sstevel@tonic-gate 		/* Use a session id of zero since we use a software provider */
59240Sstevel@tonic-gate 		if (taskq_req->dr_type == DPROV_REQ_VERIFY_INIT)
59250Sstevel@tonic-gate 			error = crypto_verify_init_prov(pd, 0, &mech, keyp,
59260Sstevel@tonic-gate 			    NULL, &DPROV_CTX_SINGLE(ctx), NULL);
59270Sstevel@tonic-gate 		else
59280Sstevel@tonic-gate 			error = crypto_verify_recover_init_prov(pd, 0, &mech,
59290Sstevel@tonic-gate 			    keyp, NULL, &DPROV_CTX_SINGLE(ctx), NULL);
59300Sstevel@tonic-gate 
59310Sstevel@tonic-gate 		/* release provider reference */
59320Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
59330Sstevel@tonic-gate 
59340Sstevel@tonic-gate 		break;
59350Sstevel@tonic-gate 
59360Sstevel@tonic-gate 	case DPROV_REQ_VERIFY:
59374072Skrishna 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
59384072Skrishna 			/* Emulate using update and final */
59394072Skrishna 			error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
59404072Skrishna 			    taskq_req->dr_mac_req.dr_data, NULL);
59414072Skrishna 			if (error == CRYPTO_SUCCESS) {
59424072Skrishna 				error = emulate_verify_with_mac(ctx,
59434072Skrishna 				    taskq_req->dr_mac_req.dr_mac);
59444072Skrishna 			}
59454072Skrishna 		} else {
59464072Skrishna 			error = crypto_verify_single(DPROV_CTX_SINGLE(ctx),
59474072Skrishna 			    taskq_req->dr_verify_req.vr_data,
59484072Skrishna 			    taskq_req->dr_verify_req.vr_signature, NULL);
59494072Skrishna 		}
59500Sstevel@tonic-gate 
59510Sstevel@tonic-gate 		ASSERT(error != CRYPTO_BUFFER_TOO_SMALL);
59520Sstevel@tonic-gate 		DPROV_CTX_SINGLE(ctx) = NULL;
59530Sstevel@tonic-gate 		(void) dprov_free_context(ctx);
59540Sstevel@tonic-gate 		break;
59550Sstevel@tonic-gate 
59560Sstevel@tonic-gate 	case DPROV_REQ_VERIFY_UPDATE:
59574072Skrishna 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
59584072Skrishna 			error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
59594072Skrishna 			    taskq_req->dr_mac_req.dr_data, NULL);
59604072Skrishna 		} else {
59614072Skrishna 			error = crypto_verify_update(DPROV_CTX_SINGLE(ctx),
59624072Skrishna 			    taskq_req->dr_verify_req.vr_data, NULL);
59634072Skrishna 		}
59640Sstevel@tonic-gate 		break;
59650Sstevel@tonic-gate 
59660Sstevel@tonic-gate 	case DPROV_REQ_VERIFY_FINAL:
59674072Skrishna 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
59684072Skrishna 			error = emulate_verify_with_mac(ctx,
59694072Skrishna 			    taskq_req->dr_mac_req.dr_mac);
59704072Skrishna 		} else {
59714072Skrishna 			error = crypto_verify_final(DPROV_CTX_SINGLE(ctx),
59724072Skrishna 			    taskq_req->dr_verify_req.vr_signature, NULL);
59734072Skrishna 		}
59740Sstevel@tonic-gate 
59750Sstevel@tonic-gate 		ASSERT(error != CRYPTO_BUFFER_TOO_SMALL);
59760Sstevel@tonic-gate 		DPROV_CTX_SINGLE(ctx) = NULL;
59770Sstevel@tonic-gate 		(void) dprov_free_context(ctx);
59780Sstevel@tonic-gate 		break;
59790Sstevel@tonic-gate 
59800Sstevel@tonic-gate 	case DPROV_REQ_VERIFY_ATOMIC:
59810Sstevel@tonic-gate 	case DPROV_REQ_VERIFY_RECOVER_ATOMIC:
59820Sstevel@tonic-gate 		/* structure assignment */
59830Sstevel@tonic-gate 		mech = *taskq_req->dr_verify_req.vr_mechanism;
59840Sstevel@tonic-gate 
59850Sstevel@tonic-gate 		mutex_enter(&softc->ds_lock);
59860Sstevel@tonic-gate 		/* get key value for secret key algorithms */
59870Sstevel@tonic-gate 		if (is_publickey_mech(mech.cm_type)) {
59880Sstevel@tonic-gate 			if ((error = dprov_key_attr_asymmetric(softc,
59890Sstevel@tonic-gate 			    taskq_req->dr_verify_req.vr_session_id,
59900Sstevel@tonic-gate 			    taskq_req->dr_type,
59910Sstevel@tonic-gate 			    taskq_req->dr_verify_req.vr_key, &key))
59920Sstevel@tonic-gate 			    != CRYPTO_SUCCESS) {
59930Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
59940Sstevel@tonic-gate 				break;
59950Sstevel@tonic-gate 			}
59960Sstevel@tonic-gate 			keyp = &key;
59970Sstevel@tonic-gate 		} else {
59980Sstevel@tonic-gate 			if ((error = dprov_key_value_secret(softc,
59990Sstevel@tonic-gate 			    taskq_req->dr_verify_req.vr_session_id,
60000Sstevel@tonic-gate 			    taskq_req->dr_type,
60010Sstevel@tonic-gate 			    taskq_req->dr_verify_req.vr_key, &key))
60020Sstevel@tonic-gate 			    != CRYPTO_SUCCESS) {
60030Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
60040Sstevel@tonic-gate 				break;
60050Sstevel@tonic-gate 			}
60060Sstevel@tonic-gate 			keyp = &key;
60070Sstevel@tonic-gate 		}
60080Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
60090Sstevel@tonic-gate 
60100Sstevel@tonic-gate 		/* get the software provider for this mechanism */
60110Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(
60120Sstevel@tonic-gate 		    taskq_req->dr_verify_req.vr_mechanism, &pd,
60130Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
60140Sstevel@tonic-gate 			break;
60150Sstevel@tonic-gate 
60160Sstevel@tonic-gate 		/* Use a session id of zero since we use a software provider */
60170Sstevel@tonic-gate 		if (taskq_req->dr_type == DPROV_REQ_VERIFY_ATOMIC)
60180Sstevel@tonic-gate 			error = crypto_verify_prov(pd, 0, &mech, keyp,
60190Sstevel@tonic-gate 			    taskq_req->dr_verify_req.vr_data,
60200Sstevel@tonic-gate 			    NULL, taskq_req->dr_verify_req.vr_signature, NULL);
60210Sstevel@tonic-gate 		else
60220Sstevel@tonic-gate 			/*
60230Sstevel@tonic-gate 			 * crypto_verify_recover_prov() has different argument
60240Sstevel@tonic-gate 			 * order than crypto_verify_prov().
60250Sstevel@tonic-gate 			 */
60260Sstevel@tonic-gate 			error = crypto_verify_recover_prov(pd, 0, &mech, keyp,
60270Sstevel@tonic-gate 			    taskq_req->dr_verify_req.vr_signature,
60280Sstevel@tonic-gate 			    NULL, taskq_req->dr_verify_req.vr_data, NULL);
60290Sstevel@tonic-gate 
60300Sstevel@tonic-gate 		/* release provider reference */
60310Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
60320Sstevel@tonic-gate 		break;
60330Sstevel@tonic-gate 
60340Sstevel@tonic-gate 	case DPROV_REQ_VERIFY_RECOVER:
60350Sstevel@tonic-gate 		/*
60360Sstevel@tonic-gate 		 * crypto_verify_recover_single() has different argument
60370Sstevel@tonic-gate 		 * order than crypto_verify_single().
60380Sstevel@tonic-gate 		 */
60390Sstevel@tonic-gate 		error = crypto_verify_recover_single(DPROV_CTX_SINGLE(ctx),
60400Sstevel@tonic-gate 		    taskq_req->dr_verify_req.vr_signature,
60410Sstevel@tonic-gate 		    taskq_req->dr_verify_req.vr_data, NULL);
60420Sstevel@tonic-gate 
60430Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
60440Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
60450Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
60460Sstevel@tonic-gate 		}
60470Sstevel@tonic-gate 		break;
60480Sstevel@tonic-gate 	}
60490Sstevel@tonic-gate 
60500Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
60510Sstevel@tonic-gate 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_task: end\n", instance));
60520Sstevel@tonic-gate }
60530Sstevel@tonic-gate 
60540Sstevel@tonic-gate /*
60550Sstevel@tonic-gate  * taskq dispatcher function for dual operations.
60560Sstevel@tonic-gate  */
60570Sstevel@tonic-gate static void
dprov_dual_task(dprov_req_t * taskq_req)60580Sstevel@tonic-gate dprov_dual_task(dprov_req_t *taskq_req)
60590Sstevel@tonic-gate {
60600Sstevel@tonic-gate 	dprov_state_t *softc;
60610Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
60620Sstevel@tonic-gate 	int instance;
60630Sstevel@tonic-gate 	int error = CRYPTO_NOT_SUPPORTED;
60640Sstevel@tonic-gate 	crypto_ctx_t *signverify_ctx = taskq_req->dr_dual_req.dr_signverify_ctx;
60650Sstevel@tonic-gate 	crypto_ctx_t *cipher_ctx = taskq_req->dr_dual_req.dr_cipher_ctx;
60660Sstevel@tonic-gate 
60670Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
60680Sstevel@tonic-gate 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_dual_task: started\n", instance));
60690Sstevel@tonic-gate 
60700Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
60710Sstevel@tonic-gate 
60720Sstevel@tonic-gate 	case DPROV_REQ_DIGEST_ENCRYPT_UPDATE:
60730Sstevel@tonic-gate 		error = crypto_digest_encrypt_update(
60740Sstevel@tonic-gate 		    DPROV_CTX_SINGLE(signverify_ctx),
60750Sstevel@tonic-gate 		    DPROV_CTX_SINGLE(cipher_ctx),
60760Sstevel@tonic-gate 		    taskq_req->dr_dual_req.dr_plaintext,
60770Sstevel@tonic-gate 		    taskq_req->dr_dual_req.dr_ciphertext, NULL);
60780Sstevel@tonic-gate 		break;
60790Sstevel@tonic-gate 
60800Sstevel@tonic-gate 	case DPROV_REQ_DECRYPT_DIGEST_UPDATE:
60810Sstevel@tonic-gate 		error = crypto_decrypt_digest_update(
60820Sstevel@tonic-gate 		    DPROV_CTX_SINGLE(cipher_ctx),
60830Sstevel@tonic-gate 		    DPROV_CTX_SINGLE(signverify_ctx),
60840Sstevel@tonic-gate 		    taskq_req->dr_dual_req.dr_ciphertext,
60850Sstevel@tonic-gate 		    taskq_req->dr_dual_req.dr_plaintext, NULL);
60860Sstevel@tonic-gate 		break;
60870Sstevel@tonic-gate 
60880Sstevel@tonic-gate 	case DPROV_REQ_SIGN_ENCRYPT_UPDATE:
60890Sstevel@tonic-gate 		error = crypto_sign_encrypt_update(
60900Sstevel@tonic-gate 		    DPROV_CTX_SINGLE(signverify_ctx),
60910Sstevel@tonic-gate 		    DPROV_CTX_SINGLE(cipher_ctx),
60920Sstevel@tonic-gate 		    taskq_req->dr_dual_req.dr_plaintext,
60930Sstevel@tonic-gate 		    taskq_req->dr_dual_req.dr_ciphertext, NULL);
60940Sstevel@tonic-gate 		break;
60950Sstevel@tonic-gate 
60960Sstevel@tonic-gate 	case DPROV_REQ_DECRYPT_VERIFY_UPDATE:
60970Sstevel@tonic-gate 		error = crypto_decrypt_verify_update(
60980Sstevel@tonic-gate 		    DPROV_CTX_SINGLE(cipher_ctx),
60990Sstevel@tonic-gate 		    DPROV_CTX_SINGLE(signverify_ctx),
61000Sstevel@tonic-gate 		    taskq_req->dr_dual_req.dr_ciphertext,
61010Sstevel@tonic-gate 		    taskq_req->dr_dual_req.dr_plaintext, NULL);
61020Sstevel@tonic-gate 		break;
61030Sstevel@tonic-gate 	}
61040Sstevel@tonic-gate 
61050Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
61060Sstevel@tonic-gate 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_dual_task: end\n", instance));
61070Sstevel@tonic-gate }
61080Sstevel@tonic-gate 
61090Sstevel@tonic-gate /*
61100Sstevel@tonic-gate  * taskq dispatcher function for cipher operations.
61110Sstevel@tonic-gate  */
61120Sstevel@tonic-gate static void
dprov_cipher_task(dprov_req_t * taskq_req)61130Sstevel@tonic-gate dprov_cipher_task(dprov_req_t *taskq_req)
61140Sstevel@tonic-gate {
61150Sstevel@tonic-gate 	kcf_provider_desc_t *pd;
61160Sstevel@tonic-gate 	dprov_state_t *softc;
61170Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
61180Sstevel@tonic-gate 	int instance;
61190Sstevel@tonic-gate 	int error = CRYPTO_NOT_SUPPORTED;
61200Sstevel@tonic-gate 	crypto_ctx_t *ctx = taskq_req->dr_cipher_req.dr_ctx;
61210Sstevel@tonic-gate 	crypto_key_t key, *keyp;
61220Sstevel@tonic-gate 	crypto_mechanism_t mech;
61230Sstevel@tonic-gate 
61240Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
61250Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_cipher_task: started\n", instance));
61260Sstevel@tonic-gate 
61270Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
61280Sstevel@tonic-gate 
61290Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_INIT:
61300Sstevel@tonic-gate 	case DPROV_REQ_DECRYPT_INIT:
61310Sstevel@tonic-gate 		/* allocate a dprov-private context */
61320Sstevel@tonic-gate 		if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
61330Sstevel@tonic-gate 		    CRYPTO_SUCCESS)
61340Sstevel@tonic-gate 			break;
61350Sstevel@tonic-gate 
61360Sstevel@tonic-gate 		/* structure assignment */
61370Sstevel@tonic-gate 		mech = *taskq_req->dr_cipher_req.dr_mechanism;
61380Sstevel@tonic-gate 
61390Sstevel@tonic-gate 		mutex_enter(&softc->ds_lock);
61400Sstevel@tonic-gate 		/* get key value for secret key algorithms */
61410Sstevel@tonic-gate 		if (is_publickey_mech(mech.cm_type)) {
61420Sstevel@tonic-gate 			if ((error = dprov_key_attr_asymmetric(softc,
61430Sstevel@tonic-gate 			    ctx->cc_session, taskq_req->dr_type,
61440Sstevel@tonic-gate 			    taskq_req->dr_cipher_req.dr_key, &key))
61450Sstevel@tonic-gate 			    != CRYPTO_SUCCESS) {
61460Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
61470Sstevel@tonic-gate 				break;
61480Sstevel@tonic-gate 			}
61490Sstevel@tonic-gate 			keyp = &key;
61500Sstevel@tonic-gate 		} else {
61510Sstevel@tonic-gate 			if ((error = dprov_key_value_secret(softc,
61520Sstevel@tonic-gate 			    ctx->cc_session, taskq_req->dr_type,
61530Sstevel@tonic-gate 			    taskq_req->dr_cipher_req.dr_key, &key))
61540Sstevel@tonic-gate 			    != CRYPTO_SUCCESS) {
61550Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
61560Sstevel@tonic-gate 				break;
61570Sstevel@tonic-gate 			}
61580Sstevel@tonic-gate 			keyp = &key;
61590Sstevel@tonic-gate 		}
61600Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
61610Sstevel@tonic-gate 
61620Sstevel@tonic-gate 		/* get the software provider for this mechanism */
61630Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(
61640Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_mechanism, &pd,
61650Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
61660Sstevel@tonic-gate 			break;
61670Sstevel@tonic-gate 
61680Sstevel@tonic-gate 		/* Use a session id of zero since we use a software provider */
61690Sstevel@tonic-gate 		if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_INIT)
61700Sstevel@tonic-gate 			error = crypto_encrypt_init_prov(pd, 0, &mech, keyp,
61710Sstevel@tonic-gate 			    NULL, &DPROV_CTX_SINGLE(ctx), NULL);
61720Sstevel@tonic-gate 		else
61730Sstevel@tonic-gate 			error = crypto_decrypt_init_prov(pd, 0, &mech, keyp,
61740Sstevel@tonic-gate 			    NULL, &DPROV_CTX_SINGLE(ctx), NULL);
61750Sstevel@tonic-gate 
61763708Skrishna 		if (ctx->cc_flags & CRYPTO_INIT_OPSTATE) {
61773708Skrishna 			crypto_ctx_t *lctx =
61783708Skrishna 			    (crypto_ctx_t *)(DPROV_CTX_SINGLE(ctx));
61793708Skrishna 
61803708Skrishna 			ctx->cc_opstate = lctx->cc_provider_private;
61813708Skrishna 			ctx->cc_flags |= CRYPTO_USE_OPSTATE;
61823708Skrishna 		}
61833708Skrishna 
61840Sstevel@tonic-gate 		/* release provider reference */
61850Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
61860Sstevel@tonic-gate 		break;
61870Sstevel@tonic-gate 
61880Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT:
61890Sstevel@tonic-gate 		error = crypto_encrypt_single(DPROV_CTX_SINGLE(ctx),
61900Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_plaintext,
61910Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_ciphertext, NULL);
61920Sstevel@tonic-gate 
61930Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
61940Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
61950Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
61960Sstevel@tonic-gate 		}
61970Sstevel@tonic-gate 		break;
61980Sstevel@tonic-gate 
61990Sstevel@tonic-gate 	case DPROV_REQ_DECRYPT:
62000Sstevel@tonic-gate 		error = crypto_decrypt_single(DPROV_CTX_SINGLE(ctx),
62010Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_ciphertext,
62020Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_plaintext, NULL);
62030Sstevel@tonic-gate 
62040Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
62050Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
62060Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
62070Sstevel@tonic-gate 		}
62080Sstevel@tonic-gate 		break;
62090Sstevel@tonic-gate 
62100Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_UPDATE:
62113708Skrishna 		ASSERT(!(ctx->cc_flags & CRYPTO_INIT_OPSTATE) ||
62123708Skrishna 		    (ctx->cc_flags & CRYPTO_USE_OPSTATE));
62130Sstevel@tonic-gate 		error = crypto_encrypt_update(DPROV_CTX_SINGLE(ctx),
62140Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_plaintext,
62150Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_ciphertext, NULL);
62160Sstevel@tonic-gate 		break;
62170Sstevel@tonic-gate 
62180Sstevel@tonic-gate 	case DPROV_REQ_DECRYPT_UPDATE:
62193708Skrishna 		ASSERT(!(ctx->cc_flags & CRYPTO_INIT_OPSTATE) ||
62203708Skrishna 		    (ctx->cc_flags & CRYPTO_USE_OPSTATE));
62210Sstevel@tonic-gate 		error = crypto_decrypt_update(DPROV_CTX_SINGLE(ctx),
62220Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_ciphertext,
62230Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_plaintext, NULL);
62240Sstevel@tonic-gate 		break;
62250Sstevel@tonic-gate 
62260Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_FINAL:
62270Sstevel@tonic-gate 		error = crypto_encrypt_final(DPROV_CTX_SINGLE(ctx),
62280Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_ciphertext, NULL);
62290Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
62300Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
62310Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
62320Sstevel@tonic-gate 		}
62330Sstevel@tonic-gate 		break;
62340Sstevel@tonic-gate 
62350Sstevel@tonic-gate 	case DPROV_REQ_DECRYPT_FINAL:
62360Sstevel@tonic-gate 		error = crypto_decrypt_final(DPROV_CTX_SINGLE(ctx),
62370Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_plaintext, NULL);
62380Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
62390Sstevel@tonic-gate 			DPROV_CTX_SINGLE(ctx) = NULL;
62400Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
62410Sstevel@tonic-gate 		}
62420Sstevel@tonic-gate 		break;
62430Sstevel@tonic-gate 
62440Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_ATOMIC:
62450Sstevel@tonic-gate 	case DPROV_REQ_DECRYPT_ATOMIC:
62460Sstevel@tonic-gate 		/* structure assignment */
62470Sstevel@tonic-gate 		mech = *taskq_req->dr_cipher_req.dr_mechanism;
62480Sstevel@tonic-gate 
62490Sstevel@tonic-gate 		mutex_enter(&softc->ds_lock);
62500Sstevel@tonic-gate 		/* get key value for secret key algorithms */
62510Sstevel@tonic-gate 		if (is_publickey_mech(mech.cm_type)) {
62520Sstevel@tonic-gate 			if ((error = dprov_key_attr_asymmetric(softc,
62530Sstevel@tonic-gate 			    taskq_req->dr_cipher_req.dr_session_id,
62540Sstevel@tonic-gate 			    taskq_req->dr_type,
62550Sstevel@tonic-gate 			    taskq_req->dr_cipher_req.dr_key,
62560Sstevel@tonic-gate 			    &key)) != CRYPTO_SUCCESS) {
62570Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
62580Sstevel@tonic-gate 				break;
62590Sstevel@tonic-gate 			}
62600Sstevel@tonic-gate 			keyp = &key;
62610Sstevel@tonic-gate 		} else {
62620Sstevel@tonic-gate 			if ((error = dprov_key_value_secret(softc,
62630Sstevel@tonic-gate 			    taskq_req->dr_cipher_req.dr_session_id,
62640Sstevel@tonic-gate 			    taskq_req->dr_type, taskq_req->dr_cipher_req.dr_key,
62650Sstevel@tonic-gate 			    &key))
62660Sstevel@tonic-gate 			    != CRYPTO_SUCCESS) {
62670Sstevel@tonic-gate 				mutex_exit(&softc->ds_lock);
62680Sstevel@tonic-gate 				break;
62690Sstevel@tonic-gate 			}
62700Sstevel@tonic-gate 			keyp = &key;
62710Sstevel@tonic-gate 		}
62720Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
62730Sstevel@tonic-gate 
62740Sstevel@tonic-gate 		/* get the software provider for this mechanism */
62750Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(
62760Sstevel@tonic-gate 		    taskq_req->dr_cipher_req.dr_mechanism, &pd,
62770Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
62780Sstevel@tonic-gate 			break;
62790Sstevel@tonic-gate 
62800Sstevel@tonic-gate 		/* use a session id of zero since we use a software provider */
62810Sstevel@tonic-gate 		if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_ATOMIC)
6282904Smcpowers 			error = crypto_encrypt_prov(pd, 0, &mech,
62830Sstevel@tonic-gate 			    taskq_req->dr_cipher_req.dr_plaintext,
62840Sstevel@tonic-gate 			    keyp, NULL,
6285904Smcpowers 			    taskq_req->dr_cipher_req.dr_ciphertext, NULL);
62860Sstevel@tonic-gate 		else
6287904Smcpowers 			error = crypto_decrypt_prov(pd, 0, &mech,
62880Sstevel@tonic-gate 			    taskq_req->dr_cipher_req.dr_ciphertext,
62890Sstevel@tonic-gate 			    keyp, NULL,
6290904Smcpowers 			    taskq_req->dr_cipher_req.dr_plaintext, NULL);
62910Sstevel@tonic-gate 
62920Sstevel@tonic-gate 		/* release provider reference */
62930Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
62940Sstevel@tonic-gate 
62950Sstevel@tonic-gate 		break;
62960Sstevel@tonic-gate 	}
62970Sstevel@tonic-gate 
62980Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
62990Sstevel@tonic-gate 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: end\n", instance));
63000Sstevel@tonic-gate }
63010Sstevel@tonic-gate 
63020Sstevel@tonic-gate /*
63030Sstevel@tonic-gate  * Helper function for the cipher/mac dual operation taskq dispatch
63040Sstevel@tonic-gate  * function. Initialize the cipher and mac key values and find the
63050Sstevel@tonic-gate  * providers that can process the request for the specified mechanisms.
63060Sstevel@tonic-gate  */
63070Sstevel@tonic-gate static int
dprov_cipher_mac_key_pd(dprov_state_t * softc,crypto_session_id_t sid,dprov_req_t * taskq_req,crypto_key_t * cipher_key,crypto_key_t * mac_key,kcf_provider_desc_t ** cipher_pd,kcf_provider_desc_t ** mac_pd,crypto_mech_type_t * cipher_mech_type,crypto_mech_type_t * mac_mech_type)63080Sstevel@tonic-gate dprov_cipher_mac_key_pd(dprov_state_t *softc, crypto_session_id_t sid,
63090Sstevel@tonic-gate     dprov_req_t *taskq_req, crypto_key_t *cipher_key, crypto_key_t *mac_key,
63100Sstevel@tonic-gate     kcf_provider_desc_t **cipher_pd, kcf_provider_desc_t **mac_pd,
63110Sstevel@tonic-gate     crypto_mech_type_t *cipher_mech_type, crypto_mech_type_t *mac_mech_type)
63120Sstevel@tonic-gate {
63130Sstevel@tonic-gate 	int error;
63140Sstevel@tonic-gate 
63150Sstevel@tonic-gate 	/* get the cipher key value */
63160Sstevel@tonic-gate 	mutex_enter(&softc->ds_lock);
6317904Smcpowers 	error = dprov_key_value_secret(softc, sid, DPROV_REQ_ENCRYPT_ATOMIC,
63180Sstevel@tonic-gate 	    taskq_req->dr_cipher_mac_req.mr_cipher_key, cipher_key);
63190Sstevel@tonic-gate 	if (error != CRYPTO_SUCCESS) {
63200Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
63210Sstevel@tonic-gate 		return (error);
63220Sstevel@tonic-gate 	}
63230Sstevel@tonic-gate 
63240Sstevel@tonic-gate 	/* get the mac key value */
6325904Smcpowers 	error = dprov_key_value_secret(softc, sid, DPROV_REQ_MAC_ATOMIC,
63260Sstevel@tonic-gate 	    taskq_req->dr_cipher_mac_req.mr_mac_key, mac_key);
63270Sstevel@tonic-gate 	mutex_exit(&softc->ds_lock);
63280Sstevel@tonic-gate 	if (error != CRYPTO_SUCCESS)
63290Sstevel@tonic-gate 		return (error);
63300Sstevel@tonic-gate 
63310Sstevel@tonic-gate 	/* get the SW provider to perform the cipher operation */
63320Sstevel@tonic-gate 	if ((error = dprov_get_sw_prov(
63330Sstevel@tonic-gate 	    taskq_req->dr_cipher_mac_req.mr_cipher_mech, cipher_pd,
63340Sstevel@tonic-gate 	    cipher_mech_type)) != CRYPTO_SUCCESS)
63350Sstevel@tonic-gate 		return (error);
63360Sstevel@tonic-gate 
63370Sstevel@tonic-gate 	/* get the SW provider to perform the mac operation */
63380Sstevel@tonic-gate 	error = dprov_get_sw_prov(taskq_req->dr_cipher_mac_req.mr_mac_mech,
63390Sstevel@tonic-gate 	    mac_pd, mac_mech_type);
63400Sstevel@tonic-gate 
63410Sstevel@tonic-gate 	return (error);
63420Sstevel@tonic-gate }
63430Sstevel@tonic-gate 
63440Sstevel@tonic-gate /*
63450Sstevel@tonic-gate  * taskq dispatcher function for cipher/mac dual operations.
63460Sstevel@tonic-gate  */
63470Sstevel@tonic-gate static void
dprov_cipher_mac_task(dprov_req_t * taskq_req)63480Sstevel@tonic-gate dprov_cipher_mac_task(dprov_req_t *taskq_req)
63490Sstevel@tonic-gate {
63500Sstevel@tonic-gate 	dprov_state_t *softc;
63510Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
63520Sstevel@tonic-gate 	int instance;
63530Sstevel@tonic-gate 	int error = CRYPTO_NOT_SUPPORTED;
63540Sstevel@tonic-gate 	crypto_ctx_t *ctx = taskq_req->dr_cipher_mac_req.mr_ctx;
63550Sstevel@tonic-gate 	kcf_provider_desc_t *cipher_pd;
63560Sstevel@tonic-gate 	kcf_provider_desc_t *mac_pd;
63570Sstevel@tonic-gate 	crypto_key_t cipher_key;
63580Sstevel@tonic-gate 	crypto_key_t mac_key;
63590Sstevel@tonic-gate 	crypto_dual_data_t *dual_data =
63600Sstevel@tonic-gate 	    taskq_req->dr_cipher_mac_req.mr_dual_data;
63610Sstevel@tonic-gate 	crypto_data_t cipher_data;
63620Sstevel@tonic-gate 	crypto_data_t mac_data;
63630Sstevel@tonic-gate 	crypto_mechanism_t cipher_mech, mac_mech;
63640Sstevel@tonic-gate 	crypto_session_id_t session_id;
63650Sstevel@tonic-gate 
63660Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
63670Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_cipher_mac_task: started\n",
63680Sstevel@tonic-gate 	    instance));
63690Sstevel@tonic-gate 
63700Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
63710Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_MAC_INIT:
63720Sstevel@tonic-gate 	case DPROV_REQ_MAC_DECRYPT_INIT:
63730Sstevel@tonic-gate 		/* structure assignment */
63740Sstevel@tonic-gate 		cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech;
63750Sstevel@tonic-gate 		mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech;
63760Sstevel@tonic-gate 
63770Sstevel@tonic-gate 		/* get the keys values and providers to use for operations */
63780Sstevel@tonic-gate 		if ((error = dprov_cipher_mac_key_pd(softc, ctx->cc_session,
63790Sstevel@tonic-gate 		    taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd,
63800Sstevel@tonic-gate 		    &cipher_mech.cm_type, &mac_mech.cm_type)) != CRYPTO_SUCCESS)
63810Sstevel@tonic-gate 			break;
63820Sstevel@tonic-gate 
63830Sstevel@tonic-gate 		/* allocate a dprov-private context */
63840Sstevel@tonic-gate 		if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
63850Sstevel@tonic-gate 		    CRYPTO_SUCCESS)
63860Sstevel@tonic-gate 			break;
63870Sstevel@tonic-gate 
63880Sstevel@tonic-gate 		if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_MAC_INIT)
63890Sstevel@tonic-gate 			/* do the encryption initialization */
63900Sstevel@tonic-gate 			error = crypto_encrypt_init_prov(cipher_pd, 0,
63910Sstevel@tonic-gate 			    &cipher_mech, &cipher_key, NULL,
63920Sstevel@tonic-gate 			    &DPROV_CTX_DUAL_CIPHER(ctx), NULL);
63930Sstevel@tonic-gate 		else
63940Sstevel@tonic-gate 			/* do the decryption initialization */
63950Sstevel@tonic-gate 			error = crypto_decrypt_init_prov(cipher_pd, 0,
63960Sstevel@tonic-gate 			    &cipher_mech, &cipher_key, NULL,
63970Sstevel@tonic-gate 			    &DPROV_CTX_DUAL_CIPHER(ctx), NULL);
63980Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
63990Sstevel@tonic-gate 			break;
64000Sstevel@tonic-gate 
64010Sstevel@tonic-gate 		/* do the mac initialization */
64020Sstevel@tonic-gate 		if ((error = crypto_mac_init_prov(mac_pd, 0,
64030Sstevel@tonic-gate 		    &mac_mech, &mac_key, NULL, &DPROV_CTX_DUAL_MAC(ctx),
64040Sstevel@tonic-gate 		    NULL)) != CRYPTO_SUCCESS)
64050Sstevel@tonic-gate 			break;
64060Sstevel@tonic-gate 
64070Sstevel@tonic-gate 		/* release references to providers */
64080Sstevel@tonic-gate 		KCF_PROV_REFRELE(cipher_pd);
64090Sstevel@tonic-gate 		KCF_PROV_REFRELE(mac_pd);
64100Sstevel@tonic-gate 
64110Sstevel@tonic-gate 		break;
64120Sstevel@tonic-gate 
64130Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_MAC: {
64140Sstevel@tonic-gate 		size_t encrypted;
64150Sstevel@tonic-gate 		boolean_t inplace;
64160Sstevel@tonic-gate 
64170Sstevel@tonic-gate 		crypto_data_t *plaintext_tmp, *ciphertext_tmp;
64180Sstevel@tonic-gate 
64190Sstevel@tonic-gate 		cipher_data = *((crypto_data_t *)dual_data);
64200Sstevel@tonic-gate 
64210Sstevel@tonic-gate 		/* do an encrypt update */
64220Sstevel@tonic-gate 		inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL);
64230Sstevel@tonic-gate 		if (inplace) {
64240Sstevel@tonic-gate 			plaintext_tmp = &cipher_data;
64250Sstevel@tonic-gate 			ciphertext_tmp = NULL;
64260Sstevel@tonic-gate 		} else {
64270Sstevel@tonic-gate 			plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data;
64280Sstevel@tonic-gate 			ciphertext_tmp = &cipher_data;
64290Sstevel@tonic-gate 		}
64300Sstevel@tonic-gate 		if ((error = crypto_encrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
64310Sstevel@tonic-gate 		    plaintext_tmp, ciphertext_tmp, NULL)) != CRYPTO_SUCCESS)
64320Sstevel@tonic-gate 			break;
64330Sstevel@tonic-gate 
64340Sstevel@tonic-gate 		/* do an encrypt final */
64350Sstevel@tonic-gate 		encrypted = cipher_data.cd_length;
64360Sstevel@tonic-gate 
64370Sstevel@tonic-gate 		cipher_data.cd_offset += encrypted;
64380Sstevel@tonic-gate 		cipher_data.cd_length = dual_data->dd_len1 - encrypted;
64390Sstevel@tonic-gate 
64400Sstevel@tonic-gate 		if ((error = crypto_encrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
64410Sstevel@tonic-gate 		    &cipher_data, NULL)) != CRYPTO_SUCCESS)
64420Sstevel@tonic-gate 			break;
64430Sstevel@tonic-gate 
64440Sstevel@tonic-gate 		/*
64450Sstevel@tonic-gate 		 * Do a mac update on the resulting ciphertext, but with no
64460Sstevel@tonic-gate 		 * more bytes than specified by dual_data, and starting at
64470Sstevel@tonic-gate 		 * offset specified by dual_data. For in-place operations,
64480Sstevel@tonic-gate 		 * we use the length specified by the dual_data.
64490Sstevel@tonic-gate 		 */
64500Sstevel@tonic-gate 		mac_data = cipher_data;
64510Sstevel@tonic-gate 		mac_data.cd_offset = dual_data->dd_offset2;
64520Sstevel@tonic-gate 		mac_data.cd_length = dual_data->dd_len2;
64530Sstevel@tonic-gate 		if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
64540Sstevel@tonic-gate 		    &mac_data, NULL)) != CRYPTO_SUCCESS)
64550Sstevel@tonic-gate 			break;
64560Sstevel@tonic-gate 
64570Sstevel@tonic-gate 		/* do a mac final */
64580Sstevel@tonic-gate 		error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
64590Sstevel@tonic-gate 		    taskq_req->dr_cipher_mac_req.mr_mac, NULL);
64600Sstevel@tonic-gate 
64610Sstevel@tonic-gate 		/* Set the total size of the ciphertext, when successful */
64620Sstevel@tonic-gate 		if (error == CRYPTO_SUCCESS)
64630Sstevel@tonic-gate 			dual_data->dd_len1 = encrypted + cipher_data.cd_length;
64640Sstevel@tonic-gate 
64650Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
64660Sstevel@tonic-gate 			DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
64670Sstevel@tonic-gate 			DPROV_CTX_DUAL_MAC(ctx) = NULL;
64680Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
64690Sstevel@tonic-gate 		}
64700Sstevel@tonic-gate 		break;
64710Sstevel@tonic-gate 	}
64720Sstevel@tonic-gate 
64730Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_MAC_UPDATE: {
64740Sstevel@tonic-gate 		crypto_data_t *plaintext_tmp, *ciphertext_tmp;
64750Sstevel@tonic-gate 		size_t encrypted;
64760Sstevel@tonic-gate 		ssize_t maclen;
64770Sstevel@tonic-gate 		boolean_t inplace;
64780Sstevel@tonic-gate 
64790Sstevel@tonic-gate 		cipher_data = *((crypto_data_t *)dual_data);
64800Sstevel@tonic-gate 
64810Sstevel@tonic-gate 		/* do an encrypt update */
64820Sstevel@tonic-gate 		inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL);
64830Sstevel@tonic-gate 		if (inplace) {
64840Sstevel@tonic-gate 			plaintext_tmp = &cipher_data;
64850Sstevel@tonic-gate 			ciphertext_tmp = NULL;
64860Sstevel@tonic-gate 		} else {
64870Sstevel@tonic-gate 			plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data;
64880Sstevel@tonic-gate 			ciphertext_tmp = &cipher_data;
64890Sstevel@tonic-gate 		}
64900Sstevel@tonic-gate 		if ((error = crypto_encrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
64910Sstevel@tonic-gate 		    plaintext_tmp, ciphertext_tmp, NULL)) != CRYPTO_SUCCESS)
64920Sstevel@tonic-gate 			break;
64930Sstevel@tonic-gate 
64940Sstevel@tonic-gate 		encrypted = cipher_data.cd_length;
64950Sstevel@tonic-gate 
64960Sstevel@tonic-gate 		/*
64970Sstevel@tonic-gate 		 * Do a mac update on the resulting ciphertext, but with no
64980Sstevel@tonic-gate 		 * more bytes than specified by dual_data, and starting at
64990Sstevel@tonic-gate 		 * offset specified by dual_data. For in-place operations,
65000Sstevel@tonic-gate 		 * we use the length specified by the dual_data.
65010Sstevel@tonic-gate 		 * There is an edge case, when the encryption step produced
65020Sstevel@tonic-gate 		 * zero bytes in the ciphertext. Only the portion between
65030Sstevel@tonic-gate 		 * offset2 and offset1 is then thrown in the MAC mix.
65040Sstevel@tonic-gate 		 */
65050Sstevel@tonic-gate 		maclen = dual_data->dd_offset1 - dual_data->dd_offset2 +
65060Sstevel@tonic-gate 		    encrypted;
65070Sstevel@tonic-gate 		if (maclen > 0) {
65080Sstevel@tonic-gate 			mac_data = cipher_data;
65090Sstevel@tonic-gate 			mac_data.cd_offset = dual_data->dd_offset2;
65100Sstevel@tonic-gate 			mac_data.cd_length = min(dual_data->dd_len2, maclen);
65110Sstevel@tonic-gate 			if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
65120Sstevel@tonic-gate 			    &mac_data, NULL)) != CRYPTO_SUCCESS)
65130Sstevel@tonic-gate 				break;
65140Sstevel@tonic-gate 		}
65150Sstevel@tonic-gate 		/* Set the total size of the ciphertext, when successful */
65160Sstevel@tonic-gate 		if (error == CRYPTO_SUCCESS)
65170Sstevel@tonic-gate 			dual_data->dd_len1 = encrypted;
65180Sstevel@tonic-gate 
65190Sstevel@tonic-gate 		break;
65200Sstevel@tonic-gate 	}
65210Sstevel@tonic-gate 
65220Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_MAC_FINAL:
65230Sstevel@tonic-gate 		cipher_data = *((crypto_data_t *)dual_data);
65240Sstevel@tonic-gate 
65250Sstevel@tonic-gate 		/* do an encrypt final */
65260Sstevel@tonic-gate 		if ((error = crypto_encrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
65270Sstevel@tonic-gate 		    taskq_req->dr_cipher_mac_req.mr_data == NULL ?
65280Sstevel@tonic-gate 		    &cipher_data : taskq_req->dr_cipher_mac_req.mr_data,
65290Sstevel@tonic-gate 		    NULL)) != CRYPTO_SUCCESS)
65300Sstevel@tonic-gate 			break;
65310Sstevel@tonic-gate 
65320Sstevel@tonic-gate 		/*
65330Sstevel@tonic-gate 		 * If ciphertext length is different from zero, do a mac
65340Sstevel@tonic-gate 		 * update on it. This does not apply to in-place since we
65350Sstevel@tonic-gate 		 * do not allow partial updates, hence no final residual.
65360Sstevel@tonic-gate 		 */
65370Sstevel@tonic-gate 		if (taskq_req->dr_cipher_mac_req.mr_data != NULL &&
65380Sstevel@tonic-gate 		    taskq_req->dr_cipher_mac_req.mr_data->cd_length > 0)
65390Sstevel@tonic-gate 			if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
65400Sstevel@tonic-gate 			    taskq_req->dr_cipher_mac_req.mr_data, NULL)) !=
65410Sstevel@tonic-gate 			    CRYPTO_SUCCESS)
65420Sstevel@tonic-gate 				break;
65430Sstevel@tonic-gate 
65440Sstevel@tonic-gate 		/* do a mac final */
65450Sstevel@tonic-gate 		error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
65460Sstevel@tonic-gate 		    taskq_req->dr_cipher_mac_req.mr_mac, NULL);
65470Sstevel@tonic-gate 
65480Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
65490Sstevel@tonic-gate 			DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
65500Sstevel@tonic-gate 			DPROV_CTX_DUAL_MAC(ctx) = NULL;
65510Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
65520Sstevel@tonic-gate 		}
65530Sstevel@tonic-gate 		break;
65540Sstevel@tonic-gate 
65550Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_MAC_ATOMIC: {
65560Sstevel@tonic-gate 		crypto_data_t *plaintext_tmp, *ciphertext_tmp;
65570Sstevel@tonic-gate 		boolean_t inplace;
65580Sstevel@tonic-gate 
65590Sstevel@tonic-gate 		cipher_data = *((crypto_data_t *)dual_data);
65600Sstevel@tonic-gate 
65610Sstevel@tonic-gate 		/* do an encrypt atomic */
65620Sstevel@tonic-gate 		inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL);
65630Sstevel@tonic-gate 		if (inplace) {
65640Sstevel@tonic-gate 			plaintext_tmp = &cipher_data;
65650Sstevel@tonic-gate 			ciphertext_tmp = NULL;
65660Sstevel@tonic-gate 		} else {
65670Sstevel@tonic-gate 			plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data;
65680Sstevel@tonic-gate 			ciphertext_tmp = &cipher_data;
65690Sstevel@tonic-gate 		}
65700Sstevel@tonic-gate 
65710Sstevel@tonic-gate 		/* structure assignment */
65720Sstevel@tonic-gate 		cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech;
65730Sstevel@tonic-gate 		mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech;
65740Sstevel@tonic-gate 		session_id = taskq_req->dr_cipher_mac_req.mr_session_id;
65750Sstevel@tonic-gate 
65760Sstevel@tonic-gate 		/* get the keys values and providers to use for operations */
65770Sstevel@tonic-gate 		if ((error = dprov_cipher_mac_key_pd(softc, session_id,
65780Sstevel@tonic-gate 		    taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd,
65790Sstevel@tonic-gate 		    &cipher_mech.cm_type, &mac_mech.cm_type)) !=
65800Sstevel@tonic-gate 		    CRYPTO_SUCCESS)
65810Sstevel@tonic-gate 			break;
65820Sstevel@tonic-gate 
65830Sstevel@tonic-gate 		/* do the atomic encrypt */
6584904Smcpowers 		if ((error = crypto_encrypt_prov(cipher_pd, 0,
65850Sstevel@tonic-gate 		    &cipher_mech, plaintext_tmp, &cipher_key, NULL,
6586904Smcpowers 		    ciphertext_tmp, NULL)) != CRYPTO_SUCCESS)
65870Sstevel@tonic-gate 			break;
65880Sstevel@tonic-gate 
65890Sstevel@tonic-gate 		/* do the atomic mac */
65900Sstevel@tonic-gate 		mac_data = cipher_data;
65910Sstevel@tonic-gate 		mac_data.cd_length = dual_data->dd_len2;
65920Sstevel@tonic-gate 		mac_data.cd_offset = dual_data->dd_offset2;
6593904Smcpowers 		error = crypto_mac_prov(mac_pd, 0, &mac_mech, &mac_data,
6594904Smcpowers 		    &mac_key, NULL, taskq_req->dr_cipher_mac_req.mr_mac, NULL);
65950Sstevel@tonic-gate 
65960Sstevel@tonic-gate 		dual_data->dd_len1 = cipher_data.cd_length;
65970Sstevel@tonic-gate 
65980Sstevel@tonic-gate 		break;
65990Sstevel@tonic-gate 	}
66000Sstevel@tonic-gate 
66010Sstevel@tonic-gate 	case DPROV_REQ_MAC_DECRYPT: {
66020Sstevel@tonic-gate 		uint_t decrypted;
66030Sstevel@tonic-gate 		crypto_data_t plaintext_tmp;
66040Sstevel@tonic-gate 
66050Sstevel@tonic-gate 		cipher_data = *((crypto_data_t *)dual_data);
66060Sstevel@tonic-gate 
66070Sstevel@tonic-gate 		/* do a mac update and final on the ciphertext */
66080Sstevel@tonic-gate 		if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
66090Sstevel@tonic-gate 		    &mac_data, NULL)) != CRYPTO_SUCCESS)
66100Sstevel@tonic-gate 			break;
66110Sstevel@tonic-gate 
66120Sstevel@tonic-gate 		/* do a mac final */
66130Sstevel@tonic-gate 		if ((error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
66140Sstevel@tonic-gate 		    taskq_req->dr_cipher_mac_req.mr_mac, NULL)) !=
66150Sstevel@tonic-gate 		    CRYPTO_SUCCESS)
66160Sstevel@tonic-gate 			break;
66170Sstevel@tonic-gate 
66180Sstevel@tonic-gate 		/* do an decrypt update */
66190Sstevel@tonic-gate 		cipher_data = mac_data;
66200Sstevel@tonic-gate 		cipher_data.cd_length = dual_data->dd_len2;
66210Sstevel@tonic-gate 		cipher_data.cd_offset = dual_data->dd_offset2;
66220Sstevel@tonic-gate 		if (taskq_req->dr_cipher_mac_req.mr_data == NULL)
66230Sstevel@tonic-gate 			/* in-place */
66240Sstevel@tonic-gate 			plaintext_tmp = cipher_data;
66250Sstevel@tonic-gate 		else
66260Sstevel@tonic-gate 			plaintext_tmp = *taskq_req->dr_cipher_mac_req.mr_data;
66270Sstevel@tonic-gate 
66280Sstevel@tonic-gate 		if ((error = crypto_decrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
66290Sstevel@tonic-gate 		    &cipher_data, taskq_req->dr_cipher_mac_req.mr_data,
66300Sstevel@tonic-gate 		    NULL)) != CRYPTO_SUCCESS)
66310Sstevel@tonic-gate 			break;
66320Sstevel@tonic-gate 
66330Sstevel@tonic-gate 		/* do an decrypt final */
66340Sstevel@tonic-gate 		if (taskq_req->dr_cipher_mac_req.mr_data == NULL)
66350Sstevel@tonic-gate 			/* in-place, everything must have been decrypted */
66360Sstevel@tonic-gate 			decrypted = cipher_data.cd_length;
66370Sstevel@tonic-gate 		else
66380Sstevel@tonic-gate 			decrypted =
66390Sstevel@tonic-gate 			    taskq_req->dr_cipher_mac_req.mr_data->cd_length;
66400Sstevel@tonic-gate 		plaintext_tmp.cd_offset += decrypted;
66410Sstevel@tonic-gate 		plaintext_tmp.cd_length -= decrypted;
66420Sstevel@tonic-gate 
66430Sstevel@tonic-gate 		error = crypto_decrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
66440Sstevel@tonic-gate 		    &plaintext_tmp, NULL);
66450Sstevel@tonic-gate 		if (taskq_req->dr_cipher_mac_req.mr_data != NULL)
66460Sstevel@tonic-gate 			taskq_req->dr_cipher_mac_req.mr_data->cd_length +=
66470Sstevel@tonic-gate 			    plaintext_tmp.cd_length;
66480Sstevel@tonic-gate 
66490Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
66500Sstevel@tonic-gate 			DPROV_CTX_DUAL_MAC(ctx) = NULL;
66510Sstevel@tonic-gate 			DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
66520Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
66530Sstevel@tonic-gate 		}
66540Sstevel@tonic-gate 		break;
66550Sstevel@tonic-gate 	}
66560Sstevel@tonic-gate 
66570Sstevel@tonic-gate 	case DPROV_REQ_MAC_DECRYPT_UPDATE:
66580Sstevel@tonic-gate 		cipher_data = *((crypto_data_t *)dual_data);
66590Sstevel@tonic-gate 
66600Sstevel@tonic-gate 		/* do mac update */
66610Sstevel@tonic-gate 		if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
66620Sstevel@tonic-gate 		    &cipher_data, NULL)) != CRYPTO_SUCCESS)
66630Sstevel@tonic-gate 			break;
66640Sstevel@tonic-gate 
66650Sstevel@tonic-gate 		/* do a decrypt update */
66660Sstevel@tonic-gate 		cipher_data.cd_length = dual_data->dd_len2;
66670Sstevel@tonic-gate 		cipher_data.cd_offset = dual_data->dd_offset2;
66680Sstevel@tonic-gate 		error = crypto_decrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
66690Sstevel@tonic-gate 		    &cipher_data, taskq_req->dr_cipher_mac_req.mr_data, NULL);
66700Sstevel@tonic-gate 
66710Sstevel@tonic-gate 		break;
66720Sstevel@tonic-gate 
66730Sstevel@tonic-gate 	case DPROV_REQ_MAC_DECRYPT_FINAL:
66740Sstevel@tonic-gate 		/* do a mac final */
66750Sstevel@tonic-gate 		if ((error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
66760Sstevel@tonic-gate 		    taskq_req->dr_cipher_mac_req.mr_mac, NULL)) !=
66770Sstevel@tonic-gate 		    CRYPTO_SUCCESS)
66780Sstevel@tonic-gate 			break;
66790Sstevel@tonic-gate 
66800Sstevel@tonic-gate 		/* do a decrypt final */
66810Sstevel@tonic-gate 		error = crypto_decrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
66820Sstevel@tonic-gate 		    taskq_req->dr_cipher_mac_req.mr_data, NULL);
66830Sstevel@tonic-gate 
66840Sstevel@tonic-gate 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
66850Sstevel@tonic-gate 			DPROV_CTX_DUAL_MAC(ctx) = NULL;
66860Sstevel@tonic-gate 			DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
66870Sstevel@tonic-gate 			(void) dprov_free_context(ctx);
66880Sstevel@tonic-gate 		}
66890Sstevel@tonic-gate 		break;
66900Sstevel@tonic-gate 
66910Sstevel@tonic-gate 	case DPROV_REQ_MAC_DECRYPT_ATOMIC:
66920Sstevel@tonic-gate 	case DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC:
66930Sstevel@tonic-gate 		cipher_data = *((crypto_data_t *)dual_data);
66940Sstevel@tonic-gate 
66950Sstevel@tonic-gate 		/* structure assignment */
66960Sstevel@tonic-gate 		cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech;
66970Sstevel@tonic-gate 		mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech;
66980Sstevel@tonic-gate 		session_id = taskq_req->dr_cipher_mac_req.mr_session_id;
66990Sstevel@tonic-gate 
67000Sstevel@tonic-gate 		/* get the keys values and providers to use for operations */
67010Sstevel@tonic-gate 		if ((error = dprov_cipher_mac_key_pd(softc, session_id,
67020Sstevel@tonic-gate 		    taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd,
67030Sstevel@tonic-gate 		    &cipher_mech.cm_type, &mac_mech.cm_type)) != CRYPTO_SUCCESS)
67040Sstevel@tonic-gate 			break;
67050Sstevel@tonic-gate 
67060Sstevel@tonic-gate 		/* do the atomic mac */
67070Sstevel@tonic-gate 		if (taskq_req->dr_type == DPROV_REQ_MAC_DECRYPT_ATOMIC)
6708904Smcpowers 			error = crypto_mac_prov(mac_pd, 0, &mac_mech,
6709904Smcpowers 			    &cipher_data, &mac_key, NULL,
6710904Smcpowers 			    taskq_req->dr_cipher_mac_req.mr_mac, NULL);
67110Sstevel@tonic-gate 		else
67120Sstevel@tonic-gate 			/* DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC */
6713904Smcpowers 			error = crypto_mac_verify_prov(mac_pd, 0, &mac_mech,
6714904Smcpowers 			    &cipher_data, &mac_key, NULL,
6715904Smcpowers 			    taskq_req->dr_cipher_mac_req.mr_mac, NULL);
67160Sstevel@tonic-gate 
67170Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
67180Sstevel@tonic-gate 			break;
67190Sstevel@tonic-gate 
67200Sstevel@tonic-gate 		/* do the atomic decrypt */
67210Sstevel@tonic-gate 		cipher_data.cd_length = dual_data->dd_len2;
67220Sstevel@tonic-gate 		cipher_data.cd_offset = dual_data->dd_offset2;
6723904Smcpowers 		error = crypto_decrypt_prov(cipher_pd, 0, &cipher_mech,
6724904Smcpowers 		    &cipher_data, &cipher_key, NULL,
6725904Smcpowers 		    taskq_req->dr_cipher_mac_req.mr_data, NULL);
67260Sstevel@tonic-gate 
67270Sstevel@tonic-gate 		break;
67280Sstevel@tonic-gate 	}
67290Sstevel@tonic-gate 
67300Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
67310Sstevel@tonic-gate 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_cipher_mac_task: end\n",
67320Sstevel@tonic-gate 	    instance));
67330Sstevel@tonic-gate }
67340Sstevel@tonic-gate 
67350Sstevel@tonic-gate /*
67360Sstevel@tonic-gate  * taskq dispatcher function for random number generation.
67370Sstevel@tonic-gate  */
67380Sstevel@tonic-gate static void
dprov_random_task(dprov_req_t * taskq_req)67390Sstevel@tonic-gate dprov_random_task(dprov_req_t *taskq_req)
67400Sstevel@tonic-gate {
67410Sstevel@tonic-gate 	dprov_state_t *softc;
67420Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
67430Sstevel@tonic-gate 	int instance;
67440Sstevel@tonic-gate 	int error = CRYPTO_SUCCESS;
67450Sstevel@tonic-gate 
67460Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
67470Sstevel@tonic-gate 	DPROV_DEBUG(D_RANDOM, ("(%d) dprov_random_task: started\n", instance));
67480Sstevel@tonic-gate 
67490Sstevel@tonic-gate 	mutex_enter(&softc->ds_lock);
67500Sstevel@tonic-gate 
67510Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
67520Sstevel@tonic-gate 
67530Sstevel@tonic-gate 	DPROV_REQ_RANDOM_SEED:
67540Sstevel@tonic-gate 		/*
67550Sstevel@tonic-gate 		 * Since we don't really generate random numbers
67560Sstevel@tonic-gate 		 * nothing to do.
67570Sstevel@tonic-gate 		 */
67580Sstevel@tonic-gate 		break;
67590Sstevel@tonic-gate 
67600Sstevel@tonic-gate 	case DPROV_REQ_RANDOM_GENERATE: {
67610Sstevel@tonic-gate 		uint_t i;
67620Sstevel@tonic-gate 		uchar_t c = 0;
67630Sstevel@tonic-gate 
67640Sstevel@tonic-gate 		/*
67650Sstevel@tonic-gate 		 * We don't generate random numbers so that the result
67660Sstevel@tonic-gate 		 * of the operation can be checked during testing.
67670Sstevel@tonic-gate 		 */
67680Sstevel@tonic-gate 
67690Sstevel@tonic-gate 		for (i = 0; i < taskq_req->dr_random_req.rr_len; i++)
67700Sstevel@tonic-gate 			taskq_req->dr_random_req.rr_buf[i] = c++;
67710Sstevel@tonic-gate 
67720Sstevel@tonic-gate 		break;
67730Sstevel@tonic-gate 	}
67740Sstevel@tonic-gate 	}
67750Sstevel@tonic-gate 
67760Sstevel@tonic-gate 	mutex_exit(&softc->ds_lock);
67770Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
67780Sstevel@tonic-gate 	DPROV_DEBUG(D_RANDOM, ("(%d) dprov_random_task: end\n", instance));
67790Sstevel@tonic-gate }
67800Sstevel@tonic-gate 
67810Sstevel@tonic-gate 
67820Sstevel@tonic-gate /*
67830Sstevel@tonic-gate  * taskq dispatcher function for session management operations.
67840Sstevel@tonic-gate  */
67850Sstevel@tonic-gate static void
dprov_session_task(dprov_req_t * taskq_req)67860Sstevel@tonic-gate dprov_session_task(dprov_req_t *taskq_req)
67870Sstevel@tonic-gate {
67880Sstevel@tonic-gate 	dprov_state_t *softc;
67890Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
67900Sstevel@tonic-gate 	int instance;
67910Sstevel@tonic-gate 	int error = CRYPTO_NOT_SUPPORTED;
67920Sstevel@tonic-gate 	crypto_session_id_t session_id =
67930Sstevel@tonic-gate 	    taskq_req->dr_session_req.sr_session_id;
67940Sstevel@tonic-gate 	dprov_session_t *session;
67950Sstevel@tonic-gate 	dprov_object_t *object;
67960Sstevel@tonic-gate 	int i;
67970Sstevel@tonic-gate 
67980Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
67990Sstevel@tonic-gate 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_task: started\n",
68000Sstevel@tonic-gate 	    instance));
68010Sstevel@tonic-gate 
68020Sstevel@tonic-gate 	mutex_enter(&softc->ds_lock);
68030Sstevel@tonic-gate 
68040Sstevel@tonic-gate 	if (taskq_req->dr_type != DPROV_REQ_SESSION_OPEN)
68050Sstevel@tonic-gate 		/* validate session id and get ptr to session */
68060Sstevel@tonic-gate 		if ((session = softc->ds_sessions[session_id]) == NULL) {
68070Sstevel@tonic-gate 			mutex_exit(&softc->ds_lock);
68080Sstevel@tonic-gate 			dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID);
68090Sstevel@tonic-gate 			return;
68100Sstevel@tonic-gate 		}
68110Sstevel@tonic-gate 
68120Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
68130Sstevel@tonic-gate 
68140Sstevel@tonic-gate 	case DPROV_REQ_SESSION_OPEN: {
68150Sstevel@tonic-gate 		dprov_session_t **new_sessions;
68160Sstevel@tonic-gate 
68170Sstevel@tonic-gate 		if (softc->ds_token_initialized == B_FALSE) {
68180Sstevel@tonic-gate 			error = CRYPTO_OPERATION_NOT_INITIALIZED;
68190Sstevel@tonic-gate 			break;
68200Sstevel@tonic-gate 		}
68210Sstevel@tonic-gate 
68220Sstevel@tonic-gate 		/* search for available session slot */
68230Sstevel@tonic-gate 		for (i = 0; i < softc->ds_sessions_slots; i++)
68240Sstevel@tonic-gate 			if (softc->ds_sessions[i] == NULL)
68250Sstevel@tonic-gate 				break;
68260Sstevel@tonic-gate 
68270Sstevel@tonic-gate 		if (i == softc->ds_sessions_slots) {
68280Sstevel@tonic-gate 			/* ran out of slots, grow sessions array */
68297357SBhargava.Yenduri@Sun.COM 			new_sessions = kmem_zalloc(
68307357SBhargava.Yenduri@Sun.COM 			    2 * softc->ds_sessions_slots *
68317357SBhargava.Yenduri@Sun.COM 			    sizeof (dprov_session_t *), KM_NOSLEEP);
68320Sstevel@tonic-gate 			if (new_sessions == NULL) {
68330Sstevel@tonic-gate 				error = CRYPTO_SESSION_COUNT;
68340Sstevel@tonic-gate 				break;
68350Sstevel@tonic-gate 			}
68360Sstevel@tonic-gate 			bcopy(softc->ds_sessions, new_sessions,
68377357SBhargava.Yenduri@Sun.COM 			    softc->ds_sessions_slots *
68387357SBhargava.Yenduri@Sun.COM 			    sizeof (dprov_session_t *));
68390Sstevel@tonic-gate 			kmem_free(softc->ds_sessions, softc->ds_sessions_slots *
68400Sstevel@tonic-gate 			    sizeof (dprov_session_t *));
68410Sstevel@tonic-gate 			softc->ds_sessions = new_sessions;
68420Sstevel@tonic-gate 			softc->ds_sessions_slots *= 2;
68430Sstevel@tonic-gate 		}
68440Sstevel@tonic-gate 
68450Sstevel@tonic-gate 		/* allocate and initialize new session */
68460Sstevel@tonic-gate 		softc->ds_sessions[i] = kmem_zalloc(
68470Sstevel@tonic-gate 		    sizeof (dprov_session_t), KM_NOSLEEP);
68480Sstevel@tonic-gate 		if (softc->ds_sessions[i] == NULL) {
68490Sstevel@tonic-gate 			error = CRYPTO_HOST_MEMORY;
68500Sstevel@tonic-gate 			break;
68510Sstevel@tonic-gate 		}
68520Sstevel@tonic-gate 		softc->ds_sessions_count++;
68530Sstevel@tonic-gate 
68540Sstevel@tonic-gate 		/* initialize session state */
68550Sstevel@tonic-gate 		softc->ds_sessions[i]->ds_state = DPROV_SESSION_STATE_PUBLIC;
68560Sstevel@tonic-gate 
68570Sstevel@tonic-gate 		/* return new session id to caller */
68580Sstevel@tonic-gate 		*(taskq_req->dr_session_req.sr_session_id_ptr) = i;
68590Sstevel@tonic-gate 
68600Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
68610Sstevel@tonic-gate 		break;
68620Sstevel@tonic-gate 	}
68630Sstevel@tonic-gate 
68640Sstevel@tonic-gate 	case DPROV_REQ_SESSION_CLOSE:
68650Sstevel@tonic-gate 		softc->ds_sessions[session_id] = NULL;
68660Sstevel@tonic-gate 
68670Sstevel@tonic-gate 		if (softc->ds_token_initialized == B_FALSE) {
68680Sstevel@tonic-gate 			error = CRYPTO_OPERATION_NOT_INITIALIZED;
68690Sstevel@tonic-gate 			break;
68700Sstevel@tonic-gate 		}
68710Sstevel@tonic-gate 
68720Sstevel@tonic-gate 		dprov_release_session_objects(session);
68730Sstevel@tonic-gate 
68740Sstevel@tonic-gate 		/* free session state and corresponding slot */
68750Sstevel@tonic-gate 		kmem_free(session, sizeof (dprov_session_t));
68760Sstevel@tonic-gate 		softc->ds_sessions_count--;
68770Sstevel@tonic-gate 
68780Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
68790Sstevel@tonic-gate 		break;
68800Sstevel@tonic-gate 
68810Sstevel@tonic-gate 	case DPROV_REQ_SESSION_LOGIN: {
68820Sstevel@tonic-gate 		char *pin = taskq_req->dr_session_req.sr_pin;
68830Sstevel@tonic-gate 		size_t pin_len = taskq_req->dr_session_req.sr_pin_len;
68840Sstevel@tonic-gate 		crypto_user_type_t user_type =
68850Sstevel@tonic-gate 		    taskq_req->dr_session_req.sr_user_type;
68860Sstevel@tonic-gate 
68870Sstevel@tonic-gate 		/* check user type */
68880Sstevel@tonic-gate 		if (user_type != CRYPTO_SO && user_type != CRYPTO_USER) {
68890Sstevel@tonic-gate 			error = CRYPTO_USER_TYPE_INVALID;
68900Sstevel@tonic-gate 			break;
68910Sstevel@tonic-gate 		}
68920Sstevel@tonic-gate 
68930Sstevel@tonic-gate 		/* check pin length */
68940Sstevel@tonic-gate 		if (pin_len > DPROV_MAX_PIN_LEN) {
68950Sstevel@tonic-gate 			error = CRYPTO_PIN_LEN_RANGE;
68960Sstevel@tonic-gate 			break;
68970Sstevel@tonic-gate 		}
68980Sstevel@tonic-gate 
68990Sstevel@tonic-gate 		/* check pin */
69000Sstevel@tonic-gate 		if (pin == NULL) {
69010Sstevel@tonic-gate 			error = CRYPTO_PIN_INVALID;
69020Sstevel@tonic-gate 			break;
69030Sstevel@tonic-gate 		}
69040Sstevel@tonic-gate 
69050Sstevel@tonic-gate 		/* validate PIN state */
69060Sstevel@tonic-gate 		if ((user_type == CRYPTO_SO) && !softc->ds_token_initialized ||
69070Sstevel@tonic-gate 		    (user_type == CRYPTO_USER) && !softc->ds_user_pin_set) {
69080Sstevel@tonic-gate 			error = CRYPTO_USER_PIN_NOT_INITIALIZED;
69090Sstevel@tonic-gate 			break;
69100Sstevel@tonic-gate 		}
69110Sstevel@tonic-gate 
69120Sstevel@tonic-gate 		if ((user_type == CRYPTO_SO &&
69130Sstevel@tonic-gate 		    softc->ds_sessions[session_id]->ds_state ==
69140Sstevel@tonic-gate 		    DPROV_SESSION_STATE_SO) ||
69150Sstevel@tonic-gate 		    (user_type == CRYPTO_USER &&
69160Sstevel@tonic-gate 		    softc->ds_sessions[session_id]->ds_state ==
69170Sstevel@tonic-gate 		    DPROV_SESSION_STATE_USER)) {
69180Sstevel@tonic-gate 			/* SO or user already logged in */
69190Sstevel@tonic-gate 			error = CRYPTO_USER_ALREADY_LOGGED_IN;
69200Sstevel@tonic-gate 			break;
69210Sstevel@tonic-gate 		}
69220Sstevel@tonic-gate 
69230Sstevel@tonic-gate 		if (softc->ds_sessions[session_id]->ds_state !=
69240Sstevel@tonic-gate 		    DPROV_SESSION_STATE_PUBLIC) {
69250Sstevel@tonic-gate 			/* another user already logged in */
69260Sstevel@tonic-gate 			error = CRYPTO_USER_ANOTHER_ALREADY_LOGGED_IN;
69270Sstevel@tonic-gate 			break;
69280Sstevel@tonic-gate 		}
69290Sstevel@tonic-gate 
69300Sstevel@tonic-gate 		/* everything's fine, update session */
69310Sstevel@tonic-gate 		softc->ds_sessions[session_id]->ds_state =
69320Sstevel@tonic-gate 		    user_type == CRYPTO_SO ?
69330Sstevel@tonic-gate 		    DPROV_SESSION_STATE_SO : DPROV_SESSION_STATE_USER;
69340Sstevel@tonic-gate 
69350Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
69360Sstevel@tonic-gate 		break;
69370Sstevel@tonic-gate 	}
69380Sstevel@tonic-gate 
69390Sstevel@tonic-gate 	case DPROV_REQ_SESSION_LOGOUT:
69400Sstevel@tonic-gate 		/* fail if not logged in */
69410Sstevel@tonic-gate 		if (softc->ds_sessions[session_id]->ds_state ==
69420Sstevel@tonic-gate 		    DPROV_SESSION_STATE_PUBLIC) {
69430Sstevel@tonic-gate 			error = CRYPTO_USER_NOT_LOGGED_IN;
69440Sstevel@tonic-gate 			break;
69450Sstevel@tonic-gate 		}
69460Sstevel@tonic-gate 
69470Sstevel@tonic-gate 		/*
69480Sstevel@tonic-gate 		 * Destroy all private session objects.
69490Sstevel@tonic-gate 		 * Invalidate handles to all private objects.
69500Sstevel@tonic-gate 		 */
69510Sstevel@tonic-gate 		for (i = 0; i < DPROV_MAX_OBJECTS; i++) {
69520Sstevel@tonic-gate 			object = softc->ds_sessions[session_id]->ds_objects[i];
69530Sstevel@tonic-gate 			if (object != NULL && dprov_object_is_private(object)) {
69540Sstevel@tonic-gate 				if (!dprov_object_is_token(object))
69550Sstevel@tonic-gate 					/* It's a session object, free it */
69560Sstevel@tonic-gate 					DPROV_OBJECT_REFRELE(object);
69570Sstevel@tonic-gate 				softc->ds_sessions[session_id]->ds_objects[i] =
69580Sstevel@tonic-gate 				    NULL;
69590Sstevel@tonic-gate 			}
69600Sstevel@tonic-gate 		}
69610Sstevel@tonic-gate 
69620Sstevel@tonic-gate 		/* update session state */
69630Sstevel@tonic-gate 		softc->ds_sessions[session_id]->ds_state =
69640Sstevel@tonic-gate 		    DPROV_SESSION_STATE_PUBLIC;
69650Sstevel@tonic-gate 
69660Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
69670Sstevel@tonic-gate 		break;
69680Sstevel@tonic-gate 	}
69690Sstevel@tonic-gate 
69700Sstevel@tonic-gate 	mutex_exit(&softc->ds_lock);
69710Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
69720Sstevel@tonic-gate 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_task: end\n", instance));
69730Sstevel@tonic-gate }
69740Sstevel@tonic-gate 
6975904Smcpowers /* return true if attribute is defined to be a PKCS#11 long */
6976904Smcpowers static boolean_t
fixed_size_attribute(crypto_attr_type_t type)6977904Smcpowers fixed_size_attribute(crypto_attr_type_t type)
6978904Smcpowers {
6979904Smcpowers 	return (type == DPROV_CKA_CLASS ||
6980904Smcpowers 	    type == DPROV_CKA_CERTIFICATE_TYPE ||
6981904Smcpowers 	    type == DPROV_CKA_KEY_TYPE ||
6982904Smcpowers 	    type == DPROV_HW_FEATURE_TYPE);
6983904Smcpowers }
6984904Smcpowers 
6985904Smcpowers /*
6986904Smcpowers  * Attributes defined to be a PKCS#11 long causes problems for dprov
6987904Smcpowers  * because 32-bit applications set the size to 4 and 64-bit applications
6988904Smcpowers  * set the size to 8. dprov always stores these fixed-size attributes
6989904Smcpowers  * as uint32_t.
6990904Smcpowers  */
6991904Smcpowers static ssize_t
attribute_size(crypto_attr_type_t type,ssize_t len)6992904Smcpowers attribute_size(crypto_attr_type_t type, ssize_t len)
6993904Smcpowers {
6994904Smcpowers 	if (fixed_size_attribute(type))
6995904Smcpowers 		return (sizeof (uint32_t));
6996904Smcpowers 
6997904Smcpowers 	return (len);
6998904Smcpowers }
6999904Smcpowers 
70000Sstevel@tonic-gate /*
70010Sstevel@tonic-gate  * taskq dispatcher function for object management operations.
70020Sstevel@tonic-gate  */
70030Sstevel@tonic-gate static void
dprov_object_task(dprov_req_t * taskq_req)70040Sstevel@tonic-gate dprov_object_task(dprov_req_t *taskq_req)
70050Sstevel@tonic-gate {
70060Sstevel@tonic-gate 	dprov_state_t *softc;
70070Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
70080Sstevel@tonic-gate 	int instance;
70090Sstevel@tonic-gate 	int error = CRYPTO_NOT_SUPPORTED;
70100Sstevel@tonic-gate 	crypto_object_id_t object_id = taskq_req->dr_object_req.or_object_id;
70110Sstevel@tonic-gate 	crypto_session_id_t session_id = taskq_req->dr_object_req.or_session_id;
70120Sstevel@tonic-gate 	crypto_object_attribute_t *template =
70130Sstevel@tonic-gate 	    taskq_req->dr_object_req.or_template;
70140Sstevel@tonic-gate 	uint_t attr_count = taskq_req->dr_object_req.or_attribute_count;
70150Sstevel@tonic-gate 	dprov_object_t *object;
70160Sstevel@tonic-gate 	dprov_session_t *session;
70170Sstevel@tonic-gate 
70180Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
70190Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_task: started\n", instance));
70200Sstevel@tonic-gate 
70210Sstevel@tonic-gate 	mutex_enter(&softc->ds_lock);
70220Sstevel@tonic-gate 
70230Sstevel@tonic-gate 	/* validate session id and get ptr to session */
70240Sstevel@tonic-gate 	if ((session = softc->ds_sessions[session_id]) == NULL) {
70250Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
70260Sstevel@tonic-gate 		dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID);
70270Sstevel@tonic-gate 		return;
70280Sstevel@tonic-gate 	}
70290Sstevel@tonic-gate 
70300Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
70310Sstevel@tonic-gate 
70320Sstevel@tonic-gate 	case DPROV_REQ_OBJECT_CREATE:
70330Sstevel@tonic-gate 		/* create the object from the specified template */
70340Sstevel@tonic-gate 		if ((error = dprov_create_object_from_template(softc, session,
70350Sstevel@tonic-gate 		    template, attr_count,
70360Sstevel@tonic-gate 		    taskq_req->dr_object_req.or_object_id_ptr, B_TRUE,
70370Sstevel@tonic-gate 		    B_FALSE)) != CRYPTO_SUCCESS)
70380Sstevel@tonic-gate 			break;
70390Sstevel@tonic-gate 
70400Sstevel@tonic-gate 		break;
70410Sstevel@tonic-gate 
70420Sstevel@tonic-gate 	case DPROV_REQ_OBJECT_COPY:
70430Sstevel@tonic-gate 		/* check object id */
70440Sstevel@tonic-gate 		if (object_id >= DPROV_MAX_OBJECTS ||
70450Sstevel@tonic-gate 		    (object = session->ds_objects[object_id]) == NULL) {
70460Sstevel@tonic-gate 			error = CRYPTO_OBJECT_HANDLE_INVALID;
70470Sstevel@tonic-gate 			break;
70480Sstevel@tonic-gate 		}
70490Sstevel@tonic-gate 
70500Sstevel@tonic-gate 		/*
70510Sstevel@tonic-gate 		 * Create a new object from the object passed as
70520Sstevel@tonic-gate 		 * argument.
70530Sstevel@tonic-gate 		 */
70540Sstevel@tonic-gate 		if ((error = dprov_create_object_from_template(softc, session,
70550Sstevel@tonic-gate 		    object->do_attr, DPROV_MAX_ATTR,
70560Sstevel@tonic-gate 		    taskq_req->dr_object_req.or_object_id_ptr, B_TRUE,
70570Sstevel@tonic-gate 		    B_FALSE)) != CRYPTO_SUCCESS)
70580Sstevel@tonic-gate 			break;
70590Sstevel@tonic-gate 
70600Sstevel@tonic-gate 		/*
70610Sstevel@tonic-gate 		 * Add the attributes specified by the template to the
70620Sstevel@tonic-gate 		 * newly created object, replacing existing ones if needed.
70630Sstevel@tonic-gate 		 */
70640Sstevel@tonic-gate 		error = dprov_object_set_attr(session,
70650Sstevel@tonic-gate 		    *taskq_req->dr_object_req.or_object_id_ptr,
70660Sstevel@tonic-gate 		    taskq_req->dr_object_req.or_template,
70670Sstevel@tonic-gate 		    taskq_req->dr_object_req.or_attribute_count, B_TRUE);
70680Sstevel@tonic-gate 
70690Sstevel@tonic-gate 		break;
70700Sstevel@tonic-gate 
70710Sstevel@tonic-gate 	case DPROV_REQ_OBJECT_DESTROY:
70720Sstevel@tonic-gate 		/* destroy the object */
70730Sstevel@tonic-gate 		error = dprov_destroy_object(softc, session,
70740Sstevel@tonic-gate 		    taskq_req->dr_object_req.or_object_id);
70750Sstevel@tonic-gate 
70760Sstevel@tonic-gate 		break;
70770Sstevel@tonic-gate 
70780Sstevel@tonic-gate 	case DPROV_REQ_OBJECT_GET_SIZE:
70790Sstevel@tonic-gate 		/* get ptr to object */
70800Sstevel@tonic-gate 		if (object_id >= DPROV_MAX_OBJECTS ||
70810Sstevel@tonic-gate 		    session->ds_objects[object_id] == NULL) {
70820Sstevel@tonic-gate 			error = CRYPTO_OBJECT_HANDLE_INVALID;
70830Sstevel@tonic-gate 			break;
70840Sstevel@tonic-gate 		}
70850Sstevel@tonic-gate 
70860Sstevel@tonic-gate 		/*
70870Sstevel@tonic-gate 		 * The PKCS11 specification does not specifies what
70880Sstevel@tonic-gate 		 * the object size really is, here we just return
70890Sstevel@tonic-gate 		 * the number of possible attributes of the object.
70900Sstevel@tonic-gate 		 */
70910Sstevel@tonic-gate 		*taskq_req->dr_object_req.or_object_size = DPROV_MAX_ATTR;
70920Sstevel@tonic-gate 
70930Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
70940Sstevel@tonic-gate 		break;
70950Sstevel@tonic-gate 
70960Sstevel@tonic-gate 	case DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE: {
7097904Smcpowers 		crypto_attr_type_t type;
7098904Smcpowers 		size_t olen, tlen;
7099904Smcpowers 		offset_t offset;
71000Sstevel@tonic-gate 		int tmpl_idx;
71010Sstevel@tonic-gate 		int object_idx;
71020Sstevel@tonic-gate 		ulong_t class = DPROV_CKO_DATA;
71030Sstevel@tonic-gate 		boolean_t extractable = B_TRUE;
71040Sstevel@tonic-gate 
71050Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
71060Sstevel@tonic-gate 
71070Sstevel@tonic-gate 		/* get ptr to object */
71080Sstevel@tonic-gate 		if (object_id >= DPROV_MAX_OBJECTS ||
71090Sstevel@tonic-gate 		    (object = session->ds_objects[object_id]) == NULL) {
71100Sstevel@tonic-gate 			error = CRYPTO_OBJECT_HANDLE_INVALID;
71110Sstevel@tonic-gate 			break;
71120Sstevel@tonic-gate 		}
71130Sstevel@tonic-gate 
71140Sstevel@tonic-gate 		(void) dprov_get_object_attr_boolean(object,
71150Sstevel@tonic-gate 		    DPROV_CKA_EXTRACTABLE, &extractable);
71160Sstevel@tonic-gate 
71170Sstevel@tonic-gate 		(void) dprov_get_object_attr_ulong(object,
71180Sstevel@tonic-gate 		    DPROV_CKA_CLASS, &class);
71190Sstevel@tonic-gate 
71200Sstevel@tonic-gate 		/* return the specified attributes, when possible */
71210Sstevel@tonic-gate 		for (tmpl_idx = 0; tmpl_idx < attr_count; tmpl_idx++) {
71220Sstevel@tonic-gate 			/*
71230Sstevel@tonic-gate 			 * Attribute can't be revealed if the CKA_EXTRACTABLE
71240Sstevel@tonic-gate 			 * attribute is set to false.
71250Sstevel@tonic-gate 			 */
7126904Smcpowers 			type = template[tmpl_idx].oa_type;
71270Sstevel@tonic-gate 			if (!extractable && class == DPROV_CKO_SECRET_KEY) {
7128904Smcpowers 				if (type == DPROV_CKA_VALUE) {
71290Sstevel@tonic-gate 					template[tmpl_idx].oa_value_len = -1;
71300Sstevel@tonic-gate 					error = CRYPTO_ATTRIBUTE_SENSITIVE;
71310Sstevel@tonic-gate 					continue;
71320Sstevel@tonic-gate 				}
71330Sstevel@tonic-gate 			}
71340Sstevel@tonic-gate 			if (!extractable && class == DPROV_CKO_PRIVATE_KEY) {
7135904Smcpowers 				if (type == DPROV_CKA_PRIVATE_EXPONENT) {
71360Sstevel@tonic-gate 					template[tmpl_idx].oa_value_len = -1;
71370Sstevel@tonic-gate 					error = CRYPTO_ATTRIBUTE_SENSITIVE;
71380Sstevel@tonic-gate 					continue;
71390Sstevel@tonic-gate 				}
71400Sstevel@tonic-gate 			}
71410Sstevel@tonic-gate 
71420Sstevel@tonic-gate 			object_idx = dprov_find_attr(object->do_attr,
7143904Smcpowers 			    DPROV_MAX_ATTR, type);
71440Sstevel@tonic-gate 			if (object_idx == -1) {
71450Sstevel@tonic-gate 				/* attribute not found in object */
71460Sstevel@tonic-gate 				template[tmpl_idx].oa_value_len = -1;
71470Sstevel@tonic-gate 				error = CRYPTO_ATTRIBUTE_TYPE_INVALID;
71480Sstevel@tonic-gate 				continue;
71490Sstevel@tonic-gate 			}
71500Sstevel@tonic-gate 
7151904Smcpowers 			tlen = template[tmpl_idx].oa_value_len;
7152904Smcpowers 			olen = object->do_attr[object_idx].oa_value_len;
7153904Smcpowers 			/* return attribute length */
71540Sstevel@tonic-gate 			if (template[tmpl_idx].oa_value == NULL) {
7155904Smcpowers 				/*
7156904Smcpowers 				 * The size of the attribute is set by the
7157904Smcpowers 				 * library according to the data model of the
7158904Smcpowers 				 * application, so don't overwrite it with
7159904Smcpowers 				 * dprov's size.
7160904Smcpowers 				 */
7161904Smcpowers 				if (!fixed_size_attribute(type))
7162904Smcpowers 					template[tmpl_idx].oa_value_len = olen;
71630Sstevel@tonic-gate 				continue;
71640Sstevel@tonic-gate 			}
7165904Smcpowers 
7166904Smcpowers 			if (tlen < olen) {
71670Sstevel@tonic-gate 				template[tmpl_idx].oa_value_len = -1;
71680Sstevel@tonic-gate 				error = CRYPTO_BUFFER_TOO_SMALL;
71690Sstevel@tonic-gate 				continue;
71700Sstevel@tonic-gate 			}
7171904Smcpowers 
7172904Smcpowers 			/* copy attribute value */
7173904Smcpowers 			bzero(template[tmpl_idx].oa_value, tlen);
7174904Smcpowers 
7175904Smcpowers 			offset = 0;
7176904Smcpowers #ifdef _BIG_ENDIAN
7177904Smcpowers 			if (fixed_size_attribute(type)) {
7178904Smcpowers 				offset = tlen - olen;
7179904Smcpowers 			}
7180904Smcpowers #endif
71810Sstevel@tonic-gate 			bcopy(object->do_attr[object_idx].oa_value,
7182904Smcpowers 			    &template[tmpl_idx].oa_value[offset], olen);
7183904Smcpowers 
7184904Smcpowers 			/* don't update length for fixed-size attributes */
7185904Smcpowers 			if (!fixed_size_attribute(type))
7186904Smcpowers 				template[tmpl_idx].oa_value_len = olen;
71870Sstevel@tonic-gate 		}
71880Sstevel@tonic-gate 
71890Sstevel@tonic-gate 		break;
71900Sstevel@tonic-gate 	}
71910Sstevel@tonic-gate 
71920Sstevel@tonic-gate 	case DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE:
71930Sstevel@tonic-gate 		/*
71940Sstevel@tonic-gate 		 * Add the attributes specified by the template to the
71950Sstevel@tonic-gate 		 * newly created object, replacing existing ones if needed.
71960Sstevel@tonic-gate 		 */
71970Sstevel@tonic-gate 		error = dprov_object_set_attr(session,
71980Sstevel@tonic-gate 		    taskq_req->dr_object_req.or_object_id,
71990Sstevel@tonic-gate 		    taskq_req->dr_object_req.or_template,
72000Sstevel@tonic-gate 		    taskq_req->dr_object_req.or_attribute_count, B_TRUE);
72010Sstevel@tonic-gate 
72020Sstevel@tonic-gate 		break;
72030Sstevel@tonic-gate 
72040Sstevel@tonic-gate 	case DPROV_REQ_OBJECT_FIND_INIT: {
72050Sstevel@tonic-gate 		dprov_find_ctx_t *find_ctx;
72060Sstevel@tonic-gate 		int so_idx;		/* session object index */
72070Sstevel@tonic-gate 		int to_idx;		/* token object index */
72080Sstevel@tonic-gate 
72090Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
72100Sstevel@tonic-gate 		/* allocate find context */
72110Sstevel@tonic-gate 		find_ctx = kmem_zalloc(sizeof (dprov_find_ctx_t), KM_SLEEP);
72120Sstevel@tonic-gate 		*taskq_req->dr_object_req.or_find_pp = find_ctx;
72130Sstevel@tonic-gate 
72140Sstevel@tonic-gate 		/* first go through the existing session objects */
72150Sstevel@tonic-gate 		for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++) {
72160Sstevel@tonic-gate 			if ((object = session->ds_objects[so_idx]) == NULL)
72170Sstevel@tonic-gate 				continue;
72180Sstevel@tonic-gate 
72190Sstevel@tonic-gate 			/* setting count to zero means find all objects */
72200Sstevel@tonic-gate 			if (attr_count > 0) {
72210Sstevel@tonic-gate 				if (!dprov_attributes_match(object, template,
72220Sstevel@tonic-gate 				    attr_count))
72230Sstevel@tonic-gate 					continue;
72240Sstevel@tonic-gate 			}
72250Sstevel@tonic-gate 
72260Sstevel@tonic-gate 			/* session object attributes matches template */
72270Sstevel@tonic-gate 			find_ctx->fc_ids[find_ctx->fc_nids] = so_idx;
72280Sstevel@tonic-gate 			find_ctx->fc_nids++;
72290Sstevel@tonic-gate 		}
72300Sstevel@tonic-gate 
72310Sstevel@tonic-gate 		/*
72320Sstevel@tonic-gate 		 * Go through the token object. For each token object
72330Sstevel@tonic-gate 		 * that can be accessed:
72340Sstevel@tonic-gate 		 * If there was already an session object id assigned
72350Sstevel@tonic-gate 		 * to that token object, skip it, since it was returned
72360Sstevel@tonic-gate 		 * during the check of session objects, else,
72370Sstevel@tonic-gate 		 * assign a new object id for that token object and
72380Sstevel@tonic-gate 		 * add it to the array of matching objects.
72390Sstevel@tonic-gate 		 */
72400Sstevel@tonic-gate 		for (to_idx = 0; to_idx < DPROV_MAX_OBJECTS &&
72410Sstevel@tonic-gate 		    error == CRYPTO_SUCCESS; to_idx++) {
72420Sstevel@tonic-gate 			if ((object = softc->ds_objects[to_idx]) == NULL)
72430Sstevel@tonic-gate 				continue;
72440Sstevel@tonic-gate 
72450Sstevel@tonic-gate 			/* setting count to zero means find all objects */
72460Sstevel@tonic-gate 			if (attr_count > 0) {
72470Sstevel@tonic-gate 				if (!dprov_attributes_match(object, template,
72480Sstevel@tonic-gate 				    attr_count))
72490Sstevel@tonic-gate 					continue;
72500Sstevel@tonic-gate 			}
72510Sstevel@tonic-gate 
72520Sstevel@tonic-gate 			/* if the the object has been destroyed, skip it */
72530Sstevel@tonic-gate 			if (object->do_destroyed)
72540Sstevel@tonic-gate 				continue;
72550Sstevel@tonic-gate 
72560Sstevel@tonic-gate 			/* skip object if it cannot be accessed from session */
72570Sstevel@tonic-gate 			if (dprov_object_is_private(object) &&
72580Sstevel@tonic-gate 			    session->ds_state != DPROV_SESSION_STATE_USER)
72590Sstevel@tonic-gate 				continue;
72600Sstevel@tonic-gate 
72610Sstevel@tonic-gate 			/*
72620Sstevel@tonic-gate 			 * Is there already a session object id for this
72630Sstevel@tonic-gate 			 * token object?
72640Sstevel@tonic-gate 			 */
72650Sstevel@tonic-gate 			for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++)
72660Sstevel@tonic-gate 				if (session->ds_objects[so_idx] != NULL &&
72670Sstevel@tonic-gate 				    session->ds_objects[so_idx]->do_token_idx ==
72680Sstevel@tonic-gate 				    to_idx)
72690Sstevel@tonic-gate 					break;
72700Sstevel@tonic-gate 			if (so_idx < DPROV_MAX_OBJECTS)
72710Sstevel@tonic-gate 				/* object found in session table, skip it */
72720Sstevel@tonic-gate 				continue;
72730Sstevel@tonic-gate 
72740Sstevel@tonic-gate 			/* find free session slot for this object */
72750Sstevel@tonic-gate 			for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++)
72760Sstevel@tonic-gate 				if (session->ds_objects[so_idx] == NULL)
72770Sstevel@tonic-gate 					break;
72780Sstevel@tonic-gate 			if (so_idx == DPROV_MAX_OBJECTS) {
72790Sstevel@tonic-gate 				/* ran out of session objects slots */
72800Sstevel@tonic-gate 				kmem_free(find_ctx, sizeof (dprov_find_ctx_t));
72810Sstevel@tonic-gate 				error = CRYPTO_HOST_MEMORY;
72820Sstevel@tonic-gate 				break;
72830Sstevel@tonic-gate 			}
72840Sstevel@tonic-gate 
72850Sstevel@tonic-gate 			/* add object to session objects table */
72860Sstevel@tonic-gate 			session->ds_objects[so_idx] = object;
72870Sstevel@tonic-gate 			DPROV_OBJECT_REFHOLD(object);
72880Sstevel@tonic-gate 
72890Sstevel@tonic-gate 			/* add object to list of objects to return */
72900Sstevel@tonic-gate 			find_ctx->fc_ids[find_ctx->fc_nids] = so_idx;
72910Sstevel@tonic-gate 			find_ctx->fc_nids++;
72920Sstevel@tonic-gate 		}
72930Sstevel@tonic-gate 
72940Sstevel@tonic-gate 		break;
72950Sstevel@tonic-gate 	}
72960Sstevel@tonic-gate 
72970Sstevel@tonic-gate 	case DPROV_REQ_OBJECT_FIND: {
72980Sstevel@tonic-gate 		crypto_object_id_t *object_ids =
72994424Sizick 		    taskq_req->dr_object_req.or_object_id_ptr;
73000Sstevel@tonic-gate 		uint_t max_object_count =
73014424Sizick 		    taskq_req->dr_object_req.or_max_object_count;
73020Sstevel@tonic-gate 		dprov_find_ctx_t *find_ctx =
73034424Sizick 		    taskq_req->dr_object_req.or_find_p;
73040Sstevel@tonic-gate 		uint_t ret_oid_idx;
73050Sstevel@tonic-gate 
73060Sstevel@tonic-gate 		/* return the desired number of object ids */
73070Sstevel@tonic-gate 		for (ret_oid_idx = 0; ret_oid_idx < max_object_count &&
73080Sstevel@tonic-gate 		    find_ctx->fc_next < find_ctx->fc_nids; ret_oid_idx++)
73090Sstevel@tonic-gate 			object_ids[ret_oid_idx] =
73100Sstevel@tonic-gate 			    find_ctx->fc_ids[find_ctx->fc_next++];
73110Sstevel@tonic-gate 
73120Sstevel@tonic-gate 		*taskq_req->dr_object_req.or_object_count_ptr = ret_oid_idx;
73130Sstevel@tonic-gate 
73140Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
73150Sstevel@tonic-gate 		break;
73160Sstevel@tonic-gate 	}
73170Sstevel@tonic-gate 
73180Sstevel@tonic-gate 	case DPROV_REQ_OBJECT_FIND_FINAL:
73190Sstevel@tonic-gate 		kmem_free(taskq_req->dr_object_req.or_find_p,
73200Sstevel@tonic-gate 		    sizeof (dprov_find_ctx_t));
73210Sstevel@tonic-gate 
73220Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
73230Sstevel@tonic-gate 		break;
73240Sstevel@tonic-gate 	}
73250Sstevel@tonic-gate 
73260Sstevel@tonic-gate 	mutex_exit(&softc->ds_lock);
73270Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
73280Sstevel@tonic-gate 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_task: end\n", instance));
73290Sstevel@tonic-gate }
73300Sstevel@tonic-gate 
73310Sstevel@tonic-gate /*
73324424Sizick  * Copy attribute values into a template. RSA values are precomputed.
73334424Sizick  */
73344424Sizick static int
nostore_copy_attribute(crypto_object_attribute_t * template,uint_t count,uint64_t attr_type)73354424Sizick nostore_copy_attribute(crypto_object_attribute_t *template, uint_t count,
73364424Sizick     uint64_t attr_type)
73374424Sizick {
73384424Sizick 	void *value, *dprov_attribute_value;
73394424Sizick 	size_t dprov_attribute_size;
73404424Sizick 	size_t value_len = 0;
73414424Sizick 	int error;
73424424Sizick 
73434424Sizick 	switch (attr_type) {
73444424Sizick 	case DPROV_CKA_VALUE:
73454424Sizick 		dprov_attribute_size = sizeof (dh_value);
73464424Sizick 		dprov_attribute_value = dh_value;
73474424Sizick 		break;
73484424Sizick 
73494424Sizick 	case DPROV_CKA_MODULUS:
73504424Sizick 		dprov_attribute_size = sizeof (modulus);
73514424Sizick 		dprov_attribute_value = modulus;
73524424Sizick 		break;
73534424Sizick 
73544424Sizick 	case DPROV_CKA_PUBLIC_EXPONENT:
73554424Sizick 		dprov_attribute_size = sizeof (public_exponent);
73564424Sizick 		dprov_attribute_value = public_exponent;
73574424Sizick 		break;
73584424Sizick 
73594424Sizick 	case DPROV_CKA_PRIVATE_EXPONENT:
73604424Sizick 		dprov_attribute_size = sizeof (private_exponent);
73614424Sizick 		dprov_attribute_value = private_exponent;
73624424Sizick 		break;
73634424Sizick 
73644424Sizick 	default:
73654424Sizick 		return (CRYPTO_ATTRIBUTE_TYPE_INVALID);
73664424Sizick 	}
73674424Sizick 
73684424Sizick 	error = dprov_get_template_attr_array(template, count, attr_type,
73694424Sizick 	    &value, &value_len);
73704424Sizick 	if (error != CRYPTO_SUCCESS)
73714424Sizick 		return (error);
73724424Sizick 
73734424Sizick 	if (value_len < dprov_attribute_size)
73744424Sizick 		return (CRYPTO_BUFFER_TOO_SMALL);
73754424Sizick 
73764424Sizick 	/*
73774424Sizick 	 * The updated template will be returned to libpkcs11.
73784424Sizick 	 */
73794424Sizick 	bcopy(dprov_attribute_value, value, dprov_attribute_size);
73804424Sizick 
73814424Sizick 	return (CRYPTO_SUCCESS);
73824424Sizick }
73834424Sizick 
73844424Sizick static void
fill_dh(void * value,size_t len)73854424Sizick fill_dh(void *value, size_t len)
73864424Sizick {
73874424Sizick 	int i = 0;
73884424Sizick 	char *p = value;
73894424Sizick 	while (i < len) {
73904424Sizick 		p[i++] = 'D';
73914424Sizick 		if (i >= len)
73924424Sizick 			break;
73934424Sizick 		p[i++] = 'H';
73944424Sizick 	}
73954424Sizick }
73964424Sizick 
73974424Sizick /*
73980Sstevel@tonic-gate  * taskq dispatcher function for key management operations.
73990Sstevel@tonic-gate  */
74000Sstevel@tonic-gate static void
dprov_key_task(dprov_req_t * taskq_req)74010Sstevel@tonic-gate dprov_key_task(dprov_req_t *taskq_req)
74020Sstevel@tonic-gate {
74030Sstevel@tonic-gate 	dprov_state_t *softc;
74040Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
74050Sstevel@tonic-gate 	int instance;
74060Sstevel@tonic-gate 	int error = CRYPTO_NOT_SUPPORTED;
74070Sstevel@tonic-gate 	kcf_provider_desc_t *pd;
74080Sstevel@tonic-gate 	crypto_session_id_t session_id = taskq_req->dr_key_req.kr_session_id;
74090Sstevel@tonic-gate 	dprov_session_t *session;
74100Sstevel@tonic-gate 
74110Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
74120Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_task: started\n", instance));
74130Sstevel@tonic-gate 
74140Sstevel@tonic-gate 	mutex_enter(&softc->ds_lock);
74150Sstevel@tonic-gate 
74160Sstevel@tonic-gate 	/* validate session id and get ptr to session */
74170Sstevel@tonic-gate 	if ((session = softc->ds_sessions[session_id]) == NULL) {
74180Sstevel@tonic-gate 		mutex_exit(&softc->ds_lock);
74190Sstevel@tonic-gate 		dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID);
74200Sstevel@tonic-gate 		return;
74210Sstevel@tonic-gate 	}
74220Sstevel@tonic-gate 
74230Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
74240Sstevel@tonic-gate 	case DPROV_REQ_KEY_GENERATE: {
74250Sstevel@tonic-gate 		crypto_mechanism_t *mechp;
74260Sstevel@tonic-gate 		crypto_object_id_t *object_id_ptr;
74270Sstevel@tonic-gate 		crypto_object_attribute_t *template;
74280Sstevel@tonic-gate 		crypto_object_attribute_t attribute;
74290Sstevel@tonic-gate 		uint_t attribute_count;
74300Sstevel@tonic-gate 		ulong_t key_type = ~0UL, class = ~0UL;
74310Sstevel@tonic-gate 		ulong_t value_len;
74320Sstevel@tonic-gate 		size_t key_len = 0;
74330Sstevel@tonic-gate 
74340Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
74350Sstevel@tonic-gate 
74360Sstevel@tonic-gate 		template = taskq_req->dr_key_req.kr_template;
74370Sstevel@tonic-gate 		attribute_count = taskq_req->dr_key_req.kr_attribute_count;
74380Sstevel@tonic-gate 		object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr;
74390Sstevel@tonic-gate 		mechp = taskq_req->dr_key_req.kr_mechanism;
74400Sstevel@tonic-gate 
74410Sstevel@tonic-gate 		/* optional */
74420Sstevel@tonic-gate 		(void) dprov_get_template_attr_ulong(template, attribute_count,
74430Sstevel@tonic-gate 		    DPROV_CKA_CLASS, &class);
74440Sstevel@tonic-gate 
74450Sstevel@tonic-gate 		/* optional */
74460Sstevel@tonic-gate 		(void) dprov_get_template_attr_ulong(template, attribute_count,
74470Sstevel@tonic-gate 		    DPROV_CKA_KEY_TYPE, &key_type);
74480Sstevel@tonic-gate 
74490Sstevel@tonic-gate 		if (class != ~0UL && class != DPROV_CKO_SECRET_KEY) {
74500Sstevel@tonic-gate 			error = CRYPTO_TEMPLATE_INCONSISTENT;
74510Sstevel@tonic-gate 			break;
74520Sstevel@tonic-gate 		}
74530Sstevel@tonic-gate 
74540Sstevel@tonic-gate 		switch (mechp->cm_type) {
74550Sstevel@tonic-gate 		case DES_KEY_GEN_MECH_INFO_TYPE:
74560Sstevel@tonic-gate 			if (key_type != ~0UL && key_type != DPROV_CKK_DES) {
74570Sstevel@tonic-gate 				error = CRYPTO_TEMPLATE_INCONSISTENT;
74580Sstevel@tonic-gate 				break;
74590Sstevel@tonic-gate 			}
74600Sstevel@tonic-gate 			key_len = DES_KEY_LEN;
74610Sstevel@tonic-gate 			key_type = DPROV_CKK_DES;
74620Sstevel@tonic-gate 			break;
74630Sstevel@tonic-gate 
74640Sstevel@tonic-gate 		case DES3_KEY_GEN_MECH_INFO_TYPE:
74650Sstevel@tonic-gate 			if (key_type != ~0UL && key_type != DPROV_CKK_DES3) {
74660Sstevel@tonic-gate 				error = CRYPTO_TEMPLATE_INCONSISTENT;
74670Sstevel@tonic-gate 				break;
74680Sstevel@tonic-gate 			}
74690Sstevel@tonic-gate 			key_len = DES3_KEY_LEN;
74700Sstevel@tonic-gate 			key_type = DPROV_CKK_DES3;
74710Sstevel@tonic-gate 			break;
74720Sstevel@tonic-gate 
74730Sstevel@tonic-gate 		case AES_KEY_GEN_MECH_INFO_TYPE:
74740Sstevel@tonic-gate 			if (key_type != ~0UL && key_type != DPROV_CKK_AES) {
74750Sstevel@tonic-gate 				error = CRYPTO_TEMPLATE_INCONSISTENT;
74760Sstevel@tonic-gate 				break;
74770Sstevel@tonic-gate 			}
74780Sstevel@tonic-gate 			if (dprov_get_template_attr_ulong(template,
74790Sstevel@tonic-gate 			    attribute_count, DPROV_CKA_VALUE_LEN,
74800Sstevel@tonic-gate 			    &value_len) != CRYPTO_SUCCESS) {
74810Sstevel@tonic-gate 				error = CRYPTO_TEMPLATE_INCOMPLETE;
74820Sstevel@tonic-gate 				break;
74830Sstevel@tonic-gate 			}
74840Sstevel@tonic-gate 			if (value_len >= AES_MAX_KEY_LEN) {
74850Sstevel@tonic-gate 				error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
74860Sstevel@tonic-gate 				break;
74870Sstevel@tonic-gate 			}
74880Sstevel@tonic-gate 			key_len = value_len;
74890Sstevel@tonic-gate 			key_type = DPROV_CKK_AES;
74900Sstevel@tonic-gate 			break;
74910Sstevel@tonic-gate 
7492676Sizick 		case BLOWFISH_KEY_GEN_MECH_INFO_TYPE:
7493676Sizick 			if (key_type != ~0UL &&
7494676Sizick 			    key_type != DPROV_CKK_BLOWFISH) {
7495676Sizick 				error = CRYPTO_TEMPLATE_INCONSISTENT;
7496676Sizick 				break;
7497676Sizick 			}
7498676Sizick 			if (dprov_get_template_attr_ulong(template,
7499676Sizick 			    attribute_count, DPROV_CKA_VALUE_LEN,
7500676Sizick 			    &value_len) != CRYPTO_SUCCESS) {
7501676Sizick 				error = CRYPTO_TEMPLATE_INCOMPLETE;
7502676Sizick 				break;
7503676Sizick 			}
7504676Sizick 			if (value_len >= BLOWFISH_MAX_KEY_LEN) {
7505676Sizick 				error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
7506676Sizick 				break;
7507676Sizick 			}
7508676Sizick 			key_len = value_len;
7509676Sizick 			key_type = DPROV_CKK_BLOWFISH;
7510676Sizick 			break;
7511676Sizick 
75120Sstevel@tonic-gate 		case RC4_KEY_GEN_MECH_INFO_TYPE:
75130Sstevel@tonic-gate 			if (key_type != ~0UL && key_type != DPROV_CKK_RC4) {
75140Sstevel@tonic-gate 				error = CRYPTO_TEMPLATE_INCONSISTENT;
75150Sstevel@tonic-gate 				break;
75160Sstevel@tonic-gate 			}
75170Sstevel@tonic-gate 			if (dprov_get_template_attr_ulong(template,
75180Sstevel@tonic-gate 			    attribute_count, DPROV_CKA_VALUE_LEN,
75190Sstevel@tonic-gate 			    &value_len) != CRYPTO_SUCCESS) {
75200Sstevel@tonic-gate 				error = CRYPTO_TEMPLATE_INCOMPLETE;
75210Sstevel@tonic-gate 				break;
75220Sstevel@tonic-gate 			}
75230Sstevel@tonic-gate 			if (value_len >=
75240Sstevel@tonic-gate 			    CRYPTO_BITS2BYTES(ARCFOUR_MAX_KEY_BITS)) {
75250Sstevel@tonic-gate 				error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
75260Sstevel@tonic-gate 				break;
75270Sstevel@tonic-gate 			}
75280Sstevel@tonic-gate 			key_len = value_len;
75290Sstevel@tonic-gate 			key_type = DPROV_CKK_RC4;
75300Sstevel@tonic-gate 			break;
75310Sstevel@tonic-gate 
75320Sstevel@tonic-gate 		default:
75330Sstevel@tonic-gate 			error = CRYPTO_MECHANISM_INVALID;
75340Sstevel@tonic-gate 		}
75350Sstevel@tonic-gate 
75360Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
75370Sstevel@tonic-gate 			break;
75380Sstevel@tonic-gate 
75390Sstevel@tonic-gate 		error = dprov_create_object_from_template(softc, session,
75400Sstevel@tonic-gate 		    template, attribute_count, object_id_ptr, B_FALSE, B_TRUE);
75410Sstevel@tonic-gate 
75420Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
75430Sstevel@tonic-gate 			break;
75440Sstevel@tonic-gate 
75450Sstevel@tonic-gate 		/* make sure class is set */
75460Sstevel@tonic-gate 		attribute.oa_type = DPROV_CKA_CLASS;
75470Sstevel@tonic-gate 		attribute.oa_value = (char *)&class;
75480Sstevel@tonic-gate 		attribute.oa_value_len = sizeof (ulong_t);
75490Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *object_id_ptr,
75500Sstevel@tonic-gate 		    &attribute, 1, B_FALSE);
75510Sstevel@tonic-gate 
75520Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
75530Sstevel@tonic-gate 			goto destroy_object;
75540Sstevel@tonic-gate 		}
75550Sstevel@tonic-gate 
75560Sstevel@tonic-gate 		/* make sure key_type is set */
75570Sstevel@tonic-gate 		attribute.oa_type = DPROV_CKA_KEY_TYPE;
75580Sstevel@tonic-gate 		attribute.oa_value = (char *)&key_type;
75590Sstevel@tonic-gate 		attribute.oa_value_len = sizeof (ulong_t);
75600Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *object_id_ptr,
75610Sstevel@tonic-gate 		    &attribute, 1, B_FALSE);
75620Sstevel@tonic-gate 
75630Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
75640Sstevel@tonic-gate 			goto destroy_object;
75650Sstevel@tonic-gate 		}
75660Sstevel@tonic-gate 
75670Sstevel@tonic-gate 		attribute.oa_type = DPROV_CKA_VALUE;
75680Sstevel@tonic-gate 		attribute.oa_value = kmem_alloc(key_len, KM_SLEEP);
75690Sstevel@tonic-gate 		attribute.oa_value_len = key_len;
75700Sstevel@tonic-gate 
75710Sstevel@tonic-gate 		if (random_get_pseudo_bytes((uchar_t *)attribute.oa_value,
75720Sstevel@tonic-gate 		    key_len) != 0) {
75730Sstevel@tonic-gate 			bzero(attribute.oa_value, key_len);
75740Sstevel@tonic-gate 			kmem_free(attribute.oa_value, key_len);
75750Sstevel@tonic-gate 			goto destroy_object;
75760Sstevel@tonic-gate 		}
75770Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *object_id_ptr,
75780Sstevel@tonic-gate 		    &attribute, 1, B_FALSE);
75790Sstevel@tonic-gate 
75800Sstevel@tonic-gate 		bzero(attribute.oa_value, key_len);
75810Sstevel@tonic-gate 		kmem_free(attribute.oa_value, key_len);
75820Sstevel@tonic-gate 
75830Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
75840Sstevel@tonic-gate 			goto destroy_object;
75850Sstevel@tonic-gate 		}
75860Sstevel@tonic-gate 		break;
75870Sstevel@tonic-gate 
75880Sstevel@tonic-gate destroy_object:
75890Sstevel@tonic-gate 		(void) dprov_destroy_object(softc, session, *object_id_ptr);
75900Sstevel@tonic-gate 		break;
75910Sstevel@tonic-gate 	}
75920Sstevel@tonic-gate 
75930Sstevel@tonic-gate 	case DPROV_REQ_KEY_GENERATE_PAIR: {
75940Sstevel@tonic-gate 		crypto_mechanism_t *mechp;
75950Sstevel@tonic-gate 		crypto_object_id_t *pub_object_id_ptr;
75960Sstevel@tonic-gate 		crypto_object_id_t *pri_object_id_ptr;
75970Sstevel@tonic-gate 		crypto_object_attribute_t *pub_template;
75980Sstevel@tonic-gate 		crypto_object_attribute_t *pri_template;
75990Sstevel@tonic-gate 		crypto_object_attribute_t attribute;
76000Sstevel@tonic-gate 		uint_t pub_attribute_count;
76010Sstevel@tonic-gate 		uint_t pri_attribute_count;
76020Sstevel@tonic-gate 		ulong_t pub_key_type = ~0UL, pub_class = ~0UL;
76030Sstevel@tonic-gate 		ulong_t pri_key_type = ~0UL, pri_class = ~0UL;
76040Sstevel@tonic-gate 
76050Sstevel@tonic-gate 		pub_template = taskq_req->dr_key_req.kr_template;
76060Sstevel@tonic-gate 		pub_attribute_count = taskq_req->dr_key_req.kr_attribute_count;
76070Sstevel@tonic-gate 		pub_object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr;
76080Sstevel@tonic-gate 		pri_template = taskq_req->dr_key_req.kr_private_key_template;
76090Sstevel@tonic-gate 		pri_attribute_count =
76100Sstevel@tonic-gate 		    taskq_req->dr_key_req.kr_private_key_attribute_count;
76110Sstevel@tonic-gate 		pri_object_id_ptr =
76120Sstevel@tonic-gate 		    taskq_req->dr_key_req.kr_private_key_object_id_ptr;
76130Sstevel@tonic-gate 		mechp = taskq_req->dr_key_req.kr_mechanism;
76140Sstevel@tonic-gate 
76150Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
76160Sstevel@tonic-gate 
76170Sstevel@tonic-gate 		/* optional */
76180Sstevel@tonic-gate 		(void) dprov_get_template_attr_ulong(pub_template,
76190Sstevel@tonic-gate 		    pub_attribute_count, DPROV_CKA_CLASS, &pub_class);
76200Sstevel@tonic-gate 
76210Sstevel@tonic-gate 		/* optional */
76220Sstevel@tonic-gate 		(void) dprov_get_template_attr_ulong(pri_template,
76230Sstevel@tonic-gate 		    pri_attribute_count, DPROV_CKA_CLASS, &pri_class);
76240Sstevel@tonic-gate 
76250Sstevel@tonic-gate 		/* optional */
76260Sstevel@tonic-gate 		(void) dprov_get_template_attr_ulong(pub_template,
76270Sstevel@tonic-gate 		    pub_attribute_count, DPROV_CKA_KEY_TYPE, &pub_key_type);
76280Sstevel@tonic-gate 
76290Sstevel@tonic-gate 		/* optional */
76300Sstevel@tonic-gate 		(void) dprov_get_template_attr_ulong(pri_template,
76310Sstevel@tonic-gate 		    pri_attribute_count, DPROV_CKA_KEY_TYPE, &pri_key_type);
76320Sstevel@tonic-gate 
76330Sstevel@tonic-gate 		if (pub_class != ~0UL && pub_class != DPROV_CKO_PUBLIC_KEY) {
76340Sstevel@tonic-gate 			error = CRYPTO_TEMPLATE_INCONSISTENT;
76350Sstevel@tonic-gate 			break;
76360Sstevel@tonic-gate 		}
76370Sstevel@tonic-gate 
76380Sstevel@tonic-gate 		if (pri_class != ~0UL && pri_class != DPROV_CKO_PRIVATE_KEY) {
76390Sstevel@tonic-gate 			error = CRYPTO_TEMPLATE_INCONSISTENT;
76400Sstevel@tonic-gate 			break;
76410Sstevel@tonic-gate 		}
76420Sstevel@tonic-gate 
76430Sstevel@tonic-gate 		switch (mechp->cm_type) {
76440Sstevel@tonic-gate 		case RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE:
76450Sstevel@tonic-gate 			if (pub_key_type != ~0UL &&
76460Sstevel@tonic-gate 			    pub_key_type != DPROV_CKK_RSA) {
76470Sstevel@tonic-gate 				error = CRYPTO_TEMPLATE_INCONSISTENT;
76480Sstevel@tonic-gate 				break;
76490Sstevel@tonic-gate 			}
76504219Smcpowers 			pub_key_type = DPROV_CKK_RSA;
76510Sstevel@tonic-gate 
76520Sstevel@tonic-gate 			if (pri_key_type != ~0UL &&
76530Sstevel@tonic-gate 			    pri_key_type != DPROV_CKK_RSA) {
76540Sstevel@tonic-gate 				error = CRYPTO_TEMPLATE_INCONSISTENT;
76550Sstevel@tonic-gate 				break;
76560Sstevel@tonic-gate 			}
76570Sstevel@tonic-gate 			pri_key_type = DPROV_CKK_RSA;
76580Sstevel@tonic-gate 
76590Sstevel@tonic-gate 			if (pub_class != ~0UL &&
76600Sstevel@tonic-gate 			    pub_class != DPROV_CKO_PUBLIC_KEY) {
76610Sstevel@tonic-gate 				error = CRYPTO_TEMPLATE_INCONSISTENT;
76620Sstevel@tonic-gate 				break;
76630Sstevel@tonic-gate 			}
76640Sstevel@tonic-gate 			pub_class = DPROV_CKO_PUBLIC_KEY;
76650Sstevel@tonic-gate 
76660Sstevel@tonic-gate 			if (pri_class != ~0UL &&
76670Sstevel@tonic-gate 			    pri_class != DPROV_CKO_PRIVATE_KEY) {
76680Sstevel@tonic-gate 				error = CRYPTO_TEMPLATE_INCONSISTENT;
76690Sstevel@tonic-gate 				break;
76700Sstevel@tonic-gate 			}
76710Sstevel@tonic-gate 			pri_class = DPROV_CKO_PRIVATE_KEY;
76720Sstevel@tonic-gate 			break;
76730Sstevel@tonic-gate 
76740Sstevel@tonic-gate 		default:
76750Sstevel@tonic-gate 			error = CRYPTO_MECHANISM_INVALID;
76760Sstevel@tonic-gate 		}
76770Sstevel@tonic-gate 
76780Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
76790Sstevel@tonic-gate 			break;
76800Sstevel@tonic-gate 
76810Sstevel@tonic-gate 		error = dprov_create_object_from_template(softc, session,
76820Sstevel@tonic-gate 		    pub_template, pub_attribute_count, pub_object_id_ptr,
76830Sstevel@tonic-gate 		    B_FALSE, B_TRUE);
76840Sstevel@tonic-gate 
76850Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
76860Sstevel@tonic-gate 			break;
76870Sstevel@tonic-gate 
76880Sstevel@tonic-gate 		/* make sure class is set */
76890Sstevel@tonic-gate 		attribute.oa_type = DPROV_CKA_CLASS;
76900Sstevel@tonic-gate 		attribute.oa_value = (char *)&pub_class;
76910Sstevel@tonic-gate 		attribute.oa_value_len = sizeof (ulong_t);
76920Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *pub_object_id_ptr,
76930Sstevel@tonic-gate 		    &attribute, 1, B_FALSE);
76940Sstevel@tonic-gate 
76950Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
76960Sstevel@tonic-gate 			goto destroy_public_object;
76970Sstevel@tonic-gate 		}
76980Sstevel@tonic-gate 
76990Sstevel@tonic-gate 		/* make sure key_type is set */
77000Sstevel@tonic-gate 		attribute.oa_type = DPROV_CKA_KEY_TYPE;
77010Sstevel@tonic-gate 		attribute.oa_value = (char *)&pub_key_type;
77020Sstevel@tonic-gate 		attribute.oa_value_len = sizeof (ulong_t);
77030Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *pub_object_id_ptr,
77040Sstevel@tonic-gate 		    &attribute, 1, B_FALSE);
77050Sstevel@tonic-gate 
77060Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
77070Sstevel@tonic-gate 			goto destroy_public_object;
77080Sstevel@tonic-gate 		}
77090Sstevel@tonic-gate 
77100Sstevel@tonic-gate 		attribute.oa_type = DPROV_CKA_MODULUS;
77110Sstevel@tonic-gate 		attribute.oa_value = (char *)modulus;
77120Sstevel@tonic-gate 		attribute.oa_value_len = sizeof (modulus);
77130Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *pub_object_id_ptr,
77140Sstevel@tonic-gate 		    &attribute, 1, B_FALSE);
77150Sstevel@tonic-gate 
77160Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
77170Sstevel@tonic-gate 			goto destroy_public_object;
77180Sstevel@tonic-gate 		}
77190Sstevel@tonic-gate 
77200Sstevel@tonic-gate 		attribute.oa_type = DPROV_CKA_PUBLIC_EXPONENT;
77210Sstevel@tonic-gate 		attribute.oa_value = public_exponent;
77220Sstevel@tonic-gate 		attribute.oa_value_len = sizeof (public_exponent);
77230Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *pub_object_id_ptr,
77240Sstevel@tonic-gate 		    &attribute, 1, B_FALSE);
77250Sstevel@tonic-gate 
77260Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
77270Sstevel@tonic-gate 			goto destroy_public_object;
77280Sstevel@tonic-gate 		}
77290Sstevel@tonic-gate 
77300Sstevel@tonic-gate 		error = dprov_create_object_from_template(softc, session,
77310Sstevel@tonic-gate 		    pri_template, pri_attribute_count, pri_object_id_ptr,
77320Sstevel@tonic-gate 		    B_FALSE, B_TRUE);
77330Sstevel@tonic-gate 
77340Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
77350Sstevel@tonic-gate 			break;
77360Sstevel@tonic-gate 
77370Sstevel@tonic-gate 		/* make sure class is set */
77380Sstevel@tonic-gate 		attribute.oa_type = DPROV_CKA_CLASS;
77390Sstevel@tonic-gate 		attribute.oa_value = (char *)&pri_class;
77400Sstevel@tonic-gate 		attribute.oa_value_len = sizeof (ulong_t);
77410Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *pri_object_id_ptr,
77420Sstevel@tonic-gate 		    &attribute, 1, B_FALSE);
77430Sstevel@tonic-gate 
77440Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
77450Sstevel@tonic-gate 			goto destroy_private_object;
77460Sstevel@tonic-gate 		}
77470Sstevel@tonic-gate 
77480Sstevel@tonic-gate 		/* make sure key_type is set */
77490Sstevel@tonic-gate 		attribute.oa_type = DPROV_CKA_KEY_TYPE;
77500Sstevel@tonic-gate 		attribute.oa_value = (char *)&pri_key_type;
77510Sstevel@tonic-gate 		attribute.oa_value_len = sizeof (ulong_t);
77520Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *pri_object_id_ptr,
77530Sstevel@tonic-gate 		    &attribute, 1, B_FALSE);
77540Sstevel@tonic-gate 
77550Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
77560Sstevel@tonic-gate 			goto destroy_private_object;
77570Sstevel@tonic-gate 		}
77580Sstevel@tonic-gate 
77590Sstevel@tonic-gate 		attribute.oa_type = DPROV_CKA_MODULUS;
77600Sstevel@tonic-gate 		attribute.oa_value = (char *)modulus;
77610Sstevel@tonic-gate 		attribute.oa_value_len = sizeof (modulus);
77620Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *pri_object_id_ptr,
77630Sstevel@tonic-gate 		    &attribute, 1, B_FALSE);
77640Sstevel@tonic-gate 
77650Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
77660Sstevel@tonic-gate 			goto destroy_private_object;
77670Sstevel@tonic-gate 		}
77680Sstevel@tonic-gate 
77690Sstevel@tonic-gate 		attribute.oa_type = DPROV_CKA_PRIVATE_EXPONENT;
77700Sstevel@tonic-gate 		attribute.oa_value = (char *)private_exponent;
77710Sstevel@tonic-gate 		attribute.oa_value_len = sizeof (private_exponent);
77720Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *pri_object_id_ptr,
77730Sstevel@tonic-gate 		    &attribute, 1, B_FALSE);
77740Sstevel@tonic-gate 
77750Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
77760Sstevel@tonic-gate 			goto destroy_private_object;
77770Sstevel@tonic-gate 		}
77780Sstevel@tonic-gate 		break;
77790Sstevel@tonic-gate 
77800Sstevel@tonic-gate destroy_private_object:
77810Sstevel@tonic-gate 		(void) dprov_destroy_object(softc, session,
77820Sstevel@tonic-gate 		    *pri_object_id_ptr);
77830Sstevel@tonic-gate destroy_public_object:
77840Sstevel@tonic-gate 		(void) dprov_destroy_object(softc, session,
77850Sstevel@tonic-gate 		    *pub_object_id_ptr);
77860Sstevel@tonic-gate 
77870Sstevel@tonic-gate 		break;
77880Sstevel@tonic-gate 	}
77890Sstevel@tonic-gate 
77900Sstevel@tonic-gate 	case DPROV_REQ_KEY_WRAP: {
77910Sstevel@tonic-gate 		crypto_mechanism_t mech, *mechp;
77920Sstevel@tonic-gate 		crypto_key_t key, *keyp;
77930Sstevel@tonic-gate 		crypto_object_id_t object_id;
77940Sstevel@tonic-gate 		ulong_t class = DPROV_CKO_DATA;
77950Sstevel@tonic-gate 		boolean_t extractable = B_TRUE;
77960Sstevel@tonic-gate 		dprov_object_t *object;
77970Sstevel@tonic-gate 		int object_idx;
77980Sstevel@tonic-gate 		char *plaintext_key;
77990Sstevel@tonic-gate 		size_t plaintext_key_len;
78000Sstevel@tonic-gate 		crypto_data_t plaintext;
78010Sstevel@tonic-gate 		crypto_data_t ciphertext;
78020Sstevel@tonic-gate 		size_t *lenp;
78030Sstevel@tonic-gate 
78040Sstevel@tonic-gate 		mechp = taskq_req->dr_key_req.kr_mechanism;
78050Sstevel@tonic-gate 		/* structure assignment */
78060Sstevel@tonic-gate 		mech = *mechp;
78070Sstevel@tonic-gate 
78080Sstevel@tonic-gate 		/* get wrapping key value */
78090Sstevel@tonic-gate 		if (is_publickey_mech(mech.cm_type)) {
78100Sstevel@tonic-gate 			if ((error = dprov_key_attr_asymmetric(softc,
78110Sstevel@tonic-gate 			    session_id, taskq_req->dr_type,
78120Sstevel@tonic-gate 			    taskq_req->dr_key_req.kr_key,
78130Sstevel@tonic-gate 			    &key)) != CRYPTO_SUCCESS)
78140Sstevel@tonic-gate 				break;
78150Sstevel@tonic-gate 			keyp = &key;
78160Sstevel@tonic-gate 		} else {
78170Sstevel@tonic-gate 			if ((error = dprov_key_value_secret(softc,
78180Sstevel@tonic-gate 			    session_id, taskq_req->dr_type,
78190Sstevel@tonic-gate 			    taskq_req->dr_key_req.kr_key,
78200Sstevel@tonic-gate 			    &key)) != CRYPTO_SUCCESS)
78210Sstevel@tonic-gate 				break;
78220Sstevel@tonic-gate 			keyp = &key;
78230Sstevel@tonic-gate 		}
78240Sstevel@tonic-gate 
78250Sstevel@tonic-gate 		/* get the software provider for this mechanism */
78260Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(mechp, &pd,
78270Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
78280Sstevel@tonic-gate 			break;
78290Sstevel@tonic-gate 
78300Sstevel@tonic-gate 		object_id = *taskq_req->dr_key_req.kr_object_id_ptr;
78310Sstevel@tonic-gate 		if (object_id >= DPROV_MAX_OBJECTS) {
78320Sstevel@tonic-gate 			error = CRYPTO_KEY_HANDLE_INVALID;
78330Sstevel@tonic-gate 			break;
78340Sstevel@tonic-gate 		}
78350Sstevel@tonic-gate 
78360Sstevel@tonic-gate 		/* get ptr to object */
78370Sstevel@tonic-gate 		if ((object = session->ds_objects[object_id]) == NULL) {
78380Sstevel@tonic-gate 			error = CRYPTO_OBJECT_HANDLE_INVALID;
78390Sstevel@tonic-gate 			break;
78400Sstevel@tonic-gate 		}
78410Sstevel@tonic-gate 
78420Sstevel@tonic-gate 		(void) dprov_get_object_attr_boolean(object,
78430Sstevel@tonic-gate 		    DPROV_CKA_EXTRACTABLE, &extractable);
78440Sstevel@tonic-gate 
78450Sstevel@tonic-gate 		if (!extractable) {
78460Sstevel@tonic-gate 			error = CRYPTO_ATTRIBUTE_SENSITIVE;
78470Sstevel@tonic-gate 			break;
78480Sstevel@tonic-gate 		}
78490Sstevel@tonic-gate 
78500Sstevel@tonic-gate 		(void) dprov_get_object_attr_ulong(object,
78510Sstevel@tonic-gate 		    DPROV_CKA_CLASS, &class);
78520Sstevel@tonic-gate 
78530Sstevel@tonic-gate 		switch (class) {
78540Sstevel@tonic-gate 		case DPROV_CKO_SECRET_KEY:
78550Sstevel@tonic-gate 			object_idx = dprov_find_attr(object->do_attr,
78560Sstevel@tonic-gate 			    DPROV_MAX_ATTR, DPROV_CKA_VALUE);
78570Sstevel@tonic-gate 			if (object_idx == -1) {
78580Sstevel@tonic-gate 				error = CRYPTO_ATTRIBUTE_TYPE_INVALID;
78590Sstevel@tonic-gate 				break;
78600Sstevel@tonic-gate 			}
78610Sstevel@tonic-gate 			break;
78620Sstevel@tonic-gate 
78634424Sizick 			case DPROV_CKO_PRIVATE_KEY:
78640Sstevel@tonic-gate 			/*
78650Sstevel@tonic-gate 			 * PKCS#11 says that ASN.1 should be used to encode
78660Sstevel@tonic-gate 			 * specific attributes before encrypting the blob.
78670Sstevel@tonic-gate 			 * We only encrypt the private exponent for the
78680Sstevel@tonic-gate 			 * purpose of testing.
78690Sstevel@tonic-gate 			 */
78700Sstevel@tonic-gate 			object_idx = dprov_find_attr(object->do_attr,
78710Sstevel@tonic-gate 			    DPROV_MAX_ATTR, DPROV_CKA_PRIVATE_EXPONENT);
78720Sstevel@tonic-gate 			if (object_idx == -1) {
78730Sstevel@tonic-gate 				error = CRYPTO_ATTRIBUTE_TYPE_INVALID;
78740Sstevel@tonic-gate 				break;
78750Sstevel@tonic-gate 			}
78760Sstevel@tonic-gate 			break;
78770Sstevel@tonic-gate 		default:
78780Sstevel@tonic-gate 			error = CRYPTO_KEY_NOT_WRAPPABLE;
78790Sstevel@tonic-gate 			break;
78800Sstevel@tonic-gate 		}
78810Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
78820Sstevel@tonic-gate 			break;
78830Sstevel@tonic-gate 
78840Sstevel@tonic-gate 		plaintext_key = object->do_attr[object_idx].oa_value;
78850Sstevel@tonic-gate 		plaintext_key_len = object->do_attr[object_idx].oa_value_len;
78860Sstevel@tonic-gate 		lenp = taskq_req->dr_key_req.kr_wrapped_key_len_ptr;
78870Sstevel@tonic-gate 
78880Sstevel@tonic-gate 		/* session id is 0 for software provider */
78890Sstevel@tonic-gate 		plaintext.cd_format = CRYPTO_DATA_RAW;
78900Sstevel@tonic-gate 		plaintext.cd_offset = 0;
78910Sstevel@tonic-gate 		plaintext.cd_length = plaintext_key_len;
78920Sstevel@tonic-gate 		plaintext.cd_raw.iov_base = plaintext_key;
78930Sstevel@tonic-gate 		plaintext.cd_raw.iov_len = plaintext_key_len;
78940Sstevel@tonic-gate 		plaintext.cd_miscdata = NULL;
78950Sstevel@tonic-gate 
78960Sstevel@tonic-gate 		ciphertext.cd_format = CRYPTO_DATA_RAW;
78970Sstevel@tonic-gate 		ciphertext.cd_offset = 0;
78980Sstevel@tonic-gate 		ciphertext.cd_length = *lenp;
78990Sstevel@tonic-gate 		ciphertext.cd_raw.iov_base =
79000Sstevel@tonic-gate 		    (char *)taskq_req->dr_key_req.kr_wrapped_key;
79010Sstevel@tonic-gate 		ciphertext.cd_raw.iov_len = ciphertext.cd_length;
79020Sstevel@tonic-gate 		ciphertext.cd_miscdata = NULL;
79030Sstevel@tonic-gate 
7904904Smcpowers 		error = crypto_encrypt_prov(pd, 0, &mech, &plaintext, keyp,
7905904Smcpowers 		    NULL, &ciphertext, NULL);
79060Sstevel@tonic-gate 
79070Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
79080Sstevel@tonic-gate 		if (error == CRYPTO_SUCCESS ||
79090Sstevel@tonic-gate 		    error == CRYPTO_BUFFER_TOO_SMALL) {
79100Sstevel@tonic-gate 			*lenp = ciphertext.cd_length;
79110Sstevel@tonic-gate 		}
79120Sstevel@tonic-gate 		break;
79130Sstevel@tonic-gate 	}
79140Sstevel@tonic-gate 
79150Sstevel@tonic-gate 	case DPROV_REQ_KEY_UNWRAP: {
79160Sstevel@tonic-gate 		crypto_mechanism_t mech, *mechp;
79170Sstevel@tonic-gate 		crypto_key_t key, *keyp;
79180Sstevel@tonic-gate 		crypto_object_id_t *object_id_ptr;
79190Sstevel@tonic-gate 		ulong_t class = DPROV_CKO_DATA;
79200Sstevel@tonic-gate 		uchar_t *wrapped_key;
79210Sstevel@tonic-gate 		char *plaintext_buf;
79220Sstevel@tonic-gate 		size_t wrapped_key_len;
79230Sstevel@tonic-gate 		crypto_data_t plaintext;
79240Sstevel@tonic-gate 		crypto_data_t ciphertext;
79250Sstevel@tonic-gate 		crypto_object_attribute_t unwrapped_key;
79260Sstevel@tonic-gate 		crypto_object_attribute_t *template;
79270Sstevel@tonic-gate 		uint_t attribute_count;
79280Sstevel@tonic-gate 
79290Sstevel@tonic-gate 		template = taskq_req->dr_key_req.kr_template;
79300Sstevel@tonic-gate 		attribute_count = taskq_req->dr_key_req.kr_attribute_count;
79310Sstevel@tonic-gate 		object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr;
79320Sstevel@tonic-gate 
79330Sstevel@tonic-gate 		/* all objects must have an object class attribute */
79340Sstevel@tonic-gate 		if (dprov_get_template_attr_ulong(template, attribute_count,
79350Sstevel@tonic-gate 		    DPROV_CKA_CLASS, &class) != CRYPTO_SUCCESS) {
79360Sstevel@tonic-gate 			error = CRYPTO_TEMPLATE_INCOMPLETE;
79370Sstevel@tonic-gate 			break;
79380Sstevel@tonic-gate 		}
79390Sstevel@tonic-gate 
79400Sstevel@tonic-gate 		mechp = taskq_req->dr_key_req.kr_mechanism;
79410Sstevel@tonic-gate 		/* structure assignment */
79420Sstevel@tonic-gate 		mech = *mechp;
79430Sstevel@tonic-gate 
79440Sstevel@tonic-gate 		/* get unwrapping key value */
79450Sstevel@tonic-gate 		if (is_publickey_mech(mech.cm_type)) {
79460Sstevel@tonic-gate 			if ((error = dprov_key_attr_asymmetric(softc,
79470Sstevel@tonic-gate 			    session_id, taskq_req->dr_type,
79480Sstevel@tonic-gate 			    taskq_req->dr_key_req.kr_key,
79490Sstevel@tonic-gate 			    &key)) != CRYPTO_SUCCESS)
79500Sstevel@tonic-gate 				break;
79510Sstevel@tonic-gate 			keyp = &key;
79520Sstevel@tonic-gate 		} else {
79530Sstevel@tonic-gate 			if ((error = dprov_key_value_secret(softc,
79540Sstevel@tonic-gate 			    session_id, taskq_req->dr_type,
79550Sstevel@tonic-gate 			    taskq_req->dr_key_req.kr_key,
79560Sstevel@tonic-gate 			    &key)) != CRYPTO_SUCCESS)
79570Sstevel@tonic-gate 				break;
79580Sstevel@tonic-gate 			keyp = &key;
79590Sstevel@tonic-gate 		}
79600Sstevel@tonic-gate 
79610Sstevel@tonic-gate 		/* get the software provider for this mechanism */
79620Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(mechp, &pd,
79630Sstevel@tonic-gate 		    &mech.cm_type)) != CRYPTO_SUCCESS)
79640Sstevel@tonic-gate 			break;
79650Sstevel@tonic-gate 
79660Sstevel@tonic-gate 		wrapped_key = taskq_req->dr_key_req.kr_wrapped_key;
79670Sstevel@tonic-gate 		wrapped_key_len = *taskq_req->dr_key_req.kr_wrapped_key_len_ptr;
79680Sstevel@tonic-gate 		ciphertext.cd_format = CRYPTO_DATA_RAW;
79690Sstevel@tonic-gate 		ciphertext.cd_offset = 0;
79700Sstevel@tonic-gate 		ciphertext.cd_length = wrapped_key_len;
79710Sstevel@tonic-gate 		ciphertext.cd_raw.iov_base = (char *)wrapped_key;
79720Sstevel@tonic-gate 		ciphertext.cd_raw.iov_len = wrapped_key_len;
79730Sstevel@tonic-gate 		ciphertext.cd_miscdata = NULL;
79740Sstevel@tonic-gate 
79750Sstevel@tonic-gate 		/*
79760Sstevel@tonic-gate 		 * Plaintext length is less than or equal to
79770Sstevel@tonic-gate 		 * the length of the ciphertext.
79780Sstevel@tonic-gate 		 */
79790Sstevel@tonic-gate 		plaintext_buf = kmem_alloc(wrapped_key_len, KM_SLEEP);
79800Sstevel@tonic-gate 		plaintext.cd_format = CRYPTO_DATA_RAW;
79810Sstevel@tonic-gate 		plaintext.cd_offset = 0;
79820Sstevel@tonic-gate 		plaintext.cd_length = wrapped_key_len;
79830Sstevel@tonic-gate 		plaintext.cd_raw.iov_base = plaintext_buf;
79840Sstevel@tonic-gate 		plaintext.cd_raw.iov_len = wrapped_key_len;
79850Sstevel@tonic-gate 		plaintext.cd_miscdata = NULL;
79860Sstevel@tonic-gate 
7987904Smcpowers 		error = crypto_decrypt_prov(pd, 0, &mech, &ciphertext, keyp,
7988904Smcpowers 		    NULL, &plaintext, NULL);
79890Sstevel@tonic-gate 
79900Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
79910Sstevel@tonic-gate 
79920Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
79930Sstevel@tonic-gate 			goto free_unwrapped_key;
79940Sstevel@tonic-gate 
79950Sstevel@tonic-gate 		error = dprov_create_object_from_template(softc, session,
79960Sstevel@tonic-gate 		    template, attribute_count, object_id_ptr, B_FALSE, B_FALSE);
79970Sstevel@tonic-gate 
79980Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
79990Sstevel@tonic-gate 			goto free_unwrapped_key;
80000Sstevel@tonic-gate 
80010Sstevel@tonic-gate 		switch (class) {
80020Sstevel@tonic-gate 		case DPROV_CKO_SECRET_KEY:
80030Sstevel@tonic-gate 			unwrapped_key.oa_type = DPROV_CKA_VALUE;
80040Sstevel@tonic-gate 			unwrapped_key.oa_value_len = plaintext.cd_length;
80050Sstevel@tonic-gate 			unwrapped_key.oa_value = plaintext_buf;
80060Sstevel@tonic-gate 			break;
80070Sstevel@tonic-gate 		case DPROV_CKO_PRIVATE_KEY:
80080Sstevel@tonic-gate 			/*
80090Sstevel@tonic-gate 			 * PKCS#11 says that ASN.1 should be used to encode
80100Sstevel@tonic-gate 			 * specific attributes before encrypting the blob.
80110Sstevel@tonic-gate 			 * We only encrypt the private exponent for the
80120Sstevel@tonic-gate 			 * purpose of testing.
80130Sstevel@tonic-gate 			 */
80140Sstevel@tonic-gate 			unwrapped_key.oa_type = DPROV_CKA_PRIVATE_EXPONENT;
80150Sstevel@tonic-gate 			unwrapped_key.oa_value_len = plaintext.cd_length;
80160Sstevel@tonic-gate 			unwrapped_key.oa_value = plaintext_buf;
80170Sstevel@tonic-gate 			break;
80180Sstevel@tonic-gate 		default:
80190Sstevel@tonic-gate 			error = CRYPTO_TEMPLATE_INCONSISTENT;
80200Sstevel@tonic-gate 			goto free_unwrapped_key;
80210Sstevel@tonic-gate 		}
80220Sstevel@tonic-gate 
80230Sstevel@tonic-gate 		if ((error = dprov_object_set_attr(session, *object_id_ptr,
80240Sstevel@tonic-gate 		    &unwrapped_key, 1, B_FALSE)) == CRYPTO_SUCCESS)
80250Sstevel@tonic-gate 			break;	/* don't free the unwrapped key */
80260Sstevel@tonic-gate 
80270Sstevel@tonic-gate 		/* failure */
80280Sstevel@tonic-gate 		(void) dprov_destroy_object(softc, session, *object_id_ptr);
80290Sstevel@tonic-gate 		break;
80300Sstevel@tonic-gate 
80310Sstevel@tonic-gate free_unwrapped_key:
80320Sstevel@tonic-gate 		bzero(plaintext_buf, wrapped_key_len);
80330Sstevel@tonic-gate 		kmem_free(plaintext_buf, wrapped_key_len);
80340Sstevel@tonic-gate 		break;
80350Sstevel@tonic-gate 	}
80360Sstevel@tonic-gate 
80370Sstevel@tonic-gate 	case DPROV_REQ_KEY_DERIVE: {
80380Sstevel@tonic-gate 		crypto_mechanism_t digest_mech, *mechp;
80390Sstevel@tonic-gate 		crypto_key_t key, *base_keyp;
80400Sstevel@tonic-gate 		crypto_object_id_t *object_id_ptr;
80410Sstevel@tonic-gate 		crypto_data_t data;
80420Sstevel@tonic-gate 		crypto_data_t digest;
80430Sstevel@tonic-gate 		size_t hash_size;
80440Sstevel@tonic-gate 		char *digest_buf;
80450Sstevel@tonic-gate 		crypto_object_attribute_t derived_key;
80460Sstevel@tonic-gate 		crypto_object_attribute_t *template;
80470Sstevel@tonic-gate 		uint_t attribute_count;
80480Sstevel@tonic-gate 		ulong_t key_type;
80490Sstevel@tonic-gate 		void *value;
80500Sstevel@tonic-gate 		size_t value_len = 0;
80510Sstevel@tonic-gate 
80520Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
80530Sstevel@tonic-gate 
80540Sstevel@tonic-gate 		template = taskq_req->dr_key_req.kr_template;
80550Sstevel@tonic-gate 		attribute_count = taskq_req->dr_key_req.kr_attribute_count;
80560Sstevel@tonic-gate 		object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr;
80570Sstevel@tonic-gate 
80580Sstevel@tonic-gate 		/* required */
80590Sstevel@tonic-gate 		if (dprov_get_template_attr_ulong(template, attribute_count,
80600Sstevel@tonic-gate 		    DPROV_CKA_KEY_TYPE, &key_type) != CRYPTO_SUCCESS) {
80610Sstevel@tonic-gate 			error = CRYPTO_TEMPLATE_INCOMPLETE;
80620Sstevel@tonic-gate 			break;
80630Sstevel@tonic-gate 		}
80640Sstevel@tonic-gate 
80650Sstevel@tonic-gate 		mechp = taskq_req->dr_key_req.kr_mechanism;
80660Sstevel@tonic-gate 		/* structure assignment */
80670Sstevel@tonic-gate 		digest_mech = *mechp;
80680Sstevel@tonic-gate 
80690Sstevel@tonic-gate 		switch (digest_mech.cm_type) {
80700Sstevel@tonic-gate 		case SHA1_KEY_DERIVATION_MECH_INFO_TYPE:
80710Sstevel@tonic-gate 			hash_size = SHA1_DIGEST_LEN;
80720Sstevel@tonic-gate 			digest_mech.cm_type = SHA1_MECH_INFO_TYPE;
80730Sstevel@tonic-gate 			break;
80740Sstevel@tonic-gate 
8075676Sizick 		case SHA256_KEY_DERIVATION_MECH_INFO_TYPE:
8076676Sizick 			hash_size = SHA256_DIGEST_LENGTH;
8077676Sizick 			digest_mech.cm_type = SHA256_MECH_INFO_TYPE;
8078676Sizick 			break;
8079676Sizick 
8080676Sizick 		case SHA384_KEY_DERIVATION_MECH_INFO_TYPE:
8081676Sizick 			hash_size = SHA384_DIGEST_LENGTH;
8082676Sizick 			digest_mech.cm_type = SHA384_MECH_INFO_TYPE;
8083676Sizick 			break;
8084676Sizick 
8085676Sizick 		case SHA512_KEY_DERIVATION_MECH_INFO_TYPE:
8086676Sizick 			hash_size = SHA512_DIGEST_LENGTH;
8087676Sizick 			digest_mech.cm_type = SHA512_MECH_INFO_TYPE;
8088676Sizick 			break;
8089676Sizick 
80900Sstevel@tonic-gate 		case MD5_KEY_DERIVATION_MECH_INFO_TYPE:
80910Sstevel@tonic-gate 			hash_size = MD5_DIGEST_LEN;
80920Sstevel@tonic-gate 			digest_mech.cm_type = MD5_MECH_INFO_TYPE;
80930Sstevel@tonic-gate 			break;
80940Sstevel@tonic-gate 
80950Sstevel@tonic-gate 		default:
80960Sstevel@tonic-gate 			error = CRYPTO_MECHANISM_INVALID;
80970Sstevel@tonic-gate 		}
80980Sstevel@tonic-gate 
80990Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
81000Sstevel@tonic-gate 			break;
81010Sstevel@tonic-gate 
81020Sstevel@tonic-gate 		/* CKA_VALUE is optional */
81030Sstevel@tonic-gate 		(void) dprov_get_template_attr_array(template, attribute_count,
81040Sstevel@tonic-gate 		    DPROV_CKA_VALUE, &value, &value_len);
81050Sstevel@tonic-gate 
81060Sstevel@tonic-gate 		/* check for inconsistent value length */
81070Sstevel@tonic-gate 		switch (key_type) {
81080Sstevel@tonic-gate 		case DPROV_CKK_GENERIC_SECRET:
81090Sstevel@tonic-gate 			if (value_len > 0) {
81100Sstevel@tonic-gate 				if (value_len > hash_size)
81110Sstevel@tonic-gate 					error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
81120Sstevel@tonic-gate 			} else {
81130Sstevel@tonic-gate 				value_len = hash_size;
81140Sstevel@tonic-gate 			}
81150Sstevel@tonic-gate 			break;
81160Sstevel@tonic-gate 
81170Sstevel@tonic-gate 		case DPROV_CKK_RC4:
81180Sstevel@tonic-gate 		case DPROV_CKK_AES:
81190Sstevel@tonic-gate 			if (value_len == 0 ||
81200Sstevel@tonic-gate 			    value_len > hash_size) {
81210Sstevel@tonic-gate 				error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
81220Sstevel@tonic-gate 			}
81230Sstevel@tonic-gate 			break;
81240Sstevel@tonic-gate 
81250Sstevel@tonic-gate 		case DPROV_CKK_DES:
81260Sstevel@tonic-gate 			if (value_len > 0 &&
81270Sstevel@tonic-gate 			    value_len != DES_KEY_LEN) {
81280Sstevel@tonic-gate 				error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
81290Sstevel@tonic-gate 			}
81300Sstevel@tonic-gate 			value_len = DES_KEY_LEN;
81310Sstevel@tonic-gate 			break;
81320Sstevel@tonic-gate 
81330Sstevel@tonic-gate 		case DPROV_CKK_DES3:
81340Sstevel@tonic-gate 			if (value_len > 0 &&
81350Sstevel@tonic-gate 			    value_len != DES3_KEY_LEN) {
81360Sstevel@tonic-gate 				error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
81370Sstevel@tonic-gate 			}
81380Sstevel@tonic-gate 			value_len = DES3_KEY_LEN;
81390Sstevel@tonic-gate 			break;
81400Sstevel@tonic-gate 
81410Sstevel@tonic-gate 		default:
81420Sstevel@tonic-gate 			error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
81430Sstevel@tonic-gate 			break;
81440Sstevel@tonic-gate 		}
81450Sstevel@tonic-gate 
81460Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
81470Sstevel@tonic-gate 			break;
81480Sstevel@tonic-gate 
81490Sstevel@tonic-gate 		/* get the software provider for this mechanism */
81500Sstevel@tonic-gate 		if ((error = dprov_get_sw_prov(&digest_mech, &pd,
81510Sstevel@tonic-gate 		    &digest_mech.cm_type)) != CRYPTO_SUCCESS)
81520Sstevel@tonic-gate 			break;
81530Sstevel@tonic-gate 
81540Sstevel@tonic-gate 		/* get the base key */
81550Sstevel@tonic-gate 		error = dprov_key_value_secret(softc, session_id,
81560Sstevel@tonic-gate 		    taskq_req->dr_type, taskq_req->dr_key_req.kr_key, &key);
81570Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
81580Sstevel@tonic-gate 			break;
81590Sstevel@tonic-gate 
81600Sstevel@tonic-gate 		base_keyp = &key;
81610Sstevel@tonic-gate 
81620Sstevel@tonic-gate 		data.cd_format = CRYPTO_DATA_RAW;
81630Sstevel@tonic-gate 		data.cd_offset = 0;
81640Sstevel@tonic-gate 		data.cd_length = CRYPTO_BITS2BYTES(base_keyp->ck_length);
81650Sstevel@tonic-gate 		data.cd_raw.iov_base = base_keyp->ck_data;
81660Sstevel@tonic-gate 		data.cd_raw.iov_len = data.cd_length;
81670Sstevel@tonic-gate 
81680Sstevel@tonic-gate 		digest_buf = kmem_alloc(hash_size, KM_SLEEP);
81690Sstevel@tonic-gate 		digest.cd_format = CRYPTO_DATA_RAW;
81700Sstevel@tonic-gate 		digest.cd_offset = 0;
81710Sstevel@tonic-gate 		digest.cd_length = hash_size;
81720Sstevel@tonic-gate 		digest.cd_raw.iov_base = digest_buf;
81730Sstevel@tonic-gate 		digest.cd_raw.iov_len = hash_size;
81740Sstevel@tonic-gate 
8175904Smcpowers 		error = crypto_digest_prov(pd, 0, &digest_mech, &data,
8176904Smcpowers 		    &digest, NULL);
81770Sstevel@tonic-gate 
81780Sstevel@tonic-gate 		KCF_PROV_REFRELE(pd);
81790Sstevel@tonic-gate 
81800Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
81810Sstevel@tonic-gate 			goto free_derived_key;
81820Sstevel@tonic-gate 
81830Sstevel@tonic-gate 		error = dprov_create_object_from_template(softc, session,
81840Sstevel@tonic-gate 		    template, attribute_count, object_id_ptr, B_FALSE, B_FALSE);
81850Sstevel@tonic-gate 
81860Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS)
81870Sstevel@tonic-gate 			goto free_derived_key;
81880Sstevel@tonic-gate 
81890Sstevel@tonic-gate 		derived_key.oa_type = DPROV_CKA_VALUE;
81900Sstevel@tonic-gate 		derived_key.oa_value = digest_buf;
81910Sstevel@tonic-gate 		derived_key.oa_value_len = value_len;
81920Sstevel@tonic-gate 
81930Sstevel@tonic-gate 		error = dprov_object_set_attr(session, *object_id_ptr,
81940Sstevel@tonic-gate 		    &derived_key, 1, B_FALSE);
81950Sstevel@tonic-gate 
81960Sstevel@tonic-gate 		if (error != CRYPTO_SUCCESS) {
81970Sstevel@tonic-gate 			(void) dprov_destroy_object(softc, session,
81980Sstevel@tonic-gate 			    *object_id_ptr);
81990Sstevel@tonic-gate 		}
82000Sstevel@tonic-gate 
82010Sstevel@tonic-gate free_derived_key:
82020Sstevel@tonic-gate 		bzero(digest_buf, hash_size);
82030Sstevel@tonic-gate 		kmem_free(digest_buf, hash_size);
82044219Smcpowers 		break;
82054219Smcpowers 	}
82064219Smcpowers 
82074219Smcpowers 	case DPROV_REQ_NOSTORE_KEY_GENERATE: {
82084219Smcpowers 		crypto_object_attribute_t *out_template;
82094219Smcpowers 		uint_t out_attribute_count;
82104219Smcpowers 		void *value;
82114219Smcpowers 		size_t value_len = 0;
82124219Smcpowers 
82134219Smcpowers 		out_template = taskq_req->dr_key_req.kr_out_template1;
82144219Smcpowers 		out_attribute_count =
82154219Smcpowers 		    taskq_req->dr_key_req.kr_out_attribute_count1;
82164219Smcpowers 
82174219Smcpowers 		error = dprov_get_template_attr_array(out_template,
82184219Smcpowers 		    out_attribute_count, DPROV_CKA_VALUE, &value, &value_len);
82194219Smcpowers 		if (error != CRYPTO_SUCCESS)
82204219Smcpowers 			break;
82214219Smcpowers 
82224219Smcpowers 		/* fill the entire array with pattern */
82234219Smcpowers 		{
82244219Smcpowers 			int i = 0;
82254219Smcpowers 			char *p = value;
82264219Smcpowers 			while (i < value_len) {
82274219Smcpowers 				p[i++] = 'A';
82284219Smcpowers 				if (i >= value_len)
82294219Smcpowers 					break;
82304219Smcpowers 				p[i++] = 'B';
82314219Smcpowers 				if (i >= value_len)
82324219Smcpowers 					break;
82334219Smcpowers 				p[i++] = 'C';
82344219Smcpowers 			}
82354219Smcpowers 		}
82364219Smcpowers 
82374219Smcpowers 		error = CRYPTO_SUCCESS;
82384219Smcpowers 		break;
82394219Smcpowers 	}
82404424Sizick 
82414424Sizick 	case DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR: {
82424424Sizick 		crypto_mechanism_t *mechp;
82434424Sizick 		crypto_object_attribute_t *pub_template;
82445697Smcpowers 		crypto_object_attribute_t *pri_template;
82454424Sizick 		uint_t pub_attribute_count;
82465697Smcpowers 		uint_t pri_attribute_count;
82474424Sizick 		crypto_object_attribute_t *out_pub_template;
82484424Sizick 		crypto_object_attribute_t *out_pri_template;
82494424Sizick 		uint_t out_pub_attribute_count;
82504424Sizick 		uint_t out_pri_attribute_count;
82514424Sizick 
82524424Sizick 		mechp = taskq_req->dr_key_req.kr_mechanism;
82534424Sizick 		pub_template = taskq_req->dr_key_req.kr_template;
82544424Sizick 		pub_attribute_count = taskq_req->dr_key_req.kr_attribute_count;
82555697Smcpowers 		pri_template = taskq_req->dr_key_req.kr_private_key_template;
82565697Smcpowers 		pri_attribute_count =
82575697Smcpowers 		    taskq_req->dr_key_req.kr_private_key_attribute_count;
82584424Sizick 		out_pub_template = taskq_req->dr_key_req.kr_out_template1;
82594424Sizick 		out_pub_attribute_count =
82604424Sizick 		    taskq_req->dr_key_req.kr_out_attribute_count1;
82614424Sizick 		out_pri_template = taskq_req->dr_key_req.kr_out_template2;
82624424Sizick 		out_pri_attribute_count =
82634424Sizick 		    taskq_req->dr_key_req.kr_out_attribute_count2;
82644424Sizick 
82654424Sizick 		switch (mechp->cm_type) {
82664424Sizick 		case RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE:
82674424Sizick 			error = nostore_copy_attribute(out_pub_template,
82684424Sizick 			    out_pub_attribute_count, DPROV_CKA_MODULUS);
82694424Sizick 			if (error != CRYPTO_SUCCESS)
82704424Sizick 				break;
82714424Sizick 
82724424Sizick 			error = nostore_copy_attribute(out_pub_template,
82734424Sizick 			    out_pub_attribute_count, DPROV_CKA_PUBLIC_EXPONENT);
82744424Sizick 			if (error == CRYPTO_ARGUMENTS_BAD) {
82754424Sizick 				size_t tmp_len = 0;
82764424Sizick 				void *tmp;
82774424Sizick 
82784424Sizick 				/* public exponent must be here */
82794424Sizick 				error = dprov_get_template_attr_array(
82804424Sizick 				    pub_template, pub_attribute_count,
82814424Sizick 				    DPROV_CKA_PUBLIC_EXPONENT, &tmp, &tmp_len);
82824424Sizick 				if (error != CRYPTO_SUCCESS)
82834424Sizick 					break;
82844424Sizick 			}
82854424Sizick 			error = nostore_copy_attribute(out_pri_template,
82864424Sizick 			    out_pri_attribute_count, DPROV_CKA_MODULUS);
82874424Sizick 			if (error != CRYPTO_SUCCESS)
82884424Sizick 				break;
82894424Sizick 
82904424Sizick 			error = nostore_copy_attribute(out_pri_template,
82914424Sizick 			    out_pri_attribute_count,
82924424Sizick 			    DPROV_CKA_PRIVATE_EXPONENT);
82934424Sizick 			break;
82944424Sizick 
82954424Sizick 		case DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE:
82964424Sizick 			/*
82974424Sizick 			 * There is no software provider for DH mechanism;
82984424Sizick 			 * Just return pre-defined values.
82994424Sizick 			 */
83004424Sizick 			error = nostore_copy_attribute(out_pub_template,
83014424Sizick 			    out_pub_attribute_count, DPROV_CKA_VALUE);
83024424Sizick 			error = nostore_copy_attribute(out_pri_template,
83034424Sizick 			    out_pri_attribute_count, DPROV_CKA_VALUE);
83044424Sizick 			break;
83054424Sizick 
83065697Smcpowers 		case EC_KEY_PAIR_GEN_MECH_INFO_TYPE: {
83075697Smcpowers 			crypto_mechanism_t mech, *mechp;
83085697Smcpowers 			kcf_req_params_t params;
83095697Smcpowers 			crypto_object_attribute_t *pub_template;
83105697Smcpowers 			uint_t pub_attribute_count;
83115697Smcpowers 			crypto_object_attribute_t *out_pub_template;
83125697Smcpowers 			crypto_object_attribute_t *out_pri_template;
83135697Smcpowers 			uint_t out_pub_attribute_count;
83145697Smcpowers 			uint_t out_pri_attribute_count;
83155697Smcpowers 
83165697Smcpowers 			mechp = taskq_req->dr_key_req.kr_mechanism;
83175697Smcpowers 			pub_template = taskq_req->dr_key_req.kr_template;
83185697Smcpowers 			pub_attribute_count =
83195697Smcpowers 			    taskq_req->dr_key_req.kr_attribute_count;
83205697Smcpowers 			out_pub_template =
83215697Smcpowers 			    taskq_req->dr_key_req.kr_out_template1;
83225697Smcpowers 			out_pub_attribute_count =
83235697Smcpowers 			    taskq_req->dr_key_req.kr_out_attribute_count1;
83245697Smcpowers 			out_pri_template =
83255697Smcpowers 			    taskq_req->dr_key_req.kr_out_template2;
83265697Smcpowers 			out_pri_attribute_count =
83275697Smcpowers 			    taskq_req->dr_key_req.kr_out_attribute_count2;
83285697Smcpowers 
83295697Smcpowers 			/* get the software provider for this mechanism */
83305697Smcpowers 			mech = *mechp;
83315697Smcpowers 			if ((error = dprov_get_sw_prov(mechp, &pd,
83325697Smcpowers 			    &mech.cm_type)) != CRYPTO_SUCCESS)
83335697Smcpowers 				break;
83345697Smcpowers 			/*
83355697Smcpowers 			 * Turn 32-bit values into 64-bit values for certain
83365697Smcpowers 			 * attributes like CKA_CLASS.
83375697Smcpowers 			 */
83385697Smcpowers 			dprov_adjust_attrs(pub_template, pub_attribute_count);
83395697Smcpowers 			dprov_adjust_attrs(pri_template, pri_attribute_count);
83405697Smcpowers 
83415697Smcpowers 			/* bypass the kernel API for now */
83425697Smcpowers 			KCF_WRAP_NOSTORE_KEY_OPS_PARAMS(&params,
83435697Smcpowers 			    KCF_OP_KEY_GENERATE_PAIR,
83445697Smcpowers 			    0, /* session 0 for sw provider */
83455697Smcpowers 			    &mech, pub_template, pub_attribute_count,
83465697Smcpowers 			    pri_template, pri_attribute_count, NULL,
83475697Smcpowers 			    out_pub_template, out_pub_attribute_count,
83485697Smcpowers 			    out_pri_template, out_pri_attribute_count);
83495697Smcpowers 
83505697Smcpowers 			error = kcf_submit_request(pd, NULL, NULL, &params,
83515697Smcpowers 			    B_FALSE);
83525697Smcpowers 
83535697Smcpowers 			KCF_PROV_REFRELE(pd);
83545697Smcpowers 			break;
83555697Smcpowers 		}
83564424Sizick 		default:
83574424Sizick 			error = CRYPTO_MECHANISM_INVALID;
83584424Sizick 		}
83594424Sizick 		break;
83604424Sizick 	}
83614424Sizick 
83624424Sizick 	case DPROV_REQ_NOSTORE_KEY_DERIVE: {
83634424Sizick 		crypto_mechanism_t *mechp;
83644424Sizick 		crypto_object_attribute_t *in_template, *out_template;
83654424Sizick 		crypto_key_t *base_key;
83664424Sizick 		uint_t in_attribute_count, out_attribute_count;
83674424Sizick 		ulong_t key_type;
83684424Sizick 		void *value;
83694424Sizick 		size_t value_len = 0;
83704424Sizick 		size_t value_len_value = 0;
83714424Sizick 
83724424Sizick 		in_template = taskq_req->dr_key_req.kr_template;
83734424Sizick 		out_template = taskq_req->dr_key_req.kr_out_template1;
83744424Sizick 		in_attribute_count = taskq_req->dr_key_req.kr_attribute_count;
83754424Sizick 		out_attribute_count =
83764424Sizick 		    taskq_req->dr_key_req.kr_out_attribute_count1;
83774424Sizick 		mechp = taskq_req->dr_key_req.kr_mechanism;
83784424Sizick 		base_key = taskq_req->dr_key_req.kr_key;
83794424Sizick 
83804424Sizick 		/*
83814424Sizick 		 * CKA_VALUE must be present so the derived key can
83824424Sizick 		 * be returned by value.
83834424Sizick 		 */
83844424Sizick 		if (dprov_get_template_attr_array(out_template,
83854424Sizick 		    out_attribute_count, DPROV_CKA_VALUE, &value,
83864424Sizick 		    &value_len) != CRYPTO_SUCCESS) {
83874424Sizick 			error = CRYPTO_TEMPLATE_INCOMPLETE;
83884424Sizick 			break;
83894424Sizick 		}
83904424Sizick 
83914424Sizick 		if (dprov_get_template_attr_ulong(in_template,
83924424Sizick 		    in_attribute_count, DPROV_CKA_KEY_TYPE,
83934424Sizick 		    &key_type) != CRYPTO_SUCCESS) {
83944424Sizick 			error = CRYPTO_TEMPLATE_INCOMPLETE;
83954424Sizick 			break;
83964424Sizick 		}
83974424Sizick 		switch (mechp->cm_type) {
83984424Sizick 		case DH_PKCS_DERIVE_MECH_INFO_TYPE: {
83994424Sizick 			size_t tmp_len = 0;
84004424Sizick 			void *tmp;
84014424Sizick 
84024424Sizick 			if (base_key->ck_format != CRYPTO_KEY_ATTR_LIST) {
84034424Sizick 				error = CRYPTO_ARGUMENTS_BAD;
84044424Sizick 				break;
84054424Sizick 			}
84064424Sizick 
84074424Sizick 			if ((dprov_get_template_attr_array(base_key->ck_attrs,
84084424Sizick 			    base_key->ck_count, DPROV_CKA_BASE, &tmp,
84094424Sizick 			    &tmp_len) != CRYPTO_SUCCESS) ||
84104424Sizick 			    (dprov_get_template_attr_array(base_key->ck_attrs,
84114424Sizick 			    base_key->ck_count, DPROV_CKA_PRIME, &tmp,
84124424Sizick 			    &tmp_len) != CRYPTO_SUCCESS) ||
84134424Sizick 			    (dprov_get_template_attr_array(base_key->ck_attrs,
84144424Sizick 			    base_key->ck_count, DPROV_CKA_VALUE, &tmp,
84154424Sizick 			    &tmp_len) != CRYPTO_SUCCESS)) {
84164424Sizick 				error = CRYPTO_TEMPLATE_INCOMPLETE;
84174424Sizick 				break;
84184424Sizick 			}
84194424Sizick 
84204424Sizick 			/*
84214424Sizick 			 * CKA_VALUE is added to the derived key template by
84224424Sizick 			 * the library.
84234424Sizick 			 */
84244424Sizick 			error = CRYPTO_SUCCESS;
84254424Sizick 			switch (key_type) {
84264424Sizick 			case DPROV_CKK_AES:
84274424Sizick 				if (dprov_get_template_attr_ulong(in_template,
84284424Sizick 				    in_attribute_count, DPROV_CKA_VALUE_LEN,
84294424Sizick 				    &value_len_value) != CRYPTO_SUCCESS) {
84304424Sizick 					error = CRYPTO_TEMPLATE_INCOMPLETE;
84314424Sizick 					break;
84324424Sizick 				}
84334424Sizick 				if (value_len != value_len_value) {
84344424Sizick 					error = CRYPTO_TEMPLATE_INCONSISTENT;
84354424Sizick 					break;
84364424Sizick 				}
84374424Sizick 			default:
84384424Sizick 				error = CRYPTO_MECHANISM_INVALID;
84394424Sizick 			}
84404424Sizick 			if (error == CRYPTO_SUCCESS)
84414424Sizick 				fill_dh(value, value_len);
84424424Sizick 			break;
84434424Sizick 		}
84445697Smcpowers 		case ECDH1_DERIVE_MECH_INFO_TYPE: {
84455697Smcpowers 			crypto_mechanism_t mech;
84465697Smcpowers 			kcf_req_params_t params;
84475697Smcpowers 
84485697Smcpowers 			/* get the software provider for this mechanism */
84495697Smcpowers 			mech = *mechp;
84505697Smcpowers 			if ((error = dprov_get_sw_prov(mechp, &pd,
84515697Smcpowers 			    &mech.cm_type)) != CRYPTO_SUCCESS)
84525697Smcpowers 				break;
84535697Smcpowers 
84545697Smcpowers 			/*
84555697Smcpowers 			 * Turn 32-bit values into 64-bit values for certain
84565697Smcpowers 			 * attributes like CKA_VALUE_LEN.
84575697Smcpowers 			 */
84585697Smcpowers 			dprov_adjust_attrs(in_template, in_attribute_count);
84595697Smcpowers 
84605697Smcpowers 			/* bypass the kernel API for now */
84615697Smcpowers 			KCF_WRAP_NOSTORE_KEY_OPS_PARAMS(&params,
84625697Smcpowers 			    KCF_OP_KEY_DERIVE,
84635697Smcpowers 			    0, /* session 0 for sw provider */
84645697Smcpowers 			    &mech, in_template, in_attribute_count,
84655697Smcpowers 			    NULL, 0, base_key,
84665697Smcpowers 			    out_template, out_attribute_count,
84675697Smcpowers 			    NULL, 0);
84685697Smcpowers 
84695697Smcpowers 			error = kcf_submit_request(pd, NULL, NULL, &params,
84705697Smcpowers 			    B_FALSE);
84715697Smcpowers 
84725697Smcpowers 			KCF_PROV_REFRELE(pd);
84735697Smcpowers 			break;
84745697Smcpowers 		}
84755697Smcpowers 
84764424Sizick 		default:
84774424Sizick 			error = CRYPTO_MECHANISM_INVALID;
84784424Sizick 		}
84794424Sizick 		break;
84804424Sizick 	default:
84814424Sizick 		error = CRYPTO_MECHANISM_INVALID;
84824424Sizick 	}
84834219Smcpowers 	} /* end case */
84840Sstevel@tonic-gate 
84850Sstevel@tonic-gate 	mutex_exit(&softc->ds_lock);
84860Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
84870Sstevel@tonic-gate 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_task: end\n", instance));
84880Sstevel@tonic-gate }
84890Sstevel@tonic-gate 
84900Sstevel@tonic-gate /*
84910Sstevel@tonic-gate  * taskq dispatcher function for provider management operations.
84920Sstevel@tonic-gate  */
84930Sstevel@tonic-gate static void
dprov_mgmt_task(dprov_req_t * taskq_req)84940Sstevel@tonic-gate dprov_mgmt_task(dprov_req_t *taskq_req)
84950Sstevel@tonic-gate {
84960Sstevel@tonic-gate 	dprov_state_t *softc;
84970Sstevel@tonic-gate 	/* LINTED E_FUNC_SET_NOT_USED */
84980Sstevel@tonic-gate 	int instance;
84990Sstevel@tonic-gate 	int error = CRYPTO_NOT_SUPPORTED;
85000Sstevel@tonic-gate 
85010Sstevel@tonic-gate 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
85020Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_mgmt_task: started\n", instance));
85030Sstevel@tonic-gate 
85040Sstevel@tonic-gate 	mutex_enter(&softc->ds_lock);
85050Sstevel@tonic-gate 
85060Sstevel@tonic-gate 	switch (taskq_req->dr_type) {
85070Sstevel@tonic-gate 	case DPROV_REQ_MGMT_EXTINFO: {
85080Sstevel@tonic-gate 		crypto_provider_ext_info_t *ext_info =
85090Sstevel@tonic-gate 		    taskq_req->dr_mgmt_req.mr_ext_info;
85100Sstevel@tonic-gate 
85110Sstevel@tonic-gate 		(void) memset(ext_info->ei_label, ' ', CRYPTO_EXT_SIZE_LABEL);
85120Sstevel@tonic-gate 		if (!softc->ds_token_initialized) {
85130Sstevel@tonic-gate 			bcopy("(not initialized)", ext_info->ei_label,
85140Sstevel@tonic-gate 			    strlen("(not initialized)"));
85150Sstevel@tonic-gate 		} else {
85160Sstevel@tonic-gate 			bcopy(softc->ds_label, ext_info->ei_label,
85170Sstevel@tonic-gate 			    CRYPTO_EXT_SIZE_LABEL);
85180Sstevel@tonic-gate 		}
85190Sstevel@tonic-gate 
85200Sstevel@tonic-gate 		bcopy(DPROV_MANUFACTURER, ext_info->ei_manufacturerID,
85210Sstevel@tonic-gate 		    CRYPTO_EXT_SIZE_MANUF);
85220Sstevel@tonic-gate 		bcopy(DPROV_MODEL, ext_info->ei_model, CRYPTO_EXT_SIZE_MODEL);
85230Sstevel@tonic-gate 
85240Sstevel@tonic-gate 		(void) snprintf((char *)ext_info->ei_serial_number, 16, "%d%s",
85250Sstevel@tonic-gate 		    instance, DPROV_ALLSPACES);
85260Sstevel@tonic-gate 		/* PKCS#11 blank padding */
85270Sstevel@tonic-gate 		ext_info->ei_serial_number[15] = ' ';
85280Sstevel@tonic-gate 		ext_info->ei_max_session_count = CRYPTO_EFFECTIVELY_INFINITE;
85290Sstevel@tonic-gate 		ext_info->ei_max_pin_len = (ulong_t)DPROV_MAX_PIN_LEN;
85300Sstevel@tonic-gate 		ext_info->ei_min_pin_len = 1;
85310Sstevel@tonic-gate 		ext_info->ei_total_public_memory = CRYPTO_EFFECTIVELY_INFINITE;
85320Sstevel@tonic-gate 		ext_info->ei_free_public_memory = CRYPTO_EFFECTIVELY_INFINITE;
85330Sstevel@tonic-gate 		ext_info->ei_total_private_memory = CRYPTO_EFFECTIVELY_INFINITE;
85340Sstevel@tonic-gate 		ext_info->ei_free_private_memory = CRYPTO_EFFECTIVELY_INFINITE;
85350Sstevel@tonic-gate 		ext_info->ei_hardware_version.cv_major = 1;
85360Sstevel@tonic-gate 		ext_info->ei_hardware_version.cv_minor = 0;
85370Sstevel@tonic-gate 		ext_info->ei_firmware_version.cv_major = 1;
85380Sstevel@tonic-gate 		ext_info->ei_firmware_version.cv_minor = 0;
85390Sstevel@tonic-gate 
85400Sstevel@tonic-gate 		ext_info->ei_flags = CRYPTO_EXTF_RNG |
85412800Skrishna 		    CRYPTO_EXTF_LOGIN_REQUIRED |
85420Sstevel@tonic-gate 		    CRYPTO_EXTF_DUAL_CRYPTO_OPERATIONS;
85430Sstevel@tonic-gate 		if (softc->ds_user_pin_set)
85440Sstevel@tonic-gate 			ext_info->ei_flags |= CRYPTO_EXTF_USER_PIN_INITIALIZED;
85450Sstevel@tonic-gate 		if (softc->ds_token_initialized)
85460Sstevel@tonic-gate 			ext_info->ei_flags |= CRYPTO_EXTF_TOKEN_INITIALIZED;
85470Sstevel@tonic-gate 
854811304SJanie.Lu@Sun.COM 		ext_info->ei_hash_max_input_len = dprov_max_digestsz;
854911304SJanie.Lu@Sun.COM 		ext_info->ei_hmac_max_input_len = dprov_max_digestsz;
85500Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
85510Sstevel@tonic-gate 		break;
85520Sstevel@tonic-gate 	}
85530Sstevel@tonic-gate 	case DPROV_REQ_MGMT_INITTOKEN: {
85540Sstevel@tonic-gate 		char *pin = taskq_req->dr_mgmt_req.mr_pin;
85550Sstevel@tonic-gate 		size_t pin_len = taskq_req->dr_mgmt_req.mr_pin_len;
85560Sstevel@tonic-gate 		char *label = taskq_req->dr_mgmt_req.mr_label;
85570Sstevel@tonic-gate 
85580Sstevel@tonic-gate 		/* cannot initialize token when a session is open */
85590Sstevel@tonic-gate 		if (softc->ds_sessions_count > 0) {
85600Sstevel@tonic-gate 			error = CRYPTO_SESSION_EXISTS;
85610Sstevel@tonic-gate 			break;
85620Sstevel@tonic-gate 		}
85630Sstevel@tonic-gate 
85640Sstevel@tonic-gate 		/* check PIN length */
85650Sstevel@tonic-gate 		if (pin_len > DPROV_MAX_PIN_LEN) {
85660Sstevel@tonic-gate 			error = CRYPTO_PIN_LEN_RANGE;
85670Sstevel@tonic-gate 			break;
85680Sstevel@tonic-gate 		}
85690Sstevel@tonic-gate 
85700Sstevel@tonic-gate 		/* check PIN */
85710Sstevel@tonic-gate 		if (pin == NULL) {
85720Sstevel@tonic-gate 			error = CRYPTO_PIN_INVALID;
85730Sstevel@tonic-gate 			break;
85740Sstevel@tonic-gate 		}
85750Sstevel@tonic-gate 
85760Sstevel@tonic-gate 		/*
85770Sstevel@tonic-gate 		 * If the token has already been initialized, need
85780Sstevel@tonic-gate 		 * to validate supplied PIN.
85790Sstevel@tonic-gate 		 */
85800Sstevel@tonic-gate 		if (softc->ds_token_initialized &&
85810Sstevel@tonic-gate 		    (softc->ds_so_pin_len != pin_len ||
85820Sstevel@tonic-gate 		    strncmp(softc->ds_so_pin, pin, pin_len) != 0)) {
85830Sstevel@tonic-gate 			/* invalid SO PIN */
85840Sstevel@tonic-gate 			error = CRYPTO_PIN_INCORRECT;
85850Sstevel@tonic-gate 			break;
85860Sstevel@tonic-gate 		}
85870Sstevel@tonic-gate 
85880Sstevel@tonic-gate 		/* set label */
85890Sstevel@tonic-gate 		bcopy(label, softc->ds_label, CRYPTO_EXT_SIZE_LABEL);
85900Sstevel@tonic-gate 
85910Sstevel@tonic-gate 		/* set new SO PIN, update state */
85920Sstevel@tonic-gate 		bcopy(pin, softc->ds_so_pin, pin_len);
85930Sstevel@tonic-gate 		softc->ds_so_pin_len = pin_len;
85940Sstevel@tonic-gate 		softc->ds_token_initialized = B_TRUE;
85950Sstevel@tonic-gate 		softc->ds_user_pin_set = B_FALSE;
85960Sstevel@tonic-gate 
85970Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
85980Sstevel@tonic-gate 		break;
85990Sstevel@tonic-gate 	}
86000Sstevel@tonic-gate 	case DPROV_REQ_MGMT_INITPIN: {
86010Sstevel@tonic-gate 		char *pin = taskq_req->dr_mgmt_req.mr_pin;
86020Sstevel@tonic-gate 		size_t pin_len = taskq_req->dr_mgmt_req.mr_pin_len;
86030Sstevel@tonic-gate 		crypto_session_id_t session_id =
86040Sstevel@tonic-gate 		    taskq_req->dr_mgmt_req.mr_session_id;
86050Sstevel@tonic-gate 
86060Sstevel@tonic-gate 		/* check session id */
86070Sstevel@tonic-gate 		if (softc->ds_sessions[session_id] == NULL) {
86080Sstevel@tonic-gate 			error = CRYPTO_SESSION_HANDLE_INVALID;
86090Sstevel@tonic-gate 			break;
86100Sstevel@tonic-gate 		}
86110Sstevel@tonic-gate 
86120Sstevel@tonic-gate 		/* fail if not logged in as SO */
86130Sstevel@tonic-gate 		if (softc->ds_sessions[session_id]->ds_state !=
86140Sstevel@tonic-gate 		    DPROV_SESSION_STATE_SO) {
86150Sstevel@tonic-gate 			error = CRYPTO_USER_NOT_LOGGED_IN;
86160Sstevel@tonic-gate 			break;
86170Sstevel@tonic-gate 		}
86180Sstevel@tonic-gate 
86190Sstevel@tonic-gate 		/* check PIN length */
86200Sstevel@tonic-gate 		if (pin_len > DPROV_MAX_PIN_LEN) {
86210Sstevel@tonic-gate 			error = CRYPTO_PIN_LEN_RANGE;
86220Sstevel@tonic-gate 			break;
86230Sstevel@tonic-gate 		}
86240Sstevel@tonic-gate 
86250Sstevel@tonic-gate 		/* check PIN */
86260Sstevel@tonic-gate 		if (pin == NULL) {
86270Sstevel@tonic-gate 			error = CRYPTO_PIN_INVALID;
86280Sstevel@tonic-gate 			break;
86290Sstevel@tonic-gate 		}
86300Sstevel@tonic-gate 
86310Sstevel@tonic-gate 		/* set new normal user PIN */
86320Sstevel@tonic-gate 		bcopy(pin, softc->ds_user_pin, pin_len);
86330Sstevel@tonic-gate 		softc->ds_user_pin_len = pin_len;
86340Sstevel@tonic-gate 		softc->ds_user_pin_set = B_TRUE;
86350Sstevel@tonic-gate 
86360Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
86370Sstevel@tonic-gate 		break;
86380Sstevel@tonic-gate 	}
86390Sstevel@tonic-gate 	case DPROV_REQ_MGMT_SETPIN: {
86400Sstevel@tonic-gate 		char *new_pin = taskq_req->dr_mgmt_req.mr_pin;
86410Sstevel@tonic-gate 		size_t new_pin_len = taskq_req->dr_mgmt_req.mr_pin_len;
86420Sstevel@tonic-gate 		char *old_pin = taskq_req->dr_mgmt_req.mr_old_pin;
86430Sstevel@tonic-gate 		size_t old_pin_len = taskq_req->dr_mgmt_req.mr_old_pin_len;
86440Sstevel@tonic-gate 		crypto_session_id_t session_id =
86450Sstevel@tonic-gate 		    taskq_req->dr_mgmt_req.mr_session_id;
86460Sstevel@tonic-gate 
86470Sstevel@tonic-gate 		/* check session id */
86480Sstevel@tonic-gate 		if (softc->ds_sessions[session_id] == NULL) {
86490Sstevel@tonic-gate 			error = CRYPTO_SESSION_HANDLE_INVALID;
86500Sstevel@tonic-gate 			break;
86510Sstevel@tonic-gate 		}
86520Sstevel@tonic-gate 
86530Sstevel@tonic-gate 		/* check PIN length */
86540Sstevel@tonic-gate 		if (old_pin_len > DPROV_MAX_PIN_LEN ||
86550Sstevel@tonic-gate 		    new_pin_len > DPROV_MAX_PIN_LEN) {
86560Sstevel@tonic-gate 			error = CRYPTO_PIN_LEN_RANGE;
86570Sstevel@tonic-gate 			break;
86580Sstevel@tonic-gate 		}
86590Sstevel@tonic-gate 
86600Sstevel@tonic-gate 		/* check PIN */
86610Sstevel@tonic-gate 		if (old_pin == NULL || new_pin == NULL) {
86620Sstevel@tonic-gate 			error = CRYPTO_PIN_INVALID;
86630Sstevel@tonic-gate 			break;
86640Sstevel@tonic-gate 		}
86650Sstevel@tonic-gate 
86660Sstevel@tonic-gate 		/* check user PIN state */
86670Sstevel@tonic-gate 		if (!softc->ds_user_pin_set) {
86680Sstevel@tonic-gate 			error = CRYPTO_USER_PIN_NOT_INITIALIZED;
86690Sstevel@tonic-gate 			break;
86700Sstevel@tonic-gate 		}
86710Sstevel@tonic-gate 
86720Sstevel@tonic-gate 		/*
86730Sstevel@tonic-gate 		 * If the token has already been initialized, need
86740Sstevel@tonic-gate 		 * to validate supplied PIN.
86750Sstevel@tonic-gate 		 */
86760Sstevel@tonic-gate 		if (softc->ds_user_pin_len != old_pin_len ||
86770Sstevel@tonic-gate 		    strncmp(softc->ds_user_pin, old_pin, old_pin_len) != 0) {
86780Sstevel@tonic-gate 			/* invalid SO PIN */
86790Sstevel@tonic-gate 			error = CRYPTO_PIN_INCORRECT;
86800Sstevel@tonic-gate 			break;
86810Sstevel@tonic-gate 		}
86820Sstevel@tonic-gate 
86830Sstevel@tonic-gate 		/* set new PIN */
86840Sstevel@tonic-gate 		bcopy(new_pin, softc->ds_user_pin, new_pin_len);
86850Sstevel@tonic-gate 		softc->ds_user_pin_len = new_pin_len;
86860Sstevel@tonic-gate 
86870Sstevel@tonic-gate 		error = CRYPTO_SUCCESS;
86880Sstevel@tonic-gate 		break;
86890Sstevel@tonic-gate 	}
86900Sstevel@tonic-gate 	}
86910Sstevel@tonic-gate 
86920Sstevel@tonic-gate 	mutex_exit(&softc->ds_lock);
86930Sstevel@tonic-gate 	dprov_op_done(taskq_req, error);
86940Sstevel@tonic-gate 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_mgmt_task: end\n", instance));
86950Sstevel@tonic-gate }
86960Sstevel@tonic-gate 
86970Sstevel@tonic-gate /*
86980Sstevel@tonic-gate  * Returns in the location pointed to by pd a pointer to the descriptor
86990Sstevel@tonic-gate  * for the software provider for the specified mechanism.
87000Sstevel@tonic-gate  * The provider descriptor is returned held. Returns one of the CRYPTO_
87010Sstevel@tonic-gate  * error codes on failure, CRYPTO_SUCCESS on success.
87020Sstevel@tonic-gate  */
87030Sstevel@tonic-gate static int
dprov_get_sw_prov(crypto_mechanism_t * mech,kcf_provider_desc_t ** pd,crypto_mech_type_t * provider_mech_type)87040Sstevel@tonic-gate dprov_get_sw_prov(crypto_mechanism_t *mech, kcf_provider_desc_t **pd,
87050Sstevel@tonic-gate     crypto_mech_type_t *provider_mech_type)
87060Sstevel@tonic-gate {
87070Sstevel@tonic-gate 	crypto_mech_type_t kcf_mech_type = CRYPTO_MECH_INVALID;
87080Sstevel@tonic-gate 	int i, rv;
87090Sstevel@tonic-gate 
87100Sstevel@tonic-gate 	/* lookup the KCF mech type associated with our mech type */
87110Sstevel@tonic-gate 	for (i = 0; i < sizeof (dprov_mech_info_tab)/
87120Sstevel@tonic-gate 	    sizeof (crypto_mech_info_t); i++) {
87130Sstevel@tonic-gate 		if (mech->cm_type == dprov_mech_info_tab[i].cm_mech_number) {
87140Sstevel@tonic-gate 			kcf_mech_type = crypto_mech2id_common(
87154424Sizick 			    dprov_mech_info_tab[i].cm_mech_name, B_TRUE);
87160Sstevel@tonic-gate 		}
87170Sstevel@tonic-gate 	}
87180Sstevel@tonic-gate 
87193708Skrishna 	rv = kcf_get_sw_prov(kcf_mech_type, pd, NULL, B_TRUE);
87200Sstevel@tonic-gate 	if (rv == CRYPTO_SUCCESS)
87210Sstevel@tonic-gate 		*provider_mech_type = kcf_mech_type;
87220Sstevel@tonic-gate 
87230Sstevel@tonic-gate 	return (rv);
87240Sstevel@tonic-gate }
87250Sstevel@tonic-gate 
87260Sstevel@tonic-gate /*
87270Sstevel@tonic-gate  * Object management helper functions.
87280Sstevel@tonic-gate  */
87290Sstevel@tonic-gate 
87300Sstevel@tonic-gate /*
87310Sstevel@tonic-gate  * Given a crypto_key_t, return whether the key can be used or not
87320Sstevel@tonic-gate  * for the specified request. The attributes used here are defined
87330Sstevel@tonic-gate  * in table 42 of the PKCS#11 spec (Common secret key attributes).
87340Sstevel@tonic-gate  */
87350Sstevel@tonic-gate static int
dprov_key_can_use(dprov_object_t * object,dprov_req_type_t req_type)87360Sstevel@tonic-gate dprov_key_can_use(dprov_object_t *object, dprov_req_type_t req_type)
87370Sstevel@tonic-gate {
87380Sstevel@tonic-gate 	boolean_t ret = 0;
87390Sstevel@tonic-gate 	int rv = CRYPTO_SUCCESS;
87400Sstevel@tonic-gate 
87410Sstevel@tonic-gate 	/* check if object is allowed for specified operation */
87420Sstevel@tonic-gate 	switch (req_type) {
87430Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_INIT:
87440Sstevel@tonic-gate 	case DPROV_REQ_ENCRYPT_ATOMIC:
87450Sstevel@tonic-gate 		rv = dprov_get_object_attr_boolean(object,
87460Sstevel@tonic-gate 		    DPROV_CKA_ENCRYPT, &ret);
87470Sstevel@tonic-gate 		break;
87480Sstevel@tonic-gate 	case DPROV_REQ_DECRYPT_INIT:
87490Sstevel@tonic-gate 	case DPROV_REQ_DECRYPT_ATOMIC:
87500Sstevel@tonic-gate 		rv = dprov_get_object_attr_boolean(object,
87510Sstevel@tonic-gate 		    DPROV_CKA_DECRYPT, &ret);
87520Sstevel@tonic-gate 		break;
87530Sstevel@tonic-gate 	case DPROV_REQ_SIGN_INIT:
87540Sstevel@tonic-gate 	case DPROV_REQ_SIGN_ATOMIC:
87550Sstevel@tonic-gate 	case DPROV_REQ_MAC_INIT:
87560Sstevel@tonic-gate 	case DPROV_REQ_MAC_ATOMIC:
8757904Smcpowers 	case DPROV_REQ_MAC_VERIFY_ATOMIC:
87580Sstevel@tonic-gate 		rv = dprov_get_object_attr_boolean(object,
87590Sstevel@tonic-gate 		    DPROV_CKA_SIGN, &ret);
87600Sstevel@tonic-gate 		break;
87610Sstevel@tonic-gate 	case DPROV_REQ_SIGN_RECOVER_INIT:
87620Sstevel@tonic-gate 	case DPROV_REQ_SIGN_RECOVER_ATOMIC:
87630Sstevel@tonic-gate 		rv = dprov_get_object_attr_boolean(object,
87640Sstevel@tonic-gate 		    DPROV_CKA_SIGN_RECOVER, &ret);
87650Sstevel@tonic-gate 		break;
87660Sstevel@tonic-gate 	case DPROV_REQ_VERIFY_INIT:
87670Sstevel@tonic-gate 	case DPROV_REQ_VERIFY_ATOMIC:
87680Sstevel@tonic-gate 		rv = dprov_get_object_attr_boolean(object,
87690Sstevel@tonic-gate 		    DPROV_CKA_VERIFY, &ret);
87700Sstevel@tonic-gate 		break;
87710Sstevel@tonic-gate 	case DPROV_REQ_VERIFY_RECOVER_INIT:
87720Sstevel@tonic-gate 	case DPROV_REQ_VERIFY_RECOVER_ATOMIC:
87730Sstevel@tonic-gate 		rv = dprov_get_object_attr_boolean(object,
87740Sstevel@tonic-gate 		    DPROV_CKA_VERIFY_RECOVER, &ret);
87750Sstevel@tonic-gate 		break;
87760Sstevel@tonic-gate 	case DPROV_REQ_KEY_WRAP:
87770Sstevel@tonic-gate 		rv = dprov_get_object_attr_boolean(object,
87780Sstevel@tonic-gate 		    DPROV_CKA_WRAP, &ret);
87790Sstevel@tonic-gate 		break;
87800Sstevel@tonic-gate 	case DPROV_REQ_KEY_UNWRAP:
87810Sstevel@tonic-gate 		rv = dprov_get_object_attr_boolean(object,
87820Sstevel@tonic-gate 		    DPROV_CKA_UNWRAP, &ret);
87830Sstevel@tonic-gate 		break;
87840Sstevel@tonic-gate 	case DPROV_REQ_DIGEST_KEY:
87850Sstevel@tonic-gate 		/*
87860Sstevel@tonic-gate 		 * There is no attribute to check for; therefore,
87870Sstevel@tonic-gate 		 * any secret key can be used.
87880Sstevel@tonic-gate 		 */
87890Sstevel@tonic-gate 		ret = B_TRUE;
87900Sstevel@tonic-gate 		rv = CRYPTO_SUCCESS;
87910Sstevel@tonic-gate 		break;
87920Sstevel@tonic-gate 	case DPROV_REQ_KEY_DERIVE:
87930Sstevel@tonic-gate 		rv = dprov_get_object_attr_boolean(object,
87940Sstevel@tonic-gate 		    DPROV_CKA_DERIVE, &ret);
87950Sstevel@tonic-gate 		break;
87960Sstevel@tonic-gate 	}
87970Sstevel@tonic-gate 
87980Sstevel@tonic-gate 	if (rv != CRYPTO_SUCCESS || !ret)
87990Sstevel@tonic-gate 		return (CRYPTO_KEY_FUNCTION_NOT_PERMITTED);
88000Sstevel@tonic-gate 
88010Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
88020Sstevel@tonic-gate }
88030Sstevel@tonic-gate 
88040Sstevel@tonic-gate /*
88050Sstevel@tonic-gate  * Given a crypto_key_t corresponding to a secret key (i.e. for
88060Sstevel@tonic-gate  * use with symmetric crypto algorithms) specified in raw format, by
88070Sstevel@tonic-gate  * attribute, or by reference, initialize the ck_data and ck_length
88080Sstevel@tonic-gate  * fields of the ret_key argument so that they specify the key value
88090Sstevel@tonic-gate  * and length.
88100Sstevel@tonic-gate  *
88110Sstevel@tonic-gate  * For a key by value, this function uess the ck_data and ck_length,
88120Sstevel@tonic-gate  * for a key by reference, it looks up the corresponding object and
88130Sstevel@tonic-gate  * returns the appropriate attribute. For a key by attribute, it returns
88140Sstevel@tonic-gate  * the appropriate attribute. The attributes used are CKA_VALUE to retrieve
88150Sstevel@tonic-gate  * the value of the key, and CKA_VALUE_LEN to retrieve its length in bytes.
88160Sstevel@tonic-gate  */
88170Sstevel@tonic-gate static int
dprov_key_value_secret(dprov_state_t * softc,crypto_session_id_t session_id,dprov_req_type_t req_type,crypto_key_t * key,crypto_key_t * ret_key)88180Sstevel@tonic-gate dprov_key_value_secret(dprov_state_t *softc, crypto_session_id_t session_id,
88190Sstevel@tonic-gate     dprov_req_type_t req_type, crypto_key_t *key, crypto_key_t *ret_key)
88200Sstevel@tonic-gate {
88210Sstevel@tonic-gate 	ulong_t key_type;
88220Sstevel@tonic-gate 	int ret = CRYPTO_SUCCESS;
88230Sstevel@tonic-gate 
88240Sstevel@tonic-gate 	ret_key->ck_format = CRYPTO_KEY_RAW;
88250Sstevel@tonic-gate 
88260Sstevel@tonic-gate 	switch (key->ck_format) {
88270Sstevel@tonic-gate 
88280Sstevel@tonic-gate 	case CRYPTO_KEY_RAW:
88290Sstevel@tonic-gate 		ret_key->ck_data = key->ck_data;
88300Sstevel@tonic-gate 		ret_key->ck_length = key->ck_length;
88310Sstevel@tonic-gate 		break;
88320Sstevel@tonic-gate 
88330Sstevel@tonic-gate 	case CRYPTO_KEY_ATTR_LIST: {
88340Sstevel@tonic-gate 		void *value;
88350Sstevel@tonic-gate 		size_t len, value_len;
88360Sstevel@tonic-gate 
88370Sstevel@tonic-gate 		if ((ret = dprov_get_key_attr_ulong(key, DPROV_CKA_KEY_TYPE,
88380Sstevel@tonic-gate 		    &key_type)) != CRYPTO_SUCCESS)
88390Sstevel@tonic-gate 			break;
88400Sstevel@tonic-gate 
88410Sstevel@tonic-gate 		if ((ret = dprov_get_key_attr_array(key, DPROV_CKA_VALUE,
88420Sstevel@tonic-gate 		    &value, &len)) != CRYPTO_SUCCESS)
88430Sstevel@tonic-gate 			break;
88440Sstevel@tonic-gate 
88450Sstevel@tonic-gate 		/*
88460Sstevel@tonic-gate 		 * The length of the array is expressed in bytes.
88470Sstevel@tonic-gate 		 * Convert to bits now since that's how keys are measured.
88480Sstevel@tonic-gate 		 */
8849*11413Sopensolaris@drydog.com 		len  = CRYPTO_BYTES2BITS(len);
88500Sstevel@tonic-gate 
88510Sstevel@tonic-gate 		/* optional */
88520Sstevel@tonic-gate 		if ((dprov_get_key_attr_ulong(key, DPROV_CKA_VALUE_LEN,
88530Sstevel@tonic-gate 		    &value_len)) == CRYPTO_SUCCESS) {
88540Sstevel@tonic-gate 			len = value_len;
88550Sstevel@tonic-gate 		}
88560Sstevel@tonic-gate 
88570Sstevel@tonic-gate 		ret_key->ck_data = value;
88580Sstevel@tonic-gate 		ret_key->ck_length = (uint_t)len;
88590Sstevel@tonic-gate 
88600Sstevel@tonic-gate 		break;
88610Sstevel@tonic-gate 	}
88620Sstevel@tonic-gate 
88630Sstevel@tonic-gate 	case CRYPTO_KEY_REFERENCE: {
88640Sstevel@tonic-gate 		dprov_object_t *object;
88650Sstevel@tonic-gate 		void *value;
88660Sstevel@tonic-gate 		size_t len, value_len;
88670Sstevel@tonic-gate 
88680Sstevel@tonic-gate 		/* check session id */
88690Sstevel@tonic-gate 		if (softc->ds_sessions[session_id] == NULL) {
88700Sstevel@tonic-gate 			ret = CRYPTO_SESSION_HANDLE_INVALID;
88710Sstevel@tonic-gate 			break;
88720Sstevel@tonic-gate 		}
88730Sstevel@tonic-gate 
88740Sstevel@tonic-gate 		if (key->ck_obj_id >= DPROV_MAX_OBJECTS) {
88750Sstevel@tonic-gate 			ret = CRYPTO_KEY_HANDLE_INVALID;
88760Sstevel@tonic-gate 			goto bail;
88770Sstevel@tonic-gate 		}
88780Sstevel@tonic-gate 
88790Sstevel@tonic-gate 		/* check if object id specified by key is valid */
88800Sstevel@tonic-gate 		object = softc->ds_sessions[session_id]->
88810Sstevel@tonic-gate 		    ds_objects[key->ck_obj_id];
88820Sstevel@tonic-gate 		if (object == NULL) {
88830Sstevel@tonic-gate 			ret = CRYPTO_KEY_HANDLE_INVALID;
88840Sstevel@tonic-gate 			goto bail;
88850Sstevel@tonic-gate 		}
88860Sstevel@tonic-gate 
88870Sstevel@tonic-gate 		/* check if object can be used for operation */
88880Sstevel@tonic-gate 		if ((ret = dprov_key_can_use(object, req_type)) !=
88890Sstevel@tonic-gate 		    CRYPTO_SUCCESS)
88900Sstevel@tonic-gate 			goto bail;
88910Sstevel@tonic-gate 
88920Sstevel@tonic-gate 		if ((ret = dprov_get_object_attr_ulong(object,
88930Sstevel@tonic-gate 		    DPROV_CKA_KEY_TYPE, &key_type)) != CRYPTO_SUCCESS)
88940Sstevel@tonic-gate 			goto bail;
88950Sstevel@tonic-gate 
88960Sstevel@tonic-gate 		if ((ret = dprov_get_object_attr_array(object,
88970Sstevel@tonic-gate 		    DPROV_CKA_VALUE, &value, &len)) != CRYPTO_SUCCESS)
88980Sstevel@tonic-gate 			goto bail;
88990Sstevel@tonic-gate 
89000Sstevel@tonic-gate 		/* optional */
89010Sstevel@tonic-gate 		if ((dprov_get_object_attr_ulong(object, DPROV_CKA_VALUE_LEN,
89020Sstevel@tonic-gate 		    &value_len)) == CRYPTO_SUCCESS) {
89030Sstevel@tonic-gate 			len = value_len;
89040Sstevel@tonic-gate 		}
89050Sstevel@tonic-gate 
89060Sstevel@tonic-gate 		/*
89070Sstevel@tonic-gate 		 * The length of attributes are in bytes.
89080Sstevel@tonic-gate 		 * Convert to bits now since that's how keys are measured.
89090Sstevel@tonic-gate 		 */
8910*11413Sopensolaris@drydog.com 		len  = CRYPTO_BYTES2BITS(len);
89110Sstevel@tonic-gate 
89120Sstevel@tonic-gate 		ret_key->ck_data = value;
89130Sstevel@tonic-gate 		ret_key->ck_length = (uint_t)len;
89140Sstevel@tonic-gate bail:
89150Sstevel@tonic-gate 		break;
89160Sstevel@tonic-gate 	}
89170Sstevel@tonic-gate 
89180Sstevel@tonic-gate 	default:
89190Sstevel@tonic-gate 		ret = CRYPTO_ARGUMENTS_BAD;
89200Sstevel@tonic-gate 		break;
89210Sstevel@tonic-gate 	}
89220Sstevel@tonic-gate 
89230Sstevel@tonic-gate 	return (ret);
89240Sstevel@tonic-gate }
89250Sstevel@tonic-gate 
89260Sstevel@tonic-gate /*
89270Sstevel@tonic-gate  * Get the attribute list for the specified asymmetric key.
89280Sstevel@tonic-gate  */
89290Sstevel@tonic-gate static int
dprov_key_attr_asymmetric(dprov_state_t * softc,crypto_session_id_t session_id,dprov_req_type_t req_type,crypto_key_t * key,crypto_key_t * ret_key)89300Sstevel@tonic-gate dprov_key_attr_asymmetric(dprov_state_t *softc, crypto_session_id_t session_id,
89310Sstevel@tonic-gate     dprov_req_type_t req_type, crypto_key_t *key, crypto_key_t *ret_key)
89320Sstevel@tonic-gate {
89330Sstevel@tonic-gate 	int ret = CRYPTO_SUCCESS;
89340Sstevel@tonic-gate 
89350Sstevel@tonic-gate 	ret_key->ck_format = CRYPTO_KEY_ATTR_LIST;
89360Sstevel@tonic-gate 
89370Sstevel@tonic-gate 	switch (key->ck_format) {
89380Sstevel@tonic-gate 
89390Sstevel@tonic-gate 	case CRYPTO_KEY_ATTR_LIST:
89400Sstevel@tonic-gate 		ret_key->ck_attrs = key->ck_attrs;
89410Sstevel@tonic-gate 		ret_key->ck_count = key->ck_count;
89420Sstevel@tonic-gate 		break;
89430Sstevel@tonic-gate 
89440Sstevel@tonic-gate 	case CRYPTO_KEY_REFERENCE: {
89450Sstevel@tonic-gate 		dprov_object_t *object;
89460Sstevel@tonic-gate 
89470Sstevel@tonic-gate 		/* check session id */
89480Sstevel@tonic-gate 		if (softc->ds_sessions[session_id] == NULL) {
89490Sstevel@tonic-gate 			ret = CRYPTO_SESSION_HANDLE_INVALID;
89500Sstevel@tonic-gate 			break;
89510Sstevel@tonic-gate 		}
89520Sstevel@tonic-gate 
89530Sstevel@tonic-gate 		/* check if object id specified by key is valid */
89540Sstevel@tonic-gate 		object = softc->ds_sessions[session_id]->
89550Sstevel@tonic-gate 		    ds_objects[key->ck_obj_id];
89560Sstevel@tonic-gate 		if (object == NULL) {
89570Sstevel@tonic-gate 			ret = CRYPTO_KEY_HANDLE_INVALID;
89580Sstevel@tonic-gate 			break;
89590Sstevel@tonic-gate 		}
89600Sstevel@tonic-gate 
89610Sstevel@tonic-gate 		/* check if object can be used for operation */
89620Sstevel@tonic-gate 		if ((ret = dprov_key_can_use(object, req_type)) !=
89630Sstevel@tonic-gate 		    CRYPTO_SUCCESS)
89640Sstevel@tonic-gate 			break;
89650Sstevel@tonic-gate 
89660Sstevel@tonic-gate 		ret_key->ck_attrs = object->do_attr;
89670Sstevel@tonic-gate 		ret_key->ck_count = DPROV_MAX_ATTR;
89680Sstevel@tonic-gate 		break;
89690Sstevel@tonic-gate 	}
89700Sstevel@tonic-gate 
89710Sstevel@tonic-gate 	default:
89720Sstevel@tonic-gate 		ret = CRYPTO_ARGUMENTS_BAD;
89730Sstevel@tonic-gate 	}
89740Sstevel@tonic-gate 
89750Sstevel@tonic-gate 	return (ret);
89760Sstevel@tonic-gate }
89770Sstevel@tonic-gate 
89780Sstevel@tonic-gate /*
89790Sstevel@tonic-gate  * Return the index of an attribute of specified type found in
89800Sstevel@tonic-gate  * the specified array of attributes. If the attribute cannot
89810Sstevel@tonic-gate  * found, return -1.
89820Sstevel@tonic-gate  */
89830Sstevel@tonic-gate static int
dprov_find_attr(crypto_object_attribute_t * attr,uint_t nattr,uint64_t attr_type)89840Sstevel@tonic-gate dprov_find_attr(crypto_object_attribute_t *attr, uint_t nattr,
89850Sstevel@tonic-gate     uint64_t attr_type)
89860Sstevel@tonic-gate {
89870Sstevel@tonic-gate 	int i;
89880Sstevel@tonic-gate 
89890Sstevel@tonic-gate 	for (i = 0; i < nattr; i++)
89900Sstevel@tonic-gate 		if (attr[i].oa_value != NULL &&
89910Sstevel@tonic-gate 		    attr[i].oa_type == attr_type)
89920Sstevel@tonic-gate 			return (i);
89930Sstevel@tonic-gate 
89940Sstevel@tonic-gate 	return (-1);
89950Sstevel@tonic-gate }
89960Sstevel@tonic-gate 
89970Sstevel@tonic-gate /*
89980Sstevel@tonic-gate  * Given the given object template and session, return whether
89990Sstevel@tonic-gate  * an object can be created from that template according to the
90000Sstevel@tonic-gate  * following rules:
90010Sstevel@tonic-gate  * - private objects can be created only by a logged-in user
90020Sstevel@tonic-gate  */
90030Sstevel@tonic-gate static int
dprov_template_can_create(dprov_session_t * session,crypto_object_attribute_t * template,uint_t nattr,boolean_t check_for_secret)90040Sstevel@tonic-gate dprov_template_can_create(dprov_session_t *session,
90050Sstevel@tonic-gate     crypto_object_attribute_t *template, uint_t nattr,
90060Sstevel@tonic-gate     boolean_t check_for_secret)
90070Sstevel@tonic-gate {
90080Sstevel@tonic-gate 	boolean_t is_private = B_FALSE;
90090Sstevel@tonic-gate 	ulong_t key_type, class;
90100Sstevel@tonic-gate 	int error;
90110Sstevel@tonic-gate 
90120Sstevel@tonic-gate 	/* check CKA_PRIVATE attribute value */
90130Sstevel@tonic-gate 	error = dprov_get_template_attr_boolean(template, nattr,
90140Sstevel@tonic-gate 	    DPROV_CKA_PRIVATE, &is_private);
90150Sstevel@tonic-gate 	if (error == CRYPTO_SUCCESS && is_private) {
90160Sstevel@tonic-gate 		/* it's a private object */
90170Sstevel@tonic-gate 		if (session->ds_state != DPROV_SESSION_STATE_USER) {
90180Sstevel@tonic-gate 			/*
90190Sstevel@tonic-gate 			 * Cannot create private object with SO or public
90200Sstevel@tonic-gate 			 * sessions.
90210Sstevel@tonic-gate 			 */
90220Sstevel@tonic-gate 			return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
90230Sstevel@tonic-gate 		}
90240Sstevel@tonic-gate 	}
90250Sstevel@tonic-gate 
90260Sstevel@tonic-gate 	/* all objects must have an object class attribute */
90270Sstevel@tonic-gate 	if (dprov_get_template_attr_ulong(template, nattr, DPROV_CKA_CLASS,
90280Sstevel@tonic-gate 	    &class) != CRYPTO_SUCCESS) {
90290Sstevel@tonic-gate 		return (CRYPTO_TEMPLATE_INCOMPLETE);
90300Sstevel@tonic-gate 	}
90310Sstevel@tonic-gate 
90320Sstevel@tonic-gate 	/* key objects must have a key type attribute */
90330Sstevel@tonic-gate 	if (class == DPROV_CKO_SECRET_KEY ||
90340Sstevel@tonic-gate 	    class == DPROV_CKO_PUBLIC_KEY ||
90350Sstevel@tonic-gate 	    class == DPROV_CKO_PRIVATE_KEY) {
90360Sstevel@tonic-gate 		if (!dprov_template_attr_present(template, nattr,
90370Sstevel@tonic-gate 		    DPROV_CKA_KEY_TYPE)) {
90380Sstevel@tonic-gate 			return (CRYPTO_TEMPLATE_INCOMPLETE);
90390Sstevel@tonic-gate 		}
90400Sstevel@tonic-gate 	}
90410Sstevel@tonic-gate 
90420Sstevel@tonic-gate 	/* check for RSA public key attributes that must be present */
90430Sstevel@tonic-gate 	if (class == DPROV_CKO_PUBLIC_KEY) {
90440Sstevel@tonic-gate 		if (dprov_get_template_attr_ulong(template, nattr,
90450Sstevel@tonic-gate 		    DPROV_CKA_KEY_TYPE, &key_type) == CRYPTO_SUCCESS) {
90460Sstevel@tonic-gate 			if (key_type == DPROV_CKK_RSA) {
90470Sstevel@tonic-gate 				if (!dprov_template_attr_present(template,
90480Sstevel@tonic-gate 				    nattr, DPROV_CKA_MODULUS) ||
90490Sstevel@tonic-gate 				    !dprov_template_attr_present(template,
90500Sstevel@tonic-gate 				    nattr, DPROV_CKA_PUBLIC_EXPONENT)) {
90510Sstevel@tonic-gate 					return (CRYPTO_TEMPLATE_INCOMPLETE);
90520Sstevel@tonic-gate 				}
90530Sstevel@tonic-gate 
90540Sstevel@tonic-gate 				/* these attributes should not be present */
90550Sstevel@tonic-gate 				if (dprov_template_attr_present(template, nattr,
90560Sstevel@tonic-gate 				    DPROV_CKA_MODULUS_BITS)) {
90570Sstevel@tonic-gate 					return (CRYPTO_TEMPLATE_INCONSISTENT);
90580Sstevel@tonic-gate 				}
90590Sstevel@tonic-gate 			}
90600Sstevel@tonic-gate 		}
90610Sstevel@tonic-gate 	}
90620Sstevel@tonic-gate 
90630Sstevel@tonic-gate 	/* check for RSA private key attributes that must be present */
90640Sstevel@tonic-gate 	if (class == DPROV_CKO_PRIVATE_KEY) {
90650Sstevel@tonic-gate 		if (dprov_get_template_attr_ulong(template, nattr,
90660Sstevel@tonic-gate 		    DPROV_CKA_KEY_TYPE, &key_type) == CRYPTO_SUCCESS) {
90670Sstevel@tonic-gate 			if (key_type == DPROV_CKK_RSA) {
90680Sstevel@tonic-gate 				if (!dprov_template_attr_present(template,
90690Sstevel@tonic-gate 				    nattr, DPROV_CKA_MODULUS))
90700Sstevel@tonic-gate 					return (CRYPTO_TEMPLATE_INCOMPLETE);
90710Sstevel@tonic-gate 
90720Sstevel@tonic-gate 				if (check_for_secret) {
90730Sstevel@tonic-gate 					if (!dprov_template_attr_present(
90740Sstevel@tonic-gate 					    template, nattr,
90750Sstevel@tonic-gate 					    DPROV_CKA_PRIVATE_EXPONENT))
90760Sstevel@tonic-gate 						return (
90770Sstevel@tonic-gate 						    CRYPTO_TEMPLATE_INCOMPLETE);
90780Sstevel@tonic-gate 				}
90790Sstevel@tonic-gate 			}
90800Sstevel@tonic-gate 		}
90810Sstevel@tonic-gate 	}
90820Sstevel@tonic-gate 
90830Sstevel@tonic-gate 	/* check for secret key attributes that must be present */
90840Sstevel@tonic-gate 	if (class == DPROV_CKO_SECRET_KEY) {
90850Sstevel@tonic-gate 		if (check_for_secret) {
90860Sstevel@tonic-gate 			if (!dprov_template_attr_present(template, nattr,
90870Sstevel@tonic-gate 			    DPROV_CKA_VALUE)) {
90880Sstevel@tonic-gate 				return (CRYPTO_TEMPLATE_INCOMPLETE);
90890Sstevel@tonic-gate 			}
90900Sstevel@tonic-gate 		}
90910Sstevel@tonic-gate 
90920Sstevel@tonic-gate 		/* these attributes should not be present */
90930Sstevel@tonic-gate 		if (dprov_template_attr_present(template, nattr,
90940Sstevel@tonic-gate 		    DPROV_CKA_VALUE_LEN)) {
90950Sstevel@tonic-gate 			return (CRYPTO_TEMPLATE_INCONSISTENT);
90960Sstevel@tonic-gate 		}
90970Sstevel@tonic-gate 	}
90980Sstevel@tonic-gate 
90990Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
91000Sstevel@tonic-gate }
91010Sstevel@tonic-gate 
91020Sstevel@tonic-gate /*
91030Sstevel@tonic-gate  * Create an object from the specified template. Checks whether the
91040Sstevel@tonic-gate  * object can be created according to its attributes and the state
91050Sstevel@tonic-gate  * of the session. The new session object id is returned. If the
91060Sstevel@tonic-gate  * object is a token object, it is added to the per-instance object
91070Sstevel@tonic-gate  * table as well.
91080Sstevel@tonic-gate  */
91090Sstevel@tonic-gate static int
dprov_create_object_from_template(dprov_state_t * softc,dprov_session_t * session,crypto_object_attribute_t * template,uint_t nattr,crypto_object_id_t * object_id,boolean_t check_for_secret,boolean_t force)91100Sstevel@tonic-gate dprov_create_object_from_template(dprov_state_t *softc,
91110Sstevel@tonic-gate     dprov_session_t *session, crypto_object_attribute_t *template,
91120Sstevel@tonic-gate     uint_t nattr, crypto_object_id_t *object_id, boolean_t check_for_secret,
91130Sstevel@tonic-gate     boolean_t force)
91140Sstevel@tonic-gate {
91150Sstevel@tonic-gate 	dprov_object_t *object;
91160Sstevel@tonic-gate 	boolean_t is_token = B_FALSE;
91170Sstevel@tonic-gate 	boolean_t extractable_attribute_present = B_FALSE;
91184219Smcpowers 	boolean_t sensitive_attribute_present = B_FALSE;
91190Sstevel@tonic-gate 	boolean_t private_attribute_present = B_FALSE;
91204219Smcpowers 	boolean_t token_attribute_present = B_FALSE;
91210Sstevel@tonic-gate 	uint_t i;
91220Sstevel@tonic-gate 	int error;
91230Sstevel@tonic-gate 	uint_t attr;
91240Sstevel@tonic-gate 	uint_t oattr;
9125904Smcpowers 	crypto_attr_type_t type;
9126904Smcpowers 	size_t old_len, new_len;
9127904Smcpowers 	offset_t offset;
91280Sstevel@tonic-gate 
91290Sstevel@tonic-gate 	if (nattr > DPROV_MAX_ATTR)
91300Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
91310Sstevel@tonic-gate 
91320Sstevel@tonic-gate 	if (!force) {
91330Sstevel@tonic-gate 		/* verify that object can be created */
91340Sstevel@tonic-gate 		if ((error = dprov_template_can_create(session, template,
91350Sstevel@tonic-gate 		    nattr, check_for_secret)) != CRYPTO_SUCCESS)
91360Sstevel@tonic-gate 			return (error);
91370Sstevel@tonic-gate 	}
91380Sstevel@tonic-gate 
91390Sstevel@tonic-gate 	/* allocate new object */
91400Sstevel@tonic-gate 	object = kmem_zalloc(sizeof (dprov_object_t), KM_SLEEP);
91410Sstevel@tonic-gate 	if (object == NULL)
91420Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
91430Sstevel@tonic-gate 
91440Sstevel@tonic-gate 	/* is it a token object? */
91450Sstevel@tonic-gate 	/* check CKA_TOKEN attribute value */
91460Sstevel@tonic-gate 	error = dprov_get_template_attr_boolean(template, nattr,
91470Sstevel@tonic-gate 	    DPROV_CKA_TOKEN, &is_token);
91480Sstevel@tonic-gate 	if (error == CRYPTO_SUCCESS && is_token) {
91490Sstevel@tonic-gate 		/* token object, add it to the per-instance object table */
91500Sstevel@tonic-gate 		for (i = 0; i < DPROV_MAX_OBJECTS; i++)
91510Sstevel@tonic-gate 			if (softc->ds_objects[i] == NULL)
91520Sstevel@tonic-gate 				break;
91530Sstevel@tonic-gate 		if (i == DPROV_MAX_OBJECTS)
91540Sstevel@tonic-gate 			/* no free slot */
91550Sstevel@tonic-gate 			return (CRYPTO_HOST_MEMORY);
91560Sstevel@tonic-gate 		softc->ds_objects[i] = object;
91570Sstevel@tonic-gate 		object->do_token_idx = i;
91580Sstevel@tonic-gate 		DPROV_OBJECT_REFHOLD(object);
91590Sstevel@tonic-gate 	}
91600Sstevel@tonic-gate 
91610Sstevel@tonic-gate 	/* add object to session object table */
91620Sstevel@tonic-gate 	for (i = 0; i < DPROV_MAX_OBJECTS; i++)
91630Sstevel@tonic-gate 		if (session->ds_objects[i] == NULL)
91640Sstevel@tonic-gate 			break;
91650Sstevel@tonic-gate 	if (i == DPROV_MAX_OBJECTS) {
91660Sstevel@tonic-gate 		/* no more session object slots */
91670Sstevel@tonic-gate 		DPROV_OBJECT_REFRELE(object);
91680Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
91690Sstevel@tonic-gate 	}
91700Sstevel@tonic-gate 	session->ds_objects[i] = object;
91710Sstevel@tonic-gate 	DPROV_OBJECT_REFHOLD(object);
91720Sstevel@tonic-gate 	*object_id = i;
91730Sstevel@tonic-gate 
91740Sstevel@tonic-gate 	/* initialize object from template */
91750Sstevel@tonic-gate 	for (attr = 0, oattr = 0; attr < nattr; attr++) {
91760Sstevel@tonic-gate 		if (template[attr].oa_value == NULL)
91770Sstevel@tonic-gate 			continue;
9178904Smcpowers 		type = template[attr].oa_type;
9179904Smcpowers 		old_len = template[attr].oa_value_len;
9180904Smcpowers 		new_len = attribute_size(type, old_len);
9181904Smcpowers 
9182904Smcpowers 		if (type == DPROV_CKA_EXTRACTABLE) {
91830Sstevel@tonic-gate 			extractable_attribute_present = B_TRUE;
9184904Smcpowers 		} else if (type == DPROV_CKA_PRIVATE) {
91850Sstevel@tonic-gate 			private_attribute_present = B_TRUE;
91864219Smcpowers 		} else if (type == DPROV_CKA_TOKEN) {
91874219Smcpowers 			token_attribute_present = B_TRUE;
91880Sstevel@tonic-gate 		}
9189904Smcpowers 		object->do_attr[oattr].oa_type = type;
9190904Smcpowers 		object->do_attr[oattr].oa_value_len = new_len;
9191904Smcpowers 
9192904Smcpowers 		object->do_attr[oattr].oa_value = kmem_zalloc(new_len,
9193904Smcpowers 		    KM_SLEEP);
9194904Smcpowers 
9195904Smcpowers 		offset = 0;
9196904Smcpowers #ifdef _BIG_ENDIAN
9197904Smcpowers 		if (fixed_size_attribute(type)) {
9198904Smcpowers 			offset = old_len - new_len;
9199904Smcpowers 		}
9200904Smcpowers #endif
9201904Smcpowers 		bcopy(&template[attr].oa_value[offset],
9202904Smcpowers 		    object->do_attr[oattr].oa_value, new_len);
92030Sstevel@tonic-gate 		oattr++;
92040Sstevel@tonic-gate 	}
92050Sstevel@tonic-gate 
92060Sstevel@tonic-gate 	/* add boolean attributes that must be present */
92070Sstevel@tonic-gate 	if (extractable_attribute_present == B_FALSE) {
92080Sstevel@tonic-gate 		object->do_attr[oattr].oa_type = DPROV_CKA_EXTRACTABLE;
92090Sstevel@tonic-gate 		object->do_attr[oattr].oa_value_len = 1;
92100Sstevel@tonic-gate 		object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP);
92110Sstevel@tonic-gate 		object->do_attr[oattr].oa_value[0] = B_TRUE;
92120Sstevel@tonic-gate 		oattr++;
92130Sstevel@tonic-gate 	}
92140Sstevel@tonic-gate 
92150Sstevel@tonic-gate 	if (private_attribute_present == B_FALSE) {
92160Sstevel@tonic-gate 		object->do_attr[oattr].oa_type = DPROV_CKA_PRIVATE;
92170Sstevel@tonic-gate 		object->do_attr[oattr].oa_value_len = 1;
92180Sstevel@tonic-gate 		object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP);
92190Sstevel@tonic-gate 		object->do_attr[oattr].oa_value[0] = B_FALSE;
92200Sstevel@tonic-gate 		oattr++;
92210Sstevel@tonic-gate 	}
92220Sstevel@tonic-gate 
92234219Smcpowers 	if (token_attribute_present == B_FALSE) {
92244219Smcpowers 		object->do_attr[oattr].oa_type = DPROV_CKA_TOKEN;
92254219Smcpowers 		object->do_attr[oattr].oa_value_len = 1;
92264219Smcpowers 		object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP);
92274219Smcpowers 		object->do_attr[oattr].oa_value[0] = B_FALSE;
92284219Smcpowers 		oattr++;
92294219Smcpowers 	}
92304219Smcpowers 
92314219Smcpowers 	if (sensitive_attribute_present == B_FALSE) {
92324219Smcpowers 		object->do_attr[oattr].oa_type = DPROV_CKA_SENSITIVE;
92334219Smcpowers 		object->do_attr[oattr].oa_value_len = 1;
92344219Smcpowers 		object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP);
92354219Smcpowers 		object->do_attr[oattr].oa_value[0] = B_FALSE;
92364219Smcpowers 		oattr++;
92374219Smcpowers 	}
92380Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
92390Sstevel@tonic-gate }
92400Sstevel@tonic-gate 
92410Sstevel@tonic-gate /*
92420Sstevel@tonic-gate  * Checks whether or not the object matches the specified attributes.
9243904Smcpowers  *
9244904Smcpowers  * PKCS#11 attributes which are longs are stored in uint32_t containers
9245904Smcpowers  * so they can be matched by both 32 and 64-bit applications.
92460Sstevel@tonic-gate  */
92470Sstevel@tonic-gate static boolean_t
dprov_attributes_match(dprov_object_t * object,crypto_object_attribute_t * template,uint_t nattr)92480Sstevel@tonic-gate dprov_attributes_match(dprov_object_t *object,
92490Sstevel@tonic-gate     crypto_object_attribute_t *template, uint_t nattr)
92500Sstevel@tonic-gate {
9251904Smcpowers 	crypto_attr_type_t type;
9252904Smcpowers 	size_t tlen, olen, diff;
92530Sstevel@tonic-gate 	int ta_idx;	/* template attribute index */
92540Sstevel@tonic-gate 	int oa_idx;	/* object attribute index */
92550Sstevel@tonic-gate 
92560Sstevel@tonic-gate 	for (ta_idx = 0; ta_idx < nattr; ta_idx++) {
92570Sstevel@tonic-gate 		/* no value for template attribute */
92580Sstevel@tonic-gate 		if (template[ta_idx].oa_value == NULL)
92590Sstevel@tonic-gate 			continue;
92600Sstevel@tonic-gate 
92610Sstevel@tonic-gate 		/* find attribute in object */
9262904Smcpowers 		type = template[ta_idx].oa_type;
9263904Smcpowers 		oa_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR, type);
92640Sstevel@tonic-gate 
92650Sstevel@tonic-gate 		if (oa_idx == -1)
92660Sstevel@tonic-gate 			/* attribute not found in object */
92670Sstevel@tonic-gate 			return (B_FALSE);
92680Sstevel@tonic-gate 
9269904Smcpowers 		tlen = template[ta_idx].oa_value_len;
9270904Smcpowers 		olen = object->do_attr[oa_idx].oa_value_len;
9271904Smcpowers 		if (tlen < olen)
92720Sstevel@tonic-gate 			return (B_FALSE);
92730Sstevel@tonic-gate 
9274904Smcpowers 		diff = 0;
9275904Smcpowers #ifdef _BIG_ENDIAN
9276904Smcpowers 		/* application may think attribute is 8 bytes */
9277904Smcpowers 		if (fixed_size_attribute(type))
9278904Smcpowers 			diff = tlen - olen;
9279904Smcpowers #endif
9280904Smcpowers 
9281904Smcpowers 		if (bcmp(&template[ta_idx].oa_value[diff],
9282904Smcpowers 		    object->do_attr[oa_idx].oa_value, olen) != 0)
92830Sstevel@tonic-gate 			/* value mismatch */
92840Sstevel@tonic-gate 			return (B_FALSE);
92850Sstevel@tonic-gate 	}
92860Sstevel@tonic-gate 
92870Sstevel@tonic-gate 	return (B_TRUE);
92880Sstevel@tonic-gate }
92890Sstevel@tonic-gate 
92900Sstevel@tonic-gate /*
92910Sstevel@tonic-gate  * Destroy the object specified by its session and object id.
92920Sstevel@tonic-gate  */
92930Sstevel@tonic-gate static int
dprov_destroy_object(dprov_state_t * softc,dprov_session_t * session,crypto_object_id_t object_id)92940Sstevel@tonic-gate dprov_destroy_object(dprov_state_t *softc, dprov_session_t *session,
92950Sstevel@tonic-gate     crypto_object_id_t object_id)
92960Sstevel@tonic-gate {
92970Sstevel@tonic-gate 	dprov_object_t *object;
92980Sstevel@tonic-gate 
92990Sstevel@tonic-gate 	if ((object = session->ds_objects[object_id]) == NULL)
93000Sstevel@tonic-gate 		return (CRYPTO_OBJECT_HANDLE_INVALID);
93010Sstevel@tonic-gate 
93020Sstevel@tonic-gate 	/* remove from session table */
93030Sstevel@tonic-gate 	session->ds_objects[object_id] = NULL;
93043940Smcpowers 
93053940Smcpowers 	if (dprov_object_is_token(object)) {
93063940Smcpowers 		if (!object->do_destroyed) {
93073940Smcpowers 			object->do_destroyed = B_TRUE;
93083940Smcpowers 			/* remove from per-instance token table */
93093940Smcpowers 			softc->ds_objects[object->do_token_idx] = NULL;
93103940Smcpowers 			DPROV_OBJECT_REFRELE(object);
93113940Smcpowers 		} else {
93123940Smcpowers 			DPROV_DEBUG(D_OBJECT, ("dprov_destroy_object: "
93133940Smcpowers 			    "object %p already destroyed\n", (void *)object));
93143940Smcpowers 		}
93153940Smcpowers 	}
93163940Smcpowers 
93170Sstevel@tonic-gate 	DPROV_OBJECT_REFRELE(object);
93180Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
93190Sstevel@tonic-gate }
93200Sstevel@tonic-gate 
93210Sstevel@tonic-gate static int
dprov_object_can_modify(dprov_object_t * object,crypto_object_attribute_t * template,uint_t nattr)93220Sstevel@tonic-gate dprov_object_can_modify(dprov_object_t *object,
93230Sstevel@tonic-gate     crypto_object_attribute_t *template, uint_t nattr)
93240Sstevel@tonic-gate {
93250Sstevel@tonic-gate 	ulong_t object_class;
93260Sstevel@tonic-gate 
93270Sstevel@tonic-gate 	/* all objects should have an object class attribute */
93280Sstevel@tonic-gate 	if (dprov_get_object_attr_ulong(object, DPROV_CKA_CLASS,
93290Sstevel@tonic-gate 	    &object_class) != CRYPTO_SUCCESS) {
93300Sstevel@tonic-gate 		return (CRYPTO_SUCCESS);
93310Sstevel@tonic-gate 	}
93320Sstevel@tonic-gate 
93330Sstevel@tonic-gate 	if (object_class == DPROV_CKO_SECRET_KEY ||
93340Sstevel@tonic-gate 	    object_class == DPROV_CKO_PUBLIC_KEY ||
93350Sstevel@tonic-gate 	    object_class == DPROV_CKO_PRIVATE_KEY) {
93360Sstevel@tonic-gate 		if (dprov_template_attr_present(template, nattr,
93370Sstevel@tonic-gate 		    DPROV_CKA_CLASS) ||
93380Sstevel@tonic-gate 		    dprov_template_attr_present(template, nattr,
93390Sstevel@tonic-gate 		    DPROV_CKA_KEY_TYPE))
93400Sstevel@tonic-gate 			return (CRYPTO_TEMPLATE_INCONSISTENT);
93410Sstevel@tonic-gate 	}
93420Sstevel@tonic-gate 
93430Sstevel@tonic-gate 	switch (object_class) {
93440Sstevel@tonic-gate 	case DPROV_CKO_SECRET_KEY:
93450Sstevel@tonic-gate 		if (dprov_template_attr_present(template, nattr,
93460Sstevel@tonic-gate 		    DPROV_CKA_VALUE))
93470Sstevel@tonic-gate 			return (CRYPTO_TEMPLATE_INCONSISTENT);
93480Sstevel@tonic-gate 		break;
93490Sstevel@tonic-gate 
93500Sstevel@tonic-gate 	case DPROV_CKO_PUBLIC_KEY:
93510Sstevel@tonic-gate 		if (dprov_template_attr_present(template, nattr,
93520Sstevel@tonic-gate 		    DPROV_CKA_MODULUS) ||
93530Sstevel@tonic-gate 		    dprov_template_attr_present(template, nattr,
93540Sstevel@tonic-gate 		    DPROV_CKA_PUBLIC_EXPONENT))
93550Sstevel@tonic-gate 			return (CRYPTO_TEMPLATE_INCONSISTENT);
93560Sstevel@tonic-gate 		break;
93570Sstevel@tonic-gate 
93580Sstevel@tonic-gate 	case DPROV_CKO_PRIVATE_KEY:
93590Sstevel@tonic-gate 		if (dprov_template_attr_present(template, nattr,
93600Sstevel@tonic-gate 		    DPROV_CKA_MODULUS) ||
93610Sstevel@tonic-gate 		    dprov_template_attr_present(template, nattr,
93620Sstevel@tonic-gate 		    DPROV_CKA_PRIVATE_EXPONENT))
93630Sstevel@tonic-gate 			return (CRYPTO_TEMPLATE_INCONSISTENT);
93640Sstevel@tonic-gate 		break;
93650Sstevel@tonic-gate 
93660Sstevel@tonic-gate 	default:
93670Sstevel@tonic-gate 		return (CRYPTO_SUCCESS);
93680Sstevel@tonic-gate 	}
93690Sstevel@tonic-gate 
93700Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
93710Sstevel@tonic-gate }
93720Sstevel@tonic-gate 
93730Sstevel@tonic-gate /*
93740Sstevel@tonic-gate  * Set the attributes specified by the template in the specified object,
93750Sstevel@tonic-gate  * replacing existing ones if needed.
93760Sstevel@tonic-gate  */
93770Sstevel@tonic-gate static int
dprov_object_set_attr(dprov_session_t * session,crypto_object_id_t object_id,crypto_object_attribute_t * template,uint_t nattr,boolean_t check_attributes)93780Sstevel@tonic-gate dprov_object_set_attr(dprov_session_t *session, crypto_object_id_t object_id,
93790Sstevel@tonic-gate     crypto_object_attribute_t *template, uint_t nattr,
93800Sstevel@tonic-gate     boolean_t check_attributes)
93810Sstevel@tonic-gate {
9382904Smcpowers 	crypto_attr_type_t type;
93830Sstevel@tonic-gate 	dprov_object_t *object;
9384904Smcpowers 	size_t old_len, new_len;
93850Sstevel@tonic-gate 	uint_t i, j;
93860Sstevel@tonic-gate 	int error;
93870Sstevel@tonic-gate 
93880Sstevel@tonic-gate 	if ((object = session->ds_objects[object_id]) == NULL)
93890Sstevel@tonic-gate 		return (CRYPTO_OBJECT_HANDLE_INVALID);
93900Sstevel@tonic-gate 
93910Sstevel@tonic-gate 	if (check_attributes) {
93920Sstevel@tonic-gate 		/* verify that attributes in the template can be modified */
93930Sstevel@tonic-gate 		if ((error = dprov_object_can_modify(object, template, nattr))
93940Sstevel@tonic-gate 		    != CRYPTO_SUCCESS)
93950Sstevel@tonic-gate 			return (error);
93960Sstevel@tonic-gate 	}
93970Sstevel@tonic-gate 
93980Sstevel@tonic-gate 	/* go through the attributes specified in the template */
93990Sstevel@tonic-gate 	for (i = 0; i < nattr; i++) {
94000Sstevel@tonic-gate 		if (template[i].oa_value == NULL)
94010Sstevel@tonic-gate 			continue;
94020Sstevel@tonic-gate 
94030Sstevel@tonic-gate 		/* find attribute in object */
9404904Smcpowers 		type = template[i].oa_type;
9405904Smcpowers 		j = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR, type);
94060Sstevel@tonic-gate 
94070Sstevel@tonic-gate 		if (j != -1) {
94080Sstevel@tonic-gate 			/* attribute already exists, free old value */
94090Sstevel@tonic-gate 			kmem_free(object->do_attr[j].oa_value,
94100Sstevel@tonic-gate 			    object->do_attr[j].oa_value_len);
94110Sstevel@tonic-gate 		} else {
94120Sstevel@tonic-gate 			/* attribute does not exist, create it */
94130Sstevel@tonic-gate 			for (j = 0; j < DPROV_MAX_ATTR; j++)
94140Sstevel@tonic-gate 				if (object->do_attr[j].oa_value == NULL)
94150Sstevel@tonic-gate 					break;
94160Sstevel@tonic-gate 			if (j == DPROV_MAX_ATTR)
94170Sstevel@tonic-gate 				/* ran out of attribute slots */
94180Sstevel@tonic-gate 				return (CRYPTO_HOST_MEMORY);
94190Sstevel@tonic-gate 		}
94200Sstevel@tonic-gate 
9421904Smcpowers 		old_len = template[i].oa_value_len;
9422904Smcpowers 		new_len = attribute_size(type, old_len);
9423904Smcpowers 
94240Sstevel@tonic-gate 		/* set object attribute value */
9425904Smcpowers 		object->do_attr[j].oa_value = kmem_alloc(new_len, KM_SLEEP);
9426904Smcpowers 		bcopy(&template[i].oa_value[old_len - new_len],
9427904Smcpowers 		    object->do_attr[j].oa_value, new_len);
9428904Smcpowers 		object->do_attr[j].oa_value_len = new_len;
94290Sstevel@tonic-gate 
94300Sstevel@tonic-gate 		/* and the type */
9431904Smcpowers 		object->do_attr[j].oa_type = type;
94320Sstevel@tonic-gate 	}
94330Sstevel@tonic-gate 
94340Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
94350Sstevel@tonic-gate }
94360Sstevel@tonic-gate 
94370Sstevel@tonic-gate 
94380Sstevel@tonic-gate /*
94390Sstevel@tonic-gate  * Free the specified object.
94400Sstevel@tonic-gate  */
94410Sstevel@tonic-gate static void
dprov_free_object(dprov_object_t * object)94420Sstevel@tonic-gate dprov_free_object(dprov_object_t *object)
94430Sstevel@tonic-gate {
94440Sstevel@tonic-gate 	int i;
94450Sstevel@tonic-gate 
94460Sstevel@tonic-gate 	/* free the object attributes values */
94470Sstevel@tonic-gate 	for (i = 0; i < DPROV_MAX_ATTR; i++)
94480Sstevel@tonic-gate 		if (object->do_attr[i].oa_value != NULL)
94490Sstevel@tonic-gate 			kmem_free(object->do_attr[i].oa_value,
94500Sstevel@tonic-gate 			    object->do_attr[i].oa_value_len);
94510Sstevel@tonic-gate 
94520Sstevel@tonic-gate 	/* free the object */
94530Sstevel@tonic-gate 	kmem_free(object, sizeof (dprov_object_t));
94540Sstevel@tonic-gate }
94550Sstevel@tonic-gate 
94560Sstevel@tonic-gate /*
94570Sstevel@tonic-gate  * Checks whether the specified object is a private or public object.
94580Sstevel@tonic-gate  */
94590Sstevel@tonic-gate static boolean_t
dprov_object_is_private(dprov_object_t * object)94600Sstevel@tonic-gate dprov_object_is_private(dprov_object_t *object)
94610Sstevel@tonic-gate {
94620Sstevel@tonic-gate 	boolean_t ret;
94630Sstevel@tonic-gate 	int err;
94640Sstevel@tonic-gate 
94650Sstevel@tonic-gate 	err = dprov_get_object_attr_boolean(object, DPROV_CKA_PRIVATE, &ret);
94660Sstevel@tonic-gate 
94670Sstevel@tonic-gate 	if (err != CRYPTO_SUCCESS)
94680Sstevel@tonic-gate 		/* by default, CKA_PRIVATE is false */
94690Sstevel@tonic-gate 		ret = B_FALSE;
94700Sstevel@tonic-gate 
94710Sstevel@tonic-gate 	return (ret);
94720Sstevel@tonic-gate }
94730Sstevel@tonic-gate 
94740Sstevel@tonic-gate /*
94750Sstevel@tonic-gate  * Checks whether the specified object is a token or session object.
94760Sstevel@tonic-gate  */
94770Sstevel@tonic-gate static boolean_t
dprov_object_is_token(dprov_object_t * object)94780Sstevel@tonic-gate dprov_object_is_token(dprov_object_t *object)
94790Sstevel@tonic-gate {
94800Sstevel@tonic-gate 	boolean_t ret;
94810Sstevel@tonic-gate 	int err;
94820Sstevel@tonic-gate 
94830Sstevel@tonic-gate 	err = dprov_get_object_attr_boolean(object, DPROV_CKA_TOKEN, &ret);
94840Sstevel@tonic-gate 
94850Sstevel@tonic-gate 	if (err != CRYPTO_SUCCESS)
94860Sstevel@tonic-gate 		/* by default, CKA_TOKEN is false */
94870Sstevel@tonic-gate 		ret = B_FALSE;
94880Sstevel@tonic-gate 
94890Sstevel@tonic-gate 	return (ret);
94900Sstevel@tonic-gate }
94910Sstevel@tonic-gate 
94920Sstevel@tonic-gate /*
94930Sstevel@tonic-gate  * Common function used by the dprov_get_object_attr_*() family of
94940Sstevel@tonic-gate  * functions. Returns the value of the specified attribute of specified
94950Sstevel@tonic-gate  * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID
94960Sstevel@tonic-gate  * if the length of the attribute does not match the specified length,
94970Sstevel@tonic-gate  * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found.
94980Sstevel@tonic-gate  */
94990Sstevel@tonic-gate static int
dprov_get_object_attr_scalar_common(dprov_object_t * object,uint64_t attr_type,void * value,size_t value_len)95000Sstevel@tonic-gate dprov_get_object_attr_scalar_common(dprov_object_t *object, uint64_t attr_type,
95010Sstevel@tonic-gate 				    void *value, size_t value_len)
95020Sstevel@tonic-gate {
95030Sstevel@tonic-gate 	int attr_idx;
95040Sstevel@tonic-gate 	size_t oa_value_len;
95050Sstevel@tonic-gate 	size_t offset = 0;
95060Sstevel@tonic-gate 
95070Sstevel@tonic-gate 	if ((attr_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR,
95080Sstevel@tonic-gate 	    attr_type)) == -1)
95090Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
95100Sstevel@tonic-gate 
95110Sstevel@tonic-gate 	oa_value_len = object->do_attr[attr_idx].oa_value_len;
95120Sstevel@tonic-gate 	if (oa_value_len != value_len) {
95130Sstevel@tonic-gate 		/*
95140Sstevel@tonic-gate 		 * For some attributes, it's okay to copy the value
95150Sstevel@tonic-gate 		 * into a larger container, e.g. copy an unsigned
95160Sstevel@tonic-gate 		 * 32-bit integer into a 64-bit container.
95170Sstevel@tonic-gate 		 */
95180Sstevel@tonic-gate 		if (attr_type == DPROV_CKA_VALUE_LEN ||
95190Sstevel@tonic-gate 		    attr_type == DPROV_CKA_KEY_TYPE ||
95200Sstevel@tonic-gate 		    attr_type == DPROV_CKA_CLASS) {
95210Sstevel@tonic-gate 			if (oa_value_len < value_len) {
95220Sstevel@tonic-gate #ifdef _BIG_ENDIAN
95230Sstevel@tonic-gate 				offset = value_len - oa_value_len;
95240Sstevel@tonic-gate #endif
95250Sstevel@tonic-gate 				bzero(value, value_len);
95260Sstevel@tonic-gate 				goto do_copy;
95270Sstevel@tonic-gate 			}
95280Sstevel@tonic-gate 		}
95290Sstevel@tonic-gate 		/* incorrect attribute value length */
95300Sstevel@tonic-gate 		return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
95310Sstevel@tonic-gate 	}
95320Sstevel@tonic-gate 
95330Sstevel@tonic-gate do_copy:
95340Sstevel@tonic-gate 	bcopy(object->do_attr[attr_idx].oa_value, (uchar_t *)value + offset,
95350Sstevel@tonic-gate 	    oa_value_len);
95360Sstevel@tonic-gate 
95370Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
95380Sstevel@tonic-gate }
95390Sstevel@tonic-gate 
95400Sstevel@tonic-gate /*
95410Sstevel@tonic-gate  * Get the value of the a boolean attribute from the specified object.
95420Sstevel@tonic-gate  */
95430Sstevel@tonic-gate static int
dprov_get_object_attr_boolean(dprov_object_t * object,uint64_t attr_type,boolean_t * attr_value)95440Sstevel@tonic-gate dprov_get_object_attr_boolean(dprov_object_t *object, uint64_t attr_type,
95450Sstevel@tonic-gate     boolean_t *attr_value)
95460Sstevel@tonic-gate {
95470Sstevel@tonic-gate 	uchar_t val;
95480Sstevel@tonic-gate 	int ret;
95490Sstevel@tonic-gate 
95500Sstevel@tonic-gate 	/* PKCS#11 defines a boolean as one byte */
95510Sstevel@tonic-gate 	ret = dprov_get_object_attr_scalar_common(object, attr_type, &val, 1);
95520Sstevel@tonic-gate 	if (ret == CRYPTO_SUCCESS) {
95530Sstevel@tonic-gate 		*attr_value = (val == '\0') ? B_FALSE : B_TRUE;
95540Sstevel@tonic-gate 	}
95550Sstevel@tonic-gate 	return (ret);
95560Sstevel@tonic-gate }
95570Sstevel@tonic-gate 
95580Sstevel@tonic-gate /*
95590Sstevel@tonic-gate  * Get the value of a ulong_t attribute from the specified object.
95600Sstevel@tonic-gate  */
95610Sstevel@tonic-gate static int
dprov_get_object_attr_ulong(dprov_object_t * object,uint64_t attr_type,ulong_t * attr_value)95620Sstevel@tonic-gate dprov_get_object_attr_ulong(dprov_object_t *object, uint64_t attr_type,
95630Sstevel@tonic-gate     ulong_t *attr_value)
95640Sstevel@tonic-gate {
95650Sstevel@tonic-gate 	return (dprov_get_object_attr_scalar_common(object, attr_type,
95660Sstevel@tonic-gate 	    attr_value, sizeof (ulong_t)));
95670Sstevel@tonic-gate }
95680Sstevel@tonic-gate 
95690Sstevel@tonic-gate /*
95700Sstevel@tonic-gate  * Find the specified byte array attribute of specified type in
95710Sstevel@tonic-gate  * the specified object. Returns CRYPTO_SUCCESS
95720Sstevel@tonic-gate  * on success or CRYPTO_ARGUMENTS_BAD if the specified
95730Sstevel@tonic-gate  * attribute cannot be found.
95740Sstevel@tonic-gate  */
95750Sstevel@tonic-gate static int
dprov_get_object_attr_array(dprov_object_t * object,uint64_t attr_type,void ** array,size_t * len)95760Sstevel@tonic-gate dprov_get_object_attr_array(dprov_object_t *object, uint64_t attr_type,
95770Sstevel@tonic-gate     void **array, size_t *len)
95780Sstevel@tonic-gate {
95790Sstevel@tonic-gate 	int attr_idx;
95800Sstevel@tonic-gate 
95810Sstevel@tonic-gate 	if ((attr_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR,
95820Sstevel@tonic-gate 	    attr_type)) == -1)
95830Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
95840Sstevel@tonic-gate 
95850Sstevel@tonic-gate 	*array = object->do_attr[attr_idx].oa_value;
95860Sstevel@tonic-gate 	*len = object->do_attr[attr_idx].oa_value_len;
95870Sstevel@tonic-gate 
95880Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
95890Sstevel@tonic-gate }
95900Sstevel@tonic-gate 
95910Sstevel@tonic-gate /*
95920Sstevel@tonic-gate  * Common function used by the dprov_get_template_attr_*() family of
95930Sstevel@tonic-gate  * functions. Returns the value of the specified attribute of specified
95940Sstevel@tonic-gate  * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID
95950Sstevel@tonic-gate  * if the length of the attribute does not match the specified length,
95960Sstevel@tonic-gate  * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found.
95970Sstevel@tonic-gate  */
95980Sstevel@tonic-gate static int
dprov_get_template_attr_scalar_common(crypto_object_attribute_t * template,uint_t nattr,uint64_t attr_type,void * value,size_t value_len)95990Sstevel@tonic-gate dprov_get_template_attr_scalar_common(crypto_object_attribute_t *template,
96000Sstevel@tonic-gate     uint_t nattr, uint64_t attr_type, void *value, size_t value_len)
96010Sstevel@tonic-gate {
96020Sstevel@tonic-gate 	size_t oa_value_len;
96030Sstevel@tonic-gate 	size_t offset = 0;
96040Sstevel@tonic-gate 	int attr_idx;
96050Sstevel@tonic-gate 
96060Sstevel@tonic-gate 	if ((attr_idx = dprov_find_attr(template, nattr, attr_type)) == -1)
96070Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
96080Sstevel@tonic-gate 
96090Sstevel@tonic-gate 	oa_value_len = template[attr_idx].oa_value_len;
96100Sstevel@tonic-gate 	if (oa_value_len != value_len) {
96110Sstevel@tonic-gate 		/*
96120Sstevel@tonic-gate 		 * For some attributes, it's okay to copy the value
96130Sstevel@tonic-gate 		 * into a larger container, e.g. copy an unsigned
96140Sstevel@tonic-gate 		 * 32-bit integer into a 64-bit container.
96150Sstevel@tonic-gate 		 */
96160Sstevel@tonic-gate 		if (attr_type == DPROV_CKA_VALUE_LEN ||
96170Sstevel@tonic-gate 		    attr_type == DPROV_CKA_KEY_TYPE ||
96180Sstevel@tonic-gate 		    attr_type == DPROV_CKA_CLASS) {
96190Sstevel@tonic-gate 			if (oa_value_len < value_len) {
96200Sstevel@tonic-gate #ifdef _BIG_ENDIAN
96210Sstevel@tonic-gate 				offset = value_len - oa_value_len;
96220Sstevel@tonic-gate #endif
96230Sstevel@tonic-gate 				bzero(value, value_len);
96240Sstevel@tonic-gate 				goto do_copy;
96250Sstevel@tonic-gate 			}
96260Sstevel@tonic-gate 		}
96270Sstevel@tonic-gate 		/* incorrect attribute value length */
96280Sstevel@tonic-gate 		return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
96290Sstevel@tonic-gate 	}
96300Sstevel@tonic-gate 
96310Sstevel@tonic-gate do_copy:
96320Sstevel@tonic-gate 	bcopy(template[attr_idx].oa_value, (uchar_t *)value + offset,
96330Sstevel@tonic-gate 	    oa_value_len);
96340Sstevel@tonic-gate 
96350Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
96360Sstevel@tonic-gate }
96370Sstevel@tonic-gate 
96380Sstevel@tonic-gate /*
96390Sstevel@tonic-gate  * Get the value of the a boolean attribute from the specified template
96400Sstevel@tonic-gate  */
96410Sstevel@tonic-gate static int
dprov_get_template_attr_boolean(crypto_object_attribute_t * template,uint_t nattr,uint64_t attr_type,boolean_t * attr_value)96420Sstevel@tonic-gate dprov_get_template_attr_boolean(crypto_object_attribute_t *template,
96430Sstevel@tonic-gate     uint_t nattr, uint64_t attr_type, boolean_t *attr_value)
96440Sstevel@tonic-gate {
96450Sstevel@tonic-gate 	uchar_t val;
96460Sstevel@tonic-gate 	int ret;
96470Sstevel@tonic-gate 
96480Sstevel@tonic-gate 	/* PKCS#11 defines a boolean as one byte */
96490Sstevel@tonic-gate 	ret = dprov_get_template_attr_scalar_common(template, nattr,
96500Sstevel@tonic-gate 	    attr_type, &val, 1);
96510Sstevel@tonic-gate 	if (ret == CRYPTO_SUCCESS) {
96520Sstevel@tonic-gate 		*attr_value = (val == '\0') ? B_FALSE : B_TRUE;
96530Sstevel@tonic-gate 	}
96540Sstevel@tonic-gate 	return (ret);
96550Sstevel@tonic-gate }
96560Sstevel@tonic-gate 
96570Sstevel@tonic-gate /*
96580Sstevel@tonic-gate  * Get the value of a ulong_t attribute from the specified template.
96590Sstevel@tonic-gate  */
96600Sstevel@tonic-gate static int
dprov_get_template_attr_ulong(crypto_object_attribute_t * template,uint_t nattr,uint64_t attr_type,ulong_t * attr_value)96610Sstevel@tonic-gate dprov_get_template_attr_ulong(crypto_object_attribute_t *template,
96620Sstevel@tonic-gate     uint_t nattr, uint64_t attr_type, ulong_t *attr_value)
96630Sstevel@tonic-gate {
96640Sstevel@tonic-gate 	return (dprov_get_template_attr_scalar_common(template, nattr,
96650Sstevel@tonic-gate 	    attr_type, attr_value, sizeof (ulong_t)));
96660Sstevel@tonic-gate }
96670Sstevel@tonic-gate 
96680Sstevel@tonic-gate static int
dprov_template_attr_present(crypto_object_attribute_t * template,uint_t nattr,uint64_t attr_type)96690Sstevel@tonic-gate dprov_template_attr_present(crypto_object_attribute_t *template,
96700Sstevel@tonic-gate     uint_t nattr, uint64_t attr_type)
96710Sstevel@tonic-gate {
96720Sstevel@tonic-gate 	return (dprov_find_attr(template, nattr,
96730Sstevel@tonic-gate 	    attr_type) == -1 ? B_FALSE : B_TRUE);
96740Sstevel@tonic-gate }
96750Sstevel@tonic-gate 
96760Sstevel@tonic-gate /*
96770Sstevel@tonic-gate  * Find the specified byte array attribute of specified type in
96780Sstevel@tonic-gate  * the specified template. Returns CRYPTO_SUCCESS on success or
96790Sstevel@tonic-gate  * CRYPTO_ARGUMENTS_BAD if the specified attribute cannot be found.
96800Sstevel@tonic-gate  */
96810Sstevel@tonic-gate static int
dprov_get_template_attr_array(crypto_object_attribute_t * template,uint_t nattr,uint64_t attr_type,void ** array,size_t * len)96820Sstevel@tonic-gate dprov_get_template_attr_array(crypto_object_attribute_t *template,
96830Sstevel@tonic-gate     uint_t nattr, uint64_t attr_type, void **array, size_t *len)
96840Sstevel@tonic-gate {
96850Sstevel@tonic-gate 	int attr_idx;
96860Sstevel@tonic-gate 
96870Sstevel@tonic-gate 	if ((attr_idx = dprov_find_attr(template, nattr, attr_type)) == -1)
96880Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
96890Sstevel@tonic-gate 
96900Sstevel@tonic-gate 	*array = template[attr_idx].oa_value;
96910Sstevel@tonic-gate 	*len = template[attr_idx].oa_value_len;
96920Sstevel@tonic-gate 
96930Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
96940Sstevel@tonic-gate }
96950Sstevel@tonic-gate 
96960Sstevel@tonic-gate /*
96970Sstevel@tonic-gate  * Common function used by the dprov_get_key_attr_*() family of
96980Sstevel@tonic-gate  * functions. Returns the value of the specified attribute of specified
96990Sstevel@tonic-gate  * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID
97000Sstevel@tonic-gate  * if the length of the attribute does not match the specified length,
97010Sstevel@tonic-gate  * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found.
97020Sstevel@tonic-gate  */
97030Sstevel@tonic-gate static int
dprov_get_key_attr_scalar_common(crypto_key_t * key,uint64_t attr_type,void * value,size_t value_len)97040Sstevel@tonic-gate dprov_get_key_attr_scalar_common(crypto_key_t *key, uint64_t attr_type,
97050Sstevel@tonic-gate     void *value, size_t value_len)
97060Sstevel@tonic-gate {
97070Sstevel@tonic-gate 	int attr_idx;
97080Sstevel@tonic-gate 
97090Sstevel@tonic-gate 	ASSERT(key->ck_format == CRYPTO_KEY_ATTR_LIST);
97100Sstevel@tonic-gate 
97110Sstevel@tonic-gate 	if ((attr_idx = dprov_find_attr(key->ck_attrs, key->ck_count,
97120Sstevel@tonic-gate 	    attr_type)) == -1)
97130Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
97140Sstevel@tonic-gate 
97150Sstevel@tonic-gate 	if (key->ck_attrs[attr_idx].oa_value_len != value_len)
97160Sstevel@tonic-gate 		/* incorrect attribute value length */
97170Sstevel@tonic-gate 		return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
97180Sstevel@tonic-gate 
97190Sstevel@tonic-gate 	bcopy(key->ck_attrs[attr_idx].oa_value, value, value_len);
97200Sstevel@tonic-gate 
97210Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
97220Sstevel@tonic-gate }
97230Sstevel@tonic-gate 
97240Sstevel@tonic-gate /*
97250Sstevel@tonic-gate  * Get the value of a ulong_t attribute from the specified key.
97260Sstevel@tonic-gate  */
97270Sstevel@tonic-gate static int
dprov_get_key_attr_ulong(crypto_key_t * key,uint64_t attr_type,ulong_t * attr_value)97280Sstevel@tonic-gate dprov_get_key_attr_ulong(crypto_key_t *key, uint64_t attr_type,
97290Sstevel@tonic-gate     ulong_t *attr_value)
97300Sstevel@tonic-gate {
97310Sstevel@tonic-gate 	return (dprov_get_key_attr_scalar_common(key, attr_type,
97320Sstevel@tonic-gate 	    attr_value, sizeof (ulong_t)));
97330Sstevel@tonic-gate }
97340Sstevel@tonic-gate 
97350Sstevel@tonic-gate /*
97360Sstevel@tonic-gate  * Find the specified byte array attribute of specified type in
97370Sstevel@tonic-gate  * the specified key by attributes. Returns CRYPTO_SUCCESS
97380Sstevel@tonic-gate  * on success or CRYPTO_ARGUMENTS_BAD if the specified
97390Sstevel@tonic-gate  * attribute cannot be found.
97400Sstevel@tonic-gate  */
97410Sstevel@tonic-gate static int
dprov_get_key_attr_array(crypto_key_t * key,uint64_t attr_type,void ** array,size_t * len)97420Sstevel@tonic-gate dprov_get_key_attr_array(crypto_key_t *key, uint64_t attr_type,
97430Sstevel@tonic-gate     void **array, size_t *len)
97440Sstevel@tonic-gate {
97450Sstevel@tonic-gate 	int attr_idx;
97460Sstevel@tonic-gate 
97470Sstevel@tonic-gate 	ASSERT(key->ck_format == CRYPTO_KEY_ATTR_LIST);
97480Sstevel@tonic-gate 
97490Sstevel@tonic-gate 	if ((attr_idx = dprov_find_attr(key->ck_attrs, key->ck_count,
97500Sstevel@tonic-gate 	    attr_type)) == -1)
97510Sstevel@tonic-gate 		return (CRYPTO_ARGUMENTS_BAD);
97520Sstevel@tonic-gate 
97530Sstevel@tonic-gate 	*array = key->ck_attrs[attr_idx].oa_value;
97540Sstevel@tonic-gate 	*len = key->ck_attrs[attr_idx].oa_value_len;
97550Sstevel@tonic-gate 
97560Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
97570Sstevel@tonic-gate }
97580Sstevel@tonic-gate 
97590Sstevel@tonic-gate static void
dprov_release_session_objects(dprov_session_t * session)97600Sstevel@tonic-gate dprov_release_session_objects(dprov_session_t *session)
97610Sstevel@tonic-gate {
97620Sstevel@tonic-gate 	dprov_object_t *object;
97630Sstevel@tonic-gate 	int i;
97640Sstevel@tonic-gate 
97650Sstevel@tonic-gate 	for (i = 0; i < DPROV_MAX_OBJECTS; i++) {
97660Sstevel@tonic-gate 		object = session->ds_objects[i];
97670Sstevel@tonic-gate 		if (object != NULL) {
97680Sstevel@tonic-gate 			DPROV_OBJECT_REFRELE(object);
97690Sstevel@tonic-gate 		}
97700Sstevel@tonic-gate 	}
97710Sstevel@tonic-gate }
97725697Smcpowers 
97735697Smcpowers /*
97745697Smcpowers  * Adjust an attribute list by turning 32-bit values into 64-bit values
97755697Smcpowers  * for certain attributes like CKA_CLASS. Assumes that at least 8 bytes
97765697Smcpowers  * of storage have been allocated for all attributes.
97775697Smcpowers  */
97785697Smcpowers static void
dprov_adjust_attrs(crypto_object_attribute_t * in,int in_count)97795697Smcpowers dprov_adjust_attrs(crypto_object_attribute_t *in, int in_count)
97805697Smcpowers {
97815697Smcpowers 	int i;
97825697Smcpowers 	size_t offset = 0;
97835697Smcpowers 	ulong_t tmp = 0;
97845697Smcpowers 
97855697Smcpowers 	for (i = 0; i < in_count; i++) {
97865697Smcpowers 		/*
97875697Smcpowers 		 * For some attributes, it's okay to copy the value
97885697Smcpowers 		 * into a larger container, e.g. copy an unsigned
97895697Smcpowers 		 * 32-bit integer into a 64-bit container.
97905697Smcpowers 		 */
97915697Smcpowers 		if (in[i].oa_type == CKA_VALUE_LEN ||
97925697Smcpowers 		    in[i].oa_type == CKA_KEY_TYPE ||
97935697Smcpowers 		    in[i].oa_type == CKA_CLASS) {
97945697Smcpowers 			if (in[i].oa_value_len < sizeof (ulong_t)) {
97955697Smcpowers #ifdef _BIG_ENDIAN
97965697Smcpowers 				offset = sizeof (ulong_t) - in[i].oa_value_len;
97975697Smcpowers #endif
97985697Smcpowers 				bcopy(in[i].oa_value, (uchar_t *)&tmp + offset,
97995697Smcpowers 				    in[i].oa_value_len);
98005697Smcpowers 				bcopy(&tmp, in[i].oa_value, sizeof (ulong_t));
98015697Smcpowers 				in[i].oa_value_len = sizeof (ulong_t);
98025697Smcpowers 			}
98035697Smcpowers 		}
98045697Smcpowers 	}
98055697Smcpowers }
9806