Home | History | Annotate | Download | only in io
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 
     27 /*
     28  * Dummy Cryptographic Provider:
     29  *
     30  * This file implements a "dummy" cryptographic provider. It is implemented
     31  * as a pseudo device driver.
     32  *
     33  */
     34 
     35 /*
     36  * This driver implements a KEF provider with the following capabilities:
     37  *
     38  * - registration/unregistration with KEF
     39  * - digest entry points
     40  * - mac entry points
     41  * - ctx management
     42  * - support for async requests
     43  * - cipher entry points
     44  * - dual entry points
     45  * - sign entry points
     46  * - verify entry points
     47  * - dual operations entry points
     48  * - dual cipher/mac operation entry points
     49  * - session management
     50  * - object management
     51  * - key management
     52  * - provider management
     53  *
     54  * In order to avoid duplicating the implementation of algorithms
     55  * provided by software providers, this pseudo driver acts as
     56  * a consumer of the framework. When invoking one of the framework's
     57  * entry points, the driver specifies the software provider to
     58  * be used for the operation.
     59  *
     60  * User management: we implement a PKCS#11 style provider which supports:
     61  * - one normal user with a PIN, and
     62  * - one SO user with a PIN.
     63  * These values are kept in the per-instance structure, and are initialized
     64  * with the provider management entry points.
     65  *
     66  */
     67 
     68 
     69 #include <sys/types.h>
     70 #include <sys/modctl.h>
     71 #include <sys/conf.h>
     72 #include <sys/stat.h>
     73 #include <sys/ddi.h>
     74 #include <sys/sunddi.h>
     75 #include <sys/kmem.h>
     76 #include <sys/errno.h>
     77 #include <sys/ksynch.h>
     78 #include <sys/file.h>
     79 #include <sys/open.h>
     80 #include <sys/cred.h>
     81 #include <sys/model.h>
     82 #include <sys/note.h>
     83 #include <sys/random.h>
     84 #include <sys/byteorder.h>
     85 #include <sys/crypto/common.h>
     86 #include <sys/crypto/spi.h>
     87 
     88 #include <sys/taskq.h>
     89 #include <sys/disp.h>
     90 #include <sys/sysmacros.h>
     91 #include <sys/crypto/impl.h>
     92 #include <sys/crypto/sched_impl.h>
     93 
     94 #include <sys/sha2.h>
     95 #include <modes/modes.h>
     96 #include <aes/aes_impl.h>
     97 #include <des/des_impl.h>
     98 #include <ecc/ecc_impl.h>
     99 #include <blowfish/blowfish_impl.h>
    100 
    101 /*
    102  * Debugging macros.
    103  */
    104 #ifdef DEBUG
    105 #define	D_INIT		0x00000001	/* _init/_fini/_info */
    106 #define	D_ATTACH	0x00000002	/* attach/detach */
    107 #define	D_DIGEST	0x00000010	/* digest entry points */
    108 #define	D_MAC		0x00000020	/* mac entry points */
    109 #define	D_CONTEXT	0x00000040	/* context entry points */
    110 #define	D_CIPHER	0x00000080	/* cipher entry points */
    111 #define	D_SIGN		0x00000100	/* sign entry points */
    112 #define	D_VERIFY	0x00000200	/* verify entry points */
    113 #define	D_SESSION	0x00000400	/* session management entry points */
    114 #define	D_MGMT		0x00000800	/* provider management entry points */
    115 #define	D_DUAL		0x00001000	/* dual ops */
    116 #define	D_CIPHER_MAC	0x00002000	/* cipher/mac dual ops */
    117 #define	D_OBJECT	0x00004000	/* object management */
    118 #define	D_RANDOM	0x00008000	/* random number generation */
    119 #define	D_KEY		0x00010000	/* key management */
    120 
    121 static uint32_t dprov_debug = 0;
    122 
    123 #define	DPROV_DEBUG(f, x)	if (dprov_debug & (f)) { (void) printf x; }
    124 #define	DPROV_CALL(f, r, x)	if (dprov_debug & (f)) { (void) r x; }
    125 #else /* DEBUG */
    126 #define	DPROV_DEBUG(f, x)
    127 #define	DPROV_CALL(f, r, x)
    128 #endif /* DEBUG */
    129 
    130 static int nostore_key_gen;
    131 static boolean_t dprov_no_multipart = B_FALSE;
    132 static int dprov_max_digestsz = INT_MAX;
    133 
    134 /*
    135  * DDI entry points.
    136  */
    137 static int dprov_attach(dev_info_t *, ddi_attach_cmd_t);
    138 static int dprov_detach(dev_info_t *, ddi_detach_cmd_t);
    139 static int dprov_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
    140 
    141 /*
    142  * Module linkage.
    143  */
    144 static struct cb_ops cbops = {
    145 	nodev,			/* cb_open */
    146 	nodev,			/* cb_close */
    147 	nodev,			/* cb_strategy */
    148 	nodev,			/* cb_print */
    149 	nodev,			/* cb_dump */
    150 	nodev,			/* cb_read */
    151 	nodev,			/* cb_write */
    152 	nodev,			/* cb_ioctl */
    153 	nodev,			/* cb_devmap */
    154 	nodev,			/* cb_mmap */
    155 	nodev,			/* cb_segmap */
    156 	nochpoll,		/* cb_chpoll */
    157 	ddi_prop_op,		/* cb_prop_op */
    158 	NULL,			/* cb_streamtab */
    159 	D_MP,			/* cb_flag */
    160 	CB_REV,			/* cb_rev */
    161 	nodev,			/* cb_aread */
    162 	nodev,			/* cb_awrite */
    163 };
    164 
    165 static struct dev_ops devops = {
    166 	DEVO_REV,		/* devo_rev */
    167 	0,			/* devo_refcnt */
    168 	dprov_getinfo,		/* devo_getinfo */
    169 	nulldev,		/* devo_identify */
    170 	nulldev,		/* devo_probe */
    171 	dprov_attach,		/* devo_attach */
    172 	dprov_detach,		/* devo_detach */
    173 	nodev,			/* devo_reset */
    174 	&cbops,			/* devo_cb_ops */
    175 	NULL,			/* devo_bus_ops */
    176 	NULL,			/* devo_power */
    177 	ddi_quiesce_not_needed,		/* devo_quiesce */
    178 };
    179 
    180 static struct modldrv modldrv = {
    181 	&mod_driverops,
    182 	"Pseudo KCF Prov (drv)",
    183 	&devops
    184 };
    185 
    186 static struct modlcrypto modlcrypto = {
    187 	&mod_cryptoops,
    188 	"Pseudo KCF Prov (crypto)"
    189 };
    190 
    191 static struct modlinkage modlinkage = {
    192 	MODREV_1,
    193 	&modldrv,
    194 	&modlcrypto,
    195 	NULL
    196 };
    197 
    198 /*
    199  * CSPI information (entry points, provider info, etc.)
    200  */
    201 
    202 typedef enum dprov_mech_type {
    203 	MD4_MECH_INFO_TYPE,		/* SUN_CKM_MD4 */
    204 
    205 	MD5_MECH_INFO_TYPE,		/* SUN_CKM_MD5 */
    206 	MD5_HMAC_MECH_INFO_TYPE,	/* SUN_CKM_MD5_HMAC */
    207 	MD5_HMAC_GEN_MECH_INFO_TYPE,	/* SUN_CKM_MD5_HMAC_GENERAL */
    208 
    209 	SHA1_HMAC_MECH_INFO_TYPE,	/* SUN_CKM_SHA1_HMAC */
    210 	SHA1_HMAC_GEN_MECH_INFO_TYPE,	/* SUN_CKM_SHA1_HMAC_GENERAL */
    211 	SHA1_MECH_INFO_TYPE,		/* SUN_CKM_SHA1 */
    212 
    213 	SHA256_HMAC_MECH_INFO_TYPE,	/* SUN_CKM_SHA256_HMAC */
    214 	SHA256_HMAC_GEN_MECH_INFO_TYPE,	/* SUN_CKM_SHA256_HMAC_GENERAL */
    215 	SHA256_MECH_INFO_TYPE,		/* SUN_CKM_SHA256 */
    216 	SHA384_HMAC_MECH_INFO_TYPE,	/* SUN_CKM_SHA384_HMAC */
    217 	SHA384_HMAC_GEN_MECH_INFO_TYPE,	/* SUN_CKM_SHA384_HMAC_GENERAL */
    218 	SHA384_MECH_INFO_TYPE,		/* SUN_CKM_SHA384 */
    219 	SHA512_HMAC_MECH_INFO_TYPE,	/* SUN_CKM_SHA512_HMAC */
    220 	SHA512_HMAC_GEN_MECH_INFO_TYPE,	/* SUN_CKM_SHA512_HMAC_GENERAL */
    221 	SHA512_MECH_INFO_TYPE,		/* SUN_CKM_SHA512 */
    222 
    223 	DES_CBC_MECH_INFO_TYPE,		/* SUN_CKM_DES_CBC */
    224 	DES3_CBC_MECH_INFO_TYPE,	/* SUN_CKM_DES3_CBC */
    225 	DES_ECB_MECH_INFO_TYPE,		/* SUN_CKM_DES_ECB */
    226 	DES3_ECB_MECH_INFO_TYPE,	/* SUN_CKM_DES3_ECB */
    227 
    228 	BLOWFISH_CBC_MECH_INFO_TYPE,	/* SUN_CKM_BLOWFISH_CBC */
    229 	BLOWFISH_ECB_MECH_INFO_TYPE,	/* SUN_CKM_BLOWFISH_ECB */
    230 	AES_CBC_MECH_INFO_TYPE,		/* SUN_CKM_AES_CBC */
    231 	AES_ECB_MECH_INFO_TYPE,		/* SUN_CKM_AES_ECB */
    232 	AES_CTR_MECH_INFO_TYPE,		/* SUN_CKM_AES_CTR */
    233 	AES_CCM_MECH_INFO_TYPE,		/* SUN_CKM_AES_CCM */
    234 	AES_GCM_MECH_INFO_TYPE,		/* SUN_CKM_AES_GCM */
    235 	AES_GMAC_MECH_INFO_TYPE,	/* SUN_CKM_AES_GMAC */
    236 	RC4_MECH_INFO_TYPE,		/* SUN_CKM_RC4 */
    237 	RSA_PKCS_MECH_INFO_TYPE,	/* SUN_CKM_RSA_PKCS */
    238 	RSA_X_509_MECH_INFO_TYPE,	/* SUN_CKM_RSA_X_509 */
    239 	MD5_RSA_PKCS_MECH_INFO_TYPE,	/* SUN_CKM_MD5_RSA_PKCS */
    240 	SHA1_RSA_PKCS_MECH_INFO_TYPE,	/* SUN_CKM_SHA1_RSA_PKCS */
    241 	SHA256_RSA_PKCS_MECH_INFO_TYPE,	/* SUN_CKM_SHA256_RSA_PKCS */
    242 	SHA384_RSA_PKCS_MECH_INFO_TYPE,	/* SUN_CKM_SHA384_RSA_PKCS */
    243 	SHA512_RSA_PKCS_MECH_INFO_TYPE,	/* SUN_CKM_SHA512_RSA_PKCS */
    244 	MD5_KEY_DERIVATION_MECH_INFO_TYPE, /* SUN_CKM_MD5_KEY_DERIVATION */
    245 	SHA1_KEY_DERIVATION_MECH_INFO_TYPE, /* SUN_CKM_SHA1_KEY_DERIVATION */
    246 	/* SUN_CKM_SHA256_KEY_DERIVATION */
    247 	SHA256_KEY_DERIVATION_MECH_INFO_TYPE,
    248 	/* SUN_CKM_SHA384_KEY_DERIVATION */
    249 	SHA384_KEY_DERIVATION_MECH_INFO_TYPE,
    250 	/* SUN_CKM_SHA512_KEY_DERIVATION */
    251 	SHA512_KEY_DERIVATION_MECH_INFO_TYPE,
    252 	DES_KEY_GEN_MECH_INFO_TYPE,	/* SUN_CKM_DES_KEY_GEN */
    253 	DES3_KEY_GEN_MECH_INFO_TYPE,	/* SUN_CKM_DES3_KEY_GEN */
    254 	AES_KEY_GEN_MECH_INFO_TYPE,	/* SUN_CKM_AES_KEY_GEN */
    255 	BLOWFISH_KEY_GEN_MECH_INFO_TYPE,	/* SUN_CKM_BLOWFISH_KEY_GEN */
    256 	RC4_KEY_GEN_MECH_INFO_TYPE,	/* SUN_CKM_RC4_KEY_GEN */
    257 	EC_KEY_PAIR_GEN_MECH_INFO_TYPE,	/* SUN_CKM_EC_KEY_PAIR_GEN */
    258 	ECDSA_MECH_INFO_TYPE,		/* SUN_CKM_ECDSA */
    259 	ECDSA_SHA1_MECH_INFO_TYPE,	/* SUN_CKM_ECDSA_SHA1 */
    260 	ECDH1_DERIVE_MECH_INFO_TYPE,	/* SUN_CKM_ECDH1_DERIVE */
    261 	DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE, /* SUN_CKM_DH_PKCS_KEY_PAIR_GEN */
    262 	DH_PKCS_DERIVE_MECH_INFO_TYPE,	/* SUN_CKM_DH_PKCS_DERIVE */
    263 	RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE /* SUN_CKM_RSA_PKCS_KEY_PAIR_GEN */
    264 } dprov_mech_type_t;
    265 
    266 /*
    267  * Mechanism info structure passed to KCF during registration.
    268  */
    269 #define	MD5_DIGEST_LEN		16	/* MD5 digest size */
    270 #define	MD5_HMAC_BLOCK_SIZE	64	/* MD5-HMAC block size */
    271 #define	MD5_HMAC_MIN_KEY_LEN	1	/* MD5-HMAC min key length in bytes */
    272 #define	MD5_HMAC_MAX_KEY_LEN	INT_MAX	/* MD5-HMAC max key length in bytes */
    273 
    274 #define	SHA1_DIGEST_LEN		20	/* SHA1 digest size */
    275 #define	SHA1_HMAC_BLOCK_SIZE	64	/* SHA1-HMAC block size */
    276 #define	SHA1_HMAC_MIN_KEY_LEN	1	/* SHA1-HMAC min key length in bytes */
    277 #define	SHA1_HMAC_MAX_KEY_LEN	INT_MAX	/* SHA1-HMAC max key length in bytes */
    278 
    279 #define	DES_KEY_LEN		8	/* DES key length in bytes */
    280 #define	DES3_KEY_LEN		24	/* DES3 key length in bytes */
    281 
    282 #define	BLOWFISH_MIN_KEY_LEN	32	/* Blowfish min key length in bits */
    283 #define	BLOWFISH_MAX_KEY_LEN	448	/* Blowfish max key length in bits */
    284 
    285 #define	AES_MIN_KEY_LEN		16	/* AES min key length in bytes */
    286 #define	AES_MAX_KEY_LEN		32	/* AES max key length in bytes */
    287 
    288 #define	ARCFOUR_MIN_KEY_BITS	40	/* RC4 min supported key size */
    289 #define	ARCFOUR_MAX_KEY_BITS	2048	/* RC4 max supported key size */
    290 
    291 #define	RSA_MIN_KEY_LEN		256	/* RSA min key length in bits */
    292 #define	RSA_MAX_KEY_LEN		4096	/* RSA max key length in bits */
    293 
    294 #define	DH_MIN_KEY_LEN		64	/* DH min key length in bits */
    295 #define	DH_MAX_KEY_LEN		4096	/* DH max key length in bits */
    296 
    297 #define	DPROV_CKM_MD5_KEY_DERIVATION	"CKM_MD5_KEY_DERIVATION"
    298 #define	DPROV_CKM_SHA1_KEY_DERIVATION	"CKM_SHA1_KEY_DERIVATION"
    299 #define	DPROV_CKM_SHA256_KEY_DERIVATION	"CKM_SHA256_KEY_DERIVATION"
    300 #define	DPROV_CKM_SHA384_KEY_DERIVATION	"CKM_SHA384_KEY_DERIVATION"
    301 #define	DPROV_CKM_SHA512_KEY_DERIVATION	"CKM_SHA512_KEY_DERIVATION"
    302 #define	DPROV_CKM_DES_KEY_GEN		"CKM_DES_KEY_GEN"
    303 #define	DPROV_CKM_DES3_KEY_GEN		"CKM_DES3_KEY_GEN"
    304 #define	DPROV_CKM_AES_KEY_GEN		"CKM_AES_KEY_GEN"
    305 #define	DPROV_CKM_BLOWFISH_KEY_GEN	"CKM_BLOWFISH_KEY_GEN"
    306 #define	DPROV_CKM_RC4_KEY_GEN		"CKM_RC4_KEY_GEN"
    307 #define	DPROV_CKM_RSA_PKCS_KEY_PAIR_GEN	"CKM_RSA_PKCS_KEY_PAIR_GEN"
    308 #define	DPROV_CKM_EC_KEY_PAIR_GEN	"CKM_EC_KEY_PAIR_GEN"
    309 #define	DPROV_CKM_ECDSA			"CKM_ECDSA"
    310 #define	DPROV_CKM_ECDSA_SHA1		"CKM_ECDSA_SHA1"
    311 #define	DPROV_CKM_ECDH1_DERIVE		"CKM_ECDH1_DERIVE"
    312 #define	DPROV_CKM_DH_PKCS_KEY_PAIR_GEN	"CKM_DH_PKCS_KEY_PAIR_GEN"
    313 #define	DPROV_CKM_DH_PKCS_DERIVE	"CKM_DH_PKCS_DERIVE"
    314 
    315 static crypto_mech_info_t dprov_mech_info_tab[] = {
    316 	/* MD4 */
    317 	{SUN_CKM_MD4, MD4_MECH_INFO_TYPE,
    318 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
    319 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
    320 	/* MD5 */
    321 	{SUN_CKM_MD5, MD5_MECH_INFO_TYPE,
    322 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
    323 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
    324 	/* MD5-HMAC */
    325 	{SUN_CKM_MD5_HMAC, MD5_HMAC_MECH_INFO_TYPE,
    326 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
    327 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
    328 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
    329 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
    330 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
    331 	    MD5_HMAC_MIN_KEY_LEN, MD5_HMAC_MAX_KEY_LEN,
    332 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    333 	/* MD5-HMAC GENERAL */
    334 	{SUN_CKM_MD5_HMAC_GENERAL, MD5_HMAC_GEN_MECH_INFO_TYPE,
    335 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
    336 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
    337 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
    338 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
    339 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
    340 	    MD5_HMAC_MIN_KEY_LEN, MD5_HMAC_MAX_KEY_LEN,
    341 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    342 	/* SHA1 */
    343 	{SUN_CKM_SHA1, SHA1_MECH_INFO_TYPE,
    344 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
    345 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
    346 	/* SHA1-HMAC */
    347 	{SUN_CKM_SHA1_HMAC, SHA1_HMAC_MECH_INFO_TYPE,
    348 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
    349 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
    350 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
    351 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
    352 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
    353 	    SHA1_HMAC_MIN_KEY_LEN, SHA1_HMAC_MAX_KEY_LEN,
    354 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    355 	/* SHA1-HMAC GENERAL */
    356 	{SUN_CKM_SHA1_HMAC_GENERAL, SHA1_HMAC_GEN_MECH_INFO_TYPE,
    357 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
    358 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
    359 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
    360 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
    361 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
    362 	    SHA1_HMAC_MIN_KEY_LEN, SHA1_HMAC_MAX_KEY_LEN,
    363 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    364 	/* SHA256 */
    365 	{SUN_CKM_SHA256, SHA256_MECH_INFO_TYPE,
    366 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
    367 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
    368 	/* SHA256-HMAC */
    369 	{SUN_CKM_SHA256_HMAC, SHA256_HMAC_MECH_INFO_TYPE,
    370 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
    371 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
    372 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
    373 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
    374 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
    375 	    SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
    376 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    377 	/* SHA256-HMAC GENERAL */
    378 	{SUN_CKM_SHA256_HMAC_GENERAL, SHA256_HMAC_GEN_MECH_INFO_TYPE,
    379 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
    380 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
    381 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
    382 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
    383 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
    384 	    SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
    385 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    386 	/* SHA384 */
    387 	{SUN_CKM_SHA384, SHA384_MECH_INFO_TYPE,
    388 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
    389 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
    390 	/* SHA384-HMAC */
    391 	{SUN_CKM_SHA384_HMAC, SHA384_HMAC_MECH_INFO_TYPE,
    392 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
    393 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
    394 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
    395 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
    396 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
    397 	    SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
    398 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    399 	/* SHA384-HMAC GENERAL */
    400 	{SUN_CKM_SHA384_HMAC_GENERAL, SHA384_HMAC_GEN_MECH_INFO_TYPE,
    401 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
    402 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
    403 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
    404 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
    405 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
    406 	    SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
    407 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    408 	/* SHA512 */
    409 	{SUN_CKM_SHA512, SHA512_MECH_INFO_TYPE,
    410 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
    411 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
    412 	/* SHA512-HMAC */
    413 	{SUN_CKM_SHA512_HMAC, SHA512_HMAC_MECH_INFO_TYPE,
    414 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
    415 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
    416 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
    417 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
    418 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
    419 	    SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
    420 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    421 	/* SHA512-HMAC GENERAL */
    422 	{SUN_CKM_SHA512_HMAC_GENERAL, SHA512_HMAC_GEN_MECH_INFO_TYPE,
    423 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
    424 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
    425 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
    426 	    CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
    427 	    CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
    428 	    SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
    429 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    430 	/* DES-CBC */
    431 	{SUN_CKM_DES_CBC, DES_CBC_MECH_INFO_TYPE,
    432 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
    433 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
    434 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
    435 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
    436 	    DES_KEY_LEN, DES_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    437 	/* DES3-CBC */
    438 	{SUN_CKM_DES3_CBC, DES3_CBC_MECH_INFO_TYPE,
    439 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
    440 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
    441 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
    442 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
    443 	    DES3_KEY_LEN, DES3_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    444 	/* DES-ECB */
    445 	{SUN_CKM_DES_ECB, DES_ECB_MECH_INFO_TYPE,
    446 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
    447 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
    448 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
    449 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
    450 	    DES_KEY_LEN, DES_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    451 	/* DES3-ECB */
    452 	{SUN_CKM_DES3_ECB, DES3_ECB_MECH_INFO_TYPE,
    453 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
    454 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
    455 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
    456 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
    457 	    DES3_KEY_LEN, DES3_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    458 	/* BLOWFISH-CBC */
    459 	{SUN_CKM_BLOWFISH_CBC, BLOWFISH_CBC_MECH_INFO_TYPE,
    460 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
    461 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
    462 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
    463 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC, BLOWFISH_MIN_KEY_LEN,
    464 	    BLOWFISH_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
    465 	/* BLOWFISH-ECB */
    466 	{SUN_CKM_BLOWFISH_ECB, BLOWFISH_ECB_MECH_INFO_TYPE,
    467 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
    468 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
    469 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
    470 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC, BLOWFISH_MIN_KEY_LEN,
    471 	    BLOWFISH_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
    472 	/* AES-CBC */
    473 	{SUN_CKM_AES_CBC, AES_CBC_MECH_INFO_TYPE,
    474 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
    475 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
    476 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
    477 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
    478 	    AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    479 	/* AES-ECB */
    480 	{SUN_CKM_AES_ECB, AES_ECB_MECH_INFO_TYPE,
    481 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
    482 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
    483 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
    484 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
    485 	    AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    486 	/* AES-CTR */
    487 	{SUN_CKM_AES_CTR, AES_CTR_MECH_INFO_TYPE,
    488 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
    489 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
    490 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
    491 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
    492 	    AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    493 	/* AES-CCM */
    494 	{SUN_CKM_AES_CCM, AES_CCM_MECH_INFO_TYPE,
    495 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
    496 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
    497 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
    498 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
    499 	    AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    500 	/* AES-GCM */
    501 	{SUN_CKM_AES_GCM, AES_GCM_MECH_INFO_TYPE,
    502 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
    503 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
    504 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
    505 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC,
    506 	    AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    507 	/* AES-GMAC */
    508 	{SUN_CKM_AES_GMAC, AES_GMAC_MECH_INFO_TYPE,
    509 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
    510 	    CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
    511 	    CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
    512 	    CRYPTO_FG_MAC_DECRYPT_ATOMIC |
    513 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
    514 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
    515 	    AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    516 	/* RC4 */
    517 	{SUN_CKM_RC4, RC4_MECH_INFO_TYPE,
    518 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
    519 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
    520 	    ARCFOUR_MIN_KEY_BITS, ARCFOUR_MAX_KEY_BITS,
    521 	    CRYPTO_KEYSIZE_UNIT_IN_BITS | CRYPTO_CAN_SHARE_OPSTATE},
    522 	/* RSA_PKCS */
    523 	{SUN_CKM_RSA_PKCS, RSA_PKCS_MECH_INFO_TYPE,
    524 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
    525 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC |
    526 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
    527 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
    528 	    CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC |
    529 	    CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC,
    530 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
    531 	/* RSA_X_509 */
    532 	{SUN_CKM_RSA_X_509, RSA_X_509_MECH_INFO_TYPE,
    533 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
    534 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC |
    535 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
    536 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
    537 	    CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC |
    538 	    CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC,
    539 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
    540 	/* MD5_RSA_PKCS */
    541 	{SUN_CKM_MD5_RSA_PKCS, MD5_RSA_PKCS_MECH_INFO_TYPE,
    542 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
    543 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
    544 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
    545 	/* SHA1_RSA_PKCS */
    546 	{SUN_CKM_SHA1_RSA_PKCS, SHA1_RSA_PKCS_MECH_INFO_TYPE,
    547 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
    548 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
    549 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
    550 	/* SHA256_RSA_PKCS */
    551 	{SUN_CKM_SHA256_RSA_PKCS, SHA256_RSA_PKCS_MECH_INFO_TYPE,
    552 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
    553 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
    554 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
    555 	/* SHA384_RSA_PKCS */
    556 	{SUN_CKM_SHA384_RSA_PKCS, SHA384_RSA_PKCS_MECH_INFO_TYPE,
    557 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
    558 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
    559 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
    560 	/* SHA512_RSA_PKCS */
    561 	{SUN_CKM_SHA512_RSA_PKCS, SHA512_RSA_PKCS_MECH_INFO_TYPE,
    562 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
    563 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
    564 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
    565 	/* MD5_KEY_DERIVATION */
    566 	{DPROV_CKM_MD5_KEY_DERIVATION, MD5_KEY_DERIVATION_MECH_INFO_TYPE,
    567 	    CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
    568 	/* SHA1_KEY_DERIVATION */
    569 	{DPROV_CKM_SHA1_KEY_DERIVATION, SHA1_KEY_DERIVATION_MECH_INFO_TYPE,
    570 	    CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
    571 	/* SHA256_KEY_DERIVATION */
    572 	{DPROV_CKM_SHA256_KEY_DERIVATION, SHA256_KEY_DERIVATION_MECH_INFO_TYPE,
    573 	    CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
    574 	/* SHA384_KEY_DERIVATION */
    575 	{DPROV_CKM_SHA384_KEY_DERIVATION, SHA384_KEY_DERIVATION_MECH_INFO_TYPE,
    576 	    CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
    577 	/* SHA512_KEY_DERIVATION */
    578 	{DPROV_CKM_SHA512_KEY_DERIVATION, SHA512_KEY_DERIVATION_MECH_INFO_TYPE,
    579 	    CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
    580 	/* DES_KEY_GENERATION */
    581 	{DPROV_CKM_DES_KEY_GEN, DES_KEY_GEN_MECH_INFO_TYPE,
    582 	    CRYPTO_FG_GENERATE, DES_KEY_LEN, DES_KEY_LEN,
    583 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    584 	/* DES3_KEY_GENERATION */
    585 	{DPROV_CKM_DES3_KEY_GEN, DES3_KEY_GEN_MECH_INFO_TYPE,
    586 	    CRYPTO_FG_GENERATE, DES3_KEY_LEN, DES3_KEY_LEN,
    587 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    588 	/* AES_KEY_GENERATION */
    589 	{DPROV_CKM_AES_KEY_GEN, AES_KEY_GEN_MECH_INFO_TYPE,
    590 	    CRYPTO_FG_GENERATE, AES_MIN_KEY_LEN, AES_MAX_KEY_LEN,
    591 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    592 	/* BLOWFISH_KEY_GENERATION */
    593 	{DPROV_CKM_BLOWFISH_KEY_GEN, BLOWFISH_KEY_GEN_MECH_INFO_TYPE,
    594 	    CRYPTO_FG_GENERATE, BLOWFISH_MIN_KEY_LEN, BLOWFISH_MAX_KEY_LEN,
    595 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
    596 	/* RC4_KEY_GENERATION */
    597 	{DPROV_CKM_RC4_KEY_GEN, RC4_KEY_GEN_MECH_INFO_TYPE,
    598 	    CRYPTO_FG_GENERATE, ARCFOUR_MIN_KEY_BITS, ARCFOUR_MAX_KEY_BITS,
    599 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
    600 	/* DH_PKCS_KEY_PAIR_GEN */
    601 	{DPROV_CKM_DH_PKCS_KEY_PAIR_GEN, DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE,
    602 	    CRYPTO_FG_GENERATE_KEY_PAIR, DH_MIN_KEY_LEN, DH_MAX_KEY_LEN,
    603 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
    604 	/* DH_PKCS_DERIVE */
    605 	{DPROV_CKM_DH_PKCS_DERIVE, DH_PKCS_DERIVE_MECH_INFO_TYPE,
    606 	    CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
    607 	/* RSA_PKCS_KEY_PAIR_GEN */
    608 	{DPROV_CKM_RSA_PKCS_KEY_PAIR_GEN, RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE,
    609 	    CRYPTO_FG_GENERATE_KEY_PAIR, RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN,
    610 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
    611 	/* EC_KEY_PAIR_GEN */
    612 	{DPROV_CKM_EC_KEY_PAIR_GEN, EC_KEY_PAIR_GEN_MECH_INFO_TYPE,
    613 	    CRYPTO_FG_GENERATE_KEY_PAIR, EC_MIN_KEY_LEN, EC_MAX_KEY_LEN,
    614 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
    615 	/* ECDSA */
    616 	{DPROV_CKM_ECDSA, ECDSA_MECH_INFO_TYPE,
    617 	    CRYPTO_FG_SIGN | CRYPTO_FG_VERIFY |
    618 	    CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC |
    619 	    EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
    620 	/* ECDSA_SHA1 */
    621 	{DPROV_CKM_ECDSA_SHA1, ECDSA_SHA1_MECH_INFO_TYPE,
    622 	    CRYPTO_FG_SIGN | CRYPTO_FG_VERIFY |
    623 	    CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC |
    624 	    EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
    625 	/* ECDH1_DERIVE */
    626 	{DPROV_CKM_ECDH1_DERIVE, ECDH1_DERIVE_MECH_INFO_TYPE,
    627 	    CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}
    628 };
    629 
    630 /*
    631  * Crypto Values
    632  *
    633  * These values are the used in the STC ef test suite.  If they are changed
    634  * the test suite needs to be changed.
    635  */
    636 static uchar_t dh_value[8] = { 'd', 'h', 'd', 'h', 'd', 'h', 'd', '\0' };
    637 char public_exponent[3] = { 0x01, 0x00, 0x01 };
    638 static uchar_t private_exponent[128] = {
    639 	0x8e, 0xc9, 0x70, 0x57, 0x6b, 0xcd, 0xfb, 0xa9,
    640 	0x19, 0xad, 0xcd, 0x91, 0x69, 0xd5, 0x52, 0xec,
    641 	0x72, 0x1e, 0x45, 0x15, 0x06, 0xdc, 0x65, 0x2d,
    642 	0x98, 0xc4, 0xce, 0x33, 0x54, 0x15, 0x70, 0x8d,
    643 	0xfa, 0x65, 0xea, 0x53, 0x44, 0xf3, 0x3e, 0x3f,
    644 	0xb4, 0x4c, 0x60, 0xd5, 0x01, 0x2d, 0xa4, 0x12,
    645 	0x99, 0xbf, 0x3f, 0x0b, 0xcd, 0xbb, 0x24, 0x10,
    646 	0x60, 0x30, 0x5e, 0x58, 0xf8, 0x59, 0xaa, 0xd1,
    647 	0x63, 0x3b, 0xbc, 0xcb, 0x94, 0x58, 0x38, 0x24,
    648 	0xfc, 0x65, 0x25, 0xc5, 0xa6, 0x51, 0xa2, 0x2e,
    649 	0xf1, 0x5e, 0xf5, 0xc1, 0xf5, 0x46, 0xf7, 0xbd,
    650 	0xc7, 0x62, 0xa8, 0xe2, 0x27, 0xd6, 0x94, 0x5b,
    651 	0xd3, 0xa2, 0xb5, 0x76, 0x42, 0x67, 0x6b, 0x86,
    652 	0x91, 0x97, 0x4d, 0x07, 0x92, 0x00, 0x4a, 0xdf,
    653 	0x0b, 0x65, 0x64, 0x05, 0x03, 0x48, 0x27, 0xeb,
    654 	0xce, 0x9a, 0x49, 0x7f, 0x3e, 0x10, 0xe0, 0x01
    655 };
    656 
    657 static uchar_t modulus[128] = {
    658 	0x94, 0x32, 0xb9, 0x12, 0x1d, 0x68, 0x2c, 0xda,
    659 	0x2b, 0xe0, 0xe4, 0x97, 0x1b, 0x4d, 0xdc, 0x43,
    660 	0xdf, 0x38, 0x6e, 0x7b, 0x9f, 0x07, 0x58, 0xae,
    661 	0x9d, 0x82, 0x1e, 0xc7, 0xbc, 0x92, 0xbf, 0xd3,
    662 	0xce, 0x00, 0xbb, 0x91, 0xc9, 0x79, 0x06, 0x03,
    663 	0x1f, 0xbc, 0x9f, 0x94, 0x75, 0x29, 0x5f, 0xd7,
    664 	0xc5, 0xf3, 0x73, 0x8a, 0xa4, 0x35, 0x43, 0x7a,
    665 	0x00, 0x32, 0x97, 0x3e, 0x86, 0xef, 0x70, 0x6f,
    666 	0x18, 0x56, 0x15, 0xaa, 0x6a, 0x87, 0xe7, 0x8d,
    667 	0x7d, 0xdd, 0x1f, 0xa4, 0xe4, 0x31, 0xd4, 0x7a,
    668 	0x8c, 0x0e, 0x20, 0xd2, 0x23, 0xf5, 0x57, 0x3c,
    669 	0x1b, 0xa8, 0x44, 0xa4, 0x57, 0x8f, 0x33, 0x52,
    670 	0xad, 0x83, 0xae, 0x4a, 0x97, 0xa6, 0x1e, 0xa6,
    671 	0x2b, 0xfa, 0xea, 0xeb, 0x6e, 0x71, 0xb8, 0xb6,
    672 	0x0a, 0x36, 0xed, 0x83, 0xce, 0xb0, 0xdf, 0xc1,
    673 	0xd4, 0x3a, 0xe9, 0x99, 0x6f, 0xf3, 0x96, 0xb7
    674 };
    675 
    676 
    677 static void dprov_provider_status(crypto_provider_handle_t, uint_t *);
    678 
    679 static crypto_control_ops_t dprov_control_ops = {
    680 	dprov_provider_status
    681 };
    682 
    683 #define	DPROV_MANUFACTURER	"SUNW                            "
    684 #define	DPROV_MODEL		"dprov           "
    685 #define	DPROV_ALLSPACES		"                "
    686 
    687 static int dprov_digest_init(crypto_ctx_t *, crypto_mechanism_t *,
    688     crypto_req_handle_t);
    689 static int dprov_digest(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
    690     crypto_req_handle_t);
    691 static int dprov_digest_update(crypto_ctx_t *, crypto_data_t *,
    692     crypto_req_handle_t);
    693 static int dprov_digest_key(crypto_ctx_t *, crypto_key_t *,
    694     crypto_req_handle_t);
    695 static int dprov_digest_final(crypto_ctx_t *, crypto_data_t *,
    696     crypto_req_handle_t);
    697 static int dprov_digest_atomic(crypto_provider_handle_t, crypto_session_id_t,
    698     crypto_mechanism_t *, crypto_data_t *, crypto_data_t *,
    699     crypto_req_handle_t);
    700 
    701 static crypto_digest_ops_t dprov_digest_ops = {
    702 	dprov_digest_init,
    703 	dprov_digest,
    704 	dprov_digest_update,
    705 	dprov_digest_key,
    706 	dprov_digest_final,
    707 	dprov_digest_atomic
    708 };
    709 
    710 static int dprov_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
    711     crypto_spi_ctx_template_t, crypto_req_handle_t);
    712 static int dprov_mac(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
    713     crypto_req_handle_t);
    714 static int dprov_mac_update(crypto_ctx_t *, crypto_data_t *,
    715     crypto_req_handle_t);
    716 static int dprov_mac_final(crypto_ctx_t *, crypto_data_t *,
    717     crypto_req_handle_t);
    718 static int dprov_mac_atomic(crypto_provider_handle_t, crypto_session_id_t,
    719     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
    720     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
    721 static int dprov_mac_verify_atomic(crypto_provider_handle_t,
    722     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
    723     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
    724 
    725 static crypto_mac_ops_t dprov_mac_ops = {
    726 	dprov_mac_init,
    727 	dprov_mac,
    728 	dprov_mac_update,
    729 	dprov_mac_final,
    730 	dprov_mac_atomic,
    731 	dprov_mac_verify_atomic
    732 };
    733 
    734 static int dprov_encrypt_init(crypto_ctx_t *, crypto_mechanism_t *,
    735     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
    736 static int dprov_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
    737     crypto_req_handle_t);
    738 static int dprov_encrypt_update(crypto_ctx_t *, crypto_data_t *,
    739     crypto_data_t *, crypto_req_handle_t);
    740 static int dprov_encrypt_final(crypto_ctx_t *, crypto_data_t *,
    741     crypto_req_handle_t);
    742 static int dprov_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
    743     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
    744     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
    745 
    746 static int dprov_decrypt_init(crypto_ctx_t *, crypto_mechanism_t *,
    747     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
    748 static int dprov_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
    749     crypto_req_handle_t);
    750 static int dprov_decrypt_update(crypto_ctx_t *, crypto_data_t *,
    751     crypto_data_t *, crypto_req_handle_t);
    752 static int dprov_decrypt_final(crypto_ctx_t *, crypto_data_t *,
    753     crypto_req_handle_t);
    754 static int dprov_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
    755     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
    756     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
    757 
    758 static crypto_cipher_ops_t dprov_cipher_ops = {
    759 	dprov_encrypt_init,
    760 	dprov_encrypt,
    761 	dprov_encrypt_update,
    762 	dprov_encrypt_final,
    763 	dprov_encrypt_atomic,
    764 	dprov_decrypt_init,
    765 	dprov_decrypt,
    766 	dprov_decrypt_update,
    767 	dprov_decrypt_final,
    768 	dprov_decrypt_atomic
    769 };
    770 
    771 static int dprov_sign_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
    772     crypto_spi_ctx_template_t, crypto_req_handle_t);
    773 static int dprov_sign(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
    774     crypto_req_handle_t);
    775 static int dprov_sign_update(crypto_ctx_t *, crypto_data_t *,
    776     crypto_req_handle_t);
    777 static int dprov_sign_final(crypto_ctx_t *, crypto_data_t *,
    778     crypto_req_handle_t);
    779 static int dprov_sign_atomic(crypto_provider_handle_t, crypto_session_id_t,
    780     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
    781     crypto_spi_ctx_template_t, crypto_req_handle_t);
    782 static int dprov_sign_recover_init(crypto_ctx_t *, crypto_mechanism_t *,
    783     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
    784 static int dprov_sign_recover(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
    785     crypto_req_handle_t);
    786 static int dprov_sign_recover_atomic(crypto_provider_handle_t,
    787     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
    788     crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
    789     crypto_req_handle_t);
    790 
    791 static crypto_sign_ops_t dprov_sign_ops = {
    792 	dprov_sign_init,
    793 	dprov_sign,
    794 	dprov_sign_update,
    795 	dprov_sign_final,
    796 	dprov_sign_atomic,
    797 	dprov_sign_recover_init,
    798 	dprov_sign_recover,
    799 	dprov_sign_recover_atomic
    800 };
    801 
    802 static int dprov_verify_init(crypto_ctx_t *, crypto_mechanism_t *,
    803     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
    804 static int dprov_verify(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
    805     crypto_req_handle_t);
    806 static int dprov_verify_update(crypto_ctx_t *, crypto_data_t *,
    807     crypto_req_handle_t);
    808 static int dprov_verify_final(crypto_ctx_t *, crypto_data_t *,
    809     crypto_req_handle_t);
    810 static int dprov_verify_atomic(crypto_provider_handle_t, crypto_session_id_t,
    811     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
    812     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
    813 static int dprov_verify_recover_init(crypto_ctx_t *, crypto_mechanism_t *,
    814     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
    815 static int dprov_verify_recover(crypto_ctx_t *, crypto_data_t *,
    816     crypto_data_t *, crypto_req_handle_t);
    817 static int dprov_verify_recover_atomic(crypto_provider_handle_t,
    818     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
    819     crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
    820     crypto_req_handle_t);
    821 
    822 static crypto_verify_ops_t dprov_verify_ops = {
    823 	dprov_verify_init,
    824 	dprov_verify,
    825 	dprov_verify_update,
    826 	dprov_verify_final,
    827 	dprov_verify_atomic,
    828 	dprov_verify_recover_init,
    829 	dprov_verify_recover,
    830 	dprov_verify_recover_atomic
    831 };
    832 
    833 static int dprov_digest_encrypt_update(crypto_ctx_t *, crypto_ctx_t *,
    834     crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
    835 static int dprov_decrypt_digest_update(crypto_ctx_t *, crypto_ctx_t *,
    836     crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
    837 static int dprov_sign_encrypt_update(crypto_ctx_t *, crypto_ctx_t *,
    838     crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
    839 static int dprov_decrypt_verify_update(crypto_ctx_t *, crypto_ctx_t *,
    840     crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
    841 
    842 static crypto_dual_ops_t dprov_dual_ops = {
    843 	dprov_digest_encrypt_update,
    844 	dprov_decrypt_digest_update,
    845 	dprov_sign_encrypt_update,
    846 	dprov_decrypt_verify_update
    847 };
    848 
    849 static int dprov_encrypt_mac_init(crypto_ctx_t *,
    850     crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *,
    851     crypto_key_t *, crypto_spi_ctx_template_t,
    852     crypto_spi_ctx_template_t, crypto_req_handle_t);
    853 static int dprov_encrypt_mac(crypto_ctx_t *,
    854     crypto_data_t *, crypto_dual_data_t *, crypto_data_t *,
    855     crypto_req_handle_t);
    856 static int dprov_encrypt_mac_update(crypto_ctx_t *,
    857     crypto_data_t *, crypto_dual_data_t *, crypto_req_handle_t);
    858 static int dprov_encrypt_mac_final(crypto_ctx_t *,
    859     crypto_dual_data_t *, crypto_data_t *, crypto_req_handle_t);
    860 static int dprov_encrypt_mac_atomic(crypto_provider_handle_t,
    861     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
    862     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
    863     crypto_dual_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
    864     crypto_spi_ctx_template_t, crypto_req_handle_t);
    865 
    866 static int dprov_mac_decrypt_init(crypto_ctx_t *,
    867     crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *,
    868     crypto_key_t *, crypto_spi_ctx_template_t,
    869     crypto_spi_ctx_template_t, crypto_req_handle_t);
    870 static int dprov_mac_decrypt(crypto_ctx_t *,
    871     crypto_dual_data_t *, crypto_data_t *, crypto_data_t *,
    872     crypto_req_handle_t);
    873 static int dprov_mac_decrypt_update(crypto_ctx_t *,
    874     crypto_dual_data_t *, crypto_data_t *, crypto_req_handle_t);
    875 static int dprov_mac_decrypt_final(crypto_ctx_t *,
    876     crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
    877 static int dprov_mac_decrypt_atomic(crypto_provider_handle_t,
    878     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
    879     crypto_mechanism_t *, crypto_key_t *, crypto_dual_data_t *,
    880     crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
    881     crypto_spi_ctx_template_t, crypto_req_handle_t);
    882 static int dprov_mac_verify_decrypt_atomic(crypto_provider_handle_t,
    883     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
    884     crypto_mechanism_t *, crypto_key_t *, crypto_dual_data_t *,
    885     crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
    886     crypto_spi_ctx_template_t, crypto_req_handle_t);
    887 
    888 static crypto_dual_cipher_mac_ops_t dprov_cipher_mac_ops = {
    889 	dprov_encrypt_mac_init,
    890 	dprov_encrypt_mac,
    891 	dprov_encrypt_mac_update,
    892 	dprov_encrypt_mac_final,
    893 	dprov_encrypt_mac_atomic,
    894 	dprov_mac_decrypt_init,
    895 	dprov_mac_decrypt,
    896 	dprov_mac_decrypt_update,
    897 	dprov_mac_decrypt_final,
    898 	dprov_mac_decrypt_atomic,
    899 	dprov_mac_verify_decrypt_atomic
    900 };
    901 
    902 static int dprov_seed_random(crypto_provider_handle_t, crypto_session_id_t,
    903     uchar_t *, size_t, uint_t, uint32_t, crypto_req_handle_t);
    904 static int dprov_generate_random(crypto_provider_handle_t, crypto_session_id_t,
    905     uchar_t *, size_t, crypto_req_handle_t);
    906 
    907 static crypto_random_number_ops_t dprov_random_number_ops = {
    908 	dprov_seed_random,
    909 	dprov_generate_random
    910 };
    911 
    912 static int dprov_session_open(crypto_provider_handle_t, crypto_session_id_t *,
    913     crypto_req_handle_t);
    914 static int dprov_session_close(crypto_provider_handle_t, crypto_session_id_t,
    915     crypto_req_handle_t);
    916 static int dprov_session_login(crypto_provider_handle_t, crypto_session_id_t,
    917     crypto_user_type_t, char *, size_t, crypto_req_handle_t);
    918 static int dprov_session_logout(crypto_provider_handle_t, crypto_session_id_t,
    919     crypto_req_handle_t);
    920 
    921 static crypto_session_ops_t dprov_session_ops = {
    922 	dprov_session_open,
    923 	dprov_session_close,
    924 	dprov_session_login,
    925 	dprov_session_logout
    926 };
    927 
    928 static int dprov_object_create(crypto_provider_handle_t, crypto_session_id_t,
    929     crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
    930     crypto_req_handle_t);
    931 static int dprov_object_copy(crypto_provider_handle_t, crypto_session_id_t,
    932     crypto_object_id_t, crypto_object_attribute_t *, uint_t,
    933     crypto_object_id_t *, crypto_req_handle_t);
    934 static int dprov_object_destroy(crypto_provider_handle_t, crypto_session_id_t,
    935     crypto_object_id_t, crypto_req_handle_t);
    936 static int dprov_object_get_size(crypto_provider_handle_t, crypto_session_id_t,
    937     crypto_object_id_t, size_t *, crypto_req_handle_t);
    938 static int dprov_object_get_attribute_value(crypto_provider_handle_t,
    939     crypto_session_id_t, crypto_object_id_t,
    940     crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
    941 static int dprov_object_set_attribute_value(crypto_provider_handle_t,
    942     crypto_session_id_t, crypto_object_id_t,
    943     crypto_object_attribute_t *,  uint_t, crypto_req_handle_t);
    944 static int dprov_object_find_init(crypto_provider_handle_t, crypto_session_id_t,
    945     crypto_object_attribute_t *, uint_t, void **,
    946     crypto_req_handle_t);
    947 static int dprov_object_find(crypto_provider_handle_t, void *,
    948     crypto_object_id_t *, uint_t, uint_t *, crypto_req_handle_t);
    949 static int dprov_object_find_final(crypto_provider_handle_t, void *,
    950     crypto_req_handle_t);
    951 
    952 static crypto_object_ops_t dprov_object_ops = {
    953 	dprov_object_create,
    954 	dprov_object_copy,
    955 	dprov_object_destroy,
    956 	dprov_object_get_size,
    957 	dprov_object_get_attribute_value,
    958 	dprov_object_set_attribute_value,
    959 	dprov_object_find_init,
    960 	dprov_object_find,
    961 	dprov_object_find_final
    962 };
    963 
    964 static int dprov_key_generate(crypto_provider_handle_t, crypto_session_id_t,
    965     crypto_mechanism_t *, crypto_object_attribute_t *, uint_t,
    966     crypto_object_id_t *, crypto_req_handle_t);
    967 static int dprov_key_generate_pair(crypto_provider_handle_t,
    968     crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *,
    969     uint_t, crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
    970     crypto_object_id_t *, crypto_req_handle_t);
    971 static int dprov_key_wrap(crypto_provider_handle_t, crypto_session_id_t,
    972     crypto_mechanism_t *, crypto_key_t *, crypto_object_id_t *,
    973     uchar_t *, size_t *, crypto_req_handle_t);
    974 static int dprov_key_unwrap(crypto_provider_handle_t, crypto_session_id_t,
    975     crypto_mechanism_t *, crypto_key_t *, uchar_t *, size_t *,
    976     crypto_object_attribute_t *, uint_t,
    977     crypto_object_id_t *, crypto_req_handle_t);
    978 static int dprov_key_derive(crypto_provider_handle_t, crypto_session_id_t,
    979     crypto_mechanism_t *, crypto_key_t *, crypto_object_attribute_t *,
    980     uint_t, crypto_object_id_t *, crypto_req_handle_t);
    981 
    982 static crypto_key_ops_t dprov_key_ops = {
    983 	dprov_key_generate,
    984 	dprov_key_generate_pair,
    985 	dprov_key_wrap,
    986 	dprov_key_unwrap,
    987 	dprov_key_derive
    988 };
    989 
    990 static int dprov_ext_info(crypto_provider_handle_t,
    991     crypto_provider_ext_info_t *, crypto_req_handle_t);
    992 static int dprov_init_token(crypto_provider_handle_t, char *, size_t,
    993     char *, crypto_req_handle_t);
    994 static int dprov_init_pin(crypto_provider_handle_t, crypto_session_id_t,
    995     char *, size_t, crypto_req_handle_t);
    996 static int dprov_set_pin(crypto_provider_handle_t, crypto_session_id_t,
    997     char *, size_t, char *, size_t, crypto_req_handle_t);
    998 
    999 static crypto_provider_management_ops_t dprov_management_ops = {
   1000 	dprov_ext_info,
   1001 	dprov_init_token,
   1002 	dprov_init_pin,
   1003 	dprov_set_pin
   1004 };
   1005 
   1006 static int dprov_free_context(crypto_ctx_t *);
   1007 static int dprov_copyin_mechanism(crypto_provider_handle_t,
   1008     crypto_mechanism_t *, crypto_mechanism_t *, int *error, int);
   1009 static int dprov_copyout_mechanism(crypto_provider_handle_t,
   1010     crypto_mechanism_t *, crypto_mechanism_t *, int *error, int);
   1011 static int dprov_free_mechanism(crypto_provider_handle_t,
   1012     crypto_mechanism_t *);
   1013 
   1014 static crypto_ctx_ops_t dprov_ctx_ops = {
   1015 	NULL,
   1016 	dprov_free_context
   1017 };
   1018 
   1019 static crypto_mech_ops_t dprov_mech_ops = {
   1020 	dprov_copyin_mechanism,
   1021 	dprov_copyout_mechanism,
   1022 	dprov_free_mechanism
   1023 };
   1024 
   1025 static int dprov_nostore_key_generate(crypto_provider_handle_t,
   1026     crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *,
   1027     uint_t, crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
   1028 static int dprov_nostore_key_generate_pair(crypto_provider_handle_t,
   1029     crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *,
   1030     uint_t, crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *,
   1031     uint_t, crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
   1032 static int dprov_nostore_key_derive(crypto_provider_handle_t,
   1033     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
   1034     crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *,
   1035     uint_t, crypto_req_handle_t);
   1036 
   1037 static crypto_nostore_key_ops_t dprov_nostore_key_ops = {
   1038 	dprov_nostore_key_generate,
   1039 	dprov_nostore_key_generate_pair,
   1040 	dprov_nostore_key_derive
   1041 };
   1042 
   1043 static crypto_ops_t dprov_crypto_ops = {
   1044 	&dprov_control_ops,
   1045 	&dprov_digest_ops,
   1046 	&dprov_cipher_ops,
   1047 	&dprov_mac_ops,
   1048 	&dprov_sign_ops,
   1049 	&dprov_verify_ops,
   1050 	&dprov_dual_ops,
   1051 	&dprov_cipher_mac_ops,
   1052 	&dprov_random_number_ops,
   1053 	&dprov_session_ops,
   1054 	&dprov_object_ops,
   1055 	&dprov_key_ops,
   1056 	&dprov_management_ops,
   1057 	&dprov_ctx_ops,
   1058 	&dprov_mech_ops
   1059 };
   1060 
   1061 
   1062 /* maximum SO and user PIN lengths */
   1063 #define	DPROV_MAX_PIN_LEN	128
   1064 
   1065 /*
   1066  * Objects: each session is associated with an array of objects.
   1067  * Unlike PKCS#11, the objects cannot be shared between sessions.
   1068  * The ioctl driver multiplexes PKCS#11 sessions to providers
   1069  * sessions in order to support this semantic. This simplifies
   1070  * the CSPI greatly since the provider does not have to associate
   1071  * sessions with a user space process.
   1072  * There is also a per-instance array of objects, which correspond
   1073  * to PKCS#11 token objects. These objects can be shared by multiple
   1074  * sesions.
   1075  *
   1076  * Token objects are identified by having a CKA_TOKEN attribute B_TRUE.
   1077  * Private objects are identified by having a CKA_PRIVATE attribute
   1078  * set to B_TRUE.
   1079  */
   1080 
   1081 #define	DPROV_MAX_OBJECTS	128	/* max # of objects */
   1082 #define	DPROV_MAX_ATTR		64	/* max # of attributes per object */
   1083 
   1084 /* object description */
   1085 typedef struct dprov_object {
   1086 	crypto_object_attribute_t do_attr[DPROV_MAX_ATTR]; /* attributes */
   1087 	uint_t do_token_idx;		/* index in per-instance table */
   1088 					/* for token objects. */
   1089 	boolean_t do_destroyed;		/* object has been destroyed. */
   1090 					/* keep object around until all */
   1091 					/* sessions that refer to it */
   1092 					/* are closed, but mark it */
   1093 					/* destroyed so that references */
   1094 					/* to the object fail. */
   1095 					/* used for token objects only */
   1096 	uint_t do_refcnt;
   1097 } dprov_object_t;
   1098 
   1099 /*
   1100  * If a session has a reference to a dprov_object_t,
   1101  * it REFHOLD()s.
   1102  */
   1103 #define	DPROV_OBJECT_REFHOLD(object) {		\
   1104 	atomic_add_32(&(object)->do_refcnt, 1);	\
   1105 	ASSERT((object)->do_refcnt != 0);		\
   1106 }
   1107 
   1108 /*
   1109  * Releases a reference to an object. When the last
   1110  * reference is released, the object is freed.
   1111  */
   1112 #define	DPROV_OBJECT_REFRELE(object) {				\
   1113 	ASSERT((object)->do_refcnt != 0);			\
   1114 	membar_exit();						\
   1115 	if (atomic_add_32_nv(&(object)->do_refcnt, -1) == 0)	\
   1116 		dprov_free_object(object);			\
   1117 }
   1118 
   1119 /*
   1120  * Object attributes are passed to the provider using crypto_object_attribute
   1121  * structures, which contain the type of the attribute, a pointer to
   1122  * it's value, and the length of its value. The attribute types values
   1123  * are defined by the PKCS#11 specification. This provider only cares
   1124  * about a subset of these attributes. In order to avoid having to
   1125  * include the PKCS#11 header files, we define here the attributes values
   1126  * which are used by the provider.
   1127  */
   1128 
   1129 #define	DPROV_CKA_CLASS			0x00000000
   1130 #define	DPROV_CKA_TOKEN			0x00000001
   1131 #define	DPROV_CKA_PRIVATE		0x00000002
   1132 #define	DPROV_CKA_VALUE			0x00000011
   1133 #define	DPROV_CKA_CERTIFICATE_TYPE	0x00000080
   1134 #define	DPROV_CKA_KEY_TYPE		0x00000100
   1135 #define	DPROV_CKA_SENSITIVE		0x00000103
   1136 #define	DPROV_CKA_ENCRYPT		0x00000104
   1137 #define	DPROV_CKA_DECRYPT		0x00000105
   1138 #define	DPROV_CKA_WRAP			0x00000106
   1139 #define	DPROV_CKA_UNWRAP		0x00000107
   1140 #define	DPROV_CKA_SIGN			0x00000108
   1141 #define	DPROV_CKA_SIGN_RECOVER		0x00000109
   1142 #define	DPROV_CKA_VERIFY		0x0000010A
   1143 #define	DPROV_CKA_VERIFY_RECOVER	0x0000010B
   1144 #define	DPROV_CKA_DERIVE		0x0000010C
   1145 #define	DPROV_CKA_MODULUS		0x00000120
   1146 #define	DPROV_CKA_MODULUS_BITS		0x00000121
   1147 #define	DPROV_CKA_PUBLIC_EXPONENT	0x00000122
   1148 #define	DPROV_CKA_PRIVATE_EXPONENT	0x00000123
   1149 #define	DPROV_CKA_PRIME			0x00000130
   1150 #define	DPROV_CKA_BASE			0x00000132
   1151 #define	DPROV_CKA_VALUE_BITS		0x00000160
   1152 #define	DPROV_CKA_VALUE_LEN		0x00000161
   1153 #define	DPROV_CKA_EXTRACTABLE		0x00000162
   1154 #define	DPROV_CKA_EC_PARAMS		0x00000180
   1155 #define	DPROV_CKA_EC_POINT		0x00000181
   1156 #define	DPROV_HW_FEATURE_TYPE		0x00000300
   1157 
   1158 /*
   1159  * Object classes from PKCS#11
   1160  */
   1161 #define	DPROV_CKO_DATA			0x00000000
   1162 #define	DPROV_CKO_CERTIFICATE		0x00000001
   1163 #define	DPROV_CKO_PUBLIC_KEY		0x00000002
   1164 #define	DPROV_CKO_PRIVATE_KEY		0x00000003
   1165 #define	DPROV_CKO_SECRET_KEY		0x00000004
   1166 #define	DPROV_CKO_HW_FEATURE		0x00000005
   1167 #define	DPROV_CKO_DOMAIN_PARAMETERS	0x00000006
   1168 #define	DPROV_CKO_VENDOR_DEFINED	0x80000000
   1169 
   1170 /*
   1171  * A few key types from PKCS#11
   1172  */
   1173 #define	DPROV_CKK_RSA			0x00000000
   1174 #define	DPROV_CKK_GENERIC_SECRET	0x00000010
   1175 #define	DPROV_CKK_RC4			0x00000012
   1176 #define	DPROV_CKK_DES			0x00000013
   1177 #define	DPROV_CKK_DES3			0x00000015
   1178 #define	DPROV_CKK_AES			0x0000001F
   1179 #define	DPROV_CKK_BLOWFISH		0x00000020
   1180 
   1181 /*
   1182  * Find object context. Allows the find object init/find/final
   1183  * to store data persistent across calls.
   1184  */
   1185 typedef struct dprov_find_ctx {
   1186 	crypto_object_id_t fc_ids[DPROV_MAX_OBJECTS];	/* object ids */
   1187 	uint_t fc_nids;			/* number of ids in fc_ids */
   1188 	uint_t fc_next;			/* next id to return */
   1189 } dprov_find_ctx_t;
   1190 
   1191 /*
   1192  * Session management: each instance is associated with an array
   1193  * of sessions. KEF providers sessions are always R/W the library and
   1194  * the ioctl maintain the PKCS#11 R/W attributes for the session.
   1195  */
   1196 
   1197 #define	DPROV_MIN_SESSIONS	32	/* # of sessions to start with */
   1198 
   1199 typedef enum dprov_session_state {
   1200 	DPROV_SESSION_STATE_PUBLIC,	/* public (default) */
   1201 	DPROV_SESSION_STATE_SO,		/* SO logged in */
   1202 	DPROV_SESSION_STATE_USER	/* user logged in */
   1203 } dprov_session_state_t;
   1204 
   1205 /* session description */
   1206 typedef struct dprov_session {
   1207 	dprov_session_state_t ds_state;	/* session state */
   1208 	dprov_object_t *ds_objects[DPROV_MAX_OBJECTS];	/* session objects */
   1209 } dprov_session_t;
   1210 
   1211 
   1212 static crypto_provider_info_t dprov_prov_info = {
   1213 	CRYPTO_SPI_VERSION_2,
   1214 	"Dummy Pseudo HW Provider",
   1215 	CRYPTO_HW_PROVIDER,
   1216 	NULL,				/* pi_provider_dev */
   1217 	NULL,				/* pi_provider_handle */
   1218 	&dprov_crypto_ops,
   1219 	sizeof (dprov_mech_info_tab)/sizeof (crypto_mech_info_t),
   1220 	dprov_mech_info_tab,
   1221 	0,				/* pi_logical_provider_count */
   1222 	NULL,				/* pi_logical_providers */
   1223 	0				/* pi_flags */
   1224 };
   1225 
   1226 /*
   1227  * Per-instance info.
   1228  */
   1229 typedef struct dprov_state {
   1230 	kmutex_t ds_lock;		/* per-instance lock */
   1231 	dev_info_t *ds_dip;		/* device info */
   1232 	crypto_kcf_provider_handle_t ds_prov_handle;	/* framework handle */
   1233 	taskq_t *ds_taskq;		/* taskq for async behavior */
   1234 	char ds_user_pin[DPROV_MAX_PIN_LEN];	/* normal user PIN */
   1235 	uint_t ds_user_pin_len;
   1236 	char ds_so_pin[DPROV_MAX_PIN_LEN];	/* SO PIN */
   1237 	uint_t ds_so_pin_len;
   1238 	dprov_session_t **ds_sessions;	/* sessions for this instance */
   1239 	uint_t ds_sessions_slots;	/* number of session slots */
   1240 	uint_t ds_sessions_count;	/* number of open sessions */
   1241 	boolean_t ds_token_initialized;	/* provider initialized? */
   1242 	boolean_t ds_user_pin_set;	/* user pin set? */
   1243 	char ds_label[CRYPTO_EXT_SIZE_LABEL];		/* "token" label */
   1244 	dprov_object_t *ds_objects[DPROV_MAX_OBJECTS];	/* "token" objects */
   1245 } dprov_state_t;
   1246 
   1247 
   1248 /*
   1249  * A taskq is associated with each instance of the pseudo driver in order
   1250  * to simulate the asynchronous execution of requests.
   1251  * The following defines the taskq request structures.
   1252  */
   1253 
   1254 /* request types */
   1255 typedef enum dprov_req_type {
   1256 	/* digest requests */
   1257 	DPROV_REQ_DIGEST_INIT = 1,
   1258 	DPROV_REQ_DIGEST,
   1259 	DPROV_REQ_DIGEST_UPDATE,
   1260 	DPROV_REQ_DIGEST_KEY,
   1261 	DPROV_REQ_DIGEST_FINAL,
   1262 	DPROV_REQ_DIGEST_ATOMIC,
   1263 	/* cipher requests */
   1264 	DPROV_REQ_ENCRYPT_INIT,
   1265 	DPROV_REQ_ENCRYPT,
   1266 	DPROV_REQ_ENCRYPT_UPDATE,
   1267 	DPROV_REQ_ENCRYPT_FINAL,
   1268 	DPROV_REQ_ENCRYPT_ATOMIC,
   1269 	DPROV_REQ_DECRYPT_INIT,
   1270 	DPROV_REQ_DECRYPT,
   1271 	DPROV_REQ_DECRYPT_UPDATE,
   1272 	DPROV_REQ_DECRYPT_FINAL,
   1273 	DPROV_REQ_DECRYPT_ATOMIC,
   1274 	/* mac requests */
   1275 	DPROV_REQ_MAC_INIT,
   1276 	DPROV_REQ_MAC,
   1277 	DPROV_REQ_MAC_UPDATE,
   1278 	DPROV_REQ_MAC_FINAL,
   1279 	DPROV_REQ_MAC_ATOMIC,
   1280 	DPROV_REQ_MAC_VERIFY_ATOMIC,
   1281 	/* sign requests */
   1282 	DPROV_REQ_SIGN_INIT,
   1283 	DPROV_REQ_SIGN,
   1284 	DPROV_REQ_SIGN_UPDATE,
   1285 	DPROV_REQ_SIGN_FINAL,
   1286 	DPROV_REQ_SIGN_ATOMIC,
   1287 	DPROV_REQ_SIGN_RECOVER_INIT,
   1288 	DPROV_REQ_SIGN_RECOVER,
   1289 	DPROV_REQ_SIGN_RECOVER_ATOMIC,
   1290 	/* verify requests */
   1291 	DPROV_REQ_VERIFY_INIT,
   1292 	DPROV_REQ_VERIFY,
   1293 	DPROV_REQ_VERIFY_UPDATE,
   1294 	DPROV_REQ_VERIFY_FINAL,
   1295 	DPROV_REQ_VERIFY_ATOMIC,
   1296 	DPROV_REQ_VERIFY_RECOVER_INIT,
   1297 	DPROV_REQ_VERIFY_RECOVER,
   1298 	DPROV_REQ_VERIFY_RECOVER_ATOMIC,
   1299 	/* dual ops requests */
   1300 	DPROV_REQ_DIGEST_ENCRYPT_UPDATE,
   1301 	DPROV_REQ_DECRYPT_DIGEST_UPDATE,
   1302 	DPROV_REQ_SIGN_ENCRYPT_UPDATE,
   1303 	DPROV_REQ_DECRYPT_VERIFY_UPDATE,
   1304 	/* dual cipher/mac requests */
   1305 	DPROV_REQ_ENCRYPT_MAC_INIT,
   1306 	DPROV_REQ_ENCRYPT_MAC,
   1307 	DPROV_REQ_ENCRYPT_MAC_UPDATE,
   1308 	DPROV_REQ_ENCRYPT_MAC_FINAL,
   1309 	DPROV_REQ_ENCRYPT_MAC_ATOMIC,
   1310 	DPROV_REQ_MAC_DECRYPT_INIT,
   1311 	DPROV_REQ_MAC_DECRYPT,
   1312 	DPROV_REQ_MAC_DECRYPT_UPDATE,
   1313 	DPROV_REQ_MAC_DECRYPT_FINAL,
   1314 	DPROV_REQ_MAC_DECRYPT_ATOMIC,
   1315 	DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC,
   1316 	/* random number ops */
   1317 	DPROV_REQ_RANDOM_SEED,
   1318 	DPROV_REQ_RANDOM_GENERATE,
   1319 	/* session management requests */
   1320 	DPROV_REQ_SESSION_OPEN,
   1321 	DPROV_REQ_SESSION_CLOSE,
   1322 	DPROV_REQ_SESSION_LOGIN,
   1323 	DPROV_REQ_SESSION_LOGOUT,
   1324 	/* object management requests */
   1325 	DPROV_REQ_OBJECT_CREATE,
   1326 	DPROV_REQ_OBJECT_COPY,
   1327 	DPROV_REQ_OBJECT_DESTROY,
   1328 	DPROV_REQ_OBJECT_GET_SIZE,
   1329 	DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE,
   1330 	DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE,
   1331 	DPROV_REQ_OBJECT_FIND_INIT,
   1332 	DPROV_REQ_OBJECT_FIND,
   1333 	DPROV_REQ_OBJECT_FIND_FINAL,
   1334 	/* key management requests */
   1335 	DPROV_REQ_KEY_GENERATE,
   1336 	DPROV_REQ_KEY_GENERATE_PAIR,
   1337 	DPROV_REQ_KEY_WRAP,
   1338 	DPROV_REQ_KEY_UNWRAP,
   1339 	DPROV_REQ_KEY_DERIVE,
   1340 	/* provider management requests */
   1341 	DPROV_REQ_MGMT_EXTINFO,
   1342 	DPROV_REQ_MGMT_INITTOKEN,
   1343 	DPROV_REQ_MGMT_INITPIN,
   1344 	DPROV_REQ_MGMT_SETPIN,
   1345 	/* no (key)store key management requests */
   1346 	DPROV_REQ_NOSTORE_KEY_GENERATE,
   1347 	DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR,
   1348 	DPROV_REQ_NOSTORE_KEY_DERIVE
   1349 } dprov_req_type_t;
   1350 
   1351 /* for DPROV_REQ_DIGEST requests */
   1352 typedef struct dprov_digest_req {
   1353 	crypto_mechanism_t *dr_mechanism;
   1354 	crypto_ctx_t *dr_ctx;
   1355 	crypto_data_t *dr_data;
   1356 	crypto_key_t *dr_key;
   1357 	crypto_data_t *dr_digest;
   1358 } dprov_digest_req_t;
   1359 
   1360 /* for DPROV_REQ_MAC requests */
   1361 typedef struct dprov_mac_req {
   1362 	crypto_mechanism_t *dr_mechanism;
   1363 	crypto_ctx_t *dr_ctx;
   1364 	crypto_key_t *dr_key;
   1365 	crypto_data_t *dr_data;
   1366 	crypto_data_t *dr_mac;
   1367 	crypto_session_id_t dr_session_id;
   1368 } dprov_mac_req_t;
   1369 
   1370 /* for DPROV_REQ_ENCRYPT and DPROV_REQ_DECRYPT requests */
   1371 typedef struct dprov_cipher_req {
   1372 	crypto_mechanism_t *dr_mechanism;
   1373 	crypto_ctx_t *dr_ctx;
   1374 	crypto_key_t *dr_key;
   1375 	crypto_data_t *dr_plaintext;
   1376 	crypto_data_t *dr_ciphertext;
   1377 	crypto_session_id_t dr_session_id;
   1378 } dprov_cipher_req_t;
   1379 
   1380 /* for DPROV_REQ_SIGN requests */
   1381 typedef struct dprov_sign_req {
   1382 	crypto_mechanism_t *sr_mechanism;
   1383 	crypto_ctx_t *sr_ctx;
   1384 	crypto_key_t *sr_key;
   1385 	crypto_data_t *sr_data;
   1386 	crypto_data_t *sr_signature;
   1387 	crypto_session_id_t sr_session_id;
   1388 } dprov_sign_req_t;
   1389 
   1390 /* for DPROV_REQ_VERIFY requests */
   1391 typedef struct dprov_verify_req {
   1392 	crypto_mechanism_t *vr_mechanism;
   1393 	crypto_ctx_t *vr_ctx;
   1394 	crypto_key_t *vr_key;
   1395 	crypto_data_t *vr_data;
   1396 	crypto_data_t *vr_signature;
   1397 	crypto_session_id_t vr_session_id;
   1398 } dprov_verify_req_t;
   1399 
   1400 /* for dual ops requests */
   1401 typedef struct dprov_dual_req {
   1402 	crypto_ctx_t *dr_signverify_ctx;
   1403 	crypto_ctx_t *dr_cipher_ctx;
   1404 	crypto_data_t *dr_plaintext;
   1405 	crypto_data_t *dr_ciphertext;
   1406 } dprov_dual_req_t;
   1407 
   1408 /* for cipher/mac dual ops requests */
   1409 typedef struct dprov_cipher_mac_req {
   1410 	crypto_session_id_t mr_session_id;
   1411 	crypto_ctx_t *mr_ctx;
   1412 	crypto_mechanism_t *mr_cipher_mech;
   1413 	crypto_key_t *mr_cipher_key;
   1414 	crypto_mechanism_t *mr_mac_mech;
   1415 	crypto_key_t *mr_mac_key;
   1416 	crypto_dual_data_t *mr_dual_data;
   1417 	crypto_data_t *mr_data;
   1418 	crypto_data_t *mr_mac;
   1419 } dprov_cipher_mac_req_t;
   1420 
   1421 /* for DPROV_REQ_RANDOM requests */
   1422 typedef struct dprov_random_req {
   1423 	uchar_t *rr_buf;
   1424 	size_t rr_len;
   1425 	crypto_session_id_t rr_session_id;
   1426 	uint_t rr_entropy_est;
   1427 	uint32_t rr_flags;
   1428 } dprov_random_req_t;
   1429 
   1430 /* for DPROV_REQ_SESSION requests */
   1431 typedef struct dprov_session_req {
   1432 	crypto_session_id_t *sr_session_id_ptr;
   1433 	crypto_session_id_t sr_session_id;
   1434 	crypto_user_type_t sr_user_type;
   1435 	char *sr_pin;
   1436 	size_t sr_pin_len;
   1437 } dprov_session_req_t;
   1438 
   1439 /* for DPROV_REQ_OBJECT requests */
   1440 typedef struct dprov_object_req {
   1441 	crypto_session_id_t or_session_id;
   1442 	crypto_object_id_t or_object_id;
   1443 	crypto_object_attribute_t *or_template;
   1444 	uint_t or_attribute_count;
   1445 	crypto_object_id_t *or_object_id_ptr;
   1446 	size_t *or_object_size;
   1447 	void **or_find_pp;
   1448 	void *or_find_p;
   1449 	uint_t or_max_object_count;
   1450 	uint_t *or_object_count_ptr;
   1451 } dprov_object_req_t;
   1452 
   1453 /* for DPROV_REQ_KEY requests */
   1454 typedef struct dprov_key_req {
   1455 	crypto_session_id_t kr_session_id;
   1456 	crypto_mechanism_t *kr_mechanism;
   1457 	crypto_object_attribute_t *kr_template;
   1458 	uint_t kr_attribute_count;
   1459 	crypto_object_id_t *kr_object_id_ptr;
   1460 	crypto_object_attribute_t *kr_private_key_template;
   1461 	uint_t kr_private_key_attribute_count;
   1462 	crypto_object_id_t *kr_private_key_object_id_ptr;
   1463 	crypto_key_t *kr_key;
   1464 	uchar_t *kr_wrapped_key;
   1465 	size_t *kr_wrapped_key_len_ptr;
   1466 	crypto_object_attribute_t *kr_out_template1;
   1467 	crypto_object_attribute_t *kr_out_template2;
   1468 	uint_t kr_out_attribute_count1;
   1469 	uint_t kr_out_attribute_count2;
   1470 } dprov_key_req_t;
   1471 
   1472 /* for DPROV_REQ_MGMT requests */
   1473 typedef struct dprov_mgmt_req {
   1474 	crypto_session_id_t mr_session_id;
   1475 	char *mr_pin;
   1476 	size_t mr_pin_len;
   1477 	char *mr_old_pin;
   1478 	size_t mr_old_pin_len;
   1479 	char *mr_label;
   1480 	crypto_provider_ext_info_t *mr_ext_info;
   1481 } dprov_mgmt_req_t;
   1482 
   1483 /* request, as queued on taskq */
   1484 typedef struct dprov_req {
   1485 	dprov_req_type_t dr_type;
   1486 	dprov_state_t *dr_softc;
   1487 	crypto_req_handle_t dr_kcf_req;
   1488 	union {
   1489 		dprov_digest_req_t dru_digest_req;
   1490 		dprov_mac_req_t dru_mac_req;
   1491 		dprov_cipher_req_t dru_cipher_req;
   1492 		dprov_sign_req_t dru_sign_req;
   1493 		dprov_verify_req_t dru_verify_req;
   1494 		dprov_dual_req_t dru_dual_req;
   1495 		dprov_cipher_mac_req_t dru_cipher_mac_req;
   1496 		dprov_random_req_t dru_random_req;
   1497 		dprov_session_req_t dru_session_req;
   1498 		dprov_object_req_t dru_object_req;
   1499 		dprov_key_req_t dru_key_req;
   1500 		dprov_mgmt_req_t dru_mgmt_req;
   1501 	} dr_req;
   1502 } dprov_req_t;
   1503 
   1504 /* shortcuts for union fields */
   1505 #define	dr_digest_req		dr_req.dru_digest_req
   1506 #define	dr_mac_req		dr_req.dru_mac_req
   1507 #define	dr_cipher_req		dr_req.dru_cipher_req
   1508 #define	dr_sign_req		dr_req.dru_sign_req
   1509 #define	dr_verify_req		dr_req.dru_verify_req
   1510 #define	dr_dual_req		dr_req.dru_dual_req
   1511 #define	dr_cipher_mac_req	dr_req.dru_cipher_mac_req
   1512 #define	dr_random_req		dr_req.dru_random_req
   1513 #define	dr_session_req		dr_req.dru_session_req
   1514 #define	dr_object_req		dr_req.dru_object_req
   1515 #define	dr_key_req		dr_req.dru_key_req
   1516 #define	dr_mgmt_req		dr_req.dru_mgmt_req
   1517 
   1518 /* prototypes for the tasq dispatcher functions */
   1519 static void dprov_digest_task(dprov_req_t *);
   1520 static void dprov_mac_task(dprov_req_t *);
   1521 static void dprov_sign_task(dprov_req_t *);
   1522 static void dprov_verify_task(dprov_req_t *);
   1523 static void dprov_dual_task(dprov_req_t *);
   1524 static void dprov_cipher_task(dprov_req_t *);
   1525 static void dprov_cipher_mac_task(dprov_req_t *);
   1526 static void dprov_random_task(dprov_req_t *);
   1527 static void dprov_session_task(dprov_req_t *);
   1528 static void dprov_object_task(dprov_req_t *);
   1529 static void dprov_key_task(dprov_req_t *);
   1530 static void dprov_mgmt_task(dprov_req_t *);
   1531 
   1532 /* helper functions */
   1533 static int dprov_digest_submit_req(dprov_req_type_t, dprov_state_t *,
   1534     crypto_req_handle_t, crypto_mechanism_t *, crypto_data_t *, crypto_key_t *,
   1535     crypto_data_t *, crypto_ctx_t *, int);
   1536 static int dprov_cipher_submit_req(dprov_req_type_t, dprov_state_t *,
   1537     crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
   1538     crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
   1539 static int dprov_mac_submit_req(dprov_req_type_t, dprov_state_t *,
   1540     crypto_req_handle_t, crypto_mechanism_t *, crypto_data_t *,
   1541     crypto_key_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
   1542 static int dprov_sign_submit_req(dprov_req_type_t, dprov_state_t *,
   1543     crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *,
   1544     crypto_data_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
   1545 static int dprov_verify_submit_req(dprov_req_type_t, dprov_state_t *,
   1546     crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *,
   1547     crypto_data_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
   1548 static int dprov_dual_submit_req(dprov_req_type_t, dprov_state_t *,
   1549     crypto_req_handle_t, crypto_ctx_t *, crypto_ctx_t *, crypto_data_t *,
   1550     crypto_data_t *);
   1551 static int dprov_cipher_mac_submit_req(dprov_req_type_t, dprov_state_t *,
   1552     crypto_req_handle_t, crypto_ctx_t *, crypto_session_id_t,
   1553     crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *, crypto_key_t *,
   1554     crypto_dual_data_t *, crypto_data_t *, crypto_data_t *, int);
   1555 static int dprov_random_submit_req(dprov_req_type_t, dprov_state_t *,
   1556     crypto_req_handle_t, uchar_t *, size_t, crypto_session_id_t, uint_t,
   1557     uint32_t);
   1558 static int dprov_session_submit_req(dprov_req_type_t, dprov_state_t *,
   1559     crypto_req_handle_t, crypto_session_id_t *, crypto_session_id_t,
   1560     crypto_user_type_t, char *, size_t);
   1561 static int dprov_object_submit_req(dprov_req_type_t, dprov_state_t *,
   1562     crypto_req_handle_t, crypto_session_id_t, crypto_object_id_t,
   1563     crypto_object_attribute_t *, uint_t, crypto_object_id_t *, size_t *,
   1564     void **, void *, uint_t, uint_t *, int);
   1565 static int dprov_key_submit_req(dprov_req_type_t, dprov_state_t *,
   1566     crypto_req_handle_t, crypto_session_id_t, crypto_mechanism_t *,
   1567     crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
   1568     crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
   1569     crypto_key_t *, uchar_t *, size_t *, crypto_object_attribute_t *,
   1570     uint_t, crypto_object_attribute_t *, uint_t);
   1571 static int dprov_mgmt_submit_req(dprov_req_type_t, dprov_state_t *,
   1572     crypto_req_handle_t, crypto_session_id_t, char *, size_t, char *, size_t,
   1573     char *, crypto_provider_ext_info_t *);
   1574 static int dprov_get_sw_prov(crypto_mechanism_t *, kcf_provider_desc_t **,
   1575     crypto_mech_type_t *);
   1576 
   1577 /* object management helper functions */
   1578 static void dprov_free_object(dprov_object_t *);
   1579 static void dprov_release_session_objects(dprov_session_t *);
   1580 static void dprov_adjust_attrs(crypto_object_attribute_t *, int);
   1581 static boolean_t dprov_object_is_private(dprov_object_t *);
   1582 static boolean_t dprov_object_is_token(dprov_object_t *);
   1583 static int dprov_key_value_secret(dprov_state_t *, crypto_session_id_t,
   1584     dprov_req_type_t, crypto_key_t *, crypto_key_t *);
   1585 static int dprov_key_attr_asymmetric(dprov_state_t *, crypto_session_id_t,
   1586     dprov_req_type_t, crypto_key_t *, crypto_key_t *);
   1587 static int dprov_get_object_attr_boolean(dprov_object_t *, uint64_t,
   1588 	boolean_t *);
   1589 static int dprov_get_object_attr_ulong(dprov_object_t *, uint64_t, ulong_t *);
   1590 static int dprov_get_object_attr_array(dprov_object_t *, uint64_t, void **,
   1591     size_t *);
   1592 static int dprov_get_key_attr_ulong(crypto_key_t *, uint64_t, ulong_t *);
   1593 static int dprov_get_key_attr_array(crypto_key_t *, uint64_t, void **,
   1594     size_t *);
   1595 static int dprov_create_object_from_template(dprov_state_t *, dprov_session_t *,
   1596     crypto_object_attribute_t *, uint_t, crypto_object_id_t *, boolean_t,
   1597     boolean_t);
   1598 static int dprov_get_template_attr_scalar_common(crypto_object_attribute_t *,
   1599     uint_t, uint64_t, void *, size_t);
   1600 static int dprov_get_template_attr_boolean(crypto_object_attribute_t *,
   1601     uint_t, uint64_t, boolean_t *);
   1602 static int dprov_get_template_attr_ulong(crypto_object_attribute_t *, uint_t,
   1603     uint64_t, ulong_t *);
   1604 static int dprov_template_attr_present(crypto_object_attribute_t *, uint_t,
   1605     uint64_t);
   1606 static int dprov_get_template_attr_array(crypto_object_attribute_t *, uint_t,
   1607     uint64_t, void **, size_t *);
   1608 static int dprov_destroy_object(dprov_state_t *, dprov_session_t *,
   1609     crypto_object_id_t);
   1610 static int dprov_object_set_attr(dprov_session_t *, crypto_object_id_t,
   1611     crypto_object_attribute_t *, uint_t, boolean_t);
   1612 static int dprov_find_attr(crypto_object_attribute_t *, uint_t, uint64_t);
   1613 static boolean_t dprov_attributes_match(dprov_object_t *,
   1614     crypto_object_attribute_t *, uint_t);
   1615 
   1616 /* retrieve the softc and instance number from a SPI crypto context */
   1617 #define	DPROV_SOFTC_FROM_CTX(ctx, softc, instance) {	\
   1618 	(softc) = (dprov_state_t *)(ctx)->cc_provider;	\
   1619 	(instance) = ddi_get_instance((softc)->ds_dip);	\
   1620 }
   1621 
   1622 /* retrieve the softc and instance number from a taskq request */
   1623 #define	DPROV_SOFTC_FROM_REQ(req, softc, instance) {	\
   1624 	(softc) = (req)->dr_softc;			\
   1625 	(instance) = ddi_get_instance((softc)->ds_dip);	\
   1626 }
   1627 
   1628 /*
   1629  * The dprov private context most of the time contains a pointer to the
   1630  * crypto_context_t that was allocated when calling a KCF function.
   1631  * Dual cipher/mac operations however require the dprov driver
   1632  * to maintain the contexts associated with the separate cipher
   1633  * and mac operations. These two types of dprov contexts are
   1634  * defined below.
   1635  */
   1636 typedef enum dprov_ctx_type {
   1637 	DPROV_CTX_SINGLE,
   1638 	DPROV_CTX_DUAL
   1639 } dprov_ctx_type_t;
   1640 
   1641 /*
   1642  * When the context refers to a single KCF context, the
   1643  * cc_provider field of a crypto_ctx_t points to a structure of
   1644  * type dprov_ctx_single.
   1645  */
   1646 typedef struct dprov_ctx_single {
   1647 	dprov_ctx_type_t dc_type;
   1648 	crypto_context_t dc_ctx;
   1649 	boolean_t dc_svrfy_to_mac;
   1650 } dprov_ctx_single_t;
   1651 
   1652 /*
   1653  * When the context is used for cipher/mac operations, it contains
   1654  * pointers to to KCF contexts, one for the cipher operation, the
   1655  * other for the mac operation.
   1656  */
   1657 typedef struct dprov_ctx_dual {
   1658 	dprov_ctx_type_t cd_type;
   1659 	crypto_context_t cd_cipher_ctx;
   1660 	crypto_context_t cd_mac_ctx;
   1661 } dprov_ctx_dual_t;
   1662 
   1663 /*
   1664  * Helper macros for context accessors. These macros return the
   1665  * k-API context corresponding to the given SPI context for
   1666  * single and dual cipher/mac operations.
   1667  */
   1668 
   1669 #define	DPROV_CTX_P(_ctx) \
   1670 	((dprov_ctx_single_t *)(_ctx)->cc_provider_private)
   1671 
   1672 #define	DPROV_CTX_SINGLE(_ctx)	((DPROV_CTX_P(_ctx))->dc_ctx)
   1673 
   1674 #define	DPROV_CTX_DUAL_CIPHER(_ctx) \
   1675 	(((dprov_ctx_dual_t *)(_ctx)->cc_provider_private)->cd_cipher_ctx)
   1676 
   1677 #define	DPROV_CTX_DUAL_MAC(_ctx) \
   1678 	(((dprov_ctx_dual_t *)(_ctx)->cc_provider_private)->cd_mac_ctx)
   1679 
   1680 static int dprov_alloc_context(dprov_req_type_t, crypto_ctx_t *);
   1681 
   1682 
   1683 
   1684 static void *statep;	/* state pointer */
   1685 
   1686 /*
   1687  * DDI entry points.
   1688  */
   1689 int
   1690 _init(void)
   1691 {
   1692 	int error;
   1693 
   1694 	DPROV_DEBUG(D_INIT, ("dprov: in _init\n"));
   1695 
   1696 	if ((error = ddi_soft_state_init(&statep, sizeof (dprov_state_t),
   1697 	    0)) != 0)
   1698 		return (error);
   1699 
   1700 	return (mod_install(&modlinkage));
   1701 }
   1702 
   1703 int
   1704 _fini(void)
   1705 {
   1706 	int error;
   1707 
   1708 	DPROV_DEBUG(D_INIT, ("dprov: in _fini\n"));
   1709 
   1710 	if ((error = mod_remove(&modlinkage)) != 0)
   1711 		return (error);
   1712 
   1713 	ddi_soft_state_fini(&statep);
   1714 
   1715 	return (0);
   1716 }
   1717 
   1718 int
   1719 _info(struct modinfo *modinfop)
   1720 {
   1721 	DPROV_DEBUG(D_INIT, ("dprov: in _info\n"));
   1722 
   1723 	return (mod_info(&modlinkage, modinfop));
   1724 }
   1725 
   1726 /* ARGSUSED */
   1727 static int
   1728 dprov_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
   1729 {
   1730 	int instance = getminor((dev_t)arg);
   1731 	dprov_state_t *softc;
   1732 
   1733 	DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_getinfo() for %d\n",
   1734 	    instance));
   1735 
   1736 	switch (cmd) {
   1737 	case DDI_INFO_DEVT2DEVINFO:
   1738 		softc = ddi_get_soft_state(statep, instance);
   1739 		*result = softc->ds_dip;
   1740 		return (DDI_SUCCESS);
   1741 
   1742 	case DDI_INFO_DEVT2INSTANCE:
   1743 		*result = (void *)(uintptr_t)instance;
   1744 		return (DDI_SUCCESS);
   1745 	}
   1746 	return (DDI_FAILURE);
   1747 }
   1748 
   1749 static int
   1750 dprov_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
   1751 {
   1752 	int instance = ddi_get_instance(dip);
   1753 	dprov_state_t *softc;
   1754 	char devname[256];
   1755 	int ret;
   1756 
   1757 	DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_attach() for %d\n",
   1758 	    instance));
   1759 
   1760 	if (cmd != DDI_ATTACH) {
   1761 		return (DDI_FAILURE);
   1762 	}
   1763 
   1764 	/* get new softc and initialize it */
   1765 	if (ddi_soft_state_zalloc(statep, instance) != DDI_SUCCESS)
   1766 		return (DDI_FAILURE);
   1767 
   1768 	softc = ddi_get_soft_state(statep, instance);
   1769 	mutex_init(&softc->ds_lock, NULL, MUTEX_DRIVER, NULL);
   1770 	softc->ds_dip = dip;
   1771 	softc->ds_prov_handle = NULL;
   1772 
   1773 	/* create minor node */
   1774 	(void) sprintf(devname, "dprov%d", instance);
   1775 	if (ddi_create_minor_node(dip, devname, S_IFCHR, instance,
   1776 	    DDI_PSEUDO, 0) != DDI_SUCCESS) {
   1777 		cmn_err(CE_WARN, "attach: failed creating minor node");
   1778 		mutex_destroy(&softc->ds_lock);
   1779 		ddi_soft_state_free(statep, instance);
   1780 		return (DDI_FAILURE);
   1781 	}
   1782 
   1783 	nostore_key_gen = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
   1784 	    DDI_PROP_DONTPASS, "nostore_key_gen", 0);
   1785 	if (nostore_key_gen != 0) {
   1786 		dprov_prov_info.pi_interface_version = CRYPTO_SPI_VERSION_3;
   1787 		dprov_crypto_ops.co_object_ops = NULL;
   1788 		dprov_crypto_ops.co_nostore_key_ops = &dprov_nostore_key_ops;
   1789 	}
   1790 
   1791 	dprov_max_digestsz = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
   1792 	    DDI_PROP_DONTPASS, "max_digest_sz", INT_MAX);
   1793 	if (dprov_max_digestsz != INT_MAX && dprov_max_digestsz != 0 &&
   1794 	    dprov_max_digestsz != DDI_PROP_NOT_FOUND) {
   1795 		dprov_no_multipart = B_TRUE;
   1796 		dprov_prov_info.pi_flags |=
   1797 		    (CRYPTO_HASH_NO_UPDATE | CRYPTO_HMAC_NO_UPDATE);
   1798 	}
   1799 
   1800 	/* create taskq */
   1801 	softc->ds_taskq = taskq_create(devname, 1, minclsyspri,
   1802 	    crypto_taskq_minalloc, crypto_taskq_maxalloc, TASKQ_PREPOPULATE);
   1803 
   1804 	/* initialize table of sessions */
   1805 	softc->ds_sessions = kmem_zalloc(DPROV_MIN_SESSIONS *
   1806 	    sizeof (dprov_session_t *), KM_SLEEP);
   1807 	softc->ds_sessions_slots = DPROV_MIN_SESSIONS;
   1808 	softc->ds_sessions_count = 0;
   1809 
   1810 	/* initialized done by init_token entry point */
   1811 	softc->ds_token_initialized = B_TRUE;
   1812 
   1813 	(void) memset(softc->ds_label, ' ', CRYPTO_EXT_SIZE_LABEL);
   1814 	bcopy("Dummy Pseudo HW Provider", softc->ds_label, 24);
   1815 
   1816 	bcopy("changeme", softc->ds_user_pin, 8);
   1817 	softc->ds_user_pin_len = 8;
   1818 	softc->ds_user_pin_set = B_TRUE;
   1819 
   1820 	/* register with the crypto framework */
   1821 	dprov_prov_info.pi_provider_dev.pd_hw = dip;
   1822 	dprov_prov_info.pi_provider_handle = softc;
   1823 
   1824 	if (dprov_no_multipart) { /* Export only single part */
   1825 		dprov_digest_ops.digest_update = NULL;
   1826 		dprov_digest_ops.digest_key = NULL;
   1827 		dprov_digest_ops.digest_final = NULL;
   1828 		dprov_object_ops.object_create = NULL;
   1829 	}
   1830 
   1831 	if ((ret = crypto_register_provider(&dprov_prov_info,
   1832 	    &softc->ds_prov_handle)) != CRYPTO_SUCCESS) {
   1833 		cmn_err(CE_WARN,
   1834 		    "dprov crypto_register_provider() failed (0x%x)", ret);
   1835 		taskq_destroy(softc->ds_taskq);
   1836 		kmem_free(softc->ds_sessions, softc->ds_sessions_slots *
   1837 		    sizeof (dprov_session_t *));
   1838 		mutex_destroy(&softc->ds_lock);
   1839 		ddi_soft_state_free(statep, instance);
   1840 		ddi_remove_minor_node(dip, NULL);
   1841 		return (DDI_FAILURE);
   1842 	}
   1843 
   1844 	/*
   1845 	 * This call is for testing only; it is not required by the SPI.
   1846 	 */
   1847 	crypto_provider_notification(softc->ds_prov_handle,
   1848 	    CRYPTO_PROVIDER_READY);
   1849 
   1850 	return (DDI_SUCCESS);
   1851 }
   1852 
   1853 static int
   1854 dprov_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
   1855 {
   1856 	int instance = ddi_get_instance(dip);
   1857 	dprov_state_t *softc = ddi_get_soft_state(statep, instance);
   1858 	dprov_session_t *session;
   1859 	int i, ret;
   1860 
   1861 	DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_detach() for %d\n",
   1862 	    instance));
   1863 
   1864 	if (cmd != DDI_DETACH)
   1865 		return (DDI_FAILURE);
   1866 
   1867 	/* unregister from the crypto framework */
   1868 	if (softc->ds_prov_handle != NULL)
   1869 		if ((ret = crypto_unregister_provider(
   1870 		    softc->ds_prov_handle)) != CRYPTO_SUCCESS) {
   1871 			cmn_err(CE_WARN, "dprov_detach: "
   1872 			    "crypto_unregister_provider() "
   1873 			    "failed (0x%x)", ret);
   1874 			return (DDI_FAILURE);
   1875 		}
   1876 
   1877 
   1878 	taskq_destroy(softc->ds_taskq);
   1879 
   1880 	for (i = 0; i < softc->ds_sessions_slots; i++) {
   1881 		if ((session = softc->ds_sessions[i]) == NULL)
   1882 			continue;
   1883 
   1884 		dprov_release_session_objects(session);
   1885 
   1886 		kmem_free(session, sizeof (dprov_session_t));
   1887 		softc->ds_sessions_count--;
   1888 
   1889 	}
   1890 
   1891 	kmem_free(softc->ds_sessions, softc->ds_sessions_slots *
   1892 	    sizeof (dprov_session_t *));
   1893 	/* free token objects */
   1894 	for (i = 0; i < DPROV_MAX_OBJECTS; i++)
   1895 		if (softc->ds_objects[i] != NULL)
   1896 			dprov_free_object(softc->ds_objects[i]);
   1897 
   1898 	mutex_destroy(&softc->ds_lock);
   1899 	ddi_soft_state_free(statep, instance);
   1900 
   1901 	ddi_remove_minor_node(dip, NULL);
   1902 
   1903 	return (DDI_SUCCESS);
   1904 }
   1905 
   1906 /*
   1907  * Control entry points.
   1908  */
   1909 static void
   1910 dprov_provider_status(crypto_provider_handle_t provider, uint_t *status)
   1911 {
   1912 	_NOTE(ARGUNUSED(provider))
   1913 
   1914 	*status = CRYPTO_PROVIDER_READY;
   1915 }
   1916 
   1917 /*
   1918  * Digest entry points.
   1919  */
   1920 
   1921 static int
   1922 dprov_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
   1923     crypto_req_handle_t req)
   1924 {
   1925 	int error = CRYPTO_FAILED;
   1926 	dprov_state_t *softc;
   1927 	/* LINTED E_FUNC_SET_NOT_USED */
   1928 	int instance;
   1929 
   1930 	/* extract softc and instance number from context */
   1931 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   1932 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_init: started\n", instance));
   1933 
   1934 	/* check mechanism */
   1935 	if (mechanism->cm_type != MD4_MECH_INFO_TYPE &&
   1936 	    mechanism->cm_type != MD5_MECH_INFO_TYPE &&
   1937 	    mechanism->cm_type != SHA1_MECH_INFO_TYPE &&
   1938 	    mechanism->cm_type != SHA256_MECH_INFO_TYPE &&
   1939 	    mechanism->cm_type != SHA384_MECH_INFO_TYPE &&
   1940 	    mechanism->cm_type != SHA512_MECH_INFO_TYPE) {
   1941 		cmn_err(CE_WARN, "dprov_digest_init: unexpected mech type "
   1942 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
   1943 		return (CRYPTO_MECHANISM_INVALID);
   1944 	}
   1945 
   1946 	/* submit request to the taskq */
   1947 	error = dprov_digest_submit_req(DPROV_REQ_DIGEST_INIT, softc, req,
   1948 	    mechanism, NULL, NULL, NULL, ctx, KM_SLEEP);
   1949 
   1950 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_init: done err = 0x%x\n",
   1951 	    instance, error));
   1952 
   1953 	return (error);
   1954 }
   1955 
   1956 static int
   1957 dprov_digest(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *digest,
   1958     crypto_req_handle_t req)
   1959 {
   1960 	int error = CRYPTO_FAILED;
   1961 	dprov_state_t *softc;
   1962 	/* LINTED E_FUNC_SET_NOT_USED */
   1963 	int instance;
   1964 
   1965 	if (dprov_no_multipart && data->cd_length > dprov_max_digestsz)
   1966 		return (CRYPTO_BUFFER_TOO_BIG);
   1967 
   1968 	/* extract softc and instance number from context */
   1969 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   1970 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest: started\n", instance));
   1971 
   1972 	/* submit request to the taskq */
   1973 	error = dprov_digest_submit_req(DPROV_REQ_DIGEST, softc, req,
   1974 	    NULL, data, NULL, digest, ctx, KM_NOSLEEP);
   1975 
   1976 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest: done, err = 0x%x\n",
   1977 	    instance, error));
   1978 
   1979 	return (error);
   1980 }
   1981 
   1982 static int
   1983 dprov_digest_update(crypto_ctx_t *ctx, crypto_data_t *data,
   1984     crypto_req_handle_t req)
   1985 {
   1986 	int error = CRYPTO_FAILED;
   1987 	dprov_state_t *softc;
   1988 	/* LINTED E_FUNC_SET_NOT_USED */
   1989 	int instance;
   1990 
   1991 	/* extract softc and instance number from context */
   1992 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   1993 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_update: started\n",
   1994 	    instance));
   1995 
   1996 	/* submit request to the taskq */
   1997 	error = dprov_digest_submit_req(DPROV_REQ_DIGEST_UPDATE, softc,
   1998 	    req, NULL, data, NULL, NULL, ctx, KM_NOSLEEP);
   1999 
   2000 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_update: done err = 0x0%x\n",
   2001 	    instance, error));
   2002 
   2003 	return (error);
   2004 }
   2005 
   2006 static int
   2007 dprov_digest_key(crypto_ctx_t *ctx, crypto_key_t *key, crypto_req_handle_t req)
   2008 {
   2009 	int error = CRYPTO_FAILED;
   2010 	dprov_state_t *softc;
   2011 	/* LINTED E_FUNC_SET_NOT_USED */
   2012 	int instance;
   2013 
   2014 	/* extract softc and instance number from context */
   2015 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2016 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_key: started\n", instance));
   2017 
   2018 	/* submit request to the taskq */
   2019 	error = dprov_digest_submit_req(DPROV_REQ_DIGEST_KEY, softc, req, NULL,
   2020 	    NULL, key, NULL, ctx, KM_NOSLEEP);
   2021 
   2022 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_key: done err = 0x0%x\n",
   2023 	    instance, error));
   2024 
   2025 	return (error);
   2026 }
   2027 
   2028 static int
   2029 dprov_digest_final(crypto_ctx_t *ctx, crypto_data_t *digest,
   2030     crypto_req_handle_t req)
   2031 {
   2032 	int error = CRYPTO_FAILED;
   2033 	dprov_state_t *softc;
   2034 	/* LINTED E_FUNC_SET_NOT_USED */
   2035 	int instance;
   2036 
   2037 	/* extract softc and instance number from context */
   2038 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2039 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_final: started\n", instance));
   2040 
   2041 	/* submit request to the taskq */
   2042 	error = dprov_digest_submit_req(DPROV_REQ_DIGEST_FINAL, softc, req,
   2043 	    NULL, NULL, NULL, digest, ctx, KM_NOSLEEP);
   2044 
   2045 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_final: done err = 0x0%x\n",
   2046 	    instance, error));
   2047 
   2048 	return (error);
   2049 }
   2050 
   2051 /* ARGSUSED */
   2052 static int
   2053 dprov_digest_atomic(crypto_provider_handle_t provider,
   2054     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
   2055     crypto_data_t *data, crypto_data_t *digest,
   2056     crypto_req_handle_t req)
   2057 {
   2058 	int error = CRYPTO_FAILED;
   2059 	dprov_state_t *softc = (dprov_state_t *)provider;
   2060 	/* LINTED E_FUNC_SET_NOT_USED */
   2061 	int instance;
   2062 
   2063 	if (dprov_no_multipart && data->cd_length > dprov_max_digestsz)
   2064 		return (CRYPTO_BUFFER_TOO_BIG);
   2065 
   2066 	instance = ddi_get_instance(softc->ds_dip);
   2067 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_atomic: started\n",
   2068 	    instance));
   2069 
   2070 	/* check mechanism */
   2071 	if (mechanism->cm_type != MD4_MECH_INFO_TYPE &&
   2072 	    mechanism->cm_type != MD5_MECH_INFO_TYPE &&
   2073 	    mechanism->cm_type != SHA1_MECH_INFO_TYPE &&
   2074 	    mechanism->cm_type != SHA256_MECH_INFO_TYPE &&
   2075 	    mechanism->cm_type != SHA384_MECH_INFO_TYPE &&
   2076 	    mechanism->cm_type != SHA512_MECH_INFO_TYPE) {
   2077 		cmn_err(CE_WARN, "dprov_digest_atomic: unexpected mech type "
   2078 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
   2079 		return (CRYPTO_MECHANISM_INVALID);
   2080 	}
   2081 
   2082 	/* submit request to the taskq */
   2083 	error = dprov_digest_submit_req(DPROV_REQ_DIGEST_ATOMIC, softc, req,
   2084 	    mechanism, data, NULL, digest, NULL, KM_SLEEP);
   2085 
   2086 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_atomic: done err = 0x0%x\n",
   2087 	    instance, error));
   2088 
   2089 	return (error);
   2090 }
   2091 
   2092 /*
   2093  * MAC entry points.
   2094  */
   2095 
   2096 /*
   2097  * Checks whether the specified mech_type is supported by mac
   2098  * entry points.
   2099  */
   2100 static boolean_t
   2101 dprov_valid_mac_mech(crypto_mech_type_t mech_type)
   2102 {
   2103 	return (mech_type == MD5_HMAC_MECH_INFO_TYPE ||
   2104 	    mech_type == MD5_HMAC_GEN_MECH_INFO_TYPE ||
   2105 	    mech_type == SHA1_HMAC_MECH_INFO_TYPE ||
   2106 	    mech_type == SHA1_HMAC_GEN_MECH_INFO_TYPE ||
   2107 	    mech_type == SHA256_HMAC_MECH_INFO_TYPE ||
   2108 	    mech_type == SHA256_HMAC_GEN_MECH_INFO_TYPE ||
   2109 	    mech_type == SHA384_HMAC_MECH_INFO_TYPE ||
   2110 	    mech_type == SHA384_HMAC_GEN_MECH_INFO_TYPE ||
   2111 	    mech_type == SHA512_HMAC_MECH_INFO_TYPE ||
   2112 	    mech_type == SHA512_HMAC_GEN_MECH_INFO_TYPE ||
   2113 	    mech_type == AES_GMAC_MECH_INFO_TYPE);
   2114 }
   2115 
   2116 static int
   2117 dprov_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
   2118     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
   2119     crypto_req_handle_t req)
   2120 {
   2121 	int error = CRYPTO_FAILED;
   2122 	dprov_state_t *softc;
   2123 	/* LINTED E_FUNC_SET_NOT_USED */
   2124 	int instance;
   2125 
   2126 	/* extract softc and instance number from context */
   2127 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2128 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_init: started\n", instance));
   2129 
   2130 	/* check mechanism */
   2131 	if (!dprov_valid_mac_mech(mechanism->cm_type)) {
   2132 		cmn_err(CE_WARN, "dprov_mac_init: unexpected mech type "
   2133 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
   2134 		return (CRYPTO_MECHANISM_INVALID);
   2135 	}
   2136 
   2137 	if (ctx_template != NULL)
   2138 		return (CRYPTO_ARGUMENTS_BAD);
   2139 
   2140 	/* submit request to the taskq */
   2141 	error = dprov_mac_submit_req(DPROV_REQ_MAC_INIT, softc, req,
   2142 	    mechanism, NULL, key, NULL, ctx, 0, KM_SLEEP);
   2143 
   2144 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_init: done err = 0x%x\n",
   2145 	    instance, error));
   2146 
   2147 	return (error);
   2148 }
   2149 
   2150 static int
   2151 dprov_mac(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *mac,
   2152     crypto_req_handle_t req)
   2153 {
   2154 	int error = CRYPTO_FAILED;
   2155 	dprov_state_t *softc;
   2156 	/* LINTED E_FUNC_SET_NOT_USED */
   2157 	int instance;
   2158 
   2159 	/* extract softc and instance number from context */
   2160 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2161 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac: started\n", instance));
   2162 
   2163 	/* submit request to the taskq */
   2164 	error = dprov_mac_submit_req(DPROV_REQ_MAC, softc, req,
   2165 	    NULL, data, NULL, mac, ctx, 0, KM_NOSLEEP);
   2166 
   2167 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac: done, err = 0x%x\n", instance,
   2168 	    error));
   2169 
   2170 	return (error);
   2171 }
   2172 
   2173 static int
   2174 dprov_mac_update(crypto_ctx_t *ctx, crypto_data_t *data,
   2175     crypto_req_handle_t req)
   2176 {
   2177 	int error = CRYPTO_FAILED;
   2178 	dprov_state_t *softc;
   2179 	/* LINTED E_FUNC_SET_NOT_USED */
   2180 	int instance;
   2181 
   2182 	/* extract softc and instance number from context */
   2183 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2184 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_update: started\n", instance));
   2185 
   2186 	/* submit request to the taskq */
   2187 	error = dprov_mac_submit_req(DPROV_REQ_MAC_UPDATE, softc,
   2188 	    req, NULL, data, NULL, NULL, ctx, 0, KM_NOSLEEP);
   2189 
   2190 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_update: done err = 0x0%x\n",
   2191 	    instance, error));
   2192 
   2193 	return (error);
   2194 }
   2195 
   2196 static int
   2197 dprov_mac_final(crypto_ctx_t *ctx, crypto_data_t *mac, crypto_req_handle_t req)
   2198 {
   2199 	int error = CRYPTO_FAILED;
   2200 	dprov_state_t *softc;
   2201 	/* LINTED E_FUNC_SET_NOT_USED */
   2202 	int instance;
   2203 
   2204 	/* extract softc and instance number from context */
   2205 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2206 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_final: started\n", instance));
   2207 
   2208 	/* submit request to the taskq */
   2209 	error = dprov_mac_submit_req(DPROV_REQ_MAC_FINAL, softc, req,
   2210 	    NULL, NULL, NULL, mac, ctx, 0, KM_NOSLEEP);
   2211 
   2212 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_final: done err = 0x0%x\n",
   2213 	    instance, error));
   2214 
   2215 	return (error);
   2216 }
   2217 
   2218 static int
   2219 dprov_mac_atomic(crypto_provider_handle_t provider,
   2220     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
   2221     crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
   2222     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
   2223 {
   2224 	int error = CRYPTO_FAILED;
   2225 	dprov_state_t *softc = (dprov_state_t *)provider;
   2226 	/* LINTED E_FUNC_SET_NOT_USED */
   2227 	int instance;
   2228 
   2229 	instance = ddi_get_instance(softc->ds_dip);
   2230 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_atomic: started\n", instance));
   2231 
   2232 	if (ctx_template != NULL)
   2233 		return (CRYPTO_ARGUMENTS_BAD);
   2234 
   2235 	/* check mechanism */
   2236 	if (!dprov_valid_mac_mech(mechanism->cm_type)) {
   2237 		cmn_err(CE_WARN, "dprov_mac_atomic: unexpected mech type "
   2238 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
   2239 		return (CRYPTO_MECHANISM_INVALID);
   2240 	}
   2241 
   2242 	/* submit request to the taskq */
   2243 	error = dprov_mac_submit_req(DPROV_REQ_MAC_ATOMIC, softc, req,
   2244 	    mechanism, data, key, mac, NULL, session_id, KM_SLEEP);
   2245 
   2246 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_atomic: done err = 0x0%x\n",
   2247 	    instance, error));
   2248 
   2249 	return (error);
   2250 }
   2251 
   2252 static int
   2253 dprov_mac_verify_atomic(crypto_provider_handle_t provider,
   2254     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
   2255     crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
   2256     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
   2257 {
   2258 	int error = CRYPTO_FAILED;
   2259 	dprov_state_t *softc = (dprov_state_t *)provider;
   2260 	/* LINTED E_FUNC_SET_NOT_USED */
   2261 	int instance;
   2262 
   2263 	instance = ddi_get_instance(softc->ds_dip);
   2264 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_verify_atomic: started\n",
   2265 	    instance));
   2266 
   2267 	if (ctx_template != NULL)
   2268 		return (CRYPTO_ARGUMENTS_BAD);
   2269 
   2270 	/* check mechanism */
   2271 	if (!dprov_valid_mac_mech(mechanism->cm_type)) {
   2272 		cmn_err(CE_WARN, "dprov_mac_verify_atomic: unexpected mech "
   2273 		    "type 0x%llx\n", (unsigned long long)mechanism->cm_type);
   2274 		return (CRYPTO_MECHANISM_INVALID);
   2275 	}
   2276 
   2277 	/* submit request to the taskq */
   2278 	error = dprov_mac_submit_req(DPROV_REQ_MAC_VERIFY_ATOMIC, softc, req,
   2279 	    mechanism, data, key, mac, NULL, session_id, KM_SLEEP);
   2280 
   2281 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_verify_atomic: done err = 0x0%x\n",
   2282 	    instance, error));
   2283 
   2284 	return (error);
   2285 }
   2286 
   2287 /*
   2288  * Cipher (encrypt/decrypt) entry points.
   2289  */
   2290 
   2291 /*
   2292  * Checks whether the specified mech_type is supported by cipher entry
   2293  * points.
   2294  */
   2295 static boolean_t
   2296 dprov_valid_cipher_mech(crypto_mech_type_t mech_type)
   2297 {
   2298 	return (mech_type == DES_CBC_MECH_INFO_TYPE ||
   2299 	    mech_type == DES3_CBC_MECH_INFO_TYPE ||
   2300 	    mech_type == DES_ECB_MECH_INFO_TYPE ||
   2301 	    mech_type == DES3_ECB_MECH_INFO_TYPE ||
   2302 	    mech_type == BLOWFISH_CBC_MECH_INFO_TYPE ||
   2303 	    mech_type == BLOWFISH_ECB_MECH_INFO_TYPE ||
   2304 	    mech_type == AES_CBC_MECH_INFO_TYPE ||
   2305 	    mech_type == AES_ECB_MECH_INFO_TYPE ||
   2306 	    mech_type == AES_CTR_MECH_INFO_TYPE ||
   2307 	    mech_type == AES_CCM_MECH_INFO_TYPE ||
   2308 	    mech_type == AES_GCM_MECH_INFO_TYPE ||
   2309 	    mech_type == AES_GMAC_MECH_INFO_TYPE ||
   2310 	    mech_type == RC4_MECH_INFO_TYPE ||
   2311 	    mech_type == RSA_PKCS_MECH_INFO_TYPE ||
   2312 	    mech_type == RSA_X_509_MECH_INFO_TYPE ||
   2313 	    mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE ||
   2314 	    mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE ||
   2315 	    mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE ||
   2316 	    mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE ||
   2317 	    mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE);
   2318 }
   2319 
   2320 static boolean_t
   2321 is_publickey_mech(crypto_mech_type_t mech_type)
   2322 {
   2323 	return (mech_type == RSA_PKCS_MECH_INFO_TYPE ||
   2324 	    mech_type == RSA_X_509_MECH_INFO_TYPE ||
   2325 	    mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE ||
   2326 	    mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE ||
   2327 	    mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE ||
   2328 	    mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE ||
   2329 	    mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE ||
   2330 	    mech_type == ECDSA_SHA1_MECH_INFO_TYPE ||
   2331 	    mech_type == ECDSA_MECH_INFO_TYPE);
   2332 }
   2333 
   2334 
   2335 /* ARGSUSED */
   2336 static int
   2337 dprov_encrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
   2338     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
   2339     crypto_req_handle_t req)
   2340 {
   2341 	int error = CRYPTO_FAILED;
   2342 	dprov_state_t *softc;
   2343 	/* LINTED E_FUNC_SET_NOT_USED */
   2344 	int instance;
   2345 
   2346 	/* extract softc and instance number from context */
   2347 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2348 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_init: started\n",
   2349 	    instance));
   2350 
   2351 	/* check mechanism */
   2352 	if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
   2353 		cmn_err(CE_WARN, "dprov_encrypt_init: unexpected mech type "
   2354 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
   2355 		return (CRYPTO_MECHANISM_INVALID);
   2356 	}
   2357 
   2358 	/* submit request to the taskq */
   2359 	error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_INIT, softc,
   2360 	    req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
   2361 
   2362 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_init: done err = 0x0%x\n",
   2363 	    instance, error));
   2364 
   2365 	return (error);
   2366 }
   2367 
   2368 /* ARGSUSED */
   2369 static int
   2370 dprov_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
   2371     crypto_data_t *ciphertext, crypto_req_handle_t req)
   2372 {
   2373 	int error = CRYPTO_FAILED;
   2374 	dprov_state_t *softc;
   2375 	/* LINTED E_FUNC_SET_NOT_USED */
   2376 	int instance;
   2377 
   2378 	/* extract softc and instance number from context */
   2379 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2380 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt: started\n", instance));
   2381 
   2382 	/* submit request to the taskq */
   2383 	error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT, softc,
   2384 	    req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
   2385 
   2386 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt: done err = 0x0%x\n",
   2387 	    instance, error));
   2388 
   2389 	return (error);
   2390 }
   2391 
   2392 /* ARGSUSED */
   2393 static int
   2394 dprov_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
   2395     crypto_data_t *ciphertext, crypto_req_handle_t req)
   2396 {
   2397 	int error = CRYPTO_FAILED;
   2398 	dprov_state_t *softc;
   2399 	/* LINTED E_FUNC_SET_NOT_USED */
   2400 	int instance;
   2401 
   2402 	/* extract softc and instance number from context */
   2403 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2404 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_update: started\n",
   2405 	    instance));
   2406 
   2407 	/* submit request to the taskq */
   2408 	error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_UPDATE, softc,
   2409 	    req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
   2410 
   2411 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_update: done err = 0x0%x\n",
   2412 	    instance, error));
   2413 
   2414 	return (error);
   2415 }
   2416 
   2417 /* ARGSUSED */
   2418 static int
   2419 dprov_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
   2420     crypto_req_handle_t req)
   2421 {
   2422 	int error = CRYPTO_FAILED;
   2423 	dprov_state_t *softc;
   2424 	/* LINTED E_FUNC_SET_NOT_USED */
   2425 	int instance;
   2426 
   2427 	/* extract softc and instance number from context */
   2428 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2429 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_final: started\n",
   2430 	    instance));
   2431 
   2432 	/* submit request to the taskq */
   2433 	error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_FINAL, softc,
   2434 	    req, NULL, NULL, NULL, ciphertext, ctx, 0, KM_NOSLEEP);
   2435 
   2436 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_final: done err = 0x0%x\n",
   2437 	    instance, error));
   2438 
   2439 	return (error);
   2440 }
   2441 
   2442 static int
   2443 dprov_encrypt_atomic(crypto_provider_handle_t provider,
   2444     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
   2445     crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext,
   2446     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
   2447 {
   2448 	int error = CRYPTO_FAILED;
   2449 	dprov_state_t *softc = (dprov_state_t *)provider;
   2450 	/* LINTED E_FUNC_SET_NOT_USED */
   2451 	int instance;
   2452 
   2453 	instance = ddi_get_instance(softc->ds_dip);
   2454 	DPROV_DEBUG(D_MAC, ("(%d) dprov_encrypt_atomic: started\n", instance));
   2455 
   2456 	if (ctx_template != NULL)
   2457 		return (CRYPTO_ARGUMENTS_BAD);
   2458 
   2459 	/* check mechanism */
   2460 	if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
   2461 		cmn_err(CE_WARN, "dprov_encrypt_atomic: unexpected mech type "
   2462 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
   2463 		return (CRYPTO_MECHANISM_INVALID);
   2464 	}
   2465 
   2466 	error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_ATOMIC, softc,
   2467 	    req, mechanism, key, plaintext, ciphertext, NULL, session_id,
   2468 	    KM_SLEEP);
   2469 
   2470 	DPROV_DEBUG(D_MAC, ("(%d) dprov_encrypt_atomic: done err = 0x0%x\n",
   2471 	    instance, error));
   2472 
   2473 	return (error);
   2474 }
   2475 
   2476 /* ARGSUSED */
   2477 static int
   2478 dprov_decrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
   2479     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
   2480     crypto_req_handle_t req)
   2481 {
   2482 	int error = CRYPTO_FAILED;
   2483 	dprov_state_t *softc;
   2484 	/* LINTED E_FUNC_SET_NOT_USED */
   2485 	int instance;
   2486 
   2487 	/* extract softc and instance number from context */
   2488 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2489 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_init: started\n",
   2490 	    instance));
   2491 
   2492 	/* check mechanism */
   2493 	if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
   2494 		cmn_err(CE_WARN, "dprov_decrypt_init: unexpected mech type "
   2495 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
   2496 		return (CRYPTO_MECHANISM_INVALID);
   2497 	}
   2498 
   2499 	/* submit request to the taskq */
   2500 	error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_INIT, softc,
   2501 	    req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
   2502 
   2503 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_init: done err = 0x0%x\n",
   2504 	    instance, error));
   2505 
   2506 	return (error);
   2507 }
   2508 
   2509 /* ARGSUSED */
   2510 static int
   2511 dprov_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
   2512     crypto_data_t *plaintext, crypto_req_handle_t req)
   2513 {
   2514 	int error = CRYPTO_FAILED;
   2515 
   2516 	dprov_state_t *softc;
   2517 	/* LINTED E_FUNC_SET_NOT_USED */
   2518 	int instance;
   2519 
   2520 	/* extract softc and instance number from context */
   2521 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2522 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt: started\n", instance));
   2523 
   2524 	/* submit request to the taskq */
   2525 	error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT, softc,
   2526 	    req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
   2527 
   2528 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt: done err = 0x0%x\n",
   2529 	    instance, error));
   2530 
   2531 	return (error);
   2532 }
   2533 
   2534 /* ARGSUSED */
   2535 static int
   2536 dprov_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
   2537     crypto_data_t *plaintext, crypto_req_handle_t req)
   2538 {
   2539 	int error = CRYPTO_FAILED;
   2540 	dprov_state_t *softc;
   2541 	/* LINTED E_FUNC_SET_NOT_USED */
   2542 	int instance;
   2543 
   2544 	/* extract softc and instance number from context */
   2545 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2546 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_update: started\n",
   2547 	    instance));
   2548 
   2549 	/* submit request to the taskq */
   2550 	error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_UPDATE, softc,
   2551 	    req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
   2552 
   2553 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_update: done err = 0x0%x\n",
   2554 	    instance, error));
   2555 
   2556 	return (error);
   2557 }
   2558 
   2559 /* ARGSUSED */
   2560 static int
   2561 dprov_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *plaintext,
   2562     crypto_req_handle_t req)
   2563 {
   2564 	int error = CRYPTO_FAILED;
   2565 	dprov_state_t *softc;
   2566 	/* LINTED E_FUNC_SET_NOT_USED */
   2567 	int instance;
   2568 
   2569 	/* extract softc and instance number from context */
   2570 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2571 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_final: started\n",
   2572 	    instance));
   2573 
   2574 	/* submit request to the taskq */
   2575 	error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_FINAL, softc,
   2576 	    req, NULL, NULL, plaintext, NULL, ctx, 0, KM_NOSLEEP);
   2577 
   2578 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_final: done err = 0x0%x\n",
   2579 	    instance, error));
   2580 
   2581 	return (error);
   2582 }
   2583 
   2584 static int
   2585 dprov_decrypt_atomic(crypto_provider_handle_t provider,
   2586     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
   2587     crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext,
   2588     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
   2589 {
   2590 	int error = CRYPTO_FAILED;
   2591 	dprov_state_t *softc = (dprov_state_t *)provider;
   2592 	/* LINTED E_FUNC_SET_NOT_USED */
   2593 	int instance;
   2594 
   2595 	instance = ddi_get_instance(softc->ds_dip);
   2596 	DPROV_DEBUG(D_MAC, ("(%d) dprov_decrypt_atomic: started\n", instance));
   2597 
   2598 	if (ctx_template != NULL)
   2599 		return (CRYPTO_ARGUMENTS_BAD);
   2600 
   2601 	/* check mechanism */
   2602 	if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
   2603 		cmn_err(CE_WARN, "dprov_atomic_init: unexpected mech type "
   2604 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
   2605 		return (CRYPTO_MECHANISM_INVALID);
   2606 	}
   2607 
   2608 	error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_ATOMIC, softc,
   2609 	    req, mechanism, key, plaintext, ciphertext, NULL, session_id,
   2610 	    KM_SLEEP);
   2611 
   2612 	DPROV_DEBUG(D_MAC, ("(%d) dprov_decrypt_atomic: done err = 0x0%x\n",
   2613 	    instance, error));
   2614 
   2615 	return (error);
   2616 }
   2617 
   2618 /*
   2619  * Sign entry points.
   2620  */
   2621 
   2622 /*
   2623  * Checks whether the specified mech_type is supported by sign/verify
   2624  * entry points.
   2625  */
   2626 static boolean_t
   2627 dprov_valid_sign_verif_mech(crypto_mech_type_t mech_type)
   2628 {
   2629 	return (mech_type == MD5_HMAC_MECH_INFO_TYPE ||
   2630 	    mech_type == MD5_HMAC_GEN_MECH_INFO_TYPE ||
   2631 	    mech_type == SHA1_HMAC_MECH_INFO_TYPE ||
   2632 	    mech_type == SHA1_HMAC_GEN_MECH_INFO_TYPE ||
   2633 	    mech_type == SHA256_HMAC_MECH_INFO_TYPE ||
   2634 	    mech_type == SHA256_HMAC_GEN_MECH_INFO_TYPE ||
   2635 	    mech_type == SHA384_HMAC_MECH_INFO_TYPE ||
   2636 	    mech_type == SHA384_HMAC_GEN_MECH_INFO_TYPE ||
   2637 	    mech_type == SHA512_HMAC_MECH_INFO_TYPE ||
   2638 	    mech_type == SHA512_HMAC_GEN_MECH_INFO_TYPE ||
   2639 	    mech_type == RSA_PKCS_MECH_INFO_TYPE ||
   2640 	    mech_type == RSA_X_509_MECH_INFO_TYPE ||
   2641 	    mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE ||
   2642 	    mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE ||
   2643 	    mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE ||
   2644 	    mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE ||
   2645 	    mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE ||
   2646 	    mech_type == ECDSA_SHA1_MECH_INFO_TYPE ||
   2647 	    mech_type == ECDSA_MECH_INFO_TYPE);
   2648 }
   2649 
   2650 static int
   2651 dprov_sign_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
   2652     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
   2653     crypto_req_handle_t req)
   2654 {
   2655 	int error = CRYPTO_FAILED;
   2656 	dprov_state_t *softc;
   2657 	/* LINTED E_FUNC_SET_NOT_USED */
   2658 	int instance;
   2659 
   2660 	/* extract softc and instance number from context */
   2661 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2662 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_init: started\n", instance));
   2663 
   2664 	/* check mechanism */
   2665 	if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
   2666 		cmn_err(CE_WARN, "dprov_sign_init: unexpected mech type "
   2667 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
   2668 		return (CRYPTO_MECHANISM_INVALID);
   2669 	}
   2670 
   2671 	if (ctx_template != NULL)
   2672 		return (CRYPTO_ARGUMENTS_BAD);
   2673 
   2674 	/* submit request to the taskq */
   2675 	error = dprov_sign_submit_req(DPROV_REQ_SIGN_INIT, softc, req,
   2676 	    mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
   2677 
   2678 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_init: done err = 0x%x\n",
   2679 	    instance, error));
   2680 
   2681 	return (error);
   2682 }
   2683 
   2684 static int
   2685 dprov_sign(crypto_ctx_t *ctx, crypto_data_t *data,
   2686     crypto_data_t *signature, crypto_req_handle_t req)
   2687 {
   2688 	int error = CRYPTO_FAILED;
   2689 	dprov_state_t *softc;
   2690 	/* LINTED E_FUNC_SET_NOT_USED */
   2691 	int instance;
   2692 
   2693 	/* extract softc and instance number from context */
   2694 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2695 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign: started\n", instance));
   2696 
   2697 	/* submit request to the taskq */
   2698 	error = dprov_sign_submit_req(DPROV_REQ_SIGN, softc, req,
   2699 	    NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
   2700 
   2701 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign: done err = 0x%x\n",
   2702 	    instance, error));
   2703 
   2704 	return (error);
   2705 }
   2706 
   2707 static int
   2708 dprov_sign_update(crypto_ctx_t *ctx, crypto_data_t *data,
   2709     crypto_req_handle_t req)
   2710 {
   2711 	int error = CRYPTO_FAILED;
   2712 	dprov_state_t *softc;
   2713 	/* LINTED E_FUNC_SET_NOT_USED */
   2714 	int instance;
   2715 
   2716 	/* extract softc and instance number from context */
   2717 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2718 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_update: started\n", instance));
   2719 
   2720 	/* submit request to the taskq */
   2721 	error = dprov_sign_submit_req(DPROV_REQ_SIGN_UPDATE, softc, req,
   2722 	    NULL, NULL, data, NULL, ctx, 0, KM_NOSLEEP);
   2723 
   2724 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_update: done err = 0x%x\n",
   2725 	    instance, error));
   2726 
   2727 	return (error);
   2728 }
   2729 
   2730 static int
   2731 dprov_sign_final(crypto_ctx_t *ctx, crypto_data_t *signature,
   2732     crypto_req_handle_t req)
   2733 {
   2734 	int error = CRYPTO_FAILED;
   2735 	dprov_state_t *softc;
   2736 	/* LINTED E_FUNC_SET_NOT_USED */
   2737 	int instance;
   2738 
   2739 	/* extract softc and instance number from context */
   2740 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2741 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_final: started\n", instance));
   2742 
   2743 	/* submit request to the taskq */
   2744 	error = dprov_sign_submit_req(DPROV_REQ_SIGN_FINAL, softc, req,
   2745 	    NULL, NULL, NULL, signature, ctx, 0, KM_NOSLEEP);
   2746 
   2747 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_final: done err = 0x%x\n",
   2748 	    instance, error));
   2749 
   2750 	return (error);
   2751 }
   2752 
   2753 static int
   2754 dprov_sign_atomic(crypto_provider_handle_t provider,
   2755     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
   2756     crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature,
   2757     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
   2758 {
   2759 	int error = CRYPTO_FAILED;
   2760 	dprov_state_t *softc = (dprov_state_t *)provider;
   2761 	/* LINTED E_FUNC_SET_NOT_USED */
   2762 	int instance;
   2763 
   2764 	instance = ddi_get_instance(softc->ds_dip);
   2765 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_atomic: started\n", instance));
   2766 
   2767 	/* check mechanism */
   2768 	if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
   2769 		cmn_err(CE_WARN, "dprov_sign_atomic: unexpected mech type "
   2770 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
   2771 		return (CRYPTO_MECHANISM_INVALID);
   2772 	}
   2773 
   2774 	if (ctx_template != NULL)
   2775 		return (CRYPTO_ARGUMENTS_BAD);
   2776 
   2777 	/* submit request to the taskq */
   2778 	error = dprov_sign_submit_req(DPROV_REQ_SIGN_ATOMIC, softc, req,
   2779 	    mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
   2780 
   2781 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_atomic: done err = 0x%x\n",
   2782 	    instance, error));
   2783 
   2784 	return (error);
   2785 }
   2786 
   2787 static int
   2788 dprov_sign_recover_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
   2789     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
   2790     crypto_req_handle_t req)
   2791 {
   2792 	int error = CRYPTO_FAILED;
   2793 	dprov_state_t *softc;
   2794 	/* LINTED E_FUNC_SET_NOT_USED */
   2795 	int instance;
   2796 
   2797 	/* extract softc and instance number from context */
   2798 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2799 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_init: started\n",
   2800 	    instance));
   2801 
   2802 	if (ctx_template != NULL)
   2803 		return (CRYPTO_ARGUMENTS_BAD);
   2804 
   2805 	/* submit request to the taskq */
   2806 	error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER_INIT, softc, req,
   2807 	    mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
   2808 
   2809 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_init: done err = 0x%x\n",
   2810 	    instance, error));
   2811 
   2812 	return (error);
   2813 }
   2814 
   2815 static int
   2816 dprov_sign_recover(crypto_ctx_t *ctx, crypto_data_t *data,
   2817     crypto_data_t *signature, crypto_req_handle_t req)
   2818 {
   2819 	int error = CRYPTO_FAILED;
   2820 	dprov_state_t *softc;
   2821 	/* LINTED E_FUNC_SET_NOT_USED */
   2822 	int instance;
   2823 
   2824 	/* extract softc and instance number from context */
   2825 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2826 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover: started\n", instance));
   2827 
   2828 	/* submit request to the taskq */
   2829 	error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER, softc, req,
   2830 	    NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
   2831 
   2832 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover: done err = 0x%x\n",
   2833 	    instance, error));
   2834 
   2835 	return (error);
   2836 }
   2837 
   2838 static int
   2839 dprov_sign_recover_atomic(crypto_provider_handle_t provider,
   2840     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
   2841     crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature,
   2842     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
   2843 {
   2844 	int error = CRYPTO_FAILED;
   2845 	dprov_state_t *softc = (dprov_state_t *)provider;
   2846 	/* LINTED E_FUNC_SET_NOT_USED */
   2847 	int instance;
   2848 
   2849 	instance = ddi_get_instance(softc->ds_dip);
   2850 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_atomic: started\n",
   2851 	    instance));
   2852 
   2853 	if (ctx_template != NULL)
   2854 		return (CRYPTO_ARGUMENTS_BAD);
   2855 
   2856 	/* submit request to the taskq */
   2857 	error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER_ATOMIC, softc, req,
   2858 	    mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
   2859 
   2860 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_atomic: done "
   2861 	    "err = 0x%x\n", instance, error));
   2862 
   2863 	return (error);
   2864 }
   2865 
   2866 /*
   2867  * Verify entry points.
   2868  */
   2869 
   2870 static int
   2871 dprov_verify_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
   2872     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
   2873     crypto_req_handle_t req)
   2874 {
   2875 	int error = CRYPTO_FAILED;
   2876 	dprov_state_t *softc;
   2877 	/* LINTED E_FUNC_SET_NOT_USED */
   2878 	int instance;
   2879 
   2880 	/* extract softc and instance number from context */
   2881 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2882 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_init: started\n", instance));
   2883 
   2884 	/* check mechanism */
   2885 	if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
   2886 		cmn_err(CE_WARN, "dprov_verify_init: unexpected mech type "
   2887 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
   2888 		return (CRYPTO_MECHANISM_INVALID);
   2889 	}
   2890 
   2891 	if (ctx_template != NULL)
   2892 		return (CRYPTO_ARGUMENTS_BAD);
   2893 
   2894 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY_INIT, softc, req,
   2895 	    mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
   2896 
   2897 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_init: done err = 0x%x\n",
   2898 	    instance, error));
   2899 
   2900 	return (error);
   2901 }
   2902 
   2903 static int
   2904 dprov_verify(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature,
   2905     crypto_req_handle_t req)
   2906 {
   2907 	int error = CRYPTO_FAILED;
   2908 	dprov_state_t *softc;
   2909 	/* LINTED E_FUNC_SET_NOT_USED */
   2910 	int instance;
   2911 
   2912 	/* extract softc and instance number from context */
   2913 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2914 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify: started\n", instance));
   2915 
   2916 	/* submit request to the taskq */
   2917 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY, softc, req,
   2918 	    NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
   2919 
   2920 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify: done err = 0x%x\n",
   2921 	    instance, error));
   2922 
   2923 	return (error);
   2924 }
   2925 
   2926 static int
   2927 dprov_verify_update(crypto_ctx_t *ctx, crypto_data_t *data,
   2928     crypto_req_handle_t req)
   2929 {
   2930 	int error = CRYPTO_FAILED;
   2931 	dprov_state_t *softc;
   2932 	/* LINTED E_FUNC_SET_NOT_USED */
   2933 	int instance;
   2934 
   2935 	/* extract softc and instance number from context */
   2936 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2937 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_update: started\n",
   2938 	    instance));
   2939 
   2940 	/* submit request to the taskq */
   2941 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY_UPDATE, softc, req,
   2942 	    NULL, NULL, data, NULL, ctx, 0, KM_NOSLEEP);
   2943 
   2944 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_update: done err = 0x%x\n",
   2945 	    instance, error));
   2946 
   2947 	return (error);
   2948 }
   2949 
   2950 static int
   2951 dprov_verify_final(crypto_ctx_t *ctx, crypto_data_t *signature,
   2952     crypto_req_handle_t req)
   2953 {
   2954 	int error = CRYPTO_FAILED;
   2955 	dprov_state_t *softc;
   2956 	/* LINTED E_FUNC_SET_NOT_USED */
   2957 	int instance;
   2958 
   2959 	/* extract softc and instance number from context */
   2960 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   2961 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_final: started\n", instance));
   2962 
   2963 	/* submit request to the taskq */
   2964 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY_FINAL, softc, req,
   2965 	    NULL, NULL, NULL, signature, ctx, 0, KM_NOSLEEP);
   2966 
   2967 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_final: done err = 0x%x\n",
   2968 	    instance, error));
   2969 
   2970 	return (error);
   2971 }
   2972 
   2973 static int
   2974 dprov_verify_atomic(crypto_provider_handle_t provider,
   2975     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
   2976     crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature,
   2977     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
   2978 {
   2979 	int error = CRYPTO_FAILED;
   2980 	dprov_state_t *softc = (dprov_state_t *)provider;
   2981 	/* LINTED E_FUNC_SET_NOT_USED */
   2982 	int instance;
   2983 
   2984 	instance = ddi_get_instance(softc->ds_dip);
   2985 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_atomic: started\n",
   2986 	    instance));
   2987 
   2988 	/* check mechanism */
   2989 	if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
   2990 		cmn_err(CE_WARN, "dprov_verify_atomic: unexpected mech type "
   2991 		    "0x%llx\n", (unsigned long long)mechanism->cm_type);
   2992 		return (CRYPTO_MECHANISM_INVALID);
   2993 	}
   2994 
   2995 	if (ctx_template != NULL)
   2996 		return (CRYPTO_ARGUMENTS_BAD);
   2997 
   2998 	/* submit request to the taskq */
   2999 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY_ATOMIC, softc, req,
   3000 	    mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
   3001 
   3002 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_atomic: done err = 0x%x\n",
   3003 	    instance, error));
   3004 
   3005 	return (error);
   3006 }
   3007 
   3008 static int
   3009 dprov_verify_recover_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
   3010     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
   3011     crypto_req_handle_t req)
   3012 {
   3013 	int error = CRYPTO_FAILED;
   3014 	dprov_state_t *softc;
   3015 	/* LINTED E_FUNC_SET_NOT_USED */
   3016 	int instance;
   3017 
   3018 	/* extract softc and instance number from context */
   3019 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   3020 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_init: started\n",
   3021 	    instance));
   3022 
   3023 	if (ctx_template != NULL)
   3024 		return (CRYPTO_ARGUMENTS_BAD);
   3025 
   3026 	/* submit request to the taskq */
   3027 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER_INIT, softc,
   3028 	    req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
   3029 
   3030 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_init: done "
   3031 	    "err = 0x%x\n", instance, error));
   3032 
   3033 	return (error);
   3034 }
   3035 
   3036 static int
   3037 dprov_verify_recover(crypto_ctx_t *ctx, crypto_data_t *signature,
   3038     crypto_data_t *data, crypto_req_handle_t req)
   3039 {
   3040 	int error = CRYPTO_FAILED;
   3041 	dprov_state_t *softc;
   3042 	/* LINTED E_FUNC_SET_NOT_USED */
   3043 	int instance;
   3044 
   3045 	/* extract softc and instance number from context */
   3046 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   3047 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover: started\n",
   3048 	    instance));
   3049 
   3050 	/* submit request to the taskq */
   3051 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER, softc, req,
   3052 	    NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
   3053 
   3054 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover: done err = 0x%x\n",
   3055 	    instance, error));
   3056 
   3057 	return (error);
   3058 }
   3059 
   3060 static int
   3061 dprov_verify_recover_atomic(crypto_provider_handle_t provider,
   3062     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
   3063     crypto_key_t *key, crypto_data_t *signature, crypto_data_t *data,
   3064     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
   3065 {
   3066 	int error = CRYPTO_FAILED;
   3067 	dprov_state_t *softc = (dprov_state_t *)provider;
   3068 	/* LINTED E_FUNC_SET_NOT_USED */
   3069 	int instance;
   3070 
   3071 	instance = ddi_get_instance(softc->ds_dip);
   3072 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_atomic: started\n",
   3073 	    instance));
   3074 
   3075 	if (ctx_template != NULL)
   3076 		return (CRYPTO_ARGUMENTS_BAD);
   3077 
   3078 	/* submit request to the taskq */
   3079 	error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER_ATOMIC, softc,
   3080 	    req, mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
   3081 
   3082 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_atomic: done "
   3083 	    "err = 0x%x\n", instance, error));
   3084 
   3085 	return (error);
   3086 }
   3087 
   3088 /*
   3089  * Dual operations entry points.
   3090  */
   3091 
   3092 static int
   3093 dprov_digest_encrypt_update(crypto_ctx_t *digest_ctx,
   3094     crypto_ctx_t *encrypt_ctx, crypto_data_t *plaintext,
   3095     crypto_data_t *ciphertext, crypto_req_handle_t req)
   3096 {
   3097 	int error = CRYPTO_FAILED;
   3098 	dprov_state_t *softc;
   3099 	/* LINTED E_FUNC_SET_NOT_USED */
   3100 	int instance;
   3101 
   3102 	/* extract softc and instance number from context */
   3103 	DPROV_SOFTC_FROM_CTX(digest_ctx, softc, instance);
   3104 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_digest_encrypt_update: started\n",
   3105 	    instance));
   3106 
   3107 	if (digest_ctx->cc_provider != encrypt_ctx->cc_provider)
   3108 		return (CRYPTO_INVALID_CONTEXT);
   3109 
   3110 	/* submit request to the taskq */
   3111 	error = dprov_dual_submit_req(DPROV_REQ_DIGEST_ENCRYPT_UPDATE,
   3112 	    softc, req, digest_ctx, encrypt_ctx, plaintext, ciphertext);
   3113 
   3114 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_digest_encrypt_update: done "
   3115 	    "err = 0x%x\n", instance, error));
   3116 
   3117 	return (error);
   3118 }
   3119 
   3120 static int
   3121 dprov_decrypt_digest_update(crypto_ctx_t *decrypt_ctx, crypto_ctx_t *digest_ctx,
   3122     crypto_data_t *ciphertext, crypto_data_t *plaintext,
   3123     crypto_req_handle_t req)
   3124 {
   3125 	int error = CRYPTO_FAILED;
   3126 	dprov_state_t *softc;
   3127 	/* LINTED E_FUNC_SET_NOT_USED */
   3128 	int instance;
   3129 
   3130 	/* extract softc and instance number from context */
   3131 	DPROV_SOFTC_FROM_CTX(decrypt_ctx, softc, instance);
   3132 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_digest_update: started\n",
   3133 	    instance));
   3134 
   3135 	if (decrypt_ctx->cc_provider != digest_ctx->cc_provider)
   3136 		return (CRYPTO_INVALID_CONTEXT);
   3137 
   3138 	/* submit request to the taskq */
   3139 	error = dprov_dual_submit_req(DPROV_REQ_DECRYPT_DIGEST_UPDATE,
   3140 	    softc, req, digest_ctx, decrypt_ctx, plaintext, ciphertext);
   3141 
   3142 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_digest_update: done "
   3143 	    "err = 0x%x\n", instance, error));
   3144 
   3145 	return (error);
   3146 }
   3147 
   3148 static int
   3149 dprov_sign_encrypt_update(crypto_ctx_t *sign_ctx, crypto_ctx_t *encrypt_ctx,
   3150     crypto_data_t *plaintext, crypto_data_t *ciphertext,
   3151     crypto_req_handle_t req)
   3152 {
   3153 	int error = CRYPTO_FAILED;
   3154 	dprov_state_t *softc;
   3155 	/* LINTED E_FUNC_SET_NOT_USED */
   3156 	int instance;
   3157 
   3158 	/* extract softc and instance number from context */
   3159 	DPROV_SOFTC_FROM_CTX(sign_ctx, softc, instance);
   3160 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_sign_encrypt_update: started\n",
   3161 	    instance));
   3162 
   3163 	if (sign_ctx->cc_provider != encrypt_ctx->cc_provider)
   3164 		return (CRYPTO_INVALID_CONTEXT);
   3165 
   3166 	/* submit request to the taskq */
   3167 	error = dprov_dual_submit_req(DPROV_REQ_SIGN_ENCRYPT_UPDATE,
   3168 	    softc, req, sign_ctx, encrypt_ctx, plaintext, ciphertext);
   3169 
   3170 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_sign_encrypt_update: done "
   3171 	    "err = 0x%x\n", instance, error));
   3172 
   3173 	return (error);
   3174 }
   3175 
   3176 static int
   3177 dprov_decrypt_verify_update(crypto_ctx_t *decrypt_ctx, crypto_ctx_t *verify_ctx,
   3178     crypto_data_t *ciphertext, crypto_data_t *plaintext,
   3179     crypto_req_handle_t req)
   3180 {
   3181 	int error = CRYPTO_FAILED;
   3182 	dprov_state_t *softc;
   3183 	/* LINTED E_FUNC_SET_NOT_USED */
   3184 	int instance;
   3185 
   3186 	/* extract softc and instance number from context */
   3187 	DPROV_SOFTC_FROM_CTX(decrypt_ctx, softc, instance);
   3188 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_verify_update: started\n",
   3189 	    instance));
   3190 
   3191 	if (decrypt_ctx->cc_provider != verify_ctx->cc_provider)
   3192 		return (CRYPTO_INVALID_CONTEXT);
   3193 
   3194 	/* submit request to the taskq */
   3195 	error = dprov_dual_submit_req(DPROV_REQ_DECRYPT_VERIFY_UPDATE,
   3196 	    softc, req, verify_ctx, decrypt_ctx, plaintext, ciphertext);
   3197 
   3198 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_verify_update: done "
   3199 	    "err = 0x%x\n", instance, error));
   3200 
   3201 	return (error);
   3202 }
   3203 
   3204 /*
   3205  * Dual cipher-mac entry points.
   3206  */
   3207 
   3208 static int
   3209 dprov_encrypt_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *encrypt_mech,
   3210     crypto_key_t *encrypt_key, crypto_mechanism_t *mac_mech,
   3211     crypto_key_t *mac_key, crypto_spi_ctx_template_t encr_ctx_template,
   3212     crypto_spi_ctx_template_t mac_ctx_template,
   3213     crypto_req_handle_t req)
   3214 {
   3215 	int error = CRYPTO_FAILED;
   3216 	dprov_state_t *softc;
   3217 	/* LINTED E_FUNC_SET_NOT_USED */
   3218 	int instance;
   3219 
   3220 	/* extract softc and instance number from context */
   3221 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   3222 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_init: started\n",
   3223 	    instance));
   3224 
   3225 	/* check mechanisms */
   3226 	if (!dprov_valid_cipher_mech(encrypt_mech->cm_type)) {
   3227 		cmn_err(CE_WARN, "dprov_encrypt_mac_init: unexpected encrypt "
   3228 		    "mech type 0x%llx\n",
   3229 		    (unsigned long long)encrypt_mech->cm_type);
   3230 		return (CRYPTO_MECHANISM_INVALID);
   3231 	}
   3232 	if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
   3233 		cmn_err(CE_WARN, "dprov_encrypt_mac_init: unexpected mac "
   3234 		    "mech type 0x%llx\n",
   3235 		    (unsigned long long)mac_mech->cm_type);
   3236 		return (CRYPTO_MECHANISM_INVALID);
   3237 	}
   3238 
   3239 	if (encr_ctx_template != NULL || mac_ctx_template != NULL)
   3240 		return (CRYPTO_ARGUMENTS_BAD);
   3241 
   3242 	/* submit request to the taskq */
   3243 	error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_INIT,
   3244 	    softc, req, ctx, 0, encrypt_mech, encrypt_key, mac_mech, mac_key,
   3245 	    NULL, NULL, NULL, KM_SLEEP);
   3246 
   3247 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_init: done "
   3248 	    "err = 0x%x\n", instance, error));
   3249 
   3250 	return (error);
   3251 }
   3252 
   3253 static int
   3254 dprov_encrypt_mac(crypto_ctx_t *ctx, crypto_data_t *plaintext,
   3255     crypto_dual_data_t *ciphertext, crypto_data_t *mac, crypto_req_handle_t req)
   3256 {
   3257 	int error = CRYPTO_FAILED;
   3258 	dprov_state_t *softc;
   3259 	/* LINTED E_FUNC_SET_NOT_USED */
   3260 	int instance;
   3261 
   3262 	/* extract softc and instance number from context */
   3263 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   3264 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac: started\n",
   3265 	    instance));
   3266 
   3267 	/*
   3268 	 * submit request to the taskq
   3269 	 * Careful! cihertext/plaintext order inversion
   3270 	 */
   3271 	error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC,
   3272 	    softc, req, ctx, 0, NULL, NULL, NULL, NULL,
   3273 	    ciphertext, plaintext, mac, KM_NOSLEEP);
   3274 
   3275 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac: done "
   3276 	    "err = 0x%x\n", instance, error));
   3277 
   3278 	return (error);
   3279 }
   3280 
   3281 static int
   3282 dprov_encrypt_mac_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
   3283     crypto_dual_data_t *ciphertext, crypto_req_handle_t req)
   3284 {
   3285 	int error = CRYPTO_FAILED;
   3286 	dprov_state_t *softc;
   3287 	/* LINTED E_FUNC_SET_NOT_USED */
   3288 	int instance;
   3289 
   3290 	/* extract softc and instance number from context */
   3291 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   3292 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_update: started\n",
   3293 	    instance));
   3294 
   3295 	/* submit request to the taskq */
   3296 	error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_UPDATE,
   3297 	    softc, req, ctx, 0, NULL, NULL, NULL, NULL,
   3298 	    ciphertext, plaintext, NULL, KM_NOSLEEP);
   3299 
   3300 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_update: done "
   3301 	    "err = 0x%x\n", instance, error));
   3302 
   3303 	return (error);
   3304 }
   3305 
   3306 static int
   3307 dprov_encrypt_mac_final(crypto_ctx_t *ctx,
   3308     crypto_dual_data_t *ciphertext, crypto_data_t *mac,
   3309     crypto_req_handle_t req)
   3310 {
   3311 	int error = CRYPTO_FAILED;
   3312 	dprov_state_t *softc;
   3313 	/* LINTED E_FUNC_SET_NOT_USED */
   3314 	int instance;
   3315 
   3316 	/* extract softc and instance number from context */
   3317 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   3318 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_final: started\n",
   3319 	    instance));
   3320 
   3321 	/* submit request to the taskq */
   3322 	error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_FINAL,
   3323 	    softc, req, ctx, 0, NULL, NULL, NULL, NULL,
   3324 	    ciphertext, NULL, mac, KM_NOSLEEP);
   3325 
   3326 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_final: done "
   3327 	    "err = 0x%x\n", instance, error));
   3328 
   3329 	return (error);
   3330 }
   3331 
   3332 static int
   3333 dprov_encrypt_mac_atomic(crypto_provider_handle_t provider,
   3334     crypto_session_id_t session_id, crypto_mechanism_t *encrypt_mech,
   3335     crypto_key_t *encrypt_key, crypto_mechanism_t *mac_mech,
   3336     crypto_key_t *mac_key, crypto_data_t *plaintext,
   3337     crypto_dual_data_t *ciphertext, crypto_data_t *mac,
   3338     crypto_spi_ctx_template_t encr_ctx_template,
   3339     crypto_spi_ctx_template_t mac_ctx_template,
   3340     crypto_req_handle_t req)
   3341 {
   3342 	int error = CRYPTO_FAILED;
   3343 	dprov_state_t *softc = (dprov_state_t *)provider;
   3344 	/* LINTED E_FUNC_SET_NOT_USED */
   3345 	int instance;
   3346 
   3347 	instance = ddi_get_instance(softc->ds_dip);
   3348 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_atomic: started\n",
   3349 	    instance));
   3350 
   3351 	/* check mechanisms */
   3352 	if (!dprov_valid_cipher_mech(encrypt_mech->cm_type)) {
   3353 		cmn_err(CE_WARN, "dprov_encrypt_mac_atomic: unexpected encrypt "
   3354 		    "mech type 0x%llx\n",
   3355 		    (unsigned long long)encrypt_mech->cm_type);
   3356 		return (CRYPTO_MECHANISM_INVALID);
   3357 	}
   3358 	if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
   3359 		cmn_err(CE_WARN, "dprov_encrypt_mac_atomic: unexpected mac "
   3360 		    "mech type 0x%llx\n",
   3361 		    (unsigned long long)mac_mech->cm_type);
   3362 		return (CRYPTO_MECHANISM_INVALID);
   3363 	}
   3364 
   3365 	if (encr_ctx_template != NULL || mac_ctx_template != NULL)
   3366 		return (CRYPTO_ARGUMENTS_BAD);
   3367 
   3368 	/* submit request to the taskq */
   3369 	error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_ATOMIC,
   3370 	    softc, req, NULL, session_id, encrypt_mech, encrypt_key, mac_mech,
   3371 	    mac_key, ciphertext, plaintext, mac, KM_SLEEP);
   3372 
   3373 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_atomic: done "
   3374 	    "err = 0x%x\n", instance, error));
   3375 
   3376 	return (error);
   3377 }
   3378 
   3379 static int
   3380 dprov_mac_decrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mac_mech,
   3381     crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech,
   3382     crypto_key_t *decrypt_key, crypto_spi_ctx_template_t mac_ctx_template,
   3383     crypto_spi_ctx_template_t decr_ctx_template,
   3384     crypto_req_handle_t req)
   3385 {
   3386 	int error = CRYPTO_FAILED;
   3387 	dprov_state_t *softc;
   3388 	/* LINTED E_FUNC_SET_NOT_USED */
   3389 	int instance;
   3390 
   3391 	/* extract softc and instance number from context */
   3392 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   3393 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_init: started\n",
   3394 	    instance));
   3395 
   3396 	/* check mechanisms */
   3397 	if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) {
   3398 		cmn_err(CE_WARN, "dprov_mac_decrypt_init: unexpected decrypt "
   3399 		    "mech type 0x%llx\n",
   3400 		    (unsigned long long)decrypt_mech->cm_type);
   3401 		return (CRYPTO_MECHANISM_INVALID);
   3402 	}
   3403 	if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
   3404 		cmn_err(CE_WARN, "dprov_mac_decrypt_init: unexpected mac "
   3405 		    "mech type 0x%llx\n",
   3406 		    (unsigned long long)mac_mech->cm_type);
   3407 		return (CRYPTO_MECHANISM_INVALID);
   3408 	}
   3409 
   3410 	if (decr_ctx_template != NULL || mac_ctx_template != NULL)
   3411 		return (CRYPTO_ARGUMENTS_BAD);
   3412 
   3413 	/* submit request to the taskq */
   3414 	error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_INIT,
   3415 	    softc, req, ctx, 0, decrypt_mech, decrypt_key, mac_mech, mac_key,
   3416 	    NULL, NULL, NULL, KM_SLEEP);
   3417 
   3418 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_init: done "
   3419 	    "err = 0x%x\n", instance, error));
   3420 
   3421 	return (error);
   3422 }
   3423 
   3424 static int
   3425 dprov_mac_decrypt(crypto_ctx_t *ctx, crypto_dual_data_t *ciphertext,
   3426     crypto_data_t *mac, crypto_data_t *plaintext, crypto_req_handle_t req)
   3427 {
   3428 	int error = CRYPTO_FAILED;
   3429 	dprov_state_t *softc;
   3430 	/* LINTED E_FUNC_SET_NOT_USED */
   3431 	int instance;
   3432 
   3433 	/* extract softc and instance number from context */
   3434 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   3435 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt: started\n",
   3436 	    instance));
   3437 
   3438 	/* submit request to the taskq */
   3439 	error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT,
   3440 	    softc, req, ctx, 0, NULL, NULL, NULL, NULL,
   3441 	    ciphertext, plaintext, mac, KM_NOSLEEP);
   3442 
   3443 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt: done "
   3444 	    "err = 0x%x\n", instance, error));
   3445 
   3446 	return (error);
   3447 }
   3448 
   3449 static int
   3450 dprov_mac_decrypt_update(crypto_ctx_t *ctx, crypto_dual_data_t *ciphertext,
   3451     crypto_data_t *plaintext, crypto_req_handle_t req)
   3452 {
   3453 	int error = CRYPTO_FAILED;
   3454 	dprov_state_t *softc;
   3455 	/* LINTED E_FUNC_SET_NOT_USED */
   3456 	int instance;
   3457 
   3458 	/* extract softc and instance number from context */
   3459 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   3460 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_update: started\n",
   3461 	    instance));
   3462 
   3463 	/* submit request to the taskq */
   3464 	error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_UPDATE,
   3465 	    softc, req, ctx, 0, NULL, NULL, NULL, NULL,
   3466 	    ciphertext, plaintext, NULL, KM_NOSLEEP);
   3467 
   3468 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_update: done "
   3469 	    "err = 0x%x\n", instance, error));
   3470 
   3471 	return (error);
   3472 }
   3473 
   3474 static int
   3475 dprov_mac_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *mac,
   3476     crypto_data_t *plaintext, crypto_req_handle_t req)
   3477 {
   3478 	int error = CRYPTO_FAILED;
   3479 	dprov_state_t *softc;
   3480 	/* LINTED E_FUNC_SET_NOT_USED */
   3481 	int instance;
   3482 
   3483 	/* extract softc and instance number from context */
   3484 	DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
   3485 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_final: started\n",
   3486 	    instance));
   3487 
   3488 	/* submit request to the taskq */
   3489 	error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_FINAL,
   3490 	    softc, req, ctx, 0, NULL, NULL, NULL, NULL,
   3491 	    NULL, plaintext, mac, KM_NOSLEEP);
   3492 
   3493 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_final: done "
   3494 	    "err = 0x%x\n", instance, error));
   3495 
   3496 	return (error);
   3497 }
   3498 
   3499 static int
   3500 dprov_mac_decrypt_atomic(crypto_provider_handle_t provider,
   3501     crypto_session_id_t session_id, crypto_mechanism_t *mac_mech,
   3502     crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech,
   3503     crypto_key_t *decrypt_key, crypto_dual_data_t *ciphertext,
   3504     crypto_data_t *mac, crypto_data_t *plaintext,
   3505     crypto_spi_ctx_template_t mac_ctx_template,
   3506     crypto_spi_ctx_template_t decr_ctx_template,
   3507     crypto_req_handle_t req)
   3508 {
   3509 	int error = CRYPTO_FAILED;
   3510 	dprov_state_t *softc = (dprov_state_t *)provider;
   3511 	/* LINTED E_FUNC_SET_NOT_USED */
   3512 	int instance;
   3513 
   3514 	instance = ddi_get_instance(softc->ds_dip);
   3515 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_atomic: started\n",
   3516 	    instance));
   3517 
   3518 	/* check mechanisms */
   3519 	if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) {
   3520 		cmn_err(CE_WARN, "dprov_mac_decrypt_atomic: unexpected encrypt "
   3521 		    "mech type 0x%llx\n",
   3522 		    (unsigned long long)decrypt_mech->cm_type);
   3523 		return (CRYPTO_MECHANISM_INVALID);
   3524 	}
   3525 	if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
   3526 		cmn_err(CE_WARN, "dprov_mac_decrypt_atomic: unexpected mac "
   3527 		    "mech type 0x%llx\n",
   3528 		    (unsigned long long)mac_mech->cm_type);
   3529 		return (CRYPTO_MECHANISM_INVALID);
   3530 	}
   3531 
   3532 	if (decr_ctx_template != NULL || mac_ctx_template != NULL)
   3533 		return (CRYPTO_ARGUMENTS_BAD);
   3534 
   3535 	/* submit request to the taskq */
   3536 	error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_ATOMIC,
   3537 	    softc, req, NULL, session_id, decrypt_mech, decrypt_key, mac_mech,
   3538 	    mac_key, ciphertext, plaintext, mac, KM_SLEEP);
   3539 
   3540 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_atomic: done "
   3541 	    "err = 0x%x\n", instance, error));
   3542 
   3543 	return (error);
   3544 }
   3545 
   3546 static int
   3547 dprov_mac_verify_decrypt_atomic(crypto_provider_handle_t provider,
   3548     crypto_session_id_t session_id, crypto_mechanism_t *mac_mech,
   3549     crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech,
   3550     crypto_key_t *decrypt_key, crypto_dual_data_t *ciphertext,
   3551     crypto_data_t *mac, crypto_data_t *plaintext,
   3552     crypto_spi_ctx_template_t mac_ctx_template,
   3553     crypto_spi_ctx_template_t decr_ctx_template,
   3554     crypto_req_handle_t req)
   3555 {
   3556 	int error = CRYPTO_FAILED;
   3557 	dprov_state_t *softc = (dprov_state_t *)provider;
   3558 	/* LINTED E_FUNC_SET_NOT_USED */
   3559 	int instance;
   3560 
   3561 	instance = ddi_get_instance(softc->ds_dip);
   3562 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_verify_decrypt_atomic:"
   3563 	    "started\n", instance));
   3564 
   3565 	/* check mechanisms */
   3566 	if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) {
   3567 		cmn_err(CE_WARN, "dprov_mac_verify_decrypt_atomic: "
   3568 		    "unexpected encrypt mech type 0x%llx\n",
   3569 		    (unsigned long long)decrypt_mech->cm_type);
   3570 		return (CRYPTO_MECHANISM_INVALID);
   3571 	}
   3572 	if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
   3573 		cmn_err(CE_WARN, "dprov_mac_verify_decrypt_atomic: "
   3574 		    "unexpected mac mech type 0x%llx\n",
   3575 		    (unsigned long long)mac_mech->cm_type);
   3576 		return (CRYPTO_MECHANISM_INVALID);
   3577 	}
   3578 
   3579 	if (decr_ctx_template != NULL || mac_ctx_template != NULL)
   3580 		return (CRYPTO_ARGUMENTS_BAD);
   3581 
   3582 	/* submit request to the taskq */
   3583 	error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC,
   3584 	    softc, req, NULL, session_id, decrypt_mech, decrypt_key, mac_mech,
   3585 	    mac_key, ciphertext, plaintext, mac, KM_SLEEP);
   3586 
   3587 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_verify_decrypt_atomic: done "
   3588 	    "err = 0x%x\n", instance, error));
   3589 
   3590 	return (error);
   3591 }
   3592 
   3593 /*
   3594  * Random number entry points.
   3595  */
   3596 
   3597 static int
   3598 dprov_seed_random(crypto_provider_handle_t provider,  crypto_session_id_t sid,
   3599     uchar_t *buf, size_t len, uint_t entropy_est, uint32_t flags,
   3600     crypto_req_handle_t req)
   3601 {
   3602 	int error = CRYPTO_FAILED;
   3603 	dprov_state_t *softc = (dprov_state_t *)provider;
   3604 	/* LINTED E_FUNC_SET_NOT_USED */
   3605 	int instance;
   3606 
   3607 	instance = ddi_get_instance(softc->ds_dip);
   3608 	DPROV_DEBUG(D_RANDOM, ("(%d) dprov_seed_random: started\n",
   3609 	    instance));
   3610 
   3611 	error = dprov_random_submit_req(DPROV_REQ_RANDOM_SEED, softc,
   3612 	    req, buf, len, sid, entropy_est, flags);
   3613 
   3614 	DPROV_DEBUG(D_RANDOM, ("(%d) dprov_seed_random: done err = 0x0%x\n",
   3615 	    instance, error));
   3616 
   3617 	return (error);
   3618 }
   3619 
   3620 static int
   3621 dprov_generate_random(crypto_provider_handle_t provider,
   3622     crypto_session_id_t sid, uchar_t *buf, size_t len, crypto_req_handle_t req)
   3623 {
   3624 	int error = CRYPTO_FAILED;
   3625 	dprov_state_t *softc = (dprov_state_t *)provider;
   3626 	/* LINTED E_FUNC_SET_NOT_USED */
   3627 	int instance;
   3628 
   3629 	instance = ddi_get_instance(softc->ds_dip);
   3630 	DPROV_DEBUG(D_RANDOM, ("(%d) dprov_generate_random: started\n",
   3631 	    instance));
   3632 
   3633 	error = dprov_random_submit_req(DPROV_REQ_RANDOM_GENERATE, softc,
   3634 	    req, buf, len, sid, 0, 0);
   3635 
   3636 	DPROV_DEBUG(D_RANDOM, ("(%d) dprov_generate_random: done "
   3637 	    "err = 0x0%x\n", instance, error));
   3638 
   3639 	return (error);
   3640 }
   3641 
   3642 /*
   3643  * Session Management entry points.
   3644  */
   3645 
   3646 static int
   3647 dprov_session_open(crypto_provider_handle_t provider,
   3648     crypto_session_id_t *session_id, crypto_req_handle_t req)
   3649 {
   3650 	int error = CRYPTO_FAILED;
   3651 	dprov_state_t *softc = (dprov_state_t *)provider;
   3652 	/* LINTED E_FUNC_SET_NOT_USED */
   3653 	int instance;
   3654 
   3655 	instance = ddi_get_instance(softc->ds_dip);
   3656 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_open: started\n",
   3657 	    instance));
   3658 
   3659 	error = dprov_session_submit_req(DPROV_REQ_SESSION_OPEN, softc,
   3660 	    req, session_id, 0, 0, NULL, 0);
   3661 
   3662 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_open: done err = 0x0%x\n",
   3663 	    instance, error));
   3664 
   3665 	return (error);
   3666 }
   3667 
   3668 static int
   3669 dprov_session_close(crypto_provider_handle_t provider,
   3670     crypto_session_id_t session_id, crypto_req_handle_t req)
   3671 {
   3672 	int error = CRYPTO_FAILED;
   3673 	dprov_state_t *softc = (dprov_state_t *)provider;
   3674 	/* LINTED E_FUNC_SET_NOT_USED */
   3675 	int instance;
   3676 
   3677 	instance = ddi_get_instance(softc->ds_dip);
   3678 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_close: started\n",
   3679 	    instance));
   3680 
   3681 	error = dprov_session_submit_req(DPROV_REQ_SESSION_CLOSE, softc,
   3682 	    req, 0, session_id, 0, NULL, 0);
   3683 
   3684 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_close: done err = 0x0%x\n",
   3685 	    instance, error));
   3686 
   3687 	return (error);
   3688 }
   3689 
   3690 static int
   3691 dprov_session_login(crypto_provider_handle_t provider,
   3692     crypto_session_id_t session_id, crypto_user_type_t user_type,
   3693     char *pin, size_t pin_len, crypto_req_handle_t req)
   3694 {
   3695 	int error = CRYPTO_FAILED;
   3696 	dprov_state_t *softc = (dprov_state_t *)provider;
   3697 	/* LINTED E_FUNC_SET_NOT_USED */
   3698 	int instance;
   3699 
   3700 	instance = ddi_get_instance(softc->ds_dip);
   3701 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_login: started\n",
   3702 	    instance));
   3703 
   3704 	error = dprov_session_submit_req(DPROV_REQ_SESSION_LOGIN, softc,
   3705 	    req, 0, session_id, user_type, pin, pin_len);
   3706 
   3707 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_login: done err = 0x0%x\n",
   3708 	    instance, error));
   3709 
   3710 	return (error);
   3711 }
   3712 
   3713 static int
   3714 dprov_session_logout(crypto_provider_handle_t provider,
   3715     crypto_session_id_t session_id, crypto_req_handle_t req)
   3716 {
   3717 	int error = CRYPTO_FAILED;
   3718 	dprov_state_t *softc = (dprov_state_t *)provider;
   3719 	/* LINTED E_FUNC_SET_NOT_USED */
   3720 	int instance;
   3721 
   3722 	instance = ddi_get_instance(softc->ds_dip);
   3723 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_logout: started\n",
   3724 	    instance));
   3725 
   3726 	error = dprov_session_submit_req(DPROV_REQ_SESSION_LOGOUT, softc,
   3727 	    req, 0, session_id, 0, NULL, 0);
   3728 
   3729 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_logout: done err = 0x0%x\n",
   3730 	    instance, error));
   3731 
   3732 	return (error);
   3733 }
   3734 
   3735 /*
   3736  * Object management entry points.
   3737  */
   3738 
   3739 static int
   3740 dprov_object_create(crypto_provider_handle_t provider,
   3741     crypto_session_id_t session_id, crypto_object_attribute_t *template,
   3742     uint_t attribute_count, crypto_object_id_t *object,
   3743     crypto_req_handle_t req)
   3744 {
   3745 	int error = CRYPTO_FAILED;
   3746 	dprov_state_t *softc = (dprov_state_t *)provider;
   3747 	/* LINTED E_FUNC_SET_NOT_USED */
   3748 	int instance;
   3749 
   3750 	instance = ddi_get_instance(softc->ds_dip);
   3751 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_create: started\n",
   3752 	    instance));
   3753 
   3754 	/* submit request to the taskq */
   3755 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_CREATE, softc, req,
   3756 	    session_id, 0, template, attribute_count, object, NULL, NULL,
   3757 	    NULL, 0, NULL, KM_NOSLEEP);
   3758 
   3759 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_create: done err = 0x0%x\n",
   3760 	    instance, error));
   3761 
   3762 	return (error);
   3763 }
   3764 
   3765 static int
   3766 dprov_object_copy(crypto_provider_handle_t provider,
   3767     crypto_session_id_t session_id, crypto_object_id_t object,
   3768     crypto_object_attribute_t *template, uint_t attribute_count,
   3769     crypto_object_id_t *new_object, crypto_req_handle_t req)
   3770 {
   3771 	int error = CRYPTO_FAILED;
   3772 	dprov_state_t *softc = (dprov_state_t *)provider;
   3773 	/* LINTED E_FUNC_SET_NOT_USED */
   3774 	int instance;
   3775 
   3776 	instance = ddi_get_instance(softc->ds_dip);
   3777 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_copy: started\n",
   3778 	    instance));
   3779 
   3780 	/* submit request to the taskq */
   3781 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_COPY, softc, req,
   3782 	    session_id, object, template, attribute_count, new_object,
   3783 	    NULL, NULL, NULL, 0, NULL, KM_NOSLEEP);
   3784 
   3785 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_copy: done err = 0x0%x\n",
   3786 	    instance, error));
   3787 
   3788 	return (error);
   3789 }
   3790 
   3791 static int
   3792 dprov_object_destroy(crypto_provider_handle_t provider,
   3793     crypto_session_id_t session_id, crypto_object_id_t object,
   3794     crypto_req_handle_t req)
   3795 {
   3796 	int error = CRYPTO_FAILED;
   3797 	dprov_state_t *softc = (dprov_state_t *)provider;
   3798 	/* LINTED E_FUNC_SET_NOT_USED */
   3799 	int instance;
   3800 
   3801 	instance = ddi_get_instance(softc->ds_dip);
   3802 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_destroy: started\n",
   3803 	    instance));
   3804 
   3805 	/* submit request to the taskq */
   3806 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_DESTROY, softc, req,
   3807 	    session_id, object, NULL, 0, NULL, NULL, NULL, NULL, 0, NULL,
   3808 	    KM_NOSLEEP);
   3809 
   3810 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_destroy: done err = 0x0%x\n",
   3811 	    instance, error));
   3812 
   3813 	return (error);
   3814 }
   3815 
   3816 static int
   3817 dprov_object_get_size(crypto_provider_handle_t provider,
   3818     crypto_session_id_t session_id, crypto_object_id_t object,
   3819     size_t *size, crypto_req_handle_t req)
   3820 {
   3821 	int error = CRYPTO_FAILED;
   3822 	dprov_state_t *softc = (dprov_state_t *)provider;
   3823 	/* LINTED E_FUNC_SET_NOT_USED */
   3824 	int instance;
   3825 
   3826 	instance = ddi_get_instance(softc->ds_dip);
   3827 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_size: started\n",
   3828 	    instance));
   3829 
   3830 	/* submit request to the taskq */
   3831 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_GET_SIZE, softc, req,
   3832 	    session_id, object, NULL, 0, NULL, size, NULL, NULL, 0, NULL,
   3833 	    KM_NOSLEEP);
   3834 
   3835 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_size: done err = 0x0%x\n",
   3836 	    instance, error));
   3837 
   3838 	return (error);
   3839 }
   3840 
   3841 static int
   3842 dprov_object_get_attribute_value(crypto_provider_handle_t provider,
   3843     crypto_session_id_t session_id, crypto_object_id_t object,
   3844     crypto_object_attribute_t *template, uint_t attribute_count,
   3845     crypto_req_handle_t req)
   3846 {
   3847 	int error = CRYPTO_FAILED;
   3848 	dprov_state_t *softc = (dprov_state_t *)provider;
   3849 	/* LINTED E_FUNC_SET_NOT_USED */
   3850 	int instance;
   3851 
   3852 	instance = ddi_get_instance(softc->ds_dip);
   3853 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_attribute_value: "
   3854 	    "started\n", instance));
   3855 
   3856 	/* submit request to the taskq */
   3857 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE,
   3858 	    softc, req, session_id, object, template, attribute_count,
   3859 	    NULL, NULL, NULL, NULL, 0, NULL, KM_NOSLEEP);
   3860 
   3861 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_attribute_value: "
   3862 	    "done err = 0x0%x\n", instance, error));
   3863 
   3864 	return (error);
   3865 }
   3866 
   3867 static int
   3868 dprov_object_set_attribute_value(crypto_provider_handle_t provider,
   3869     crypto_session_id_t session_id, crypto_object_id_t object,
   3870     crypto_object_attribute_t *template, uint_t attribute_count,
   3871     crypto_req_handle_t req)
   3872 {
   3873 	int error = CRYPTO_FAILED;
   3874 	dprov_state_t *softc = (dprov_state_t *)provider;
   3875 	/* LINTED E_FUNC_SET_NOT_USED */
   3876 	int instance;
   3877 
   3878 	instance = ddi_get_instance(softc->ds_dip);
   3879 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_set_attribute_value: "
   3880 	    "started\n", instance));
   3881 
   3882 	/* submit request to the taskq */
   3883 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE,
   3884 	    softc, req, session_id, object, template, attribute_count,
   3885 	    NULL, NULL, NULL, NULL, 0, NULL, KM_NOSLEEP);
   3886 
   3887 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_set_attribute_value: "
   3888 	    "done err = 0x0%x\n", instance, error));
   3889 
   3890 	return (error);
   3891 }
   3892 
   3893 static int
   3894 dprov_object_find_init(crypto_provider_handle_t provider,
   3895     crypto_session_id_t session_id, crypto_object_attribute_t *template,
   3896     uint_t attribute_count, void **provider_private,
   3897     crypto_req_handle_t req)
   3898 {
   3899 	int error = CRYPTO_FAILED;
   3900 	dprov_state_t *softc = (dprov_state_t *)provider;
   3901 	/* LINTED E_FUNC_SET_NOT_USED */
   3902 	int instance;
   3903 
   3904 	instance = ddi_get_instance(softc->ds_dip);
   3905 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_init: started\n",
   3906 	    instance));
   3907 
   3908 	/* submit request to the taskq */
   3909 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND_INIT, softc, req,
   3910 	    session_id, 0, template, attribute_count, NULL, NULL,
   3911 	    provider_private, NULL, 0, NULL, KM_SLEEP);
   3912 
   3913 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_init: done "
   3914 	    "err = 0x0%x\n", instance, error));
   3915 
   3916 	return (error);
   3917 }
   3918 
   3919 static int
   3920 dprov_object_find(crypto_provider_handle_t provider, void *provider_private,
   3921     crypto_object_id_t *objects, uint_t max_object_count,
   3922     uint_t *object_count, crypto_req_handle_t req)
   3923 {
   3924 	int error = CRYPTO_FAILED;
   3925 	dprov_state_t *softc = (dprov_state_t *)provider;
   3926 	/* LINTED E_FUNC_SET_NOT_USED */
   3927 	int instance;
   3928 
   3929 	instance = ddi_get_instance(softc->ds_dip);
   3930 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find: started\n",
   3931 	    instance));
   3932 
   3933 	/* submit request to the taskq */
   3934 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND, softc, req,
   3935 	    0, 0, NULL, 0, objects, NULL, NULL, provider_private,
   3936 	    max_object_count, object_count, KM_NOSLEEP);
   3937 
   3938 
   3939 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find: done err = 0x0%x\n",
   3940 	    instance, error));
   3941 
   3942 	return (error);
   3943 }
   3944 
   3945 static int
   3946 dprov_object_find_final(crypto_provider_handle_t provider,
   3947     void *provider_private, crypto_req_handle_t req)
   3948 {
   3949 	int error = CRYPTO_FAILED;
   3950 	dprov_state_t *softc = (dprov_state_t *)provider;
   3951 	/* LINTED E_FUNC_SET_NOT_USED */
   3952 	int instance;
   3953 
   3954 	instance = ddi_get_instance(softc->ds_dip);
   3955 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_final: started\n",
   3956 	    instance));
   3957 
   3958 	/* submit request to the taskq */
   3959 	error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND_FINAL, softc, req,
   3960 	    0, 0, NULL, 0, NULL, NULL, NULL, provider_private,
   3961 	    0, NULL, KM_NOSLEEP);
   3962 
   3963 	DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_final: done "
   3964 	    "err = 0x0%x\n", instance, error));
   3965 
   3966 	return (error);
   3967 }
   3968 
   3969 /*
   3970  * Key management entry points.
   3971  */
   3972 
   3973 static int
   3974 dprov_key_generate(crypto_provider_handle_t provider,
   3975     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
   3976     crypto_object_attribute_t *template, uint_t attribute_count,
   3977     crypto_object_id_t *object, crypto_req_handle_t req)
   3978 {
   3979 	int error = CRYPTO_FAILED;
   3980 	dprov_state_t *softc = (dprov_state_t *)provider;
   3981 	/* LINTED E_FUNC_SET_NOT_USED */
   3982 	int instance;
   3983 
   3984 	instance = ddi_get_instance(softc->ds_dip);
   3985 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate: started\n",
   3986 	    instance));
   3987 
   3988 	/* submit request to the taskq */
   3989 	error = dprov_key_submit_req(DPROV_REQ_KEY_GENERATE, softc, req,
   3990 	    session_id, mechanism, template, attribute_count, object, NULL,
   3991 	    0, NULL, NULL, NULL, 0, NULL, 0, NULL, 0);
   3992 
   3993 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate: done err = 0x0%x\n",
   3994 	    instance, error));
   3995 
   3996 	return (error);
   3997 }
   3998 
   3999 static int
   4000 dprov_key_generate_pair(crypto_provider_handle_t provider,
   4001     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
   4002     crypto_object_attribute_t *public_key_template,
   4003     uint_t public_key_attribute_count,
   4004     crypto_object_attribute_t *private_key_template,
   4005     uint_t private_key_attribute_count,
   4006     crypto_object_id_t *public_key, crypto_object_id_t *private_key,
   4007     crypto_req_handle_t req)
   4008 {
   4009 	int error = CRYPTO_FAILED;
   4010 	dprov_state_t *softc = (dprov_state_t *)provider;
   4011 	/* LINTED E_FUNC_SET_NOT_USED */
   4012 	int instance;
   4013 
   4014 	instance = ddi_get_instance(softc->ds_dip);
   4015 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate_pair: started\n",
   4016 	    instance));
   4017 
   4018 	/* submit request to the taskq */
   4019 	error = dprov_key_submit_req(DPROV_REQ_KEY_GENERATE_PAIR, softc, req,
   4020 	    session_id, mechanism, public_key_template,
   4021 	    public_key_attribute_count, public_key, private_key_template,
   4022 	    private_key_attribute_count, private_key, NULL, NULL, 0, NULL, 0,
   4023 	    NULL, 0);
   4024 
   4025 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate_pair: done err = 0x0%x\n",
   4026 	    instance, error));
   4027 
   4028 	return (error);
   4029 }
   4030 
   4031 static int
   4032 dprov_key_wrap(crypto_provider_handle_t provider,
   4033     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
   4034     crypto_key_t *wrapping_key, crypto_object_id_t *key,
   4035     uchar_t *wrapped_key, size_t *wrapped_key_len_ptr, crypto_req_handle_t req)
   4036 {
   4037 	int error = CRYPTO_FAILED;
   4038 	dprov_state_t *softc = (dprov_state_t *)provider;
   4039 	/* LINTED E_FUNC_SET_NOT_USED */
   4040 	int instance;
   4041 
   4042 	instance = ddi_get_instance(softc->ds_dip);
   4043 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_wrap: started\n",
   4044 	    instance));
   4045 
   4046 	/* submit request to the taskq */
   4047 	error = dprov_key_submit_req(DPROV_REQ_KEY_WRAP, softc, req,
   4048 	    session_id, mechanism, NULL, 0, key, NULL,
   4049 	    0, NULL, wrapping_key, wrapped_key, wrapped_key_len_ptr,
   4050 	    NULL, 0, NULL, 0);
   4051 
   4052 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_wrap: done err = 0x0%x\n",
   4053 	    instance, error));
   4054 
   4055 	return (error);
   4056 }
   4057 
   4058 static int
   4059 dprov_key_unwrap(crypto_provider_handle_t provider,
   4060     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
   4061     crypto_key_t *unwrapping_key, uchar_t *wrapped_key,
   4062     size_t *wrapped_key_len_ptr, crypto_object_attribute_t *template,
   4063     uint_t attribute_count, crypto_object_id_t *key, crypto_req_handle_t req)
   4064 {
   4065 	int error = CRYPTO_FAILED;
   4066 	dprov_state_t *softc = (dprov_state_t *)provider;
   4067 	/* LINTED E_FUNC_SET_NOT_USED */
   4068 	int instance;
   4069 
   4070 	instance = ddi_get_instance(softc->ds_dip);
   4071 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_unwrap: started\n",
   4072 	    instance));
   4073 
   4074 	/* submit request to the taskq */
   4075 	error = dprov_key_submit_req(DPROV_REQ_KEY_UNWRAP, softc, req,
   4076 	    session_id, mechanism, template, attribute_count, key, NULL,
   4077 	    0, NULL, unwrapping_key, wrapped_key, wrapped_key_len_ptr,
   4078 	    NULL, 0, NULL, 0);
   4079 
   4080 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_unwrap: done err = 0x0%x\n",
   4081 	    instance, error));
   4082 
   4083 	return (error);
   4084 }
   4085 
   4086 static int
   4087 dprov_key_derive(crypto_provider_handle_t provider,
   4088     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
   4089     crypto_key_t *base_key, crypto_object_attribute_t *template,
   4090     uint_t attribute_count, crypto_object_id_t *key, crypto_req_handle_t req)
   4091 {
   4092 	int error = CRYPTO_FAILED;
   4093 	dprov_state_t *softc = (dprov_state_t *)provider;
   4094 	/* LINTED E_FUNC_SET_NOT_USED */
   4095 	int instance;
   4096 
   4097 	instance = ddi_get_instance(softc->ds_dip);
   4098 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_derive: started\n",
   4099 	    instance));
   4100 
   4101 	/* submit request to the taskq */
   4102 	error = dprov_key_submit_req(DPROV_REQ_KEY_DERIVE, softc, req,
   4103 	    session_id, mechanism, template, attribute_count, key, NULL,
   4104 	    0, NULL, base_key, NULL, 0, NULL, 0, NULL, 0);
   4105 
   4106 	DPROV_DEBUG(D_KEY, ("(%d) dprov_key_derive: done err = 0x0%x\n",
   4107 	    instance, error));
   4108 
   4109 	return (error);
   4110 }
   4111 
   4112 /*
   4113  * Provider management entry points.
   4114  */
   4115 
   4116 static int
   4117 dprov_ext_info(crypto_provider_handle_t provider,
   4118     crypto_provider_ext_info_t *ext_info, crypto_req_handle_t req)
   4119 {
   4120 	int error = CRYPTO_FAILED;
   4121 	dprov_state_t *softc = (dprov_state_t *)provider;
   4122 	/* LINTED E_FUNC_SET_NOT_USED */
   4123 	int instance;
   4124 
   4125 	instance = ddi_get_instance(softc->ds_dip);
   4126 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_ext_info: started\n",
   4127 	    instance));
   4128 
   4129 	error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_EXTINFO, softc, req,
   4130 	    0, NULL, 0, NULL, 0, NULL, ext_info);
   4131 
   4132 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_ext_info: done err = 0x0%x\n",
   4133 	    instance, error));
   4134 
   4135 	return (error);
   4136 }
   4137 
   4138 static int
   4139 dprov_init_token(crypto_provider_handle_t provider, char *pin, size_t pin_len,
   4140     char *label, crypto_req_handle_t req)
   4141 {
   4142 	int error = CRYPTO_FAILED;
   4143 	dprov_state_t *softc = (dprov_state_t *)provider;
   4144 	/* LINTED E_FUNC_SET_NOT_USED */
   4145 	int instance;
   4146 
   4147 	instance = ddi_get_instance(softc->ds_dip);
   4148 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_token: started\n",
   4149 	    instance));
   4150 
   4151 	error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_INITTOKEN, softc, req,
   4152 	    0, pin, pin_len, NULL, 0, label, NULL);
   4153 
   4154 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_token: done err = 0x0%x\n",
   4155 	    instance, error));
   4156 
   4157 	return (error);
   4158 }
   4159 
   4160 static int
   4161 dprov_init_pin(crypto_provider_handle_t provider,
   4162     crypto_session_id_t session_id, char *pin, size_t pin_len,
   4163     crypto_req_handle_t req)
   4164 {
   4165 	int error = CRYPTO_FAILED;
   4166 	dprov_state_t *softc = (dprov_state_t *)provider;
   4167 	/* LINTED E_FUNC_SET_NOT_USED */
   4168 	int instance;
   4169 
   4170 	instance = ddi_get_instance(softc->ds_dip);
   4171 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_pin: started\n",
   4172 	    instance));
   4173 
   4174 	error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_INITPIN, softc, req,
   4175 	    session_id, pin, pin_len, NULL, 0, NULL, NULL);
   4176 
   4177 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_pin: done err = 0x0%x\n",
   4178 	    instance, error));
   4179 
   4180 	return (error);
   4181 }
   4182 
   4183 static int
   4184 dprov_set_pin(crypto_provider_handle_t provider, crypto_session_id_t session_id,
   4185     char *old_pin, size_t old_pin_len, char *new_pin, size_t new_pin_len,
   4186     crypto_req_handle_t req)
   4187 {
   4188 	int error = CRYPTO_FAILED;
   4189 	dprov_state_t *softc = (dprov_state_t *)provider;
   4190 	/* LINTED E_FUNC_SET_NOT_USED */
   4191 	int instance;
   4192 
   4193 	instance = ddi_get_instance(softc->ds_dip);
   4194 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_set_pin: started\n",
   4195 	    instance));
   4196 
   4197 	error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_SETPIN, softc, req,
   4198 	    session_id, new_pin, new_pin_len, old_pin, old_pin_len, NULL, NULL);
   4199 
   4200 	DPROV_DEBUG(D_MGMT, ("(%d) dprov_set_pin: done err = 0x0%x\n",
   4201 	    instance, error));
   4202 
   4203 	return (error);
   4204 }
   4205 
   4206 
   4207 /*
   4208  * Context management entry points.
   4209  */
   4210 
   4211 /*
   4212  * Allocate a dprov-private context based on the specified dprov request.
   4213  * For dual cipher/mac requests, the allocated context will
   4214  * contain a structure dprov_ctx_dual_t, for other request types,
   4215  * it will contain a dprov_ctx_single.
   4216  * Returns one of the CRYPTO_ status codes.
   4217  */
   4218 static int
   4219 dprov_alloc_context(dprov_req_type_t req_type, crypto_ctx_t *spi_ctx)
   4220 {
   4221 	dprov_ctx_single_t *dprov_private;
   4222 
   4223 	switch (req_type) {
   4224 	case DPROV_REQ_ENCRYPT_MAC_INIT:
   4225 	case DPROV_REQ_MAC_DECRYPT_INIT:
   4226 		dprov_private = kmem_zalloc(sizeof (dprov_ctx_dual_t),
   4227 		    KM_NOSLEEP);
   4228 		if (dprov_private == NULL)
   4229 			return (CRYPTO_HOST_MEMORY);
   4230 		dprov_private->dc_type = DPROV_CTX_DUAL;
   4231 		break;
   4232 	default:
   4233 		dprov_private = kmem_zalloc(sizeof (dprov_ctx_single_t),
   4234 		    KM_NOSLEEP);
   4235 		if (dprov_private == NULL)
   4236 			return (CRYPTO_HOST_MEMORY);
   4237 		dprov_private->dc_type = DPROV_CTX_SINGLE;
   4238 		dprov_private->dc_svrfy_to_mac = B_FALSE;
   4239 		break;
   4240 	}
   4241 
   4242 	spi_ctx->cc_provider_private = (void *)dprov_private;
   4243 
   4244 	return (CRYPTO_SUCCESS);
   4245 }
   4246 
   4247 static int
   4248 dprov_free_context(crypto_ctx_t *ctx)
   4249 {
   4250 	if (ctx->cc_provider_private == NULL)
   4251 		return (CRYPTO_SUCCESS);
   4252 
   4253 	DPROV_DEBUG(D_CONTEXT, ("dprov_free_context\n"));
   4254 
   4255 	{
   4256 		/*
   4257 		 * The dprov private context could contain either
   4258 		 * a dprov_ctx_single_t or a dprov_ctx_dual_t. Free
   4259 		 * the context based on its type. The k-API contexts
   4260 		 * that were attached to the dprov private context
   4261 		 * are freed by the framework.
   4262 		 */
   4263 		dprov_ctx_single_t *ctx_single =
   4264 		    (dprov_ctx_single_t *)(ctx->cc_provider_private);
   4265 
   4266 		if (ctx_single->dc_type == DPROV_CTX_SINGLE) {
   4267 			crypto_context_t context = DPROV_CTX_SINGLE(ctx);
   4268 
   4269 			/*
   4270 			 * This case happens for the crypto_cancel_ctx() case.
   4271 			 * We have to cancel the SW provider context also.
   4272 			 */
   4273 			if (context != NULL)
   4274 				crypto_cancel_ctx(context);
   4275 
   4276 			kmem_free(ctx_single, sizeof (dprov_ctx_single_t));
   4277 		} else {
   4278 			crypto_context_t cipher_context =
   4279 			    DPROV_CTX_DUAL_CIPHER(ctx);
   4280 			crypto_context_t mac_context = DPROV_CTX_DUAL_MAC(ctx);
   4281 
   4282 			/* See comments above. */
   4283 			if (cipher_context != NULL)
   4284 				crypto_cancel_ctx(cipher_context);
   4285 			if (mac_context != NULL)
   4286 				crypto_cancel_ctx(mac_context);
   4287 
   4288 			ASSERT(ctx_single->dc_type == DPROV_CTX_DUAL);
   4289 			kmem_free(ctx_single, sizeof (dprov_ctx_dual_t));
   4290 		}
   4291 		ctx->cc_provider_private = NULL;
   4292 	}
   4293 
   4294 	return (CRYPTO_SUCCESS);
   4295 }
   4296 
   4297 /*
   4298  * Resource control checks don't need to be done. Why? Because this routine
   4299  * knows the size of the structure, and it can't be overridden by a user.
   4300  * This is different from the crypto module, which has no knowledge of
   4301  * specific mechanisms, and therefore has to trust specified size of the
   4302  * parameter.  This trust, or lack of trust, is why the size of the
   4303  * parameter has to be charged against the project resource control.
   4304  */
   4305 static int
   4306 copyin_aes_ccm_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
   4307     int *out_error, int mode)
   4308 {
   4309 	STRUCT_DECL(crypto_mechanism, mech);
   4310 	STRUCT_DECL(CK_AES_CCM_PARAMS, params);
   4311 	CK_AES_CCM_PARAMS *aes_ccm_params;
   4312 	caddr_t pp;
   4313 	size_t param_len;
   4314 	int error = 0;
   4315 	int rv = 0;
   4316 
   4317 	STRUCT_INIT(mech, mode);
   4318 	STRUCT_INIT(params, mode);
   4319 	bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
   4320 	pp = STRUCT_FGETP(mech, cm_param);
   4321 	param_len = STRUCT_FGET(mech, cm_param_len);
   4322 
   4323 	if (param_len != STRUCT_SIZE(params)) {
   4324 		rv = CRYPTO_ARGUMENTS_BAD;
   4325 		goto out;
   4326 	}
   4327 
   4328 	out_mech->cm_type = STRUCT_FGET(mech, cm_type);
   4329 	out_mech->cm_param = NULL;
   4330 	out_mech->cm_param_len = 0;
   4331 	if (pp != NULL) {
   4332 		size_t nonce_len, auth_data_len, total_param_len;
   4333 
   4334 		if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
   4335 			out_mech->cm_param = NULL;
   4336 			error = EFAULT;
   4337 			goto out;
   4338 		}
   4339 
   4340 		nonce_len = STRUCT_FGET(params, ulNonceSize);
   4341 		auth_data_len = STRUCT_FGET(params, ulAuthDataSize);
   4342 
   4343 		/* allocate param structure */
   4344 		total_param_len =
   4345 		    sizeof (CK_AES_CCM_PARAMS) + nonce_len + auth_data_len;
   4346 		aes_ccm_params = kmem_alloc(total_param_len, KM_NOSLEEP);
   4347 		if (aes_ccm_params == NULL) {
   4348 			rv = CRYPTO_HOST_MEMORY;
   4349 			goto out;
   4350 		}
   4351 		aes_ccm_params->ulMACSize = STRUCT_FGET(params, ulMACSize);
   4352 		aes_ccm_params->ulNonceSize = nonce_len;
   4353 		aes_ccm_params->ulAuthDataSize = auth_data_len;
   4354 		aes_ccm_params->ulDataSize
   4355 		    = STRUCT_FGET(params, ulDataSize);
   4356 		aes_ccm_params->nonce
   4357 		    = (uchar_t *)aes_ccm_params + sizeof (CK_AES_CCM_PARAMS);
   4358 		aes_ccm_params->authData
   4359 		    = aes_ccm_params->nonce + nonce_len;
   4360 
   4361 		if (copyin((char *)STRUCT_FGETP(params, nonce),
   4362 		    aes_ccm_params->nonce, nonce_len) != 0) {
   4363 			kmem_free(aes_ccm_params, total_param_len);
   4364 			out_mech->cm_param = NULL;
   4365 			error = EFAULT;
   4366 			goto out;
   4367 		}
   4368 		if (copyin((char *)STRUCT_FGETP(params, authData),
   4369 		    aes_ccm_params->authData, auth_data_len) != 0) {
   4370 			kmem_free(aes_ccm_params, total_param_len);
   4371 			out_mech->cm_param = NULL;
   4372 			error = EFAULT;
   4373 			goto out;
   4374 		}
   4375 		out_mech->cm_param = (char *)aes_ccm_params;
   4376 		out_mech->cm_param_len = sizeof (CK_AES_CCM_PARAMS);
   4377 	}
   4378 out:
   4379 	*out_error = error;
   4380 	return (rv);
   4381 }
   4382 
   4383 /*
   4384  * Resource control checks don't need to be done. Why? Because this routine
   4385  * knows the size of the structure, and it can't be overridden by a user.
   4386  * This is different from the crypto module, which has no knowledge of
   4387  * specific mechanisms, and therefore has to trust specified size of the
   4388  * parameter.  This trust, or lack of trust, is why the size of the
   4389  * parameter has to be charged against the project resource control.
   4390  */
   4391 static int
   4392 copyin_aes_gcm_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
   4393     int *out_error, int mode)
   4394 {
   4395 	STRUCT_DECL(crypto_mechanism, mech);
   4396 	STRUCT_DECL(CK_AES_GCM_PARAMS, params);
   4397 	CK_AES_GCM_PARAMS *aes_gcm_params;
   4398 	caddr_t pp;
   4399 	size_t param_len;
   4400 	int error = 0;
   4401 	int rv = 0;
   4402 
   4403 	STRUCT_INIT(mech, mode);
   4404 	STRUCT_INIT(params, mode);
   4405 	bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
   4406 	pp = STRUCT_FGETP(mech, cm_param);
   4407 	param_len = STRUCT_FGET(mech, cm_param_len);
   4408 
   4409 	if (param_len != STRUCT_SIZE(params)) {
   4410 		rv = CRYPTO_ARGUMENTS_BAD;
   4411 		goto out;
   4412 	}
   4413 
   4414 	out_mech->cm_type = STRUCT_FGET(mech, cm_type);
   4415 	out_mech->cm_param = NULL;
   4416 	out_mech->cm_param_len = 0;
   4417 	if (pp != NULL) {
   4418 		size_t nonce_len, auth_data_len, total_param_len;
   4419 
   4420 		if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
   4421 			out_mech->cm_param = NULL;
   4422 			error = EFAULT;
   4423 			goto out;
   4424 		}
   4425 
   4426 		nonce_len = STRUCT_FGET(params, ulIvLen);
   4427 		auth_data_len = STRUCT_FGET(params, ulAADLen);
   4428 
   4429 		/* allocate param structure */
   4430 		total_param_len =
   4431 		    sizeof (CK_AES_GCM_PARAMS) + nonce_len + auth_data_len;
   4432 		aes_gcm_params = kmem_alloc(total_param_len, KM_NOSLEEP);
   4433 		if (aes_gcm_params == NULL) {
   4434 			rv = CRYPTO_HOST_MEMORY;
   4435 			goto out;
   4436 		}
   4437 		aes_gcm_params->ulTagBits = STRUCT_FGET(params, ulTagBits);
   4438 		aes_gcm_params->ulIvLen = nonce_len;
   4439 		aes_gcm_params->ulAADLen = auth_data_len;
   4440 		aes_gcm_params->pIv
   4441 		    = (uchar_t *)aes_gcm_params + sizeof (CK_AES_GCM_PARAMS);
   4442 		aes_gcm_params->pAAD = aes_gcm_params->pIv + nonce_len;
   4443 
   4444 		if (copyin((char *)STRUCT_FGETP(params, pIv),
   4445 		    aes_gcm_params->pIv, nonce_len) != 0) {
   4446 			kmem_free(aes_gcm_params, total_param_len);
   4447 			out_mech->cm_param = NULL;
   4448 			error = EFAULT;
   4449 			goto out;
   4450 		}
   4451 		if (copyin((char *)STRUCT_FGETP(params, pAAD),
   4452 		    aes_gcm_params->pAAD, auth_data_len) != 0) {
   4453 			kmem_free(aes_gcm_params, total_param_len);
   4454 			out_mech->cm_param = NULL;
   4455 			error = EFAULT;
   4456 			goto out;
   4457 		}
   4458 		out_mech->cm_param = (char *)aes_gcm_params;
   4459 		out_mech->cm_param_len = sizeof (CK_AES_GCM_PARAMS);
   4460 	}
   4461 out:
   4462 	*out_error = error;
   4463 	return (rv);
   4464 }
   4465 
   4466 static int
   4467 copyin_aes_gmac_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
   4468     int *out_error, int mode)
   4469 {
   4470 	STRUCT_DECL(crypto_mechanism, mech);
   4471 	STRUCT_DECL(CK_AES_GMAC_PARAMS, params);
   4472 	CK_AES_GMAC_PARAMS *aes_gmac_params;
   4473 	caddr_t pp;
   4474 	size_t param_len;
   4475 	int error = 0;
   4476 	int rv = 0;
   4477 
   4478 	STRUCT_INIT(mech, mode);
   4479 	STRUCT_INIT(params, mode);
   4480 	bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
   4481 	pp = STRUCT_FGETP(mech, cm_param);
   4482 	param_len = STRUCT_FGET(mech, cm_param_len);
   4483 
   4484 	if (param_len != STRUCT_SIZE(params)) {
   4485 		rv = CRYPTO_ARGUMENTS_BAD;
   4486 		goto out;
   4487 	}
   4488 
   4489 	out_mech->cm_type = STRUCT_FGET(mech, cm_type);
   4490 	out_mech->cm_param = NULL;
   4491 	out_mech->cm_param_len = 0;
   4492 	if (pp != NULL) {
   4493 		size_t auth_data_len, total_param_len;
   4494 
   4495 		if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
   4496 			out_mech->cm_param = NULL;
   4497 			error = EFAULT;
   4498 			goto out;
   4499 		}
   4500 
   4501 		auth_data_len = STRUCT_FGET(params, ulAADLen);
   4502 
   4503 		/* allocate param structure */
   4504 		total_param_len = sizeof (CK_AES_GMAC_PARAMS) +
   4505 		    AES_GMAC_IV_LEN + auth_data_len;
   4506 		aes_gmac_params = kmem_alloc(total_param_len, KM_NOSLEEP);
   4507 		if (aes_gmac_params == NULL) {
   4508 			rv = CRYPTO_HOST_MEMORY;
   4509 			goto out;
   4510 		}
   4511 		aes_gmac_params->ulAADLen = auth_data_len;
   4512 		aes_gmac_params->pIv
   4513 		    = (uchar_t *)aes_gmac_params + sizeof (CK_AES_GMAC_PARAMS);
   4514 		aes_gmac_params->pAAD = aes_gmac_params->pIv + AES_GMAC_IV_LEN;
   4515 
   4516 		if (copyin((char *)STRUCT_FGETP(params, pIv),
   4517 		    aes_gmac_params->pIv, AES_GMAC_IV_LEN) != 0) {
   4518 			kmem_free(aes_gmac_params, total_param_len);
   4519 			out_mech->cm_param = NULL;
   4520 			error = EFAULT;
   4521 			goto out;
   4522 		}
   4523 		if (copyin((char *)STRUCT_FGETP(params, pAAD),
   4524 		    aes_gmac_params->pAAD, auth_data_len) != 0) {
   4525 			kmem_free(aes_gmac_params, total_param_len);
   4526 			out_mech->cm_param = NULL;
   4527 			error = EFAULT;
   4528 			goto out;
   4529 		}
   4530 		out_mech->cm_param = (char *)aes_gmac_params;
   4531 		out_mech->cm_param_len = sizeof (CK_AES_GMAC_PARAMS);
   4532 	}
   4533 out:
   4534 	*out_error = error;
   4535 	return (rv);
   4536 }
   4537 
   4538 /*
   4539  * Resource control checks don't need to be done. Why? Because this routine
   4540  * knows the size of the structure, and it can't be overridden by a user.
   4541  * This is different from the crypto module, which has no knowledge of
   4542  * specific mechanisms, and therefore has to trust specified size of the
   4543  * parameter.  This trust, or lack of trust, is why the size of the
   4544  * parameter has to be charged against the project resource control.
   4545  */
   4546 static int
   4547 copyin_aes_ctr_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
   4548     int *out_error, int mode)
   4549 {
   4550 	STRUCT_DECL(crypto_mechanism, mech);
   4551 	STRUCT_DECL(CK_AES_CTR_PARAMS, params);
   4552 	CK_AES_CTR_PARAMS *aes_ctr_params;
   4553 	caddr_t pp;
   4554 	size_t param_len;
   4555 	int error = 0;
   4556 	int rv = 0;
   4557 
   4558 	STRUCT_INIT(mech, mode);
   4559 	STRUCT_INIT(params, mode);
   4560 	bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
   4561 	pp = STRUCT_FGETP(mech, cm_param);
   4562 	param_len = STRUCT_FGET(mech, cm_param_len);
   4563 
   4564 	if (param_len != STRUCT_SIZE(params)) {
   4565 		rv = CRYPTO_ARGUMENTS_BAD;
   4566 		goto out;
   4567 	}
   4568 
   4569 	out_mech->cm_type = STRUCT_FGET(mech, cm_type);
   4570 	out_mech->cm_param = NULL;
   4571 	out_mech->cm_param_len = 0;
   4572 	if (pp != NULL) {
   4573 		if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
   4574 			out_mech->cm_param = NULL;
   4575 			error = EFAULT;
   4576 			goto out;
   4577 		}
   4578 		/* allocate param structure and counter block */
   4579 		aes_ctr_params = kmem_alloc(sizeof (CK_AES_CTR_PARAMS),
   4580 		    KM_NOSLEEP);
   4581 		if (aes_ctr_params == NULL) {
   4582 			rv = CRYPTO_HOST_MEMORY;
   4583 			goto out;
   4584 		}
   4585 		aes_ctr_params->ulCounterBits = STRUCT_FGET(params,
   4586 		    ulCounterBits);
   4587 		bcopy(STRUCT_FGETP(params, cb), aes_ctr_params->cb, 16);
   4588 		out_mech->cm_param = (char *)aes_ctr_params;
   4589 		out_mech->cm_param_len = sizeof (CK_AES_CTR_PARAMS);
   4590 	}
   4591 out:
   4592 	*out_error = error;
   4593 	return (rv);
   4594 }
   4595 
   4596 static int
   4597 copyin_ecc_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
   4598     int *out_error, int mode)
   4599 {
   4600 	STRUCT_DECL(crypto_mechanism, mech);
   4601 	STRUCT_DECL(CK_ECDH1_DERIVE_PARAMS, params);
   4602 	CK_ECDH1_DERIVE_PARAMS *ecc_params;
   4603 	caddr_t pp;
   4604 	size_t param_len, shared_data_len, public_data_len;
   4605 	int error = 0;
   4606 	int rv = 0;
   4607 
   4608 	STRUCT_INIT(mech, mode);
   4609 	STRUCT_INIT(params, mode);
   4610 	bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
   4611 	pp = STRUCT_FGETP(mech, cm_param);
   4612 	param_len = STRUCT_FGET(mech, cm_param_len);
   4613 
   4614 	if (param_len != STRUCT_SIZE(params)) {
   4615 		rv = CRYPTO_ARGUMENTS_BAD;
   4616 		goto out;
   4617 	}
   4618 
   4619 	out_mech->cm_type = STRUCT_FGET(mech, cm_type);
   4620 	out_mech->cm_param = NULL;
   4621 	out_mech->cm_param_len = 0;
   4622 	if (pp != NULL) {
   4623 		if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
   4624 			out_mech->cm_param = NULL;
   4625 			error = EFAULT;
   4626 			goto out;
   4627 		}
   4628 		shared_data_len = STRUCT_FGET(params, ulSharedDataLen);
   4629 		public_data_len = STRUCT_FGET(params, ulPublicDataLen);
   4630 		/* allocate param structure and buffers */
   4631 		ecc_params = kmem_alloc(sizeof (CK_ECDH1_DERIVE_PARAMS) +
   4632 		    roundup(shared_data_len, sizeof (caddr_t)) +
   4633 		    roundup(public_data_len, sizeof (caddr_t)), KM_NOSLEEP);
   4634 		if (ecc_params == NULL) {
   4635 			rv = CRYPTO_HOST_MEMORY;
   4636 			goto out;
   4637 		}
   4638 		ecc_params->pSharedData = (uchar_t *)ecc_params +
   4639 		    sizeof (CK_ECDH1_DERIVE_PARAMS);
   4640 		ecc_params->pPublicData = (uchar_t *)ecc_params->pSharedData +
   4641 		    roundup(shared_data_len, sizeof (caddr_t));
   4642 		if (copyin((char *)STRUCT_FGETP(params, pSharedData),
   4643 		    ecc_params->pSharedData, shared_data_len) != 0) {
   4644 			kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) +
   4645 			    roundup(shared_data_len, sizeof (caddr_t)) +
   4646 			    roundup(public_data_len, sizeof (caddr_t)));
   4647 			out_mech->cm_param = NULL;
   4648 			error = EFAULT;
   4649 			goto out;
   4650 		}
   4651 		ecc_params->ulSharedDataLen = shared_data_len;
   4652 
   4653 		if (copyin((char *)STRUCT_FGETP(params, pPublicData),
   4654 		    ecc_params->pPublicData, public_data_len) != 0) {
   4655 			kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) +
   4656 			    roundup(shared_data_len, sizeof (caddr_t)) +
   4657 			    roundup(public_data_len, sizeof (caddr_t)));
   4658 			out_mech->cm_param = NULL;
   4659 			error = EFAULT;
   4660 			goto out;
   4661 		}
   4662 		ecc_params->ulPublicDataLen = public_data_len;
   4663 		ecc_params->kdf = STRUCT_FGET(params, kdf);
   4664 		out_mech->cm_param = (char *)ecc_params;
   4665 		out_mech->cm_param_len = sizeof (CK_ECDH1_DERIVE_PARAMS);
   4666 	}
   4667 out:
   4668 	*out_error = error;
   4669 	return (rv);
   4670 }
   4671 
   4672 /* ARGSUSED */
   4673 static int
   4674 copyout_aes_ctr_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
   4675     int *out_error, int mode)
   4676 {
   4677 	STRUCT_DECL(crypto_mechanism, mech);
   4678 	STRUCT_DECL(CK_AES_CTR_PARAMS, params);
   4679 	caddr_t pp;
   4680 	size_t param_len;
   4681 	int error = 0;
   4682 	int rv = 0;
   4683 
   4684 	STRUCT_INIT(mech, mode);
   4685 	STRUCT_INIT(params, mode);
   4686 	bcopy(out_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
   4687 	pp = STRUCT_FGETP(mech, cm_param);
   4688 	param_len = STRUCT_FGET(mech, cm_param_len);
   4689 	if (param_len != STRUCT_SIZE(params)) {
   4690 		rv = CRYPTO_ARGUMENTS_BAD;
   4691 		goto out;
   4692 	}
   4693 
   4694 	if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
   4695 		error = EFAULT;
   4696 		goto out;
   4697 	}
   4698 
   4699 	/* for testing, overwrite the iv with 16 X 'A' */
   4700 	(void) memset(STRUCT_FGETP(params, cb), 'A', 16);
   4701 	if (copyout((char *)pp, STRUCT_BUF(params),  param_len) != 0) {
   4702 		error = EFAULT;
   4703 		goto out;
   4704 	}
   4705 out:
   4706 	*out_error = error;
   4707 	return (rv);
   4708 }
   4709 
   4710 /* ARGSUSED */
   4711 static int
   4712 dprov_copyin_mechanism(crypto_provider_handle_t provider,
   4713     crypto_mechanism_t *umech, crypto_mechanism_t *kmech,
   4714     int *out_error, int mode)
   4715 {
   4716 	STRUCT_DECL(crypto_mechanism, mech);
   4717 	size_t param_len, expected_param_len;
   4718 	caddr_t pp;
   4719 	char *param;
   4720 	int rv;
   4721 	int error = 0;
   4722 
   4723 	ASSERT(!servicing_interrupt());
   4724 
   4725 	STRUCT_INIT(mech, mode);
   4726 	bcopy(umech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
   4727 	pp = STRUCT_FGETP(mech, cm_param);
   4728 	param_len = STRUCT_FGET(mech, cm_param_len);
   4729 
   4730 	kmech->cm_param = NULL;
   4731 	kmech->cm_param_len = 0;
   4732 
   4733 	switch (kmech->cm_type) {
   4734 	case DES_CBC_MECH_INFO_TYPE:
   4735 	case DES3_CBC_MECH_INFO_TYPE:
   4736 		expected_param_len = DES_BLOCK_LEN;
   4737 		break;
   4738 
   4739 	case BLOWFISH_CBC_MECH_INFO_TYPE:
   4740 		expected_param_len = BLOWFISH_BLOCK_LEN;
   4741 		break;
   4742 
   4743 	case AES_CBC_MECH_INFO_TYPE:
   4744 		expected_param_len = AES_BLOCK_LEN;
   4745 		break;
   4746 
   4747 	case AES_CTR_MECH_INFO_TYPE:
   4748 	case SHA1_KEY_DERIVATION_MECH_INFO_TYPE:	/* for testing only */
   4749 		rv = copyin_aes_ctr_mech(umech, kmech, &error, mode);
   4750 		goto out;
   4751 
   4752 	case ECDH1_DERIVE_MECH_INFO_TYPE:
   4753 		rv = copyin_ecc_mech(umech, kmech, &error, mode);
   4754 		goto out;
   4755 
   4756 	case AES_CCM_MECH_INFO_TYPE:
   4757 		rv = copyin_aes_ccm_mech(umech, kmech, &error, mode);
   4758 		goto out;
   4759 
   4760 	case AES_GCM_MECH_INFO_TYPE:
   4761 		rv = copyin_aes_gcm_mech(umech, kmech, &error, mode);
   4762 		goto out;
   4763 
   4764 	case AES_GMAC_MECH_INFO_TYPE:
   4765 		rv = copyin_aes_gmac_mech(umech, kmech, &error, mode);
   4766 		goto out;
   4767 
   4768 	case DH_PKCS_DERIVE_MECH_INFO_TYPE:
   4769 		expected_param_len = param_len;
   4770 		break;
   4771 
   4772 	default:
   4773 		/* nothing to do - mechanism has no parameters */
   4774 		rv = CRYPTO_SUCCESS;
   4775 		goto out;
   4776 	}
   4777 
   4778 	if (param_len != expected_param_len) {
   4779 		rv = CRYPTO_MECHANISM_PARAM_INVALID;
   4780 		goto out;
   4781 	}
   4782 	if (pp == NULL) {
   4783 		rv = CRYPTO_MECHANISM_PARAM_INVALID;
   4784 		goto out;
   4785 	}
   4786 	if ((param = kmem_alloc(param_len, KM_NOSLEEP)) == NULL) {
   4787 		rv = CRYPTO_HOST_MEMORY;
   4788 		goto out;
   4789 	}
   4790 	if (copyin((char *)pp, param, param_len) != 0) {
   4791 		kmem_free(param, param_len);
   4792 		error = EFAULT;
   4793 		rv = CRYPTO_FAILED;
   4794 		goto out;
   4795 	}
   4796 	kmech->cm_param = (char *)param;
   4797 	kmech->cm_param_len = param_len;
   4798 	rv = CRYPTO_SUCCESS;
   4799 out:
   4800 	*out_error = error;
   4801 	return (rv);
   4802 }
   4803 
   4804 /* ARGSUSED */
   4805 static int
   4806 dprov_copyout_mechanism(crypto_provider_handle_t provider,
   4807     crypto_mechanism_t *kmech, crypto_mechanism_t *umech,
   4808     int *out_error, int mode)
   4809 {
   4810 	ASSERT(!servicing_interrupt());
   4811 
   4812 	switch (kmech->cm_type) {
   4813 	case AES_CTR_MECH_INFO_TYPE:
   4814 	case SHA1_KEY_DERIVATION_MECH_INFO_TYPE:	/* for testing only */
   4815 		return (copyout_aes_ctr_mech(kmech, umech, out_error, mode));
   4816 	case ECDH1_DERIVE_MECH_INFO_TYPE:
   4817 		return (CRYPTO_SUCCESS);
   4818 	default:
   4819 		return (CRYPTO_MECHANISM_INVALID);
   4820 	}
   4821 }
   4822 
   4823 /*
   4824  * Free mechanism parameter that was allocated by the provider.
   4825  */
   4826 /* ARGSUSED */
   4827 static int
   4828 dprov_free_mechanism(crypto_provider_handle_t provider,
   4829     crypto_mechanism_t *mech)
   4830 {
   4831 	size_t len;
   4832 
   4833 	if (mech->cm_param == NULL || mech->cm_param_len == 0)
   4834 		return (CRYPTO_SUCCESS);
   4835 
   4836 	switch (mech->cm_type) {
   4837 	case AES_CTR_MECH_INFO_TYPE:
   4838 	case SHA1_KEY_DERIVATION_MECH_INFO_TYPE:
   4839 		len = sizeof (CK_AES_CTR_PARAMS);
   4840 		break;
   4841 	case ECDH1_DERIVE_MECH_INFO_TYPE: {
   4842 		CK_ECDH1_DERIVE_PARAMS *ecc_params;
   4843 
   4844 		/* LINTED: pointer alignment */
   4845 		ecc_params = (CK_ECDH1_DERIVE_PARAMS *)mech->cm_param;
   4846 		kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) +
   4847 		    roundup(ecc_params->ulSharedDataLen, sizeof (caddr_t)) +
   4848 		    roundup(ecc_params->ulPublicDataLen, sizeof (caddr_t)));
   4849 		return (CRYPTO_SUCCESS);
   4850 	}
   4851 	case AES_CCM_MECH_INFO_TYPE: {
   4852 		CK_AES_CCM_PARAMS *params;
   4853 		size_t total_param_len;
   4854 
   4855 		if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) {
   4856 			/* LINTED: pointer alignment */
   4857 			params = (CK_AES_CCM_PARAMS *)mech->cm_param;
   4858 			total_param_len = mech->cm_param_len +
   4859 			    params->ulNonceSize + params->ulAuthDataSize;
   4860 			kmem_free(params, total_param_len);
   4861 			mech->cm_param = NULL;
   4862 			mech->cm_param_len = 0;
   4863 		}
   4864 		return (CRYPTO_SUCCESS);
   4865 	}
   4866 	case AES_GMAC_MECH_INFO_TYPE: {
   4867 		CK_AES_GMAC_PARAMS *params;
   4868 		size_t total_param_len;
   4869 
   4870 		if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) {
   4871 			/* LINTED: pointer alignment */
   4872 			params = (CK_AES_GMAC_PARAMS *)mech->cm_param;
   4873 			total_param_len = mech->cm_param_len +
   4874 			    AES_GMAC_IV_LEN + params->ulAADLen;
   4875 			kmem_free(params, total_param_len);
   4876 			mech->cm_param = NULL;
   4877 			mech->cm_param_len = 0;
   4878 		}
   4879 		return (CRYPTO_SUCCESS);
   4880 	}
   4881 	case AES_GCM_MECH_INFO_TYPE: {
   4882 		CK_AES_GCM_PARAMS *params;
   4883 		size_t total_param_len;
   4884 
   4885 		if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) {
   4886 			/* LINTED: pointer alignment */
   4887 			params = (CK_AES_GCM_PARAMS *)mech->cm_param;
   4888 			total_param_len = mech->cm_param_len +
   4889 			    params->ulIvLen + params->ulAADLen;
   4890 			kmem_free(params, total_param_len);
   4891 			mech->cm_param = NULL;
   4892 			mech->cm_param_len = 0;
   4893 		}
   4894 		return (CRYPTO_SUCCESS);
   4895 	}
   4896 
   4897 	default:
   4898 		len = mech->cm_param_len;
   4899 	}
   4900 	kmem_free(mech->cm_param, len);
   4901 	return (CRYPTO_SUCCESS);
   4902 }
   4903 
   4904 /*
   4905  * No (Key)Store Key management entry point.
   4906  */
   4907 static int
   4908 dprov_nostore_key_generate(crypto_provider_handle_t provider,
   4909     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
   4910     crypto_object_attribute_t *template, uint_t attribute_count,
   4911     crypto_object_attribute_t *out_template, uint_t out_attribute_count,
   4912     crypto_req_handle_t req)
   4913 {
   4914 	int error = CRYPTO_FAILED;
   4915 	dprov_state_t *softc = (dprov_state_t *)provider;
   4916 	/* LINTED E_FUNC_SET_NOT_USED */
   4917 	int instance;
   4918 
   4919 	instance = ddi_get_instance(softc->ds_dip);
   4920 	DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate: started\n",
   4921 	    instance));
   4922 
   4923 	/* submit request to the taskq */
   4924 	error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_GENERATE,
   4925 	    softc, req, session_id, mechanism, template, attribute_count,
   4926 	    NULL, NULL, 0, NULL, NULL, NULL, 0, out_template,
   4927 	    out_attribute_count, NULL, 0);
   4928 
   4929 	DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate: "
   4930 	    "done err = 0x0%x\n", instance, error));
   4931 
   4932 	return (error);
   4933 }
   4934 
   4935 static int
   4936 dprov_nostore_key_generate_pair(crypto_provider_handle_t provider,
   4937     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
   4938     crypto_object_attribute_t *public_key_template,
   4939     uint_t public_key_attribute_count,
   4940     crypto_object_attribute_t *private_key_template,
   4941     uint_t private_key_attribute_count,
   4942     crypto_object_attribute_t *out_public_key_template,
   4943     uint_t out_public_key_attribute_count,
   4944     crypto_object_attribute_t *out_private_key_template,
   4945     uint_t out_private_key_attribute_count,
   4946     crypto_req_handle_t req)
   4947 {
   4948 	int error = CRYPTO_FAILED;
   4949 	dprov_state_t *softc = (dprov_state_t *)provider;
   4950 	/* LINTED E_FUNC_SET_NOT_USED */
   4951 	int instance;
   4952 
   4953 	instance = ddi_get_instance(softc->ds_dip);
   4954 	DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate_pair: started\n",
   4955 	    instance));
   4956 
   4957 	/* submit request to the taskq */
   4958 	error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR,
   4959 	    softc, req, session_id, mechanism, public_key_template,
   4960 	    public_key_attribute_count, NULL, private_key_template,
   4961 	    private_key_attribute_count, NULL, NULL, NULL, 0,
   4962 	    out_public_key_template, out_public_key_attribute_count,
   4963 	    out_private_key_template, out_private_key_attribute_count);
   4964 
   4965 	DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate_pair: "
   4966 	    "done err = 0x0%x\n", instance, error));
   4967 
   4968 	return (error);
   4969 }
   4970 
   4971 static int
   4972 dprov_nostore_key_derive(crypto_provider_handle_t provider,
   4973     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
   4974     crypto_key_t *base_key, crypto_object_attribute_t *template,
   4975     uint_t attribute_count, crypto_object_attribute_t *out_template,
   4976     uint_t out_attribute_count, crypto_req_handle_t req)
   4977 {
   4978 	int error = CRYPTO_FAILED;
   4979 	dprov_state_t *softc = (dprov_state_t *)provider;
   4980 	/* LINTED E_FUNC_SET_NOT_USED */
   4981 	int instance;
   4982 
   4983 	instance = ddi_get_instance(softc->ds_dip);
   4984 	DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_derive: started\n",
   4985 	    instance));
   4986 
   4987 	/* submit request to the taskq */
   4988 	error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_DERIVE, softc, req,
   4989 	    session_id, mechanism, template, attribute_count, NULL, NULL,
   4990 	    0, NULL, base_key, NULL, 0, out_template, out_attribute_count,
   4991 	    NULL, 0);
   4992 
   4993 	DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_derive: "
   4994 	    "done err = 0x0%x\n", instance, error));
   4995 
   4996 	return (error);
   4997 }
   4998 
   4999 /*
   5000  * Allocate a dprov taskq request and initialize the common fields.
   5001  * Return NULL if the memory allocation failed.
   5002  */
   5003 static dprov_req_t *
   5004 dprov_alloc_req(dprov_req_type_t req_type, dprov_state_t *softc,
   5005     crypto_req_handle_t kcf_req, int kmflag)
   5006 {
   5007 	dprov_req_t *taskq_req;
   5008 
   5009 	if ((taskq_req = kmem_alloc(sizeof (dprov_req_t), kmflag)) == NULL)
   5010 		return (NULL);
   5011 
   5012 	taskq_req->dr_type = req_type;
   5013 	taskq_req->dr_softc = softc;
   5014 	taskq_req->dr_kcf_req = kcf_req;
   5015 
   5016 	return (taskq_req);
   5017 }
   5018 
   5019 /*
   5020  * Dispatch a dprov request on the taskq associated with a softc.
   5021  * Returns CRYPTO_HOST_MEMORY if the request cannot be queued,
   5022  * CRYPTO_QUEUED on success.
   5023  */
   5024 static int
   5025 dprov_taskq_dispatch(dprov_state_t *softc, dprov_req_t *taskq_req,
   5026     task_func_t *func, int kmflag)
   5027 {
   5028 	if (taskq_dispatch(softc->ds_taskq, func, taskq_req,
   5029 	    kmflag == KM_NOSLEEP ? TQ_NOSLEEP : TQ_SLEEP) == (taskqid_t)0) {
   5030 		kmem_free(taskq_req, sizeof (dprov_req_t));
   5031 		return (CRYPTO_HOST_MEMORY);
   5032 	} else
   5033 		return (CRYPTO_QUEUED);
   5034 }
   5035 
   5036 /*
   5037  * Helper function to submit digest operations to the taskq.
   5038  * Returns one of the CRYPTO_ errors.
   5039  */
   5040 static int
   5041 dprov_digest_submit_req(dprov_req_type_t req_type,
   5042     dprov_state_t *softc, crypto_req_handle_t req,
   5043     crypto_mechanism_t *mechanism, crypto_data_t *data, crypto_key_t *key,
   5044     crypto_data_t *digest, crypto_ctx_t *ctx, int kmflag)
   5045 {
   5046 	dprov_req_t *taskq_req;
   5047 
   5048 	if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
   5049 		return (CRYPTO_HOST_MEMORY);
   5050 
   5051 	taskq_req->dr_digest_req.dr_mechanism = mechanism;
   5052 	taskq_req->dr_digest_req.dr_ctx = ctx;
   5053 	taskq_req->dr_digest_req.dr_data = data;
   5054 	taskq_req->dr_digest_req.dr_key = key;
   5055 	taskq_req->dr_digest_req.dr_digest = digest;
   5056 
   5057 	return (dprov_taskq_dispatch(softc, taskq_req,
   5058 	    (task_func_t *)dprov_digest_task, kmflag));
   5059 }
   5060 
   5061 /*
   5062  * Helper function to submit mac operations to the taskq.
   5063  * Returns one of the CRYPTO_ errors.
   5064  */
   5065 static int
   5066 dprov_mac_submit_req(dprov_req_type_t req_type,
   5067     dprov_state_t *softc, crypto_req_handle_t req,
   5068     crypto_mechanism_t *mechanism, crypto_data_t *data, crypto_key_t *key,
   5069     crypto_data_t *mac, crypto_ctx_t *ctx, crypto_session_id_t sid, int kmflag)
   5070 {
   5071 	dprov_req_t *taskq_req;
   5072 
   5073 	if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
   5074 		return (CRYPTO_HOST_MEMORY);
   5075 
   5076 	taskq_req->dr_mac_req.dr_mechanism = mechanism;
   5077 	taskq_req->dr_mac_req.dr_ctx = ctx;
   5078 	taskq_req->dr_mac_req.dr_data = data;
   5079 	taskq_req->dr_mac_req.dr_key = key;
   5080 	taskq_req->dr_mac_req.dr_mac = mac;
   5081 	taskq_req->dr_mac_req.dr_session_id = sid;
   5082 
   5083 	return (dprov_taskq_dispatch(softc, taskq_req,
   5084 	    (task_func_t *)dprov_mac_task, kmflag));
   5085 }
   5086 
   5087 /*
   5088  * Helper function to submit sign operations to the taskq.
   5089  * Returns one of the CRYPTO_ errors.
   5090  */
   5091 static int
   5092 dprov_sign_submit_req(dprov_req_type_t req_type,
   5093     dprov_state_t *softc, crypto_req_handle_t req,
   5094     crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data,
   5095     crypto_data_t *signature, crypto_ctx_t *ctx, crypto_session_id_t sid,
   5096     int kmflag)
   5097 {
   5098 	dprov_req_t *taskq_req;
   5099 
   5100 	if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
   5101 		return (CRYPTO_HOST_MEMORY);
   5102 
   5103 	taskq_req->dr_sign_req.sr_mechanism = mechanism;
   5104 	taskq_req->dr_sign_req.sr_ctx = ctx;
   5105 	taskq_req->dr_sign_req.sr_key = key;
   5106 	taskq_req->dr_sign_req.sr_data = data;
   5107 	taskq_req->dr_sign_req.sr_signature = signature;
   5108 	taskq_req->dr_sign_req.sr_session_id = sid;
   5109 
   5110 	return (dprov_taskq_dispatch(softc, taskq_req,
   5111 	    (task_func_t *)dprov_sign_task, kmflag));
   5112 }
   5113 
   5114 /*
   5115  * Helper function to submit verify operations to the taskq.
   5116  * Returns one of the CRYPTO_ errors.
   5117  */
   5118 static int
   5119 dprov_verify_submit_req(dprov_req_type_t req_type,
   5120     dprov_state_t *softc, crypto_req_handle_t req,
   5121     crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data,
   5122     crypto_data_t *signature, crypto_ctx_t *ctx, crypto_session_id_t sid,
   5123     int kmflag)
   5124 {
   5125 	dprov_req_t *taskq_req;
   5126 
   5127 	if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
   5128 		return (CRYPTO_HOST_MEMORY);
   5129 
   5130 	taskq_req->dr_verify_req.vr_mechanism = mechanism;
   5131 	taskq_req->dr_verify_req.vr_ctx = ctx;
   5132 	taskq_req->dr_verify_req.vr_key = key;
   5133 	taskq_req->dr_verify_req.vr_data = data;
   5134 	taskq_req->dr_verify_req.vr_signature = signature;
   5135 	taskq_req->dr_verify_req.vr_session_id = sid;
   5136 
   5137 	return (dprov_taskq_dispatch(softc, taskq_req,
   5138 	    (task_func_t *)dprov_verify_task, kmflag));
   5139 }
   5140 
   5141 /*
   5142  * Helper function to submit dual operations to the taskq.
   5143  * Returns one of the CRYPTO_ errors.
   5144  */
   5145 static int
   5146 dprov_dual_submit_req(dprov_req_type_t req_type, dprov_state_t *softc,
   5147     crypto_req_handle_t req, crypto_ctx_t *signverify_ctx,
   5148     crypto_ctx_t *cipher_ctx, crypto_data_t *plaintext,
   5149     crypto_data_t *ciphertext)
   5150 {
   5151 	dprov_req_t *taskq_req;
   5152 
   5153 	if ((taskq_req = dprov_alloc_req(req_type, softc, req,
   5154 	    KM_NOSLEEP)) == NULL)
   5155 		return (CRYPTO_HOST_MEMORY);
   5156 
   5157 	taskq_req->dr_dual_req.dr_signverify_ctx = signverify_ctx;
   5158 	taskq_req->dr_dual_req.dr_cipher_ctx = cipher_ctx;
   5159 	taskq_req->dr_dual_req.dr_plaintext = plaintext;
   5160 	taskq_req->dr_dual_req.dr_ciphertext = ciphertext;
   5161 
   5162 	return (dprov_taskq_dispatch(softc, taskq_req,
   5163 	    (task_func_t *)dprov_dual_task, KM_NOSLEEP));
   5164 }
   5165 
   5166 /*
   5167  * Helper function to submit dual cipher/mac operations to the taskq.
   5168  * Returns one of the CRYPTO_ errors.
   5169  */
   5170 static int
   5171 dprov_cipher_mac_submit_req(dprov_req_type_t req_type,
   5172     dprov_state_t *softc, crypto_req_handle_t req, crypto_ctx_t *ctx,
   5173     crypto_session_id_t sid, crypto_mechanism_t *cipher_mech,
   5174     crypto_key_t *cipher_key, crypto_mechanism_t *mac_mech,
   5175     crypto_key_t *mac_key, crypto_dual_data_t *dual_data,
   5176     crypto_data_t *data, crypto_data_t *mac, int kmflag)
   5177 {
   5178 	dprov_req_t *taskq_req;
   5179 
   5180 	if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
   5181 		return (CRYPTO_HOST_MEMORY);
   5182 
   5183 	taskq_req->dr_cipher_mac_req.mr_session_id = sid;
   5184 	taskq_req->dr_cipher_mac_req.mr_ctx = ctx;
   5185 	taskq_req->dr_cipher_mac_req.mr_cipher_mech = cipher_mech;
   5186 	taskq_req->dr_cipher_mac_req.mr_cipher_key = cipher_key;
   5187 	taskq_req->dr_cipher_mac_req.mr_mac_mech = mac_mech;
   5188 	taskq_req->dr_cipher_mac_req.mr_mac_key = mac_key;
   5189 	taskq_req->dr_cipher_mac_req.mr_dual_data = dual_data;
   5190 	taskq_req->dr_cipher_mac_req.mr_data = data;
   5191 	taskq_req->dr_cipher_mac_req.mr_mac = mac;
   5192 
   5193 	return (dprov_taskq_dispatch(softc, taskq_req,
   5194 	    (task_func_t *)dprov_cipher_mac_task, kmflag));
   5195 }
   5196 
   5197 /*
   5198  * Helper function to submit cipher operations to the taskq.
   5199  * Returns one of the CRYPTO_ errors.
   5200  */
   5201 static int
   5202 dprov_cipher_submit_req(dprov_req_type_t req_type,
   5203     dprov_state_t *softc, crypto_req_handle_t req,
   5204     crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *plaintext,
   5205     crypto_data_t *ciphertext, crypto_ctx_t *ctx, crypto_session_id_t sid,
   5206     int kmflag)
   5207 {
   5208 	dprov_req_t *taskq_req;
   5209 
   5210 	if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
   5211 		return (CRYPTO_HOST_MEMORY);
   5212 
   5213 	taskq_req->dr_cipher_req.dr_mechanism = mechanism;
   5214 	taskq_req->dr_cipher_req.dr_ctx = ctx;
   5215 	taskq_req->dr_cipher_req.dr_key = key;
   5216 	taskq_req->dr_cipher_req.dr_plaintext = plaintext;
   5217 	taskq_req->dr_cipher_req.dr_ciphertext = ciphertext;
   5218 	taskq_req->dr_cipher_req.dr_session_id = sid;
   5219 
   5220 	return (dprov_taskq_dispatch(softc, taskq_req,
   5221 	    (task_func_t *)dprov_cipher_task, kmflag));
   5222 }
   5223 
   5224 /*
   5225  * Helper function to submit random number operations to the taskq.
   5226  * Returns one of the CRYPTO_ errors.
   5227  */
   5228 static int
   5229 dprov_random_submit_req(dprov_req_type_t req_type,
   5230     dprov_state_t *softc, crypto_req_handle_t req, uchar_t *buf, size_t len,
   5231     crypto_session_id_t sid, uint_t entropy_est, uint32_t flags)
   5232 {
   5233 	dprov_req_t *taskq_req;
   5234 
   5235 	if ((taskq_req = dprov_alloc_req(req_type, softc, req,
   5236 	    KM_NOSLEEP)) == NULL)
   5237 		return (CRYPTO_HOST_MEMORY);
   5238 
   5239 	taskq_req->dr_random_req.rr_buf = buf;
   5240 	taskq_req->dr_random_req.rr_len = len;
   5241 	taskq_req->dr_random_req.rr_session_id = sid;
   5242 	taskq_req->dr_random_req.rr_entropy_est = entropy_est;
   5243 	taskq_req->dr_random_req.rr_flags = flags;
   5244 
   5245 	return (dprov_taskq_dispatch(softc, taskq_req,
   5246 	    (task_func_t *)dprov_random_task, KM_NOSLEEP));
   5247 }
   5248 
   5249 
   5250 /*
   5251  * Helper function to submit session management operations to the taskq.
   5252  * Returns one of the CRYPTO_ errors.
   5253  */
   5254 static int
   5255 dprov_session_submit_req(dprov_req_type_t req_type,
   5256     dprov_state_t *softc, crypto_req_handle_t req,
   5257     crypto_session_id_t *session_id_ptr, crypto_session_id_t session_id,
   5258     crypto_user_type_t user_type, char *pin, size_t pin_len)
   5259 {
   5260 	dprov_req_t *taskq_req;
   5261 
   5262 	if ((taskq_req = dprov_alloc_req(req_type, softc, req,
   5263 	    KM_NOSLEEP)) == NULL)
   5264 		return (CRYPTO_HOST_MEMORY);
   5265 
   5266 	taskq_req->dr_session_req.sr_session_id_ptr = session_id_ptr;
   5267 	taskq_req->dr_session_req.sr_session_id = session_id;
   5268 	taskq_req->dr_session_req.sr_user_type = user_type;
   5269 	taskq_req->dr_session_req.sr_pin = pin;
   5270 	taskq_req->dr_session_req.sr_pin_len = pin_len;
   5271 
   5272 	return (dprov_taskq_dispatch(softc, taskq_req,
   5273 	    (task_func_t *)dprov_session_task, KM_NOSLEEP));
   5274 }
   5275 
   5276 /*
   5277  * Helper function to submit object management operations to the taskq.
   5278  * Returns one of the CRYPTO_ errors.
   5279  */
   5280 static int
   5281 dprov_object_submit_req(dprov_req_type_t req_type,
   5282     dprov_state_t *softc, crypto_req_handle_t req,
   5283     crypto_session_id_t session_id, crypto_object_id_t object_id,
   5284     crypto_object_attribute_t *template, uint_t attribute_count,
   5285     crypto_object_id_t *object_id_ptr, size_t *object_size,
   5286     void **find_pp, void *find_p, uint_t max_object_count,
   5287     uint_t *object_count_ptr, int kmflag)
   5288 {
   5289 	dprov_req_t *taskq_req;
   5290 
   5291 	if ((taskq_req = dprov_alloc_req(req_type, softc, req,
   5292 	    kmflag)) == NULL)
   5293 		return (CRYPTO_HOST_MEMORY);
   5294 
   5295 	taskq_req->dr_object_req.or_session_id = session_id;
   5296 	taskq_req->dr_object_req.or_object_id = object_id;
   5297 	taskq_req->dr_object_req.or_template = template;
   5298 	taskq_req->dr_object_req.or_attribute_count = attribute_count;
   5299 	taskq_req->dr_object_req.or_object_id_ptr = object_id_ptr;
   5300 	taskq_req->dr_object_req.or_object_size = object_size;
   5301 	taskq_req->dr_object_req.or_find_pp = find_pp;
   5302 	taskq_req->dr_object_req.or_find_p = find_p;
   5303 	taskq_req->dr_object_req.or_max_object_count = max_object_count;
   5304 	taskq_req->dr_object_req.or_object_count_ptr = object_count_ptr;
   5305 
   5306 	return (dprov_taskq_dispatch(softc, taskq_req,
   5307 	    (task_func_t *)dprov_object_task, KM_NOSLEEP));
   5308 }
   5309 
   5310 /*
   5311  * Helper function to submit key management operations to the taskq.
   5312  * Returns one of the CRYPTO_ errors.
   5313  */
   5314 static int
   5315 dprov_key_submit_req(dprov_req_type_t req_type,
   5316     dprov_state_t *softc, crypto_req_handle_t req,
   5317     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
   5318     crypto_object_attribute_t *template, uint_t attribute_count,
   5319     crypto_object_id_t *object_id_ptr,
   5320     crypto_object_attribute_t *private_key_template,
   5321     uint_t private_key_attribute_count,
   5322     crypto_object_id_t *private_key_object_id_ptr, crypto_key_t *key,
   5323     uchar_t *wrapped_key, size_t *wrapped_key_len_ptr,
   5324     crypto_object_attribute_t *out_template1, uint_t out_attribute_count1,
   5325     crypto_object_attribute_t *out_template2, uint_t out_attribute_count2)
   5326 {
   5327 	dprov_req_t *taskq_req;
   5328 
   5329 	if ((taskq_req = dprov_alloc_req(req_type, softc, req,
   5330 	    KM_NOSLEEP)) == NULL)
   5331 		return (CRYPTO_HOST_MEMORY);
   5332 
   5333 	taskq_req->dr_key_req.kr_session_id = session_id;
   5334 	taskq_req->dr_key_req.kr_mechanism = mechanism;
   5335 	taskq_req->dr_key_req.kr_template = template;
   5336 	taskq_req->dr_key_req.kr_attribute_count = attribute_count;
   5337 	taskq_req->dr_key_req.kr_object_id_ptr = object_id_ptr;
   5338 	taskq_req->dr_key_req.kr_private_key_template = private_key_template;
   5339 	taskq_req->dr_key_req.kr_private_key_attribute_count =
   5340 	    private_key_attribute_count;
   5341 	taskq_req->dr_key_req.kr_private_key_object_id_ptr =
   5342 	    private_key_object_id_ptr;
   5343 	taskq_req->dr_key_req.kr_key = key;
   5344 	taskq_req->dr_key_req.kr_wrapped_key = wrapped_key;
   5345 	taskq_req->dr_key_req.kr_wrapped_key_len_ptr = wrapped_key_len_ptr;
   5346 	taskq_req->dr_key_req.kr_out_template1 = out_template1;
   5347 	taskq_req->dr_key_req.kr_out_attribute_count1 = out_attribute_count1;
   5348 	taskq_req->dr_key_req.kr_out_template2 = out_template2;
   5349 	taskq_req->dr_key_req.kr_out_attribute_count2 = out_attribute_count2;
   5350 
   5351 	return (dprov_taskq_dispatch(softc, taskq_req,
   5352 	    (task_func_t *)dprov_key_task, KM_NOSLEEP));
   5353 }
   5354 
   5355 /*
   5356  * Helper function to submit provider management operations to the taskq.
   5357  * Returns one of the CRYPTO_ errors.
   5358  */
   5359 static int
   5360 dprov_mgmt_submit_req(dprov_req_type_t req_type,
   5361     dprov_state_t *softc, crypto_req_handle_t req,
   5362     crypto_session_id_t session_id, char *pin, size_t pin_len,
   5363     char *old_pin, size_t old_pin_len, char *label,
   5364     crypto_provider_ext_info_t *ext_info)
   5365 {
   5366 	dprov_req_t *taskq_req;
   5367 
   5368 	if ((taskq_req = dprov_alloc_req(req_type, softc, req,
   5369 	    KM_NOSLEEP)) == NULL)
   5370 		return (CRYPTO_HOST_MEMORY);
   5371 
   5372 	taskq_req->dr_mgmt_req.mr_session_id = session_id;
   5373 	taskq_req->dr_mgmt_req.mr_pin = pin;
   5374 	taskq_req->dr_mgmt_req.mr_pin_len = pin_len;
   5375 	taskq_req->dr_mgmt_req.mr_old_pin = old_pin;
   5376 	taskq_req->dr_mgmt_req.mr_old_pin_len = old_pin_len;
   5377 	taskq_req->dr_mgmt_req.mr_label = label;
   5378 	taskq_req->dr_mgmt_req.mr_ext_info = ext_info;
   5379 
   5380 	return (dprov_taskq_dispatch(softc, taskq_req,
   5381 	    (task_func_t *)dprov_mgmt_task, KM_NOSLEEP));
   5382 }
   5383 
   5384 /*
   5385  * Helper function for taskq dispatcher routines. Notify the framework
   5386  * that the operation corresponding to the specified request is done,
   5387  * and pass it the error code. Finally, free the taskq_req.
   5388  */
   5389 static void
   5390 dprov_op_done(dprov_req_t *taskq_req, int error)
   5391 {
   5392 	/* notify framework that request is completed */
   5393 	crypto_op_notification(taskq_req->dr_kcf_req, error);
   5394 
   5395 	/* free taskq request structure */
   5396 	kmem_free(taskq_req, sizeof (dprov_req_t));
   5397 }
   5398 
   5399 /*
   5400  * taskq dispatcher function for digest operations.
   5401  */
   5402 static void
   5403 dprov_digest_task(dprov_req_t *taskq_req)
   5404 {
   5405 	kcf_provider_desc_t *pd;
   5406 	dprov_state_t *softc;
   5407 	/* LINTED E_FUNC_SET_NOT_USED */
   5408 	int instance;
   5409 	int error = CRYPTO_NOT_SUPPORTED;
   5410 	crypto_ctx_t *ctx = taskq_req->dr_digest_req.dr_ctx;
   5411 	crypto_mechanism_t mech;
   5412 
   5413 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
   5414 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_task: started\n", instance));
   5415 
   5416 	switch (taskq_req->dr_type) {
   5417 
   5418 	case DPROV_REQ_DIGEST_INIT:
   5419 		/* allocate a dprov-private context */
   5420 		if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
   5421 		    CRYPTO_SUCCESS)
   5422 			break;
   5423 
   5424 		/* structure assignment */
   5425 		mech = *taskq_req->dr_digest_req.dr_mechanism;
   5426 
   5427 		/* get the software provider for this mechanism */
   5428 		if ((error = dprov_get_sw_prov(
   5429 		    taskq_req->dr_digest_req.dr_mechanism, &pd,
   5430 		    &mech.cm_type)) != CRYPTO_SUCCESS)
   5431 			break;
   5432 
   5433 		/* Use a session id of zero since we use a software provider */
   5434 		error = crypto_digest_init_prov(pd, 0, &mech,
   5435 		    &DPROV_CTX_SINGLE(ctx), NULL);
   5436 
   5437 		/* release provider reference */
   5438 		KCF_PROV_REFRELE(pd);
   5439 		break;
   5440 
   5441 	case DPROV_REQ_DIGEST:
   5442 		error = crypto_digest_single(DPROV_CTX_SINGLE(ctx),
   5443 		    taskq_req->dr_digest_req.dr_data,
   5444 		    taskq_req->dr_digest_req.dr_digest, NULL);
   5445 
   5446 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
   5447 			DPROV_CTX_SINGLE(ctx) = NULL;
   5448 			(void) dprov_free_context(ctx);
   5449 		}
   5450 		break;
   5451 
   5452 	case DPROV_REQ_DIGEST_UPDATE:
   5453 		error = crypto_digest_update(DPROV_CTX_SINGLE(ctx),
   5454 		    taskq_req->dr_digest_req.dr_data, NULL);
   5455 		break;
   5456 
   5457 	case DPROV_REQ_DIGEST_KEY: {
   5458 		crypto_data_t data;
   5459 		crypto_key_t key;
   5460 		size_t len;
   5461 
   5462 		mutex_enter(&softc->ds_lock);
   5463 		error = dprov_key_value_secret(softc, ctx->cc_session,
   5464 		    taskq_req->dr_type, taskq_req->dr_digest_req.dr_key, &key);
   5465 		mutex_exit(&softc->ds_lock);
   5466 		if (error != CRYPTO_SUCCESS)
   5467 			break;
   5468 
   5469 		/* key lengths are specified in bits */
   5470 		len = CRYPTO_BITS2BYTES(key.ck_length);
   5471 		data.cd_format = CRYPTO_DATA_RAW;
   5472 		data.cd_offset = 0;
   5473 		data.cd_length = len;
   5474 		data.cd_raw.iov_base = key.ck_data;
   5475 		data.cd_raw.iov_len = len;
   5476 		error = crypto_digest_update(DPROV_CTX_SINGLE(ctx),
   5477 		    &data, NULL);
   5478 		break;
   5479 	}
   5480 
   5481 	case DPROV_REQ_DIGEST_FINAL:
   5482 		error = crypto_digest_final(DPROV_CTX_SINGLE(ctx),
   5483 		    taskq_req->dr_digest_req.dr_digest, NULL);
   5484 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
   5485 			DPROV_CTX_SINGLE(ctx) = NULL;
   5486 			(void) dprov_free_context(ctx);
   5487 		}
   5488 		break;
   5489 
   5490 	case DPROV_REQ_DIGEST_ATOMIC:
   5491 		/* structure assignment */
   5492 		mech = *taskq_req->dr_digest_req.dr_mechanism;
   5493 
   5494 		/* get the software provider for this mechanism */
   5495 		if ((error = dprov_get_sw_prov(
   5496 		    taskq_req->dr_digest_req.dr_mechanism, &pd,
   5497 		    &mech.cm_type)) != CRYPTO_SUCCESS)
   5498 			break;
   5499 
   5500 		/* use a session id of zero since we use a software provider */
   5501 		error = crypto_digest_prov(pd, 0, &mech,
   5502 		    taskq_req->dr_digest_req.dr_data,
   5503 		    taskq_req->dr_digest_req.dr_digest, NULL);
   5504 
   5505 		/* release provider reference */
   5506 		KCF_PROV_REFRELE(pd);
   5507 
   5508 		break;
   5509 	}
   5510 
   5511 	dprov_op_done(taskq_req, error);
   5512 	DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_task: end\n", instance));
   5513 }
   5514 
   5515 /*
   5516  * taskq dispatcher function for mac operations.
   5517  */
   5518 static void
   5519 dprov_mac_task(dprov_req_t *taskq_req)
   5520 {
   5521 	kcf_provider_desc_t *pd;
   5522 	dprov_state_t *softc;
   5523 	/* LINTED E_FUNC_SET_NOT_USED */
   5524 	int instance;
   5525 	int error = CRYPTO_NOT_SUPPORTED;
   5526 	crypto_ctx_t *ctx = taskq_req->dr_mac_req.dr_ctx;
   5527 	crypto_key_t key;
   5528 	crypto_mechanism_t mech;
   5529 
   5530 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
   5531 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: started\n", instance));
   5532 
   5533 	switch (taskq_req->dr_type) {
   5534 
   5535 	case DPROV_REQ_MAC_INIT:
   5536 		/* allocate a dprov-private context */
   5537 		if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
   5538 		    CRYPTO_SUCCESS)
   5539 			break;
   5540 
   5541 		/* get key value */
   5542 		mutex_enter(&softc->ds_lock);
   5543 		error = dprov_key_value_secret(softc, ctx->cc_session,
   5544 		    taskq_req->dr_type, taskq_req->dr_mac_req.dr_key, &key);
   5545 		mutex_exit(&softc->ds_lock);
   5546 		if (error != CRYPTO_SUCCESS)
   5547 			break;
   5548 
   5549 		/* structure assignment */
   5550 		mech = *taskq_req->dr_mac_req.dr_mechanism;
   5551 
   5552 		/* get the software provider for this mechanism */
   5553 		if ((error = dprov_get_sw_prov(
   5554 		    taskq_req->dr_mac_req.dr_mechanism, &pd,
   5555 		    &mech.cm_type)) != CRYPTO_SUCCESS)
   5556 			break;
   5557 
   5558 		/* Use a session id of zero since we use a software provider */
   5559 		error = crypto_mac_init_prov(pd, 0, &mech, &key, NULL,
   5560 		    &DPROV_CTX_SINGLE(ctx), NULL);
   5561 
   5562 		/* release provider reference */
   5563 		KCF_PROV_REFRELE(pd);
   5564 		break;
   5565 
   5566 	case DPROV_REQ_MAC:
   5567 		error = crypto_mac_single(DPROV_CTX_SINGLE(ctx),
   5568 		    taskq_req->dr_mac_req.dr_data,
   5569 		    taskq_req->dr_mac_req.dr_mac, NULL);
   5570 
   5571 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
   5572 			DPROV_CTX_SINGLE(ctx) = NULL;
   5573 			(void) dprov_free_context(ctx);
   5574 		}
   5575 		break;
   5576 
   5577 	case DPROV_REQ_MAC_UPDATE:
   5578 		error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
   5579 		    taskq_req->dr_mac_req.dr_data, NULL);
   5580 		break;
   5581 
   5582 	case DPROV_REQ_MAC_FINAL:
   5583 		error = crypto_mac_final(DPROV_CTX_SINGLE(ctx),
   5584 		    taskq_req->dr_mac_req.dr_mac, NULL);
   5585 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
   5586 			DPROV_CTX_SINGLE(ctx) = NULL;
   5587 			(void) dprov_free_context(ctx);
   5588 		}
   5589 		break;
   5590 
   5591 	case DPROV_REQ_MAC_ATOMIC:
   5592 	case DPROV_REQ_MAC_VERIFY_ATOMIC:
   5593 		/* get key value */
   5594 		mutex_enter(&softc->ds_lock);
   5595 		error = dprov_key_value_secret(softc,
   5596 		    taskq_req->dr_mac_req.dr_session_id,
   5597 		    taskq_req->dr_type, taskq_req->dr_mac_req.dr_key, &key);
   5598 		mutex_exit(&softc->ds_lock);
   5599 		if (error != CRYPTO_SUCCESS)
   5600 			break;
   5601 
   5602 		/* structure assignment */
   5603 		mech = *taskq_req->dr_mac_req.dr_mechanism;
   5604 
   5605 		/* get the software provider for this mechanism */
   5606 		if ((error = dprov_get_sw_prov(
   5607 		    taskq_req->dr_mac_req.dr_mechanism, &pd,
   5608 		    &mech.cm_type)) != CRYPTO_SUCCESS)
   5609 			break;
   5610 
   5611 		/* use a session id of zero since we use a software provider */
   5612 		if (taskq_req->dr_type == DPROV_REQ_MAC_ATOMIC)
   5613 			error = crypto_mac_prov(pd, 0, &mech,
   5614 			    taskq_req->dr_mac_req.dr_data,
   5615 			    &key, NULL, taskq_req->dr_mac_req.dr_mac, NULL);
   5616 		else
   5617 			error = crypto_mac_verify_prov(pd, 0, &mech,
   5618 			    taskq_req->dr_mac_req.dr_data,
   5619 			    &key, NULL, taskq_req->dr_mac_req.dr_mac, NULL);
   5620 
   5621 		/* release provider reference */
   5622 		KCF_PROV_REFRELE(pd);
   5623 
   5624 		break;
   5625 	}
   5626 
   5627 	dprov_op_done(taskq_req, error);
   5628 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: end\n", instance));
   5629 }
   5630 
   5631 /*
   5632  * taskq dispatcher function for sign operations.
   5633  */
   5634 static void
   5635 dprov_sign_task(dprov_req_t *taskq_req)
   5636 {
   5637 	kcf_provider_desc_t *pd;
   5638 	dprov_state_t *softc;
   5639 	/* LINTED E_FUNC_SET_NOT_USED */
   5640 	int instance;
   5641 	int error = CRYPTO_NOT_SUPPORTED;
   5642 	crypto_ctx_t *ctx = taskq_req->dr_sign_req.sr_ctx;
   5643 	crypto_key_t key, *keyp;
   5644 	crypto_mechanism_t mech;
   5645 
   5646 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
   5647 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_task: started\n", instance));
   5648 
   5649 	switch (taskq_req->dr_type) {
   5650 
   5651 	case DPROV_REQ_SIGN_INIT:
   5652 	case DPROV_REQ_SIGN_RECOVER_INIT:
   5653 		/* allocate a dprov-private context */
   5654 		if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
   5655 		    CRYPTO_SUCCESS)
   5656 			break;
   5657 
   5658 		/* structure assignment */
   5659 		mech = *taskq_req->dr_sign_req.sr_mechanism;
   5660 		if (dprov_valid_mac_mech(mech.cm_type)) {
   5661 			DPROV_CTX_P(ctx)->dc_svrfy_to_mac = B_TRUE;
   5662 		}
   5663 
   5664 		mutex_enter(&softc->ds_lock);
   5665 		if (is_publickey_mech(mech.cm_type)) {
   5666 			if ((error = dprov_key_attr_asymmetric(softc,
   5667 			    ctx->cc_session, taskq_req->dr_type,
   5668 			    taskq_req->dr_sign_req.sr_key, &key))
   5669 			    != CRYPTO_SUCCESS) {
   5670 				mutex_exit(&softc->ds_lock);
   5671 				break;
   5672 			}
   5673 			keyp = &key;
   5674 		} else {
   5675 			if ((error = dprov_key_value_secret(softc,
   5676 			    ctx->cc_session, taskq_req->dr_type,
   5677 			    taskq_req->dr_sign_req.sr_key, &key))
   5678 			    != CRYPTO_SUCCESS) {
   5679 				mutex_exit(&softc->ds_lock);
   5680 				break;
   5681 			}
   5682 			keyp = &key;
   5683 		}
   5684 		mutex_exit(&softc->ds_lock);
   5685 
   5686 		/* get the software provider for this mechanism */
   5687 		if ((error = dprov_get_sw_prov(
   5688 		    taskq_req->dr_sign_req.sr_mechanism, &pd,
   5689 		    &mech.cm_type)) != CRYPTO_SUCCESS)
   5690 			break;
   5691 
   5692 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
   5693 			error = crypto_mac_init_prov(pd, 0, &mech, keyp, NULL,
   5694 			    &DPROV_CTX_SINGLE(ctx), NULL);
   5695 
   5696 			/* release provider reference */
   5697 			KCF_PROV_REFRELE(pd);
   5698 			break;
   5699 		}
   5700 
   5701 		/* Use a session id of zero since we use a software provider */
   5702 		if (taskq_req->dr_type == DPROV_REQ_SIGN_INIT)
   5703 			error = crypto_sign_init_prov(pd, 0, &mech, keyp,
   5704 			    NULL, &DPROV_CTX_SINGLE(ctx), NULL);
   5705 		else
   5706 			error = crypto_sign_recover_init_prov(pd, 0, &mech,
   5707 			    keyp, NULL, &DPROV_CTX_SINGLE(ctx), NULL);
   5708 
   5709 		/* release provider reference */
   5710 		KCF_PROV_REFRELE(pd);
   5711 
   5712 		break;
   5713 
   5714 	case DPROV_REQ_SIGN:
   5715 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
   5716 			/* Emulate using update and final */
   5717 			error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
   5718 			    taskq_req->dr_mac_req.dr_data, NULL);
   5719 			if (error == CRYPTO_SUCCESS) {
   5720 				error = crypto_mac_final(DPROV_CTX_SINGLE(ctx),
   5721 				    taskq_req->dr_mac_req.dr_mac, NULL);
   5722 			}
   5723 		} else {
   5724 			error = crypto_sign_single(DPROV_CTX_SINGLE(ctx),
   5725 			    taskq_req->dr_sign_req.sr_data,
   5726 			    taskq_req->dr_sign_req.sr_signature, NULL);
   5727 		}
   5728 
   5729 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
   5730 			DPROV_CTX_SINGLE(ctx) = NULL;
   5731 			(void) dprov_free_context(ctx);
   5732 		}
   5733 		break;
   5734 
   5735 	case DPROV_REQ_SIGN_UPDATE:
   5736 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
   5737 			error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
   5738 			    taskq_req->dr_mac_req.dr_data, NULL);
   5739 		} else {
   5740 			error = crypto_sign_update(DPROV_CTX_SINGLE(ctx),
   5741 			    taskq_req->dr_sign_req.sr_data, NULL);
   5742 		}
   5743 		break;
   5744 
   5745 	case DPROV_REQ_SIGN_FINAL:
   5746 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
   5747 			error = crypto_mac_final(DPROV_CTX_SINGLE(ctx),
   5748 			    taskq_req->dr_mac_req.dr_mac, NULL);
   5749 		} else {
   5750 			error = crypto_sign_final(DPROV_CTX_SINGLE(ctx),
   5751 			    taskq_req->dr_sign_req.sr_signature, NULL);
   5752 		}
   5753 
   5754 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
   5755 			DPROV_CTX_SINGLE(ctx) = NULL;
   5756 			(void) dprov_free_context(ctx);
   5757 		}
   5758 		break;
   5759 
   5760 	case DPROV_REQ_SIGN_ATOMIC:
   5761 	case DPROV_REQ_SIGN_RECOVER_ATOMIC:
   5762 		/* structure assignment */
   5763 		mech = *taskq_req->dr_sign_req.sr_mechanism;
   5764 
   5765 		mutex_enter(&softc->ds_lock);
   5766 		/* get key value for secret key algorithms */
   5767 		if (is_publickey_mech(mech.cm_type)) {
   5768 			if ((error = dprov_key_attr_asymmetric(softc,
   5769 			    taskq_req->dr_sign_req.sr_session_id,
   5770 			    taskq_req->dr_type,
   5771 			    taskq_req->dr_sign_req.sr_key, &key))
   5772 			    != CRYPTO_SUCCESS) {
   5773 				mutex_exit(&softc->ds_lock);
   5774 				break;
   5775 			}
   5776 			keyp = &key;
   5777 		} else {
   5778 			if ((error = dprov_key_value_secret(softc,
   5779 			    taskq_req->dr_sign_req.sr_session_id,
   5780 			    taskq_req->dr_type,
   5781 			    taskq_req->dr_sign_req.sr_key, &key))
   5782 			    != CRYPTO_SUCCESS) {
   5783 				mutex_exit(&softc->ds_lock);
   5784 				break;
   5785 			}
   5786 			keyp = &key;
   5787 		}
   5788 		mutex_exit(&softc->ds_lock);
   5789 
   5790 		/* get the software provider for this mechanism */
   5791 		if ((error = dprov_get_sw_prov(
   5792 		    taskq_req->dr_sign_req.sr_mechanism, &pd,
   5793 		    &mech.cm_type)) != CRYPTO_SUCCESS)
   5794 			break;
   5795 
   5796 		/* Use a session id of zero since we use a software provider */
   5797 		if (taskq_req->dr_type == DPROV_REQ_SIGN_ATOMIC)
   5798 			error = crypto_sign_prov(pd, 0, &mech, keyp,
   5799 			    taskq_req->dr_sign_req.sr_data,
   5800 			    NULL, taskq_req->dr_sign_req.sr_signature, NULL);
   5801 		else
   5802 			error = crypto_sign_recover_prov(pd, 0, &mech, keyp,
   5803 			    taskq_req->dr_sign_req.sr_data,
   5804 			    NULL, taskq_req->dr_sign_req.sr_signature, NULL);
   5805 
   5806 		/* release provider reference */
   5807 		KCF_PROV_REFRELE(pd);
   5808 		break;
   5809 
   5810 	case DPROV_REQ_SIGN_RECOVER:
   5811 		error = crypto_sign_recover_single(DPROV_CTX_SINGLE(ctx),
   5812 		    taskq_req->dr_sign_req.sr_data,
   5813 		    taskq_req->dr_sign_req.sr_signature, NULL);
   5814 
   5815 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
   5816 			DPROV_CTX_SINGLE(ctx) = NULL;
   5817 			(void) dprov_free_context(ctx);
   5818 		}
   5819 		break;
   5820 	}
   5821 
   5822 	dprov_op_done(taskq_req, error);
   5823 	DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_task: end\n", instance));
   5824 }
   5825 
   5826 static int
   5827 emulate_verify_with_mac(crypto_ctx_t *ctx, crypto_data_t *in_mac)
   5828 {
   5829 	int error;
   5830 	crypto_data_t tmpd;
   5831 	crypto_data_t *out_mac;
   5832 	char digest[SHA512_DIGEST_LENGTH];
   5833 
   5834 	bzero(&tmpd, sizeof (crypto_data_t));
   5835 	tmpd.cd_format = CRYPTO_DATA_RAW;
   5836 	tmpd.cd_length = SHA512_DIGEST_LENGTH;
   5837 	tmpd.cd_raw.iov_base = digest;
   5838 	tmpd.cd_raw.iov_len = SHA512_DIGEST_LENGTH;
   5839 	out_mac = &tmpd;
   5840 
   5841 	error = crypto_mac_final(DPROV_CTX_SINGLE(ctx), out_mac, NULL);
   5842 	if (in_mac->cd_length != out_mac->cd_length ||
   5843 	    (bcmp(digest, (unsigned char *)in_mac->cd_raw.iov_base +
   5844 	    in_mac->cd_offset, out_mac->cd_length) != 0)) {
   5845 		error = CRYPTO_INVALID_MAC;
   5846 	}
   5847 
   5848 	return (error);
   5849 }
   5850 
   5851 /*
   5852  * taskq dispatcher function for verify operations.
   5853  */
   5854 static void
   5855 dprov_verify_task(dprov_req_t *taskq_req)
   5856 {
   5857 	kcf_provider_desc_t *pd;
   5858 	dprov_state_t *softc;
   5859 	/* LINTED E_FUNC_SET_NOT_USED */
   5860 	int instance;
   5861 	int error = CRYPTO_NOT_SUPPORTED;
   5862 	crypto_ctx_t *ctx = taskq_req->dr_verify_req.vr_ctx;
   5863 	crypto_key_t key, *keyp;
   5864 	crypto_mechanism_t mech;
   5865 
   5866 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
   5867 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_task: started\n", instance));
   5868 
   5869 	switch (taskq_req->dr_type) {
   5870 
   5871 	case DPROV_REQ_VERIFY_INIT:
   5872 	case DPROV_REQ_VERIFY_RECOVER_INIT:
   5873 		/* allocate a dprov-private context */
   5874 		if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
   5875 		    CRYPTO_SUCCESS)
   5876 			break;
   5877 
   5878 		/* structure assignment */
   5879 		mech = *taskq_req->dr_verify_req.vr_mechanism;
   5880 		if (dprov_valid_mac_mech(mech.cm_type)) {
   5881 			DPROV_CTX_P(ctx)->dc_svrfy_to_mac = B_TRUE;
   5882 		}
   5883 
   5884 		mutex_enter(&softc->ds_lock);
   5885 		/* get key value for secret key algorithms */
   5886 		if (is_publickey_mech(mech.cm_type)) {
   5887 			if ((error = dprov_key_attr_asymmetric(softc,
   5888 			    ctx->cc_session, taskq_req->dr_type,
   5889 			    taskq_req->dr_verify_req.vr_key, &key))
   5890 			    != CRYPTO_SUCCESS) {
   5891 				mutex_exit(&softc->ds_lock);
   5892 				break;
   5893 			}
   5894 			keyp = &key;
   5895 		} else {
   5896 			if ((error = dprov_key_value_secret(softc,
   5897 			    ctx->cc_session, taskq_req->dr_type,
   5898 			    taskq_req->dr_verify_req.vr_key, &key))
   5899 			    != CRYPTO_SUCCESS) {
   5900 				mutex_exit(&softc->ds_lock);
   5901 				break;
   5902 			}
   5903 			keyp = &key;
   5904 		}
   5905 		mutex_exit(&softc->ds_lock);
   5906 
   5907 		/* get the software provider for this mechanism */
   5908 		if ((error = dprov_get_sw_prov(
   5909 		    taskq_req->dr_verify_req.vr_mechanism, &pd,
   5910 		    &mech.cm_type)) != CRYPTO_SUCCESS)
   5911 			break;
   5912 
   5913 
   5914 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
   5915 			error = crypto_mac_init_prov(pd, 0, &mech, keyp, NULL,
   5916 			    &DPROV_CTX_SINGLE(ctx), NULL);
   5917 
   5918 			/* release provider reference */
   5919 			KCF_PROV_REFRELE(pd);
   5920 			break;
   5921 		}
   5922 
   5923 		/* Use a session id of zero since we use a software provider */
   5924 		if (taskq_req->dr_type == DPROV_REQ_VERIFY_INIT)
   5925 			error = crypto_verify_init_prov(pd, 0, &mech, keyp,
   5926 			    NULL, &DPROV_CTX_SINGLE(ctx), NULL);
   5927 		else
   5928 			error = crypto_verify_recover_init_prov(pd, 0, &mech,
   5929 			    keyp, NULL, &DPROV_CTX_SINGLE(ctx), NULL);
   5930 
   5931 		/* release provider reference */
   5932 		KCF_PROV_REFRELE(pd);
   5933 
   5934 		break;
   5935 
   5936 	case DPROV_REQ_VERIFY:
   5937 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
   5938 			/* Emulate using update and final */
   5939 			error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
   5940 			    taskq_req->dr_mac_req.dr_data, NULL);
   5941 			if (error == CRYPTO_SUCCESS) {
   5942 				error = emulate_verify_with_mac(ctx,
   5943 				    taskq_req->dr_mac_req.dr_mac);
   5944 			}
   5945 		} else {
   5946 			error = crypto_verify_single(DPROV_CTX_SINGLE(ctx),
   5947 			    taskq_req->dr_verify_req.vr_data,
   5948 			    taskq_req->dr_verify_req.vr_signature, NULL);
   5949 		}
   5950 
   5951 		ASSERT(error != CRYPTO_BUFFER_TOO_SMALL);
   5952 		DPROV_CTX_SINGLE(ctx) = NULL;
   5953 		(void) dprov_free_context(ctx);
   5954 		break;
   5955 
   5956 	case DPROV_REQ_VERIFY_UPDATE:
   5957 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
   5958 			error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
   5959 			    taskq_req->dr_mac_req.dr_data, NULL);
   5960 		} else {
   5961 			error = crypto_verify_update(DPROV_CTX_SINGLE(ctx),
   5962 			    taskq_req->dr_verify_req.vr_data, NULL);
   5963 		}
   5964 		break;
   5965 
   5966 	case DPROV_REQ_VERIFY_FINAL:
   5967 		if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
   5968 			error = emulate_verify_with_mac(ctx,
   5969 			    taskq_req->dr_mac_req.dr_mac);
   5970 		} else {
   5971 			error = crypto_verify_final(DPROV_CTX_SINGLE(ctx),
   5972 			    taskq_req->dr_verify_req.vr_signature, NULL);
   5973 		}
   5974 
   5975 		ASSERT(error != CRYPTO_BUFFER_TOO_SMALL);
   5976 		DPROV_CTX_SINGLE(ctx) = NULL;
   5977 		(void) dprov_free_context(ctx);
   5978 		break;
   5979 
   5980 	case DPROV_REQ_VERIFY_ATOMIC:
   5981 	case DPROV_REQ_VERIFY_RECOVER_ATOMIC:
   5982 		/* structure assignment */
   5983 		mech = *taskq_req->dr_verify_req.vr_mechanism;
   5984 
   5985 		mutex_enter(&softc->ds_lock);
   5986 		/* get key value for secret key algorithms */
   5987 		if (is_publickey_mech(mech.cm_type)) {
   5988 			if ((error = dprov_key_attr_asymmetric(softc,
   5989 			    taskq_req->dr_verify_req.vr_session_id,
   5990 			    taskq_req->dr_type,
   5991 			    taskq_req->dr_verify_req.vr_key, &key))
   5992 			    != CRYPTO_SUCCESS) {
   5993 				mutex_exit(&softc->ds_lock);
   5994 				break;
   5995 			}
   5996 			keyp = &key;
   5997 		} else {
   5998 			if ((error = dprov_key_value_secret(softc,
   5999 			    taskq_req->dr_verify_req.vr_session_id,
   6000 			    taskq_req->dr_type,
   6001 			    taskq_req->dr_verify_req.vr_key, &key))
   6002 			    != CRYPTO_SUCCESS) {
   6003 				mutex_exit(&softc->ds_lock);
   6004 				break;
   6005 			}
   6006 			keyp = &key;
   6007 		}
   6008 		mutex_exit(&softc->ds_lock);
   6009 
   6010 		/* get the software provider for this mechanism */
   6011 		if ((error = dprov_get_sw_prov(
   6012 		    taskq_req->dr_verify_req.vr_mechanism, &pd,
   6013 		    &mech.cm_type)) != CRYPTO_SUCCESS)
   6014 			break;
   6015 
   6016 		/* Use a session id of zero since we use a software provider */
   6017 		if (taskq_req->dr_type == DPROV_REQ_VERIFY_ATOMIC)
   6018 			error = crypto_verify_prov(pd, 0, &mech, keyp,
   6019 			    taskq_req->dr_verify_req.vr_data,
   6020 			    NULL, taskq_req->dr_verify_req.vr_signature, NULL);
   6021 		else
   6022 			/*
   6023 			 * crypto_verify_recover_prov() has different argument
   6024 			 * order than crypto_verify_prov().
   6025 			 */
   6026 			error = crypto_verify_recover_prov(pd, 0, &mech, keyp,
   6027 			    taskq_req->dr_verify_req.vr_signature,
   6028 			    NULL, taskq_req->dr_verify_req.vr_data, NULL);
   6029 
   6030 		/* release provider reference */
   6031 		KCF_PROV_REFRELE(pd);
   6032 		break;
   6033 
   6034 	case DPROV_REQ_VERIFY_RECOVER:
   6035 		/*
   6036 		 * crypto_verify_recover_single() has different argument
   6037 		 * order than crypto_verify_single().
   6038 		 */
   6039 		error = crypto_verify_recover_single(DPROV_CTX_SINGLE(ctx),
   6040 		    taskq_req->dr_verify_req.vr_signature,
   6041 		    taskq_req->dr_verify_req.vr_data, NULL);
   6042 
   6043 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
   6044 			DPROV_CTX_SINGLE(ctx) = NULL;
   6045 			(void) dprov_free_context(ctx);
   6046 		}
   6047 		break;
   6048 	}
   6049 
   6050 	dprov_op_done(taskq_req, error);
   6051 	DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_task: end\n", instance));
   6052 }
   6053 
   6054 /*
   6055  * taskq dispatcher function for dual operations.
   6056  */
   6057 static void
   6058 dprov_dual_task(dprov_req_t *taskq_req)
   6059 {
   6060 	dprov_state_t *softc;
   6061 	/* LINTED E_FUNC_SET_NOT_USED */
   6062 	int instance;
   6063 	int error = CRYPTO_NOT_SUPPORTED;
   6064 	crypto_ctx_t *signverify_ctx = taskq_req->dr_dual_req.dr_signverify_ctx;
   6065 	crypto_ctx_t *cipher_ctx = taskq_req->dr_dual_req.dr_cipher_ctx;
   6066 
   6067 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
   6068 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_dual_task: started\n", instance));
   6069 
   6070 	switch (taskq_req->dr_type) {
   6071 
   6072 	case DPROV_REQ_DIGEST_ENCRYPT_UPDATE:
   6073 		error = crypto_digest_encrypt_update(
   6074 		    DPROV_CTX_SINGLE(signverify_ctx),
   6075 		    DPROV_CTX_SINGLE(cipher_ctx),
   6076 		    taskq_req->dr_dual_req.dr_plaintext,
   6077 		    taskq_req->dr_dual_req.dr_ciphertext, NULL);
   6078 		break;
   6079 
   6080 	case DPROV_REQ_DECRYPT_DIGEST_UPDATE:
   6081 		error = crypto_decrypt_digest_update(
   6082 		    DPROV_CTX_SINGLE(cipher_ctx),
   6083 		    DPROV_CTX_SINGLE(signverify_ctx),
   6084 		    taskq_req->dr_dual_req.dr_ciphertext,
   6085 		    taskq_req->dr_dual_req.dr_plaintext, NULL);
   6086 		break;
   6087 
   6088 	case DPROV_REQ_SIGN_ENCRYPT_UPDATE:
   6089 		error = crypto_sign_encrypt_update(
   6090 		    DPROV_CTX_SINGLE(signverify_ctx),
   6091 		    DPROV_CTX_SINGLE(cipher_ctx),
   6092 		    taskq_req->dr_dual_req.dr_plaintext,
   6093 		    taskq_req->dr_dual_req.dr_ciphertext, NULL);
   6094 		break;
   6095 
   6096 	case DPROV_REQ_DECRYPT_VERIFY_UPDATE:
   6097 		error = crypto_decrypt_verify_update(
   6098 		    DPROV_CTX_SINGLE(cipher_ctx),
   6099 		    DPROV_CTX_SINGLE(signverify_ctx),
   6100 		    taskq_req->dr_dual_req.dr_ciphertext,
   6101 		    taskq_req->dr_dual_req.dr_plaintext, NULL);
   6102 		break;
   6103 	}
   6104 
   6105 	dprov_op_done(taskq_req, error);
   6106 	DPROV_DEBUG(D_DUAL, ("(%d) dprov_dual_task: end\n", instance));
   6107 }
   6108 
   6109 /*
   6110  * taskq dispatcher function for cipher operations.
   6111  */
   6112 static void
   6113 dprov_cipher_task(dprov_req_t *taskq_req)
   6114 {
   6115 	kcf_provider_desc_t *pd;
   6116 	dprov_state_t *softc;
   6117 	/* LINTED E_FUNC_SET_NOT_USED */
   6118 	int instance;
   6119 	int error = CRYPTO_NOT_SUPPORTED;
   6120 	crypto_ctx_t *ctx = taskq_req->dr_cipher_req.dr_ctx;
   6121 	crypto_key_t key, *keyp;
   6122 	crypto_mechanism_t mech;
   6123 
   6124 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
   6125 	DPROV_DEBUG(D_CIPHER, ("(%d) dprov_cipher_task: started\n", instance));
   6126 
   6127 	switch (taskq_req->dr_type) {
   6128 
   6129 	case DPROV_REQ_ENCRYPT_INIT:
   6130 	case DPROV_REQ_DECRYPT_INIT:
   6131 		/* allocate a dprov-private context */
   6132 		if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
   6133 		    CRYPTO_SUCCESS)
   6134 			break;
   6135 
   6136 		/* structure assignment */
   6137 		mech = *taskq_req->dr_cipher_req.dr_mechanism;
   6138 
   6139 		mutex_enter(&softc->ds_lock);
   6140 		/* get key value for secret key algorithms */
   6141 		if (is_publickey_mech(mech.cm_type)) {
   6142 			if ((error = dprov_key_attr_asymmetric(softc,
   6143 			    ctx->cc_session, taskq_req->dr_type,
   6144 			    taskq_req->dr_cipher_req.dr_key, &key))
   6145 			    != CRYPTO_SUCCESS) {
   6146 				mutex_exit(&softc->ds_lock);
   6147 				break;
   6148 			}
   6149 			keyp = &key;
   6150 		} else {
   6151 			if ((error = dprov_key_value_secret(softc,
   6152 			    ctx->cc_session, taskq_req->dr_type,
   6153 			    taskq_req->dr_cipher_req.dr_key, &key))
   6154 			    != CRYPTO_SUCCESS) {
   6155 				mutex_exit(&softc->ds_lock);
   6156 				break;
   6157 			}
   6158 			keyp = &key;
   6159 		}
   6160 		mutex_exit(&softc->ds_lock);
   6161 
   6162 		/* get the software provider for this mechanism */
   6163 		if ((error = dprov_get_sw_prov(
   6164 		    taskq_req->dr_cipher_req.dr_mechanism, &pd,
   6165 		    &mech.cm_type)) != CRYPTO_SUCCESS)
   6166 			break;
   6167 
   6168 		/* Use a session id of zero since we use a software provider */
   6169 		if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_INIT)
   6170 			error = crypto_encrypt_init_prov(pd, 0, &mech, keyp,
   6171 			    NULL, &DPROV_CTX_SINGLE(ctx), NULL);
   6172 		else
   6173 			error = crypto_decrypt_init_prov(pd, 0, &mech, keyp,
   6174 			    NULL, &DPROV_CTX_SINGLE(ctx), NULL);
   6175 
   6176 		if (ctx->cc_flags & CRYPTO_INIT_OPSTATE) {
   6177 			crypto_ctx_t *lctx =
   6178 			    (crypto_ctx_t *)(DPROV_CTX_SINGLE(ctx));
   6179 
   6180 			ctx->cc_opstate = lctx->cc_provider_private;
   6181 			ctx->cc_flags |= CRYPTO_USE_OPSTATE;
   6182 		}
   6183 
   6184 		/* release provider reference */
   6185 		KCF_PROV_REFRELE(pd);
   6186 		break;
   6187 
   6188 	case DPROV_REQ_ENCRYPT:
   6189 		error = crypto_encrypt_single(DPROV_CTX_SINGLE(ctx),
   6190 		    taskq_req->dr_cipher_req.dr_plaintext,
   6191 		    taskq_req->dr_cipher_req.dr_ciphertext, NULL);
   6192 
   6193 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
   6194 			DPROV_CTX_SINGLE(ctx) = NULL;
   6195 			(void) dprov_free_context(ctx);
   6196 		}
   6197 		break;
   6198 
   6199 	case DPROV_REQ_DECRYPT:
   6200 		error = crypto_decrypt_single(DPROV_CTX_SINGLE(ctx),
   6201 		    taskq_req->dr_cipher_req.dr_ciphertext,
   6202 		    taskq_req->dr_cipher_req.dr_plaintext, NULL);
   6203 
   6204 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
   6205 			DPROV_CTX_SINGLE(ctx) = NULL;
   6206 			(void) dprov_free_context(ctx);
   6207 		}
   6208 		break;
   6209 
   6210 	case DPROV_REQ_ENCRYPT_UPDATE:
   6211 		ASSERT(!(ctx->cc_flags & CRYPTO_INIT_OPSTATE) ||
   6212 		    (ctx->cc_flags & CRYPTO_USE_OPSTATE));
   6213 		error = crypto_encrypt_update(DPROV_CTX_SINGLE(ctx),
   6214 		    taskq_req->dr_cipher_req.dr_plaintext,
   6215 		    taskq_req->dr_cipher_req.dr_ciphertext, NULL);
   6216 		break;
   6217 
   6218 	case DPROV_REQ_DECRYPT_UPDATE:
   6219 		ASSERT(!(ctx->cc_flags & CRYPTO_INIT_OPSTATE) ||
   6220 		    (ctx->cc_flags & CRYPTO_USE_OPSTATE));
   6221 		error = crypto_decrypt_update(DPROV_CTX_SINGLE(ctx),
   6222 		    taskq_req->dr_cipher_req.dr_ciphertext,
   6223 		    taskq_req->dr_cipher_req.dr_plaintext, NULL);
   6224 		break;
   6225 
   6226 	case DPROV_REQ_ENCRYPT_FINAL:
   6227 		error = crypto_encrypt_final(DPROV_CTX_SINGLE(ctx),
   6228 		    taskq_req->dr_cipher_req.dr_ciphertext, NULL);
   6229 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
   6230 			DPROV_CTX_SINGLE(ctx) = NULL;
   6231 			(void) dprov_free_context(ctx);
   6232 		}
   6233 		break;
   6234 
   6235 	case DPROV_REQ_DECRYPT_FINAL:
   6236 		error = crypto_decrypt_final(DPROV_CTX_SINGLE(ctx),
   6237 		    taskq_req->dr_cipher_req.dr_plaintext, NULL);
   6238 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
   6239 			DPROV_CTX_SINGLE(ctx) = NULL;
   6240 			(void) dprov_free_context(ctx);
   6241 		}
   6242 		break;
   6243 
   6244 	case DPROV_REQ_ENCRYPT_ATOMIC:
   6245 	case DPROV_REQ_DECRYPT_ATOMIC:
   6246 		/* structure assignment */
   6247 		mech = *taskq_req->dr_cipher_req.dr_mechanism;
   6248 
   6249 		mutex_enter(&softc->ds_lock);
   6250 		/* get key value for secret key algorithms */
   6251 		if (is_publickey_mech(mech.cm_type)) {
   6252 			if ((error = dprov_key_attr_asymmetric(softc,
   6253 			    taskq_req->dr_cipher_req.dr_session_id,
   6254 			    taskq_req->dr_type,
   6255 			    taskq_req->dr_cipher_req.dr_key,
   6256 			    &key)) != CRYPTO_SUCCESS) {
   6257 				mutex_exit(&softc->ds_lock);
   6258 				break;
   6259 			}
   6260 			keyp = &key;
   6261 		} else {
   6262 			if ((error = dprov_key_value_secret(softc,
   6263 			    taskq_req->dr_cipher_req.dr_session_id,
   6264 			    taskq_req->dr_type, taskq_req->dr_cipher_req.dr_key,
   6265 			    &key))
   6266 			    != CRYPTO_SUCCESS) {
   6267 				mutex_exit(&softc->ds_lock);
   6268 				break;
   6269 			}
   6270 			keyp = &key;
   6271 		}
   6272 		mutex_exit(&softc->ds_lock);
   6273 
   6274 		/* get the software provider for this mechanism */
   6275 		if ((error = dprov_get_sw_prov(
   6276 		    taskq_req->dr_cipher_req.dr_mechanism, &pd,
   6277 		    &mech.cm_type)) != CRYPTO_SUCCESS)
   6278 			break;
   6279 
   6280 		/* use a session id of zero since we use a software provider */
   6281 		if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_ATOMIC)
   6282 			error = crypto_encrypt_prov(pd, 0, &mech,
   6283 			    taskq_req->dr_cipher_req.dr_plaintext,
   6284 			    keyp, NULL,
   6285 			    taskq_req->dr_cipher_req.dr_ciphertext, NULL);
   6286 		else
   6287 			error = crypto_decrypt_prov(pd, 0, &mech,
   6288 			    taskq_req->dr_cipher_req.dr_ciphertext,
   6289 			    keyp, NULL,
   6290 			    taskq_req->dr_cipher_req.dr_plaintext, NULL);
   6291 
   6292 		/* release provider reference */
   6293 		KCF_PROV_REFRELE(pd);
   6294 
   6295 		break;
   6296 	}
   6297 
   6298 	dprov_op_done(taskq_req, error);
   6299 	DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: end\n", instance));
   6300 }
   6301 
   6302 /*
   6303  * Helper function for the cipher/mac dual operation taskq dispatch
   6304  * function. Initialize the cipher and mac key values and find the
   6305  * providers that can process the request for the specified mechanisms.
   6306  */
   6307 static int
   6308 dprov_cipher_mac_key_pd(dprov_state_t *softc, crypto_session_id_t sid,
   6309     dprov_req_t *taskq_req, crypto_key_t *cipher_key, crypto_key_t *mac_key,
   6310     kcf_provider_desc_t **cipher_pd, kcf_provider_desc_t **mac_pd,
   6311     crypto_mech_type_t *cipher_mech_type, crypto_mech_type_t *mac_mech_type)
   6312 {
   6313 	int error;
   6314 
   6315 	/* get the cipher key value */
   6316 	mutex_enter(&softc->ds_lock);
   6317 	error = dprov_key_value_secret(softc, sid, DPROV_REQ_ENCRYPT_ATOMIC,
   6318 	    taskq_req->dr_cipher_mac_req.mr_cipher_key, cipher_key);
   6319 	if (error != CRYPTO_SUCCESS) {
   6320 		mutex_exit(&softc->ds_lock);
   6321 		return (error);
   6322 	}
   6323 
   6324 	/* get the mac key value */
   6325 	error = dprov_key_value_secret(softc, sid, DPROV_REQ_MAC_ATOMIC,
   6326 	    taskq_req->dr_cipher_mac_req.mr_mac_key, mac_key);
   6327 	mutex_exit(&softc->ds_lock);
   6328 	if (error != CRYPTO_SUCCESS)
   6329 		return (error);
   6330 
   6331 	/* get the SW provider to perform the cipher operation */
   6332 	if ((error = dprov_get_sw_prov(
   6333 	    taskq_req->dr_cipher_mac_req.mr_cipher_mech, cipher_pd,
   6334 	    cipher_mech_type)) != CRYPTO_SUCCESS)
   6335 		return (error);
   6336 
   6337 	/* get the SW provider to perform the mac operation */
   6338 	error = dprov_get_sw_prov(taskq_req->dr_cipher_mac_req.mr_mac_mech,
   6339 	    mac_pd, mac_mech_type);
   6340 
   6341 	return (error);
   6342 }
   6343 
   6344 /*
   6345  * taskq dispatcher function for cipher/mac dual operations.
   6346  */
   6347 static void
   6348 dprov_cipher_mac_task(dprov_req_t *taskq_req)
   6349 {
   6350 	dprov_state_t *softc;
   6351 	/* LINTED E_FUNC_SET_NOT_USED */
   6352 	int instance;
   6353 	int error = CRYPTO_NOT_SUPPORTED;
   6354 	crypto_ctx_t *ctx = taskq_req->dr_cipher_mac_req.mr_ctx;
   6355 	kcf_provider_desc_t *cipher_pd;
   6356 	kcf_provider_desc_t *mac_pd;
   6357 	crypto_key_t cipher_key;
   6358 	crypto_key_t mac_key;
   6359 	crypto_dual_data_t *dual_data =
   6360 	    taskq_req->dr_cipher_mac_req.mr_dual_data;
   6361 	crypto_data_t cipher_data;
   6362 	crypto_data_t mac_data;
   6363 	crypto_mechanism_t cipher_mech, mac_mech;
   6364 	crypto_session_id_t session_id;
   6365 
   6366 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
   6367 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_cipher_mac_task: started\n",
   6368 	    instance));
   6369 
   6370 	switch (taskq_req->dr_type) {
   6371 	case DPROV_REQ_ENCRYPT_MAC_INIT:
   6372 	case DPROV_REQ_MAC_DECRYPT_INIT:
   6373 		/* structure assignment */
   6374 		cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech;
   6375 		mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech;
   6376 
   6377 		/* get the keys values and providers to use for operations */
   6378 		if ((error = dprov_cipher_mac_key_pd(softc, ctx->cc_session,
   6379 		    taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd,
   6380 		    &cipher_mech.cm_type, &mac_mech.cm_type)) != CRYPTO_SUCCESS)
   6381 			break;
   6382 
   6383 		/* allocate a dprov-private context */
   6384 		if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
   6385 		    CRYPTO_SUCCESS)
   6386 			break;
   6387 
   6388 		if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_MAC_INIT)
   6389 			/* do the encryption initialization */
   6390 			error = crypto_encrypt_init_prov(cipher_pd, 0,
   6391 			    &cipher_mech, &cipher_key, NULL,
   6392 			    &DPROV_CTX_DUAL_CIPHER(ctx), NULL);
   6393 		else
   6394 			/* do the decryption initialization */
   6395 			error = crypto_decrypt_init_prov(cipher_pd, 0,
   6396 			    &cipher_mech, &cipher_key, NULL,
   6397 			    &DPROV_CTX_DUAL_CIPHER(ctx), NULL);
   6398 		if (error != CRYPTO_SUCCESS)
   6399 			break;
   6400 
   6401 		/* do the mac initialization */
   6402 		if ((error = crypto_mac_init_prov(mac_pd, 0,
   6403 		    &mac_mech, &mac_key, NULL, &DPROV_CTX_DUAL_MAC(ctx),
   6404 		    NULL)) != CRYPTO_SUCCESS)
   6405 			break;
   6406 
   6407 		/* release references to providers */
   6408 		KCF_PROV_REFRELE(cipher_pd);
   6409 		KCF_PROV_REFRELE(mac_pd);
   6410 
   6411 		break;
   6412 
   6413 	case DPROV_REQ_ENCRYPT_MAC: {
   6414 		size_t encrypted;
   6415 		boolean_t inplace;
   6416 
   6417 		crypto_data_t *plaintext_tmp, *ciphertext_tmp;
   6418 
   6419 		cipher_data = *((crypto_data_t *)dual_data);
   6420 
   6421 		/* do an encrypt update */
   6422 		inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL);
   6423 		if (inplace) {
   6424 			plaintext_tmp = &cipher_data;
   6425 			ciphertext_tmp = NULL;
   6426 		} else {
   6427 			plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data;
   6428 			ciphertext_tmp = &cipher_data;
   6429 		}
   6430 		if ((error = crypto_encrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
   6431 		    plaintext_tmp, ciphertext_tmp, NULL)) != CRYPTO_SUCCESS)
   6432 			break;
   6433 
   6434 		/* do an encrypt final */
   6435 		encrypted = cipher_data.cd_length;
   6436 
   6437 		cipher_data.cd_offset += encrypted;
   6438 		cipher_data.cd_length = dual_data->dd_len1 - encrypted;
   6439 
   6440 		if ((error = crypto_encrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
   6441 		    &cipher_data, NULL)) != CRYPTO_SUCCESS)
   6442 			break;
   6443 
   6444 		/*
   6445 		 * Do a mac update on the resulting ciphertext, but with no
   6446 		 * more bytes than specified by dual_data, and starting at
   6447 		 * offset specified by dual_data. For in-place operations,
   6448 		 * we use the length specified by the dual_data.
   6449 		 */
   6450 		mac_data = cipher_data;
   6451 		mac_data.cd_offset = dual_data->dd_offset2;
   6452 		mac_data.cd_length = dual_data->dd_len2;
   6453 		if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
   6454 		    &mac_data, NULL)) != CRYPTO_SUCCESS)
   6455 			break;
   6456 
   6457 		/* do a mac final */
   6458 		error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
   6459 		    taskq_req->dr_cipher_mac_req.mr_mac, NULL);
   6460 
   6461 		/* Set the total size of the ciphertext, when successful */
   6462 		if (error == CRYPTO_SUCCESS)
   6463 			dual_data->dd_len1 = encrypted + cipher_data.cd_length;
   6464 
   6465 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
   6466 			DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
   6467 			DPROV_CTX_DUAL_MAC(ctx) = NULL;
   6468 			(void) dprov_free_context(ctx);
   6469 		}
   6470 		break;
   6471 	}
   6472 
   6473 	case DPROV_REQ_ENCRYPT_MAC_UPDATE: {
   6474 		crypto_data_t *plaintext_tmp, *ciphertext_tmp;
   6475 		size_t encrypted;
   6476 		ssize_t maclen;
   6477 		boolean_t inplace;
   6478 
   6479 		cipher_data = *((crypto_data_t *)dual_data);
   6480 
   6481 		/* do an encrypt update */
   6482 		inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL);
   6483 		if (inplace) {
   6484 			plaintext_tmp = &cipher_data;
   6485 			ciphertext_tmp = NULL;
   6486 		} else {
   6487 			plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data;
   6488 			ciphertext_tmp = &cipher_data;
   6489 		}
   6490 		if ((error = crypto_encrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
   6491 		    plaintext_tmp, ciphertext_tmp, NULL)) != CRYPTO_SUCCESS)
   6492 			break;
   6493 
   6494 		encrypted = cipher_data.cd_length;
   6495 
   6496 		/*
   6497 		 * Do a mac update on the resulting ciphertext, but with no
   6498 		 * more bytes than specified by dual_data, and starting at
   6499 		 * offset specified by dual_data. For in-place operations,
   6500 		 * we use the length specified by the dual_data.
   6501 		 * There is an edge case, when the encryption step produced
   6502 		 * zero bytes in the ciphertext. Only the portion between
   6503 		 * offset2 and offset1 is then thrown in the MAC mix.
   6504 		 */
   6505 		maclen = dual_data->dd_offset1 - dual_data->dd_offset2 +
   6506 		    encrypted;
   6507 		if (maclen > 0) {
   6508 			mac_data = cipher_data;
   6509 			mac_data.cd_offset = dual_data->dd_offset2;
   6510 			mac_data.cd_length = min(dual_data->dd_len2, maclen);
   6511 			if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
   6512 			    &mac_data, NULL)) != CRYPTO_SUCCESS)
   6513 				break;
   6514 		}
   6515 		/* Set the total size of the ciphertext, when successful */
   6516 		if (error == CRYPTO_SUCCESS)
   6517 			dual_data->dd_len1 = encrypted;
   6518 
   6519 		break;
   6520 	}
   6521 
   6522 	case DPROV_REQ_ENCRYPT_MAC_FINAL:
   6523 		cipher_data = *((crypto_data_t *)dual_data);
   6524 
   6525 		/* do an encrypt final */
   6526 		if ((error = crypto_encrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
   6527 		    taskq_req->dr_cipher_mac_req.mr_data == NULL ?
   6528 		    &cipher_data : taskq_req->dr_cipher_mac_req.mr_data,
   6529 		    NULL)) != CRYPTO_SUCCESS)
   6530 			break;
   6531 
   6532 		/*
   6533 		 * If ciphertext length is different from zero, do a mac
   6534 		 * update on it. This does not apply to in-place since we
   6535 		 * do not allow partial updates, hence no final residual.
   6536 		 */
   6537 		if (taskq_req->dr_cipher_mac_req.mr_data != NULL &&
   6538 		    taskq_req->dr_cipher_mac_req.mr_data->cd_length > 0)
   6539 			if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
   6540 			    taskq_req->dr_cipher_mac_req.mr_data, NULL)) !=
   6541 			    CRYPTO_SUCCESS)
   6542 				break;
   6543 
   6544 		/* do a mac final */
   6545 		error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
   6546 		    taskq_req->dr_cipher_mac_req.mr_mac, NULL);
   6547 
   6548 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
   6549 			DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
   6550 			DPROV_CTX_DUAL_MAC(ctx) = NULL;
   6551 			(void) dprov_free_context(ctx);
   6552 		}
   6553 		break;
   6554 
   6555 	case DPROV_REQ_ENCRYPT_MAC_ATOMIC: {
   6556 		crypto_data_t *plaintext_tmp, *ciphertext_tmp;
   6557 		boolean_t inplace;
   6558 
   6559 		cipher_data = *((crypto_data_t *)dual_data);
   6560 
   6561 		/* do an encrypt atomic */
   6562 		inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL);
   6563 		if (inplace) {
   6564 			plaintext_tmp = &cipher_data;
   6565 			ciphertext_tmp = NULL;
   6566 		} else {
   6567 			plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data;
   6568 			ciphertext_tmp = &cipher_data;
   6569 		}
   6570 
   6571 		/* structure assignment */
   6572 		cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech;
   6573 		mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech;
   6574 		session_id = taskq_req->dr_cipher_mac_req.mr_session_id;
   6575 
   6576 		/* get the keys values and providers to use for operations */
   6577 		if ((error = dprov_cipher_mac_key_pd(softc, session_id,
   6578 		    taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd,
   6579 		    &cipher_mech.cm_type, &mac_mech.cm_type)) !=
   6580 		    CRYPTO_SUCCESS)
   6581 			break;
   6582 
   6583 		/* do the atomic encrypt */
   6584 		if ((error = crypto_encrypt_prov(cipher_pd, 0,
   6585 		    &cipher_mech, plaintext_tmp, &cipher_key, NULL,
   6586 		    ciphertext_tmp, NULL)) != CRYPTO_SUCCESS)
   6587 			break;
   6588 
   6589 		/* do the atomic mac */
   6590 		mac_data = cipher_data;
   6591 		mac_data.cd_length = dual_data->dd_len2;
   6592 		mac_data.cd_offset = dual_data->dd_offset2;
   6593 		error = crypto_mac_prov(mac_pd, 0, &mac_mech, &mac_data,
   6594 		    &mac_key, NULL, taskq_req->dr_cipher_mac_req.mr_mac, NULL);
   6595 
   6596 		dual_data->dd_len1 = cipher_data.cd_length;
   6597 
   6598 		break;
   6599 	}
   6600 
   6601 	case DPROV_REQ_MAC_DECRYPT: {
   6602 		uint_t decrypted;
   6603 		crypto_data_t plaintext_tmp;
   6604 
   6605 		cipher_data = *((crypto_data_t *)dual_data);
   6606 
   6607 		/* do a mac update and final on the ciphertext */
   6608 		if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
   6609 		    &mac_data, NULL)) != CRYPTO_SUCCESS)
   6610 			break;
   6611 
   6612 		/* do a mac final */
   6613 		if ((error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
   6614 		    taskq_req->dr_cipher_mac_req.mr_mac, NULL)) !=
   6615 		    CRYPTO_SUCCESS)
   6616 			break;
   6617 
   6618 		/* do an decrypt update */
   6619 		cipher_data = mac_data;
   6620 		cipher_data.cd_length = dual_data->dd_len2;
   6621 		cipher_data.cd_offset = dual_data->dd_offset2;
   6622 		if (taskq_req->dr_cipher_mac_req.mr_data == NULL)
   6623 			/* in-place */
   6624 			plaintext_tmp = cipher_data;
   6625 		else
   6626 			plaintext_tmp = *taskq_req->dr_cipher_mac_req.mr_data;
   6627 
   6628 		if ((error = crypto_decrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
   6629 		    &cipher_data, taskq_req->dr_cipher_mac_req.mr_data,
   6630 		    NULL)) != CRYPTO_SUCCESS)
   6631 			break;
   6632 
   6633 		/* do an decrypt final */
   6634 		if (taskq_req->dr_cipher_mac_req.mr_data == NULL)
   6635 			/* in-place, everything must have been decrypted */
   6636 			decrypted = cipher_data.cd_length;
   6637 		else
   6638 			decrypted =
   6639 			    taskq_req->dr_cipher_mac_req.mr_data->cd_length;
   6640 		plaintext_tmp.cd_offset += decrypted;
   6641 		plaintext_tmp.cd_length -= decrypted;
   6642 
   6643 		error = crypto_decrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
   6644 		    &plaintext_tmp, NULL);
   6645 		if (taskq_req->dr_cipher_mac_req.mr_data != NULL)
   6646 			taskq_req->dr_cipher_mac_req.mr_data->cd_length +=
   6647 			    plaintext_tmp.cd_length;
   6648 
   6649 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
   6650 			DPROV_CTX_DUAL_MAC(ctx) = NULL;
   6651 			DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
   6652 			(void) dprov_free_context(ctx);
   6653 		}
   6654 		break;
   6655 	}
   6656 
   6657 	case DPROV_REQ_MAC_DECRYPT_UPDATE:
   6658 		cipher_data = *((crypto_data_t *)dual_data);
   6659 
   6660 		/* do mac update */
   6661 		if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
   6662 		    &cipher_data, NULL)) != CRYPTO_SUCCESS)
   6663 			break;
   6664 
   6665 		/* do a decrypt update */
   6666 		cipher_data.cd_length = dual_data->dd_len2;
   6667 		cipher_data.cd_offset = dual_data->dd_offset2;
   6668 		error = crypto_decrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
   6669 		    &cipher_data, taskq_req->dr_cipher_mac_req.mr_data, NULL);
   6670 
   6671 		break;
   6672 
   6673 	case DPROV_REQ_MAC_DECRYPT_FINAL:
   6674 		/* do a mac final */
   6675 		if ((error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
   6676 		    taskq_req->dr_cipher_mac_req.mr_mac, NULL)) !=
   6677 		    CRYPTO_SUCCESS)
   6678 			break;
   6679 
   6680 		/* do a decrypt final */
   6681 		error = crypto_decrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
   6682 		    taskq_req->dr_cipher_mac_req.mr_data, NULL);
   6683 
   6684 		if (error != CRYPTO_BUFFER_TOO_SMALL) {
   6685 			DPROV_CTX_DUAL_MAC(ctx) = NULL;
   6686 			DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
   6687 			(void) dprov_free_context(ctx);
   6688 		}
   6689 		break;
   6690 
   6691 	case DPROV_REQ_MAC_DECRYPT_ATOMIC:
   6692 	case DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC:
   6693 		cipher_data = *((crypto_data_t *)dual_data);
   6694 
   6695 		/* structure assignment */
   6696 		cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech;
   6697 		mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech;
   6698 		session_id = taskq_req->dr_cipher_mac_req.mr_session_id;
   6699 
   6700 		/* get the keys values and providers to use for operations */
   6701 		if ((error = dprov_cipher_mac_key_pd(softc, session_id,
   6702 		    taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd,
   6703 		    &cipher_mech.cm_type, &mac_mech.cm_type)) != CRYPTO_SUCCESS)
   6704 			break;
   6705 
   6706 		/* do the atomic mac */
   6707 		if (taskq_req->dr_type == DPROV_REQ_MAC_DECRYPT_ATOMIC)
   6708 			error = crypto_mac_prov(mac_pd, 0, &mac_mech,
   6709 			    &cipher_data, &mac_key, NULL,
   6710 			    taskq_req->dr_cipher_mac_req.mr_mac, NULL);
   6711 		else
   6712 			/* DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC */
   6713 			error = crypto_mac_verify_prov(mac_pd, 0, &mac_mech,
   6714 			    &cipher_data, &mac_key, NULL,
   6715 			    taskq_req->dr_cipher_mac_req.mr_mac, NULL);
   6716 
   6717 		if (error != CRYPTO_SUCCESS)
   6718 			break;
   6719 
   6720 		/* do the atomic decrypt */
   6721 		cipher_data.cd_length = dual_data->dd_len2;
   6722 		cipher_data.cd_offset = dual_data->dd_offset2;
   6723 		error = crypto_decrypt_prov(cipher_pd, 0, &cipher_mech,
   6724 		    &cipher_data, &cipher_key, NULL,
   6725 		    taskq_req->dr_cipher_mac_req.mr_data, NULL);
   6726 
   6727 		break;
   6728 	}
   6729 
   6730 	dprov_op_done(taskq_req, error);
   6731 	DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_cipher_mac_task: end\n",
   6732 	    instance));
   6733 }
   6734 
   6735 /*
   6736  * taskq dispatcher function for random number generation.
   6737  */
   6738 static void
   6739 dprov_random_task(dprov_req_t *taskq_req)
   6740 {
   6741 	dprov_state_t *softc;
   6742 	/* LINTED E_FUNC_SET_NOT_USED */
   6743 	int instance;
   6744 	int error = CRYPTO_SUCCESS;
   6745 
   6746 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
   6747 	DPROV_DEBUG(D_RANDOM, ("(%d) dprov_random_task: started\n", instance));
   6748 
   6749 	mutex_enter(&softc->ds_lock);
   6750 
   6751 	switch (taskq_req->dr_type) {
   6752 
   6753 	DPROV_REQ_RANDOM_SEED:
   6754 		/*
   6755 		 * Since we don't really generate random numbers
   6756 		 * nothing to do.
   6757 		 */
   6758 		break;
   6759 
   6760 	case DPROV_REQ_RANDOM_GENERATE: {
   6761 		uint_t i;
   6762 		uchar_t c = 0;
   6763 
   6764 		/*
   6765 		 * We don't generate random numbers so that the result
   6766 		 * of the operation can be checked during testing.
   6767 		 */
   6768 
   6769 		for (i = 0; i < taskq_req->dr_random_req.rr_len; i++)
   6770 			taskq_req->dr_random_req.rr_buf[i] = c++;
   6771 
   6772 		break;
   6773 	}
   6774 	}
   6775 
   6776 	mutex_exit(&softc->ds_lock);
   6777 	dprov_op_done(taskq_req, error);
   6778 	DPROV_DEBUG(D_RANDOM, ("(%d) dprov_random_task: end\n", instance));
   6779 }
   6780 
   6781 
   6782 /*
   6783  * taskq dispatcher function for session management operations.
   6784  */
   6785 static void
   6786 dprov_session_task(dprov_req_t *taskq_req)
   6787 {
   6788 	dprov_state_t *softc;
   6789 	/* LINTED E_FUNC_SET_NOT_USED */
   6790 	int instance;
   6791 	int error = CRYPTO_NOT_SUPPORTED;
   6792 	crypto_session_id_t session_id =
   6793 	    taskq_req->dr_session_req.sr_session_id;
   6794 	dprov_session_t *session;
   6795 	dprov_object_t *object;
   6796 	int i;
   6797 
   6798 	DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
   6799 	DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_task: started\n",
   6800 	    instance));
   6801 
   6802 	mutex_enter(&softc->ds_lock);
   6803