10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
51920Smcpowers * Common Development and Distribution License (the "License").
61920Smcpowers * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*11413Sopensolaris@drydog.com * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate
270Sstevel@tonic-gate /*
280Sstevel@tonic-gate * Dummy Cryptographic Provider:
290Sstevel@tonic-gate *
300Sstevel@tonic-gate * This file implements a "dummy" cryptographic provider. It is implemented
310Sstevel@tonic-gate * as a pseudo device driver.
320Sstevel@tonic-gate *
330Sstevel@tonic-gate */
340Sstevel@tonic-gate
350Sstevel@tonic-gate /*
360Sstevel@tonic-gate * This driver implements a KEF provider with the following capabilities:
370Sstevel@tonic-gate *
380Sstevel@tonic-gate * - registration/unregistration with KEF
390Sstevel@tonic-gate * - digest entry points
400Sstevel@tonic-gate * - mac entry points
410Sstevel@tonic-gate * - ctx management
420Sstevel@tonic-gate * - support for async requests
430Sstevel@tonic-gate * - cipher entry points
440Sstevel@tonic-gate * - dual entry points
450Sstevel@tonic-gate * - sign entry points
460Sstevel@tonic-gate * - verify entry points
470Sstevel@tonic-gate * - dual operations entry points
480Sstevel@tonic-gate * - dual cipher/mac operation entry points
490Sstevel@tonic-gate * - session management
500Sstevel@tonic-gate * - object management
510Sstevel@tonic-gate * - key management
520Sstevel@tonic-gate * - provider management
530Sstevel@tonic-gate *
540Sstevel@tonic-gate * In order to avoid duplicating the implementation of algorithms
550Sstevel@tonic-gate * provided by software providers, this pseudo driver acts as
560Sstevel@tonic-gate * a consumer of the framework. When invoking one of the framework's
570Sstevel@tonic-gate * entry points, the driver specifies the software provider to
580Sstevel@tonic-gate * be used for the operation.
590Sstevel@tonic-gate *
600Sstevel@tonic-gate * User management: we implement a PKCS#11 style provider which supports:
610Sstevel@tonic-gate * - one normal user with a PIN, and
620Sstevel@tonic-gate * - one SO user with a PIN.
630Sstevel@tonic-gate * These values are kept in the per-instance structure, and are initialized
640Sstevel@tonic-gate * with the provider management entry points.
650Sstevel@tonic-gate *
660Sstevel@tonic-gate */
670Sstevel@tonic-gate
680Sstevel@tonic-gate
690Sstevel@tonic-gate #include <sys/types.h>
700Sstevel@tonic-gate #include <sys/modctl.h>
710Sstevel@tonic-gate #include <sys/conf.h>
720Sstevel@tonic-gate #include <sys/stat.h>
730Sstevel@tonic-gate #include <sys/ddi.h>
740Sstevel@tonic-gate #include <sys/sunddi.h>
750Sstevel@tonic-gate #include <sys/kmem.h>
760Sstevel@tonic-gate #include <sys/errno.h>
770Sstevel@tonic-gate #include <sys/ksynch.h>
780Sstevel@tonic-gate #include <sys/file.h>
790Sstevel@tonic-gate #include <sys/open.h>
800Sstevel@tonic-gate #include <sys/cred.h>
810Sstevel@tonic-gate #include <sys/model.h>
820Sstevel@tonic-gate #include <sys/note.h>
830Sstevel@tonic-gate #include <sys/random.h>
840Sstevel@tonic-gate #include <sys/byteorder.h>
850Sstevel@tonic-gate #include <sys/crypto/common.h>
860Sstevel@tonic-gate #include <sys/crypto/spi.h>
870Sstevel@tonic-gate
880Sstevel@tonic-gate #include <sys/taskq.h>
890Sstevel@tonic-gate #include <sys/disp.h>
900Sstevel@tonic-gate #include <sys/sysmacros.h>
910Sstevel@tonic-gate #include <sys/crypto/impl.h>
920Sstevel@tonic-gate #include <sys/crypto/sched_impl.h>
93904Smcpowers
94676Sizick #include <sys/sha2.h>
957188Smcpowers #include <modes/modes.h>
967188Smcpowers #include <aes/aes_impl.h>
97904Smcpowers #include <des/des_impl.h>
985697Smcpowers #include <ecc/ecc_impl.h>
99904Smcpowers #include <blowfish/blowfish_impl.h>
100904Smcpowers
1010Sstevel@tonic-gate /*
1020Sstevel@tonic-gate * Debugging macros.
1030Sstevel@tonic-gate */
1040Sstevel@tonic-gate #ifdef DEBUG
1050Sstevel@tonic-gate #define D_INIT 0x00000001 /* _init/_fini/_info */
1060Sstevel@tonic-gate #define D_ATTACH 0x00000002 /* attach/detach */
1070Sstevel@tonic-gate #define D_DIGEST 0x00000010 /* digest entry points */
1080Sstevel@tonic-gate #define D_MAC 0x00000020 /* mac entry points */
1090Sstevel@tonic-gate #define D_CONTEXT 0x00000040 /* context entry points */
1100Sstevel@tonic-gate #define D_CIPHER 0x00000080 /* cipher entry points */
1110Sstevel@tonic-gate #define D_SIGN 0x00000100 /* sign entry points */
1120Sstevel@tonic-gate #define D_VERIFY 0x00000200 /* verify entry points */
1130Sstevel@tonic-gate #define D_SESSION 0x00000400 /* session management entry points */
1140Sstevel@tonic-gate #define D_MGMT 0x00000800 /* provider management entry points */
1150Sstevel@tonic-gate #define D_DUAL 0x00001000 /* dual ops */
1160Sstevel@tonic-gate #define D_CIPHER_MAC 0x00002000 /* cipher/mac dual ops */
1170Sstevel@tonic-gate #define D_OBJECT 0x00004000 /* object management */
1180Sstevel@tonic-gate #define D_RANDOM 0x00008000 /* random number generation */
1190Sstevel@tonic-gate #define D_KEY 0x00010000 /* key management */
1200Sstevel@tonic-gate
1210Sstevel@tonic-gate static uint32_t dprov_debug = 0;
1220Sstevel@tonic-gate
1230Sstevel@tonic-gate #define DPROV_DEBUG(f, x) if (dprov_debug & (f)) { (void) printf x; }
1240Sstevel@tonic-gate #define DPROV_CALL(f, r, x) if (dprov_debug & (f)) { (void) r x; }
1250Sstevel@tonic-gate #else /* DEBUG */
1260Sstevel@tonic-gate #define DPROV_DEBUG(f, x)
1270Sstevel@tonic-gate #define DPROV_CALL(f, r, x)
1280Sstevel@tonic-gate #endif /* DEBUG */
1290Sstevel@tonic-gate
1304219Smcpowers static int nostore_key_gen;
1314072Skrishna static boolean_t dprov_no_multipart = B_FALSE;
1324072Skrishna static int dprov_max_digestsz = INT_MAX;
1334072Skrishna
1340Sstevel@tonic-gate /*
1350Sstevel@tonic-gate * DDI entry points.
1360Sstevel@tonic-gate */
1370Sstevel@tonic-gate static int dprov_attach(dev_info_t *, ddi_attach_cmd_t);
1380Sstevel@tonic-gate static int dprov_detach(dev_info_t *, ddi_detach_cmd_t);
1390Sstevel@tonic-gate static int dprov_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
1400Sstevel@tonic-gate
1410Sstevel@tonic-gate /*
1420Sstevel@tonic-gate * Module linkage.
1430Sstevel@tonic-gate */
1440Sstevel@tonic-gate static struct cb_ops cbops = {
1450Sstevel@tonic-gate nodev, /* cb_open */
1460Sstevel@tonic-gate nodev, /* cb_close */
1470Sstevel@tonic-gate nodev, /* cb_strategy */
1480Sstevel@tonic-gate nodev, /* cb_print */
1490Sstevel@tonic-gate nodev, /* cb_dump */
1500Sstevel@tonic-gate nodev, /* cb_read */
1510Sstevel@tonic-gate nodev, /* cb_write */
1520Sstevel@tonic-gate nodev, /* cb_ioctl */
1530Sstevel@tonic-gate nodev, /* cb_devmap */
1540Sstevel@tonic-gate nodev, /* cb_mmap */
1550Sstevel@tonic-gate nodev, /* cb_segmap */
1560Sstevel@tonic-gate nochpoll, /* cb_chpoll */
1570Sstevel@tonic-gate ddi_prop_op, /* cb_prop_op */
1580Sstevel@tonic-gate NULL, /* cb_streamtab */
1590Sstevel@tonic-gate D_MP, /* cb_flag */
1600Sstevel@tonic-gate CB_REV, /* cb_rev */
1610Sstevel@tonic-gate nodev, /* cb_aread */
1620Sstevel@tonic-gate nodev, /* cb_awrite */
1630Sstevel@tonic-gate };
1640Sstevel@tonic-gate
1650Sstevel@tonic-gate static struct dev_ops devops = {
1660Sstevel@tonic-gate DEVO_REV, /* devo_rev */
1670Sstevel@tonic-gate 0, /* devo_refcnt */
1680Sstevel@tonic-gate dprov_getinfo, /* devo_getinfo */
1690Sstevel@tonic-gate nulldev, /* devo_identify */
1700Sstevel@tonic-gate nulldev, /* devo_probe */
1710Sstevel@tonic-gate dprov_attach, /* devo_attach */
1720Sstevel@tonic-gate dprov_detach, /* devo_detach */
1730Sstevel@tonic-gate nodev, /* devo_reset */
1740Sstevel@tonic-gate &cbops, /* devo_cb_ops */
1750Sstevel@tonic-gate NULL, /* devo_bus_ops */
1760Sstevel@tonic-gate NULL, /* devo_power */
1777656SSherry.Moore@Sun.COM ddi_quiesce_not_needed, /* devo_quiesce */
1780Sstevel@tonic-gate };
1790Sstevel@tonic-gate
1800Sstevel@tonic-gate static struct modldrv modldrv = {
1810Sstevel@tonic-gate &mod_driverops,
1825072Smcpowers "Pseudo KCF Prov (drv)",
1830Sstevel@tonic-gate &devops
1840Sstevel@tonic-gate };
1850Sstevel@tonic-gate
1860Sstevel@tonic-gate static struct modlcrypto modlcrypto = {
1870Sstevel@tonic-gate &mod_cryptoops,
1885072Smcpowers "Pseudo KCF Prov (crypto)"
1890Sstevel@tonic-gate };
1900Sstevel@tonic-gate
1910Sstevel@tonic-gate static struct modlinkage modlinkage = {
1920Sstevel@tonic-gate MODREV_1,
1930Sstevel@tonic-gate &modldrv,
1940Sstevel@tonic-gate &modlcrypto,
1950Sstevel@tonic-gate NULL
1960Sstevel@tonic-gate };
1970Sstevel@tonic-gate
1980Sstevel@tonic-gate /*
1990Sstevel@tonic-gate * CSPI information (entry points, provider info, etc.)
2000Sstevel@tonic-gate */
2010Sstevel@tonic-gate
2020Sstevel@tonic-gate typedef enum dprov_mech_type {
2034002Sdarrenm MD4_MECH_INFO_TYPE, /* SUN_CKM_MD4 */
2044002Sdarrenm
2050Sstevel@tonic-gate MD5_MECH_INFO_TYPE, /* SUN_CKM_MD5 */
2060Sstevel@tonic-gate MD5_HMAC_MECH_INFO_TYPE, /* SUN_CKM_MD5_HMAC */
2070Sstevel@tonic-gate MD5_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_MD5_HMAC_GENERAL */
2080Sstevel@tonic-gate
2090Sstevel@tonic-gate SHA1_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA1_HMAC */
2100Sstevel@tonic-gate SHA1_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA1_HMAC_GENERAL */
2110Sstevel@tonic-gate SHA1_MECH_INFO_TYPE, /* SUN_CKM_SHA1 */
2120Sstevel@tonic-gate
2130Sstevel@tonic-gate SHA256_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA256_HMAC */
2140Sstevel@tonic-gate SHA256_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA256_HMAC_GENERAL */
2150Sstevel@tonic-gate SHA256_MECH_INFO_TYPE, /* SUN_CKM_SHA256 */
2160Sstevel@tonic-gate SHA384_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA384_HMAC */
2170Sstevel@tonic-gate SHA384_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA384_HMAC_GENERAL */
2180Sstevel@tonic-gate SHA384_MECH_INFO_TYPE, /* SUN_CKM_SHA384 */
2190Sstevel@tonic-gate SHA512_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA512_HMAC */
2200Sstevel@tonic-gate SHA512_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA512_HMAC_GENERAL */
2210Sstevel@tonic-gate SHA512_MECH_INFO_TYPE, /* SUN_CKM_SHA512 */
2220Sstevel@tonic-gate
2230Sstevel@tonic-gate DES_CBC_MECH_INFO_TYPE, /* SUN_CKM_DES_CBC */
2240Sstevel@tonic-gate DES3_CBC_MECH_INFO_TYPE, /* SUN_CKM_DES3_CBC */
2250Sstevel@tonic-gate DES_ECB_MECH_INFO_TYPE, /* SUN_CKM_DES_ECB */
2260Sstevel@tonic-gate DES3_ECB_MECH_INFO_TYPE, /* SUN_CKM_DES3_ECB */
2270Sstevel@tonic-gate
228676Sizick BLOWFISH_CBC_MECH_INFO_TYPE, /* SUN_CKM_BLOWFISH_CBC */
229676Sizick BLOWFISH_ECB_MECH_INFO_TYPE, /* SUN_CKM_BLOWFISH_ECB */
2300Sstevel@tonic-gate AES_CBC_MECH_INFO_TYPE, /* SUN_CKM_AES_CBC */
2310Sstevel@tonic-gate AES_ECB_MECH_INFO_TYPE, /* SUN_CKM_AES_ECB */
232904Smcpowers AES_CTR_MECH_INFO_TYPE, /* SUN_CKM_AES_CTR */
2335413Sdinak AES_CCM_MECH_INFO_TYPE, /* SUN_CKM_AES_CCM */
2349339SMark.Powers@Sun.COM AES_GCM_MECH_INFO_TYPE, /* SUN_CKM_AES_GCM */
2359339SMark.Powers@Sun.COM AES_GMAC_MECH_INFO_TYPE, /* SUN_CKM_AES_GMAC */
2360Sstevel@tonic-gate RC4_MECH_INFO_TYPE, /* SUN_CKM_RC4 */
2370Sstevel@tonic-gate RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_RSA_PKCS */
2380Sstevel@tonic-gate RSA_X_509_MECH_INFO_TYPE, /* SUN_CKM_RSA_X_509 */
2390Sstevel@tonic-gate MD5_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_MD5_RSA_PKCS */
2400Sstevel@tonic-gate SHA1_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_SHA1_RSA_PKCS */
241676Sizick SHA256_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_SHA256_RSA_PKCS */
242676Sizick SHA384_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_SHA384_RSA_PKCS */
243676Sizick SHA512_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_SHA512_RSA_PKCS */
2440Sstevel@tonic-gate MD5_KEY_DERIVATION_MECH_INFO_TYPE, /* SUN_CKM_MD5_KEY_DERIVATION */
2450Sstevel@tonic-gate SHA1_KEY_DERIVATION_MECH_INFO_TYPE, /* SUN_CKM_SHA1_KEY_DERIVATION */
246676Sizick /* SUN_CKM_SHA256_KEY_DERIVATION */
247676Sizick SHA256_KEY_DERIVATION_MECH_INFO_TYPE,
248676Sizick /* SUN_CKM_SHA384_KEY_DERIVATION */
249676Sizick SHA384_KEY_DERIVATION_MECH_INFO_TYPE,
250676Sizick /* SUN_CKM_SHA512_KEY_DERIVATION */
251676Sizick SHA512_KEY_DERIVATION_MECH_INFO_TYPE,
2520Sstevel@tonic-gate DES_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_DES_KEY_GEN */
2530Sstevel@tonic-gate DES3_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_DES3_KEY_GEN */
2540Sstevel@tonic-gate AES_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_AES_KEY_GEN */
255676Sizick BLOWFISH_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_BLOWFISH_KEY_GEN */
2560Sstevel@tonic-gate RC4_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_RC4_KEY_GEN */
2575697Smcpowers EC_KEY_PAIR_GEN_MECH_INFO_TYPE, /* SUN_CKM_EC_KEY_PAIR_GEN */
2585697Smcpowers ECDSA_MECH_INFO_TYPE, /* SUN_CKM_ECDSA */
2595697Smcpowers ECDSA_SHA1_MECH_INFO_TYPE, /* SUN_CKM_ECDSA_SHA1 */
2605697Smcpowers ECDH1_DERIVE_MECH_INFO_TYPE, /* SUN_CKM_ECDH1_DERIVE */
2614424Sizick DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE, /* SUN_CKM_DH_PKCS_KEY_PAIR_GEN */
2624424Sizick DH_PKCS_DERIVE_MECH_INFO_TYPE, /* SUN_CKM_DH_PKCS_DERIVE */
2630Sstevel@tonic-gate RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE /* SUN_CKM_RSA_PKCS_KEY_PAIR_GEN */
2640Sstevel@tonic-gate } dprov_mech_type_t;
2650Sstevel@tonic-gate
2660Sstevel@tonic-gate /*
2670Sstevel@tonic-gate * Mechanism info structure passed to KCF during registration.
2680Sstevel@tonic-gate */
2690Sstevel@tonic-gate #define MD5_DIGEST_LEN 16 /* MD5 digest size */
2700Sstevel@tonic-gate #define MD5_HMAC_BLOCK_SIZE 64 /* MD5-HMAC block size */
2719364SVladimir.Kotal@Sun.COM #define MD5_HMAC_MIN_KEY_LEN 1 /* MD5-HMAC min key length in bytes */
2729364SVladimir.Kotal@Sun.COM #define MD5_HMAC_MAX_KEY_LEN INT_MAX /* MD5-HMAC max key length in bytes */
2730Sstevel@tonic-gate
2740Sstevel@tonic-gate #define SHA1_DIGEST_LEN 20 /* SHA1 digest size */
2750Sstevel@tonic-gate #define SHA1_HMAC_BLOCK_SIZE 64 /* SHA1-HMAC block size */
2769364SVladimir.Kotal@Sun.COM #define SHA1_HMAC_MIN_KEY_LEN 1 /* SHA1-HMAC min key length in bytes */
2779364SVladimir.Kotal@Sun.COM #define SHA1_HMAC_MAX_KEY_LEN INT_MAX /* SHA1-HMAC max key length in bytes */
2780Sstevel@tonic-gate
2790Sstevel@tonic-gate #define DES_KEY_LEN 8 /* DES key length in bytes */
2800Sstevel@tonic-gate #define DES3_KEY_LEN 24 /* DES3 key length in bytes */
2810Sstevel@tonic-gate
282676Sizick #define BLOWFISH_MIN_KEY_LEN 32 /* Blowfish min key length in bits */
283676Sizick #define BLOWFISH_MAX_KEY_LEN 448 /* Blowfish max key length in bits */
2840Sstevel@tonic-gate
2850Sstevel@tonic-gate #define AES_MIN_KEY_LEN 16 /* AES min key length in bytes */
2860Sstevel@tonic-gate #define AES_MAX_KEY_LEN 32 /* AES max key length in bytes */
2870Sstevel@tonic-gate
2880Sstevel@tonic-gate #define ARCFOUR_MIN_KEY_BITS 40 /* RC4 min supported key size */
2890Sstevel@tonic-gate #define ARCFOUR_MAX_KEY_BITS 2048 /* RC4 max supported key size */
2900Sstevel@tonic-gate
2910Sstevel@tonic-gate #define RSA_MIN_KEY_LEN 256 /* RSA min key length in bits */
2920Sstevel@tonic-gate #define RSA_MAX_KEY_LEN 4096 /* RSA max key length in bits */
2930Sstevel@tonic-gate
2944424Sizick #define DH_MIN_KEY_LEN 64 /* DH min key length in bits */
2954424Sizick #define DH_MAX_KEY_LEN 4096 /* DH max key length in bits */
2964424Sizick
2970Sstevel@tonic-gate #define DPROV_CKM_MD5_KEY_DERIVATION "CKM_MD5_KEY_DERIVATION"
2980Sstevel@tonic-gate #define DPROV_CKM_SHA1_KEY_DERIVATION "CKM_SHA1_KEY_DERIVATION"
299676Sizick #define DPROV_CKM_SHA256_KEY_DERIVATION "CKM_SHA256_KEY_DERIVATION"
300676Sizick #define DPROV_CKM_SHA384_KEY_DERIVATION "CKM_SHA384_KEY_DERIVATION"
301676Sizick #define DPROV_CKM_SHA512_KEY_DERIVATION "CKM_SHA512_KEY_DERIVATION"
3020Sstevel@tonic-gate #define DPROV_CKM_DES_KEY_GEN "CKM_DES_KEY_GEN"
3030Sstevel@tonic-gate #define DPROV_CKM_DES3_KEY_GEN "CKM_DES3_KEY_GEN"
3040Sstevel@tonic-gate #define DPROV_CKM_AES_KEY_GEN "CKM_AES_KEY_GEN"
305676Sizick #define DPROV_CKM_BLOWFISH_KEY_GEN "CKM_BLOWFISH_KEY_GEN"
3060Sstevel@tonic-gate #define DPROV_CKM_RC4_KEY_GEN "CKM_RC4_KEY_GEN"
3070Sstevel@tonic-gate #define DPROV_CKM_RSA_PKCS_KEY_PAIR_GEN "CKM_RSA_PKCS_KEY_PAIR_GEN"
3085697Smcpowers #define DPROV_CKM_EC_KEY_PAIR_GEN "CKM_EC_KEY_PAIR_GEN"
3095697Smcpowers #define DPROV_CKM_ECDSA "CKM_ECDSA"
3105697Smcpowers #define DPROV_CKM_ECDSA_SHA1 "CKM_ECDSA_SHA1"
3115697Smcpowers #define DPROV_CKM_ECDH1_DERIVE "CKM_ECDH1_DERIVE"
3124424Sizick #define DPROV_CKM_DH_PKCS_KEY_PAIR_GEN "CKM_DH_PKCS_KEY_PAIR_GEN"
3134424Sizick #define DPROV_CKM_DH_PKCS_DERIVE "CKM_DH_PKCS_DERIVE"
3140Sstevel@tonic-gate
3150Sstevel@tonic-gate static crypto_mech_info_t dprov_mech_info_tab[] = {
3164002Sdarrenm /* MD4 */
3174002Sdarrenm {SUN_CKM_MD4, MD4_MECH_INFO_TYPE,
3184002Sdarrenm CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
3194002Sdarrenm CRYPTO_KEYSIZE_UNIT_IN_BITS},
3200Sstevel@tonic-gate /* MD5 */
3210Sstevel@tonic-gate {SUN_CKM_MD5, MD5_MECH_INFO_TYPE,
3220Sstevel@tonic-gate CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
3230Sstevel@tonic-gate CRYPTO_KEYSIZE_UNIT_IN_BITS},
3240Sstevel@tonic-gate /* MD5-HMAC */
3250Sstevel@tonic-gate {SUN_CKM_MD5_HMAC, MD5_HMAC_MECH_INFO_TYPE,
3260Sstevel@tonic-gate CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
3270Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
3280Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
3290Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
3300Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
3310Sstevel@tonic-gate MD5_HMAC_MIN_KEY_LEN, MD5_HMAC_MAX_KEY_LEN,
3329364SVladimir.Kotal@Sun.COM CRYPTO_KEYSIZE_UNIT_IN_BYTES},
3330Sstevel@tonic-gate /* MD5-HMAC GENERAL */
3340Sstevel@tonic-gate {SUN_CKM_MD5_HMAC_GENERAL, MD5_HMAC_GEN_MECH_INFO_TYPE,
3350Sstevel@tonic-gate CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
3360Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
3370Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
3380Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
3390Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
3400Sstevel@tonic-gate MD5_HMAC_MIN_KEY_LEN, MD5_HMAC_MAX_KEY_LEN,
3419364SVladimir.Kotal@Sun.COM CRYPTO_KEYSIZE_UNIT_IN_BYTES},
3420Sstevel@tonic-gate /* SHA1 */
3430Sstevel@tonic-gate {SUN_CKM_SHA1, SHA1_MECH_INFO_TYPE,
3440Sstevel@tonic-gate CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
3450Sstevel@tonic-gate CRYPTO_KEYSIZE_UNIT_IN_BITS},
3460Sstevel@tonic-gate /* SHA1-HMAC */
3470Sstevel@tonic-gate {SUN_CKM_SHA1_HMAC, SHA1_HMAC_MECH_INFO_TYPE,
3480Sstevel@tonic-gate CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
3490Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
3500Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
3510Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
3520Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
3530Sstevel@tonic-gate SHA1_HMAC_MIN_KEY_LEN, SHA1_HMAC_MAX_KEY_LEN,
3549364SVladimir.Kotal@Sun.COM CRYPTO_KEYSIZE_UNIT_IN_BYTES},
3550Sstevel@tonic-gate /* SHA1-HMAC GENERAL */
3560Sstevel@tonic-gate {SUN_CKM_SHA1_HMAC_GENERAL, SHA1_HMAC_GEN_MECH_INFO_TYPE,
3570Sstevel@tonic-gate CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
3580Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
3590Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
3600Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
3610Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
3620Sstevel@tonic-gate SHA1_HMAC_MIN_KEY_LEN, SHA1_HMAC_MAX_KEY_LEN,
3639364SVladimir.Kotal@Sun.COM CRYPTO_KEYSIZE_UNIT_IN_BYTES},
3640Sstevel@tonic-gate /* SHA256 */
3650Sstevel@tonic-gate {SUN_CKM_SHA256, SHA256_MECH_INFO_TYPE,
3660Sstevel@tonic-gate CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
3670Sstevel@tonic-gate CRYPTO_KEYSIZE_UNIT_IN_BITS},
3680Sstevel@tonic-gate /* SHA256-HMAC */
3690Sstevel@tonic-gate {SUN_CKM_SHA256_HMAC, SHA256_HMAC_MECH_INFO_TYPE,
3700Sstevel@tonic-gate CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
3710Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
3720Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
3730Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
3740Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
3750Sstevel@tonic-gate SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
3769364SVladimir.Kotal@Sun.COM CRYPTO_KEYSIZE_UNIT_IN_BYTES},
3770Sstevel@tonic-gate /* SHA256-HMAC GENERAL */
3780Sstevel@tonic-gate {SUN_CKM_SHA256_HMAC_GENERAL, SHA256_HMAC_GEN_MECH_INFO_TYPE,
3790Sstevel@tonic-gate CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
3800Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
3810Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
3820Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
3830Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
3840Sstevel@tonic-gate SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
3859364SVladimir.Kotal@Sun.COM CRYPTO_KEYSIZE_UNIT_IN_BYTES},
3860Sstevel@tonic-gate /* SHA384 */
3870Sstevel@tonic-gate {SUN_CKM_SHA384, SHA384_MECH_INFO_TYPE,
3880Sstevel@tonic-gate CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
3890Sstevel@tonic-gate CRYPTO_KEYSIZE_UNIT_IN_BITS},
3900Sstevel@tonic-gate /* SHA384-HMAC */
3910Sstevel@tonic-gate {SUN_CKM_SHA384_HMAC, SHA384_HMAC_MECH_INFO_TYPE,
3920Sstevel@tonic-gate CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
3930Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
3940Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
3950Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
3960Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
3970Sstevel@tonic-gate SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
3989364SVladimir.Kotal@Sun.COM CRYPTO_KEYSIZE_UNIT_IN_BYTES},
3990Sstevel@tonic-gate /* SHA384-HMAC GENERAL */
4000Sstevel@tonic-gate {SUN_CKM_SHA384_HMAC_GENERAL, SHA384_HMAC_GEN_MECH_INFO_TYPE,
4010Sstevel@tonic-gate CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
4020Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
4030Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
4040Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
4050Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4060Sstevel@tonic-gate SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
4079364SVladimir.Kotal@Sun.COM CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4080Sstevel@tonic-gate /* SHA512 */
4090Sstevel@tonic-gate {SUN_CKM_SHA512, SHA512_MECH_INFO_TYPE,
4100Sstevel@tonic-gate CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
4110Sstevel@tonic-gate CRYPTO_KEYSIZE_UNIT_IN_BITS},
4120Sstevel@tonic-gate /* SHA512-HMAC */
4130Sstevel@tonic-gate {SUN_CKM_SHA512_HMAC, SHA512_HMAC_MECH_INFO_TYPE,
4140Sstevel@tonic-gate CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
4150Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
4160Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
4170Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
4180Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4190Sstevel@tonic-gate SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
4209364SVladimir.Kotal@Sun.COM CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4210Sstevel@tonic-gate /* SHA512-HMAC GENERAL */
4220Sstevel@tonic-gate {SUN_CKM_SHA512_HMAC_GENERAL, SHA512_HMAC_GEN_MECH_INFO_TYPE,
4230Sstevel@tonic-gate CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
4240Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
4250Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
4260Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
4270Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4280Sstevel@tonic-gate SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
4299364SVladimir.Kotal@Sun.COM CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4300Sstevel@tonic-gate /* DES-CBC */
4310Sstevel@tonic-gate {SUN_CKM_DES_CBC, DES_CBC_MECH_INFO_TYPE,
4320Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4330Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4340Sstevel@tonic-gate CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
4350Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4360Sstevel@tonic-gate DES_KEY_LEN, DES_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4370Sstevel@tonic-gate /* DES3-CBC */
4380Sstevel@tonic-gate {SUN_CKM_DES3_CBC, DES3_CBC_MECH_INFO_TYPE,
4390Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4400Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4410Sstevel@tonic-gate CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
4420Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4430Sstevel@tonic-gate DES3_KEY_LEN, DES3_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4440Sstevel@tonic-gate /* DES-ECB */
4450Sstevel@tonic-gate {SUN_CKM_DES_ECB, DES_ECB_MECH_INFO_TYPE,
4460Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4470Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4480Sstevel@tonic-gate CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
4490Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4500Sstevel@tonic-gate DES_KEY_LEN, DES_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4510Sstevel@tonic-gate /* DES3-ECB */
4520Sstevel@tonic-gate {SUN_CKM_DES3_ECB, DES3_ECB_MECH_INFO_TYPE,
4530Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4540Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4550Sstevel@tonic-gate CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
4560Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4570Sstevel@tonic-gate DES3_KEY_LEN, DES3_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
458676Sizick /* BLOWFISH-CBC */
459676Sizick {SUN_CKM_BLOWFISH_CBC, BLOWFISH_CBC_MECH_INFO_TYPE,
4600Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4610Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4620Sstevel@tonic-gate CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
463676Sizick CRYPTO_FG_MAC_DECRYPT_ATOMIC, BLOWFISH_MIN_KEY_LEN,
464676Sizick BLOWFISH_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
465676Sizick /* BLOWFISH-ECB */
466676Sizick {SUN_CKM_BLOWFISH_ECB, BLOWFISH_ECB_MECH_INFO_TYPE,
4670Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4680Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4690Sstevel@tonic-gate CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
470676Sizick CRYPTO_FG_MAC_DECRYPT_ATOMIC, BLOWFISH_MIN_KEY_LEN,
471676Sizick BLOWFISH_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
4720Sstevel@tonic-gate /* AES-CBC */
4730Sstevel@tonic-gate {SUN_CKM_AES_CBC, AES_CBC_MECH_INFO_TYPE,
4740Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4750Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4760Sstevel@tonic-gate CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
4770Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4780Sstevel@tonic-gate AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4790Sstevel@tonic-gate /* AES-ECB */
4800Sstevel@tonic-gate {SUN_CKM_AES_ECB, AES_ECB_MECH_INFO_TYPE,
4810Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4820Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4830Sstevel@tonic-gate CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
4840Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4850Sstevel@tonic-gate AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
486904Smcpowers /* AES-CTR */
487904Smcpowers {SUN_CKM_AES_CTR, AES_CTR_MECH_INFO_TYPE,
488904Smcpowers CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
489904Smcpowers CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
490904Smcpowers CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
491904Smcpowers CRYPTO_FG_MAC_DECRYPT_ATOMIC,
492904Smcpowers AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
4935413Sdinak /* AES-CCM */
4945413Sdinak {SUN_CKM_AES_CCM, AES_CCM_MECH_INFO_TYPE,
4955413Sdinak CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
4965413Sdinak CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
4975413Sdinak CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
4985413Sdinak CRYPTO_FG_MAC_DECRYPT_ATOMIC,
4995413Sdinak AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
5008005SMark.Powers@Sun.COM /* AES-GCM */
5018005SMark.Powers@Sun.COM {SUN_CKM_AES_GCM, AES_GCM_MECH_INFO_TYPE,
5028005SMark.Powers@Sun.COM CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
5038005SMark.Powers@Sun.COM CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
5048005SMark.Powers@Sun.COM CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
5058005SMark.Powers@Sun.COM CRYPTO_FG_MAC_DECRYPT_ATOMIC,
5068005SMark.Powers@Sun.COM AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
5079339SMark.Powers@Sun.COM /* AES-GMAC */
5089339SMark.Powers@Sun.COM {SUN_CKM_AES_GMAC, AES_GMAC_MECH_INFO_TYPE,
5099339SMark.Powers@Sun.COM CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
5109339SMark.Powers@Sun.COM CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
5119339SMark.Powers@Sun.COM CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
5129339SMark.Powers@Sun.COM CRYPTO_FG_MAC_DECRYPT_ATOMIC |
5139339SMark.Powers@Sun.COM CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
5149339SMark.Powers@Sun.COM CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
5159339SMark.Powers@Sun.COM AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
5160Sstevel@tonic-gate /* RC4 */
5170Sstevel@tonic-gate {SUN_CKM_RC4, RC4_MECH_INFO_TYPE,
5180Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
5190Sstevel@tonic-gate CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
5200Sstevel@tonic-gate ARCFOUR_MIN_KEY_BITS, ARCFOUR_MAX_KEY_BITS,
5213708Skrishna CRYPTO_KEYSIZE_UNIT_IN_BITS | CRYPTO_CAN_SHARE_OPSTATE},
5220Sstevel@tonic-gate /* RSA_PKCS */
5230Sstevel@tonic-gate {SUN_CKM_RSA_PKCS, RSA_PKCS_MECH_INFO_TYPE,
5240Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
5250Sstevel@tonic-gate CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC |
5260Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
5270Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
5280Sstevel@tonic-gate CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC |
5290Sstevel@tonic-gate CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC,
5300Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
5310Sstevel@tonic-gate /* RSA_X_509 */
5320Sstevel@tonic-gate {SUN_CKM_RSA_X_509, RSA_X_509_MECH_INFO_TYPE,
5330Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
5340Sstevel@tonic-gate CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC |
5350Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
5360Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
5370Sstevel@tonic-gate CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC |
5380Sstevel@tonic-gate CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC,
5390Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
5400Sstevel@tonic-gate /* MD5_RSA_PKCS */
5410Sstevel@tonic-gate {SUN_CKM_MD5_RSA_PKCS, MD5_RSA_PKCS_MECH_INFO_TYPE,
5420Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
5430Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
5440Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
5450Sstevel@tonic-gate /* SHA1_RSA_PKCS */
5460Sstevel@tonic-gate {SUN_CKM_SHA1_RSA_PKCS, SHA1_RSA_PKCS_MECH_INFO_TYPE,
5470Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
5480Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
5490Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
550676Sizick /* SHA256_RSA_PKCS */
551676Sizick {SUN_CKM_SHA256_RSA_PKCS, SHA256_RSA_PKCS_MECH_INFO_TYPE,
552676Sizick CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
553676Sizick CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
554676Sizick RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
555676Sizick /* SHA384_RSA_PKCS */
556676Sizick {SUN_CKM_SHA384_RSA_PKCS, SHA384_RSA_PKCS_MECH_INFO_TYPE,
557676Sizick CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
558676Sizick CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
559676Sizick RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
560676Sizick /* SHA512_RSA_PKCS */
561676Sizick {SUN_CKM_SHA512_RSA_PKCS, SHA512_RSA_PKCS_MECH_INFO_TYPE,
562676Sizick CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
563676Sizick CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
564676Sizick RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
5650Sstevel@tonic-gate /* MD5_KEY_DERIVATION */
5660Sstevel@tonic-gate {DPROV_CKM_MD5_KEY_DERIVATION, MD5_KEY_DERIVATION_MECH_INFO_TYPE,
5670Sstevel@tonic-gate CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
5680Sstevel@tonic-gate /* SHA1_KEY_DERIVATION */
5690Sstevel@tonic-gate {DPROV_CKM_SHA1_KEY_DERIVATION, SHA1_KEY_DERIVATION_MECH_INFO_TYPE,
5700Sstevel@tonic-gate CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
571676Sizick /* SHA256_KEY_DERIVATION */
572676Sizick {DPROV_CKM_SHA256_KEY_DERIVATION, SHA256_KEY_DERIVATION_MECH_INFO_TYPE,
573676Sizick CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
574676Sizick /* SHA384_KEY_DERIVATION */
575676Sizick {DPROV_CKM_SHA384_KEY_DERIVATION, SHA384_KEY_DERIVATION_MECH_INFO_TYPE,
576676Sizick CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
577676Sizick /* SHA512_KEY_DERIVATION */
578676Sizick {DPROV_CKM_SHA512_KEY_DERIVATION, SHA512_KEY_DERIVATION_MECH_INFO_TYPE,
579676Sizick CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
5800Sstevel@tonic-gate /* DES_KEY_GENERATION */
5810Sstevel@tonic-gate {DPROV_CKM_DES_KEY_GEN, DES_KEY_GEN_MECH_INFO_TYPE,
5820Sstevel@tonic-gate CRYPTO_FG_GENERATE, DES_KEY_LEN, DES_KEY_LEN,
5830Sstevel@tonic-gate CRYPTO_KEYSIZE_UNIT_IN_BYTES},
5840Sstevel@tonic-gate /* DES3_KEY_GENERATION */
5850Sstevel@tonic-gate {DPROV_CKM_DES3_KEY_GEN, DES3_KEY_GEN_MECH_INFO_TYPE,
5860Sstevel@tonic-gate CRYPTO_FG_GENERATE, DES3_KEY_LEN, DES3_KEY_LEN,
5870Sstevel@tonic-gate CRYPTO_KEYSIZE_UNIT_IN_BYTES},
5880Sstevel@tonic-gate /* AES_KEY_GENERATION */
5890Sstevel@tonic-gate {DPROV_CKM_AES_KEY_GEN, AES_KEY_GEN_MECH_INFO_TYPE,
5900Sstevel@tonic-gate CRYPTO_FG_GENERATE, AES_MIN_KEY_LEN, AES_MAX_KEY_LEN,
5910Sstevel@tonic-gate CRYPTO_KEYSIZE_UNIT_IN_BYTES},
592676Sizick /* BLOWFISH_KEY_GENERATION */
593676Sizick {DPROV_CKM_BLOWFISH_KEY_GEN, BLOWFISH_KEY_GEN_MECH_INFO_TYPE,
594676Sizick CRYPTO_FG_GENERATE, BLOWFISH_MIN_KEY_LEN, BLOWFISH_MAX_KEY_LEN,
595676Sizick CRYPTO_KEYSIZE_UNIT_IN_BYTES},
5960Sstevel@tonic-gate /* RC4_KEY_GENERATION */
5970Sstevel@tonic-gate {DPROV_CKM_RC4_KEY_GEN, RC4_KEY_GEN_MECH_INFO_TYPE,
5980Sstevel@tonic-gate CRYPTO_FG_GENERATE, ARCFOUR_MIN_KEY_BITS, ARCFOUR_MAX_KEY_BITS,
5990Sstevel@tonic-gate CRYPTO_KEYSIZE_UNIT_IN_BITS},
6004424Sizick /* DH_PKCS_KEY_PAIR_GEN */
6014424Sizick {DPROV_CKM_DH_PKCS_KEY_PAIR_GEN, DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE,
6024424Sizick CRYPTO_FG_GENERATE_KEY_PAIR, DH_MIN_KEY_LEN, DH_MAX_KEY_LEN,
6034424Sizick CRYPTO_KEYSIZE_UNIT_IN_BITS},
6044424Sizick /* DH_PKCS_DERIVE */
6054424Sizick {DPROV_CKM_DH_PKCS_DERIVE, DH_PKCS_DERIVE_MECH_INFO_TYPE,
6064424Sizick CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
6070Sstevel@tonic-gate /* RSA_PKCS_KEY_PAIR_GEN */
6080Sstevel@tonic-gate {DPROV_CKM_RSA_PKCS_KEY_PAIR_GEN, RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE,
6090Sstevel@tonic-gate CRYPTO_FG_GENERATE_KEY_PAIR, RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN,
6105697Smcpowers CRYPTO_KEYSIZE_UNIT_IN_BITS},
6115697Smcpowers /* EC_KEY_PAIR_GEN */
6125697Smcpowers {DPROV_CKM_EC_KEY_PAIR_GEN, EC_KEY_PAIR_GEN_MECH_INFO_TYPE,
6135697Smcpowers CRYPTO_FG_GENERATE_KEY_PAIR, EC_MIN_KEY_LEN, EC_MAX_KEY_LEN,
6145697Smcpowers CRYPTO_KEYSIZE_UNIT_IN_BITS},
6155697Smcpowers /* ECDSA */
6165697Smcpowers {DPROV_CKM_ECDSA, ECDSA_MECH_INFO_TYPE,
6175697Smcpowers CRYPTO_FG_SIGN | CRYPTO_FG_VERIFY |
6185697Smcpowers CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC |
6195697Smcpowers EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
6205697Smcpowers /* ECDSA_SHA1 */
6215697Smcpowers {DPROV_CKM_ECDSA_SHA1, ECDSA_SHA1_MECH_INFO_TYPE,
6225697Smcpowers CRYPTO_FG_SIGN | CRYPTO_FG_VERIFY |
6235697Smcpowers CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC |
6245697Smcpowers EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
6255697Smcpowers /* ECDH1_DERIVE */
6265697Smcpowers {DPROV_CKM_ECDH1_DERIVE, ECDH1_DERIVE_MECH_INFO_TYPE,
6275697Smcpowers CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}
6280Sstevel@tonic-gate };
6290Sstevel@tonic-gate
6304424Sizick /*
6314424Sizick * Crypto Values
6324424Sizick *
6334424Sizick * These values are the used in the STC ef test suite. If they are changed
6344424Sizick * the test suite needs to be changed.
6354424Sizick */
6364424Sizick static uchar_t dh_value[8] = { 'd', 'h', 'd', 'h', 'd', 'h', 'd', '\0' };
6374424Sizick char public_exponent[3] = { 0x01, 0x00, 0x01 };
6384424Sizick static uchar_t private_exponent[128] = {
6394424Sizick 0x8e, 0xc9, 0x70, 0x57, 0x6b, 0xcd, 0xfb, 0xa9,
6404424Sizick 0x19, 0xad, 0xcd, 0x91, 0x69, 0xd5, 0x52, 0xec,
6414424Sizick 0x72, 0x1e, 0x45, 0x15, 0x06, 0xdc, 0x65, 0x2d,
6424424Sizick 0x98, 0xc4, 0xce, 0x33, 0x54, 0x15, 0x70, 0x8d,
6434424Sizick 0xfa, 0x65, 0xea, 0x53, 0x44, 0xf3, 0x3e, 0x3f,
6444424Sizick 0xb4, 0x4c, 0x60, 0xd5, 0x01, 0x2d, 0xa4, 0x12,
6454424Sizick 0x99, 0xbf, 0x3f, 0x0b, 0xcd, 0xbb, 0x24, 0x10,
6464424Sizick 0x60, 0x30, 0x5e, 0x58, 0xf8, 0x59, 0xaa, 0xd1,
6474424Sizick 0x63, 0x3b, 0xbc, 0xcb, 0x94, 0x58, 0x38, 0x24,
6484424Sizick 0xfc, 0x65, 0x25, 0xc5, 0xa6, 0x51, 0xa2, 0x2e,
6494424Sizick 0xf1, 0x5e, 0xf5, 0xc1, 0xf5, 0x46, 0xf7, 0xbd,
6504424Sizick 0xc7, 0x62, 0xa8, 0xe2, 0x27, 0xd6, 0x94, 0x5b,
6514424Sizick 0xd3, 0xa2, 0xb5, 0x76, 0x42, 0x67, 0x6b, 0x86,
6524424Sizick 0x91, 0x97, 0x4d, 0x07, 0x92, 0x00, 0x4a, 0xdf,
6534424Sizick 0x0b, 0x65, 0x64, 0x05, 0x03, 0x48, 0x27, 0xeb,
6544424Sizick 0xce, 0x9a, 0x49, 0x7f, 0x3e, 0x10, 0xe0, 0x01
6554424Sizick };
6564424Sizick
6574424Sizick static uchar_t modulus[128] = {
6584424Sizick 0x94, 0x32, 0xb9, 0x12, 0x1d, 0x68, 0x2c, 0xda,
6594424Sizick 0x2b, 0xe0, 0xe4, 0x97, 0x1b, 0x4d, 0xdc, 0x43,
6604424Sizick 0xdf, 0x38, 0x6e, 0x7b, 0x9f, 0x07, 0x58, 0xae,
6614424Sizick 0x9d, 0x82, 0x1e, 0xc7, 0xbc, 0x92, 0xbf, 0xd3,
6624424Sizick 0xce, 0x00, 0xbb, 0x91, 0xc9, 0x79, 0x06, 0x03,
6634424Sizick 0x1f, 0xbc, 0x9f, 0x94, 0x75, 0x29, 0x5f, 0xd7,
6644424Sizick 0xc5, 0xf3, 0x73, 0x8a, 0xa4, 0x35, 0x43, 0x7a,
6654424Sizick 0x00, 0x32, 0x97, 0x3e, 0x86, 0xef, 0x70, 0x6f,
6664424Sizick 0x18, 0x56, 0x15, 0xaa, 0x6a, 0x87, 0xe7, 0x8d,
6674424Sizick 0x7d, 0xdd, 0x1f, 0xa4, 0xe4, 0x31, 0xd4, 0x7a,
6684424Sizick 0x8c, 0x0e, 0x20, 0xd2, 0x23, 0xf5, 0x57, 0x3c,
6694424Sizick 0x1b, 0xa8, 0x44, 0xa4, 0x57, 0x8f, 0x33, 0x52,
6704424Sizick 0xad, 0x83, 0xae, 0x4a, 0x97, 0xa6, 0x1e, 0xa6,
6714424Sizick 0x2b, 0xfa, 0xea, 0xeb, 0x6e, 0x71, 0xb8, 0xb6,
6724424Sizick 0x0a, 0x36, 0xed, 0x83, 0xce, 0xb0, 0xdf, 0xc1,
6734424Sizick 0xd4, 0x3a, 0xe9, 0x99, 0x6f, 0xf3, 0x96, 0xb7
6744424Sizick };
6754424Sizick
6764424Sizick
6770Sstevel@tonic-gate static void dprov_provider_status(crypto_provider_handle_t, uint_t *);
6780Sstevel@tonic-gate
6790Sstevel@tonic-gate static crypto_control_ops_t dprov_control_ops = {
6800Sstevel@tonic-gate dprov_provider_status
6810Sstevel@tonic-gate };
6820Sstevel@tonic-gate
6830Sstevel@tonic-gate #define DPROV_MANUFACTURER "SUNW "
6840Sstevel@tonic-gate #define DPROV_MODEL "dprov "
6850Sstevel@tonic-gate #define DPROV_ALLSPACES " "
6860Sstevel@tonic-gate
6870Sstevel@tonic-gate static int dprov_digest_init(crypto_ctx_t *, crypto_mechanism_t *,
6880Sstevel@tonic-gate crypto_req_handle_t);
6890Sstevel@tonic-gate static int dprov_digest(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
6900Sstevel@tonic-gate crypto_req_handle_t);
6910Sstevel@tonic-gate static int dprov_digest_update(crypto_ctx_t *, crypto_data_t *,
6920Sstevel@tonic-gate crypto_req_handle_t);
6930Sstevel@tonic-gate static int dprov_digest_key(crypto_ctx_t *, crypto_key_t *,
6940Sstevel@tonic-gate crypto_req_handle_t);
6950Sstevel@tonic-gate static int dprov_digest_final(crypto_ctx_t *, crypto_data_t *,
6960Sstevel@tonic-gate crypto_req_handle_t);
6970Sstevel@tonic-gate static int dprov_digest_atomic(crypto_provider_handle_t, crypto_session_id_t,
6980Sstevel@tonic-gate crypto_mechanism_t *, crypto_data_t *, crypto_data_t *,
6990Sstevel@tonic-gate crypto_req_handle_t);
7000Sstevel@tonic-gate
7010Sstevel@tonic-gate static crypto_digest_ops_t dprov_digest_ops = {
7020Sstevel@tonic-gate dprov_digest_init,
7030Sstevel@tonic-gate dprov_digest,
7040Sstevel@tonic-gate dprov_digest_update,
7050Sstevel@tonic-gate dprov_digest_key,
7060Sstevel@tonic-gate dprov_digest_final,
7070Sstevel@tonic-gate dprov_digest_atomic
7080Sstevel@tonic-gate };
7090Sstevel@tonic-gate
7100Sstevel@tonic-gate static int dprov_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
7110Sstevel@tonic-gate crypto_spi_ctx_template_t, crypto_req_handle_t);
7120Sstevel@tonic-gate static int dprov_mac(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
7130Sstevel@tonic-gate crypto_req_handle_t);
7140Sstevel@tonic-gate static int dprov_mac_update(crypto_ctx_t *, crypto_data_t *,
7150Sstevel@tonic-gate crypto_req_handle_t);
7160Sstevel@tonic-gate static int dprov_mac_final(crypto_ctx_t *, crypto_data_t *,
7170Sstevel@tonic-gate crypto_req_handle_t);
7180Sstevel@tonic-gate static int dprov_mac_atomic(crypto_provider_handle_t, crypto_session_id_t,
7190Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
7200Sstevel@tonic-gate crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
7210Sstevel@tonic-gate static int dprov_mac_verify_atomic(crypto_provider_handle_t,
7220Sstevel@tonic-gate crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
7230Sstevel@tonic-gate crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
7240Sstevel@tonic-gate
7250Sstevel@tonic-gate static crypto_mac_ops_t dprov_mac_ops = {
7260Sstevel@tonic-gate dprov_mac_init,
7270Sstevel@tonic-gate dprov_mac,
7280Sstevel@tonic-gate dprov_mac_update,
7290Sstevel@tonic-gate dprov_mac_final,
7300Sstevel@tonic-gate dprov_mac_atomic,
7310Sstevel@tonic-gate dprov_mac_verify_atomic
7320Sstevel@tonic-gate };
7330Sstevel@tonic-gate
7340Sstevel@tonic-gate static int dprov_encrypt_init(crypto_ctx_t *, crypto_mechanism_t *,
7350Sstevel@tonic-gate crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
7360Sstevel@tonic-gate static int dprov_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
7370Sstevel@tonic-gate crypto_req_handle_t);
7380Sstevel@tonic-gate static int dprov_encrypt_update(crypto_ctx_t *, crypto_data_t *,
7390Sstevel@tonic-gate crypto_data_t *, crypto_req_handle_t);
7400Sstevel@tonic-gate static int dprov_encrypt_final(crypto_ctx_t *, crypto_data_t *,
7410Sstevel@tonic-gate crypto_req_handle_t);
7420Sstevel@tonic-gate static int dprov_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
7430Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
7440Sstevel@tonic-gate crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
7450Sstevel@tonic-gate
7460Sstevel@tonic-gate static int dprov_decrypt_init(crypto_ctx_t *, crypto_mechanism_t *,
7470Sstevel@tonic-gate crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
7480Sstevel@tonic-gate static int dprov_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
7490Sstevel@tonic-gate crypto_req_handle_t);
7500Sstevel@tonic-gate static int dprov_decrypt_update(crypto_ctx_t *, crypto_data_t *,
7510Sstevel@tonic-gate crypto_data_t *, crypto_req_handle_t);
7520Sstevel@tonic-gate static int dprov_decrypt_final(crypto_ctx_t *, crypto_data_t *,
7530Sstevel@tonic-gate crypto_req_handle_t);
7540Sstevel@tonic-gate static int dprov_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
7550Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
7560Sstevel@tonic-gate crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
7570Sstevel@tonic-gate
7580Sstevel@tonic-gate static crypto_cipher_ops_t dprov_cipher_ops = {
7590Sstevel@tonic-gate dprov_encrypt_init,
7600Sstevel@tonic-gate dprov_encrypt,
7610Sstevel@tonic-gate dprov_encrypt_update,
7620Sstevel@tonic-gate dprov_encrypt_final,
7630Sstevel@tonic-gate dprov_encrypt_atomic,
7640Sstevel@tonic-gate dprov_decrypt_init,
7650Sstevel@tonic-gate dprov_decrypt,
7660Sstevel@tonic-gate dprov_decrypt_update,
7670Sstevel@tonic-gate dprov_decrypt_final,
7680Sstevel@tonic-gate dprov_decrypt_atomic
7690Sstevel@tonic-gate };
7700Sstevel@tonic-gate
7710Sstevel@tonic-gate static int dprov_sign_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
7720Sstevel@tonic-gate crypto_spi_ctx_template_t, crypto_req_handle_t);
7730Sstevel@tonic-gate static int dprov_sign(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
7740Sstevel@tonic-gate crypto_req_handle_t);
7750Sstevel@tonic-gate static int dprov_sign_update(crypto_ctx_t *, crypto_data_t *,
7760Sstevel@tonic-gate crypto_req_handle_t);
7770Sstevel@tonic-gate static int dprov_sign_final(crypto_ctx_t *, crypto_data_t *,
7780Sstevel@tonic-gate crypto_req_handle_t);
7790Sstevel@tonic-gate static int dprov_sign_atomic(crypto_provider_handle_t, crypto_session_id_t,
7800Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
7810Sstevel@tonic-gate crypto_spi_ctx_template_t, crypto_req_handle_t);
7820Sstevel@tonic-gate static int dprov_sign_recover_init(crypto_ctx_t *, crypto_mechanism_t *,
7830Sstevel@tonic-gate crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
7840Sstevel@tonic-gate static int dprov_sign_recover(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
7850Sstevel@tonic-gate crypto_req_handle_t);
7860Sstevel@tonic-gate static int dprov_sign_recover_atomic(crypto_provider_handle_t,
7870Sstevel@tonic-gate crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
7880Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
7890Sstevel@tonic-gate crypto_req_handle_t);
7900Sstevel@tonic-gate
7910Sstevel@tonic-gate static crypto_sign_ops_t dprov_sign_ops = {
7920Sstevel@tonic-gate dprov_sign_init,
7930Sstevel@tonic-gate dprov_sign,
7940Sstevel@tonic-gate dprov_sign_update,
7950Sstevel@tonic-gate dprov_sign_final,
7960Sstevel@tonic-gate dprov_sign_atomic,
7970Sstevel@tonic-gate dprov_sign_recover_init,
7980Sstevel@tonic-gate dprov_sign_recover,
7990Sstevel@tonic-gate dprov_sign_recover_atomic
8000Sstevel@tonic-gate };
8010Sstevel@tonic-gate
8020Sstevel@tonic-gate static int dprov_verify_init(crypto_ctx_t *, crypto_mechanism_t *,
8030Sstevel@tonic-gate crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
8040Sstevel@tonic-gate static int dprov_verify(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
8050Sstevel@tonic-gate crypto_req_handle_t);
8060Sstevel@tonic-gate static int dprov_verify_update(crypto_ctx_t *, crypto_data_t *,
8070Sstevel@tonic-gate crypto_req_handle_t);
8080Sstevel@tonic-gate static int dprov_verify_final(crypto_ctx_t *, crypto_data_t *,
8090Sstevel@tonic-gate crypto_req_handle_t);
8100Sstevel@tonic-gate static int dprov_verify_atomic(crypto_provider_handle_t, crypto_session_id_t,
8110Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
8120Sstevel@tonic-gate crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
8130Sstevel@tonic-gate static int dprov_verify_recover_init(crypto_ctx_t *, crypto_mechanism_t *,
8140Sstevel@tonic-gate crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
8150Sstevel@tonic-gate static int dprov_verify_recover(crypto_ctx_t *, crypto_data_t *,
8160Sstevel@tonic-gate crypto_data_t *, crypto_req_handle_t);
8170Sstevel@tonic-gate static int dprov_verify_recover_atomic(crypto_provider_handle_t,
8180Sstevel@tonic-gate crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
8190Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
8200Sstevel@tonic-gate crypto_req_handle_t);
8210Sstevel@tonic-gate
8220Sstevel@tonic-gate static crypto_verify_ops_t dprov_verify_ops = {
8230Sstevel@tonic-gate dprov_verify_init,
8240Sstevel@tonic-gate dprov_verify,
8250Sstevel@tonic-gate dprov_verify_update,
8260Sstevel@tonic-gate dprov_verify_final,
8270Sstevel@tonic-gate dprov_verify_atomic,
8280Sstevel@tonic-gate dprov_verify_recover_init,
8290Sstevel@tonic-gate dprov_verify_recover,
8300Sstevel@tonic-gate dprov_verify_recover_atomic
8310Sstevel@tonic-gate };
8320Sstevel@tonic-gate
8330Sstevel@tonic-gate static int dprov_digest_encrypt_update(crypto_ctx_t *, crypto_ctx_t *,
8340Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
8350Sstevel@tonic-gate static int dprov_decrypt_digest_update(crypto_ctx_t *, crypto_ctx_t *,
8360Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
8370Sstevel@tonic-gate static int dprov_sign_encrypt_update(crypto_ctx_t *, crypto_ctx_t *,
8380Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
8390Sstevel@tonic-gate static int dprov_decrypt_verify_update(crypto_ctx_t *, crypto_ctx_t *,
8400Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
8410Sstevel@tonic-gate
8420Sstevel@tonic-gate static crypto_dual_ops_t dprov_dual_ops = {
8430Sstevel@tonic-gate dprov_digest_encrypt_update,
8440Sstevel@tonic-gate dprov_decrypt_digest_update,
8450Sstevel@tonic-gate dprov_sign_encrypt_update,
8460Sstevel@tonic-gate dprov_decrypt_verify_update
8470Sstevel@tonic-gate };
8480Sstevel@tonic-gate
8490Sstevel@tonic-gate static int dprov_encrypt_mac_init(crypto_ctx_t *,
8500Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *,
8510Sstevel@tonic-gate crypto_key_t *, crypto_spi_ctx_template_t,
8520Sstevel@tonic-gate crypto_spi_ctx_template_t, crypto_req_handle_t);
8530Sstevel@tonic-gate static int dprov_encrypt_mac(crypto_ctx_t *,
8540Sstevel@tonic-gate crypto_data_t *, crypto_dual_data_t *, crypto_data_t *,
8550Sstevel@tonic-gate crypto_req_handle_t);
8560Sstevel@tonic-gate static int dprov_encrypt_mac_update(crypto_ctx_t *,
8570Sstevel@tonic-gate crypto_data_t *, crypto_dual_data_t *, crypto_req_handle_t);
8580Sstevel@tonic-gate static int dprov_encrypt_mac_final(crypto_ctx_t *,
8590Sstevel@tonic-gate crypto_dual_data_t *, crypto_data_t *, crypto_req_handle_t);
8600Sstevel@tonic-gate static int dprov_encrypt_mac_atomic(crypto_provider_handle_t,
8610Sstevel@tonic-gate crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
8620Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
8630Sstevel@tonic-gate crypto_dual_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
8640Sstevel@tonic-gate crypto_spi_ctx_template_t, crypto_req_handle_t);
8650Sstevel@tonic-gate
8660Sstevel@tonic-gate static int dprov_mac_decrypt_init(crypto_ctx_t *,
8670Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *,
8680Sstevel@tonic-gate crypto_key_t *, crypto_spi_ctx_template_t,
8690Sstevel@tonic-gate crypto_spi_ctx_template_t, crypto_req_handle_t);
8700Sstevel@tonic-gate static int dprov_mac_decrypt(crypto_ctx_t *,
8710Sstevel@tonic-gate crypto_dual_data_t *, crypto_data_t *, crypto_data_t *,
8720Sstevel@tonic-gate crypto_req_handle_t);
8730Sstevel@tonic-gate static int dprov_mac_decrypt_update(crypto_ctx_t *,
8740Sstevel@tonic-gate crypto_dual_data_t *, crypto_data_t *, crypto_req_handle_t);
8750Sstevel@tonic-gate static int dprov_mac_decrypt_final(crypto_ctx_t *,
8760Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
8770Sstevel@tonic-gate static int dprov_mac_decrypt_atomic(crypto_provider_handle_t,
8780Sstevel@tonic-gate crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
8790Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_dual_data_t *,
8800Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
8810Sstevel@tonic-gate crypto_spi_ctx_template_t, crypto_req_handle_t);
8820Sstevel@tonic-gate static int dprov_mac_verify_decrypt_atomic(crypto_provider_handle_t,
8830Sstevel@tonic-gate crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
8840Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_dual_data_t *,
8850Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
8860Sstevel@tonic-gate crypto_spi_ctx_template_t, crypto_req_handle_t);
8870Sstevel@tonic-gate
8880Sstevel@tonic-gate static crypto_dual_cipher_mac_ops_t dprov_cipher_mac_ops = {
8890Sstevel@tonic-gate dprov_encrypt_mac_init,
8900Sstevel@tonic-gate dprov_encrypt_mac,
8910Sstevel@tonic-gate dprov_encrypt_mac_update,
8920Sstevel@tonic-gate dprov_encrypt_mac_final,
8930Sstevel@tonic-gate dprov_encrypt_mac_atomic,
8940Sstevel@tonic-gate dprov_mac_decrypt_init,
8950Sstevel@tonic-gate dprov_mac_decrypt,
8960Sstevel@tonic-gate dprov_mac_decrypt_update,
8970Sstevel@tonic-gate dprov_mac_decrypt_final,
8980Sstevel@tonic-gate dprov_mac_decrypt_atomic,
8990Sstevel@tonic-gate dprov_mac_verify_decrypt_atomic
9000Sstevel@tonic-gate };
9010Sstevel@tonic-gate
9020Sstevel@tonic-gate static int dprov_seed_random(crypto_provider_handle_t, crypto_session_id_t,
9031920Smcpowers uchar_t *, size_t, uint_t, uint32_t, crypto_req_handle_t);
9040Sstevel@tonic-gate static int dprov_generate_random(crypto_provider_handle_t, crypto_session_id_t,
9050Sstevel@tonic-gate uchar_t *, size_t, crypto_req_handle_t);
9060Sstevel@tonic-gate
9070Sstevel@tonic-gate static crypto_random_number_ops_t dprov_random_number_ops = {
9080Sstevel@tonic-gate dprov_seed_random,
9090Sstevel@tonic-gate dprov_generate_random
9100Sstevel@tonic-gate };
9110Sstevel@tonic-gate
9120Sstevel@tonic-gate static int dprov_session_open(crypto_provider_handle_t, crypto_session_id_t *,
9130Sstevel@tonic-gate crypto_req_handle_t);
9140Sstevel@tonic-gate static int dprov_session_close(crypto_provider_handle_t, crypto_session_id_t,
9150Sstevel@tonic-gate crypto_req_handle_t);
9160Sstevel@tonic-gate static int dprov_session_login(crypto_provider_handle_t, crypto_session_id_t,
9170Sstevel@tonic-gate crypto_user_type_t, char *, size_t, crypto_req_handle_t);
9180Sstevel@tonic-gate static int dprov_session_logout(crypto_provider_handle_t, crypto_session_id_t,
9190Sstevel@tonic-gate crypto_req_handle_t);
9200Sstevel@tonic-gate
9210Sstevel@tonic-gate static crypto_session_ops_t dprov_session_ops = {
9220Sstevel@tonic-gate dprov_session_open,
9230Sstevel@tonic-gate dprov_session_close,
9240Sstevel@tonic-gate dprov_session_login,
9250Sstevel@tonic-gate dprov_session_logout
9260Sstevel@tonic-gate };
9270Sstevel@tonic-gate
9280Sstevel@tonic-gate static int dprov_object_create(crypto_provider_handle_t, crypto_session_id_t,
9290Sstevel@tonic-gate crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
9300Sstevel@tonic-gate crypto_req_handle_t);
9310Sstevel@tonic-gate static int dprov_object_copy(crypto_provider_handle_t, crypto_session_id_t,
9320Sstevel@tonic-gate crypto_object_id_t, crypto_object_attribute_t *, uint_t,
9330Sstevel@tonic-gate crypto_object_id_t *, crypto_req_handle_t);
9340Sstevel@tonic-gate static int dprov_object_destroy(crypto_provider_handle_t, crypto_session_id_t,
9350Sstevel@tonic-gate crypto_object_id_t, crypto_req_handle_t);
9360Sstevel@tonic-gate static int dprov_object_get_size(crypto_provider_handle_t, crypto_session_id_t,
9370Sstevel@tonic-gate crypto_object_id_t, size_t *, crypto_req_handle_t);
9380Sstevel@tonic-gate static int dprov_object_get_attribute_value(crypto_provider_handle_t,
9390Sstevel@tonic-gate crypto_session_id_t, crypto_object_id_t,
9400Sstevel@tonic-gate crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
9410Sstevel@tonic-gate static int dprov_object_set_attribute_value(crypto_provider_handle_t,
9420Sstevel@tonic-gate crypto_session_id_t, crypto_object_id_t,
9430Sstevel@tonic-gate crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
9440Sstevel@tonic-gate static int dprov_object_find_init(crypto_provider_handle_t, crypto_session_id_t,
9450Sstevel@tonic-gate crypto_object_attribute_t *, uint_t, void **,
9460Sstevel@tonic-gate crypto_req_handle_t);
9470Sstevel@tonic-gate static int dprov_object_find(crypto_provider_handle_t, void *,
9480Sstevel@tonic-gate crypto_object_id_t *, uint_t, uint_t *, crypto_req_handle_t);
9490Sstevel@tonic-gate static int dprov_object_find_final(crypto_provider_handle_t, void *,
9500Sstevel@tonic-gate crypto_req_handle_t);
9510Sstevel@tonic-gate
9520Sstevel@tonic-gate static crypto_object_ops_t dprov_object_ops = {
9530Sstevel@tonic-gate dprov_object_create,
9540Sstevel@tonic-gate dprov_object_copy,
9550Sstevel@tonic-gate dprov_object_destroy,
9560Sstevel@tonic-gate dprov_object_get_size,
9570Sstevel@tonic-gate dprov_object_get_attribute_value,
9580Sstevel@tonic-gate dprov_object_set_attribute_value,
9590Sstevel@tonic-gate dprov_object_find_init,
9600Sstevel@tonic-gate dprov_object_find,
9610Sstevel@tonic-gate dprov_object_find_final
9620Sstevel@tonic-gate };
9630Sstevel@tonic-gate
9640Sstevel@tonic-gate static int dprov_key_generate(crypto_provider_handle_t, crypto_session_id_t,
9650Sstevel@tonic-gate crypto_mechanism_t *, crypto_object_attribute_t *, uint_t,
9660Sstevel@tonic-gate crypto_object_id_t *, crypto_req_handle_t);
9670Sstevel@tonic-gate static int dprov_key_generate_pair(crypto_provider_handle_t,
9680Sstevel@tonic-gate crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *,
9690Sstevel@tonic-gate uint_t, crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
9700Sstevel@tonic-gate crypto_object_id_t *, crypto_req_handle_t);
9710Sstevel@tonic-gate static int dprov_key_wrap(crypto_provider_handle_t, crypto_session_id_t,
9720Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_object_id_t *,
9730Sstevel@tonic-gate uchar_t *, size_t *, crypto_req_handle_t);
9740Sstevel@tonic-gate static int dprov_key_unwrap(crypto_provider_handle_t, crypto_session_id_t,
9750Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, uchar_t *, size_t *,
9760Sstevel@tonic-gate crypto_object_attribute_t *, uint_t,
9770Sstevel@tonic-gate crypto_object_id_t *, crypto_req_handle_t);
9780Sstevel@tonic-gate static int dprov_key_derive(crypto_provider_handle_t, crypto_session_id_t,
9790Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_object_attribute_t *,
9800Sstevel@tonic-gate uint_t, crypto_object_id_t *, crypto_req_handle_t);
9810Sstevel@tonic-gate
9820Sstevel@tonic-gate static crypto_key_ops_t dprov_key_ops = {
9830Sstevel@tonic-gate dprov_key_generate,
9840Sstevel@tonic-gate dprov_key_generate_pair,
9850Sstevel@tonic-gate dprov_key_wrap,
9860Sstevel@tonic-gate dprov_key_unwrap,
9870Sstevel@tonic-gate dprov_key_derive
9880Sstevel@tonic-gate };
9890Sstevel@tonic-gate
9900Sstevel@tonic-gate static int dprov_ext_info(crypto_provider_handle_t,
9910Sstevel@tonic-gate crypto_provider_ext_info_t *, crypto_req_handle_t);
9920Sstevel@tonic-gate static int dprov_init_token(crypto_provider_handle_t, char *, size_t,
9930Sstevel@tonic-gate char *, crypto_req_handle_t);
9940Sstevel@tonic-gate static int dprov_init_pin(crypto_provider_handle_t, crypto_session_id_t,
9950Sstevel@tonic-gate char *, size_t, crypto_req_handle_t);
9960Sstevel@tonic-gate static int dprov_set_pin(crypto_provider_handle_t, crypto_session_id_t,
9970Sstevel@tonic-gate char *, size_t, char *, size_t, crypto_req_handle_t);
9980Sstevel@tonic-gate
9990Sstevel@tonic-gate static crypto_provider_management_ops_t dprov_management_ops = {
10000Sstevel@tonic-gate dprov_ext_info,
10010Sstevel@tonic-gate dprov_init_token,
10020Sstevel@tonic-gate dprov_init_pin,
10030Sstevel@tonic-gate dprov_set_pin
10040Sstevel@tonic-gate };
10050Sstevel@tonic-gate
10060Sstevel@tonic-gate static int dprov_free_context(crypto_ctx_t *);
1007904Smcpowers static int dprov_copyin_mechanism(crypto_provider_handle_t,
1008904Smcpowers crypto_mechanism_t *, crypto_mechanism_t *, int *error, int);
1009904Smcpowers static int dprov_copyout_mechanism(crypto_provider_handle_t,
1010904Smcpowers crypto_mechanism_t *, crypto_mechanism_t *, int *error, int);
1011904Smcpowers static int dprov_free_mechanism(crypto_provider_handle_t,
1012904Smcpowers crypto_mechanism_t *);
10130Sstevel@tonic-gate
10140Sstevel@tonic-gate static crypto_ctx_ops_t dprov_ctx_ops = {
10150Sstevel@tonic-gate NULL,
10160Sstevel@tonic-gate dprov_free_context
10170Sstevel@tonic-gate };
10180Sstevel@tonic-gate
1019904Smcpowers static crypto_mech_ops_t dprov_mech_ops = {
1020904Smcpowers dprov_copyin_mechanism,
1021904Smcpowers dprov_copyout_mechanism,
1022904Smcpowers dprov_free_mechanism
1023904Smcpowers };
1024904Smcpowers
10254219Smcpowers static int dprov_nostore_key_generate(crypto_provider_handle_t,
10264219Smcpowers crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *,
10274219Smcpowers uint_t, crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
10284424Sizick static int dprov_nostore_key_generate_pair(crypto_provider_handle_t,
10294424Sizick crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *,
10304424Sizick uint_t, crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *,
10314424Sizick uint_t, crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
10324424Sizick static int dprov_nostore_key_derive(crypto_provider_handle_t,
10334424Sizick crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
10344424Sizick crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *,
10354424Sizick uint_t, crypto_req_handle_t);
10364219Smcpowers
10374219Smcpowers static crypto_nostore_key_ops_t dprov_nostore_key_ops = {
10384219Smcpowers dprov_nostore_key_generate,
10394424Sizick dprov_nostore_key_generate_pair,
10404424Sizick dprov_nostore_key_derive
10414219Smcpowers };
10424219Smcpowers
10430Sstevel@tonic-gate static crypto_ops_t dprov_crypto_ops = {
10440Sstevel@tonic-gate &dprov_control_ops,
10450Sstevel@tonic-gate &dprov_digest_ops,
10460Sstevel@tonic-gate &dprov_cipher_ops,
10470Sstevel@tonic-gate &dprov_mac_ops,
10480Sstevel@tonic-gate &dprov_sign_ops,
10490Sstevel@tonic-gate &dprov_verify_ops,
10500Sstevel@tonic-gate &dprov_dual_ops,
10510Sstevel@tonic-gate &dprov_cipher_mac_ops,
10520Sstevel@tonic-gate &dprov_random_number_ops,
10530Sstevel@tonic-gate &dprov_session_ops,
10540Sstevel@tonic-gate &dprov_object_ops,
10550Sstevel@tonic-gate &dprov_key_ops,
10560Sstevel@tonic-gate &dprov_management_ops,
1057904Smcpowers &dprov_ctx_ops,
1058904Smcpowers &dprov_mech_ops
10590Sstevel@tonic-gate };
10600Sstevel@tonic-gate
10610Sstevel@tonic-gate
10620Sstevel@tonic-gate /* maximum SO and user PIN lengths */
10630Sstevel@tonic-gate #define DPROV_MAX_PIN_LEN 128
10640Sstevel@tonic-gate
10650Sstevel@tonic-gate /*
10660Sstevel@tonic-gate * Objects: each session is associated with an array of objects.
10670Sstevel@tonic-gate * Unlike PKCS#11, the objects cannot be shared between sessions.
10680Sstevel@tonic-gate * The ioctl driver multiplexes PKCS#11 sessions to providers
10690Sstevel@tonic-gate * sessions in order to support this semantic. This simplifies
10700Sstevel@tonic-gate * the CSPI greatly since the provider does not have to associate
10710Sstevel@tonic-gate * sessions with a user space process.
10720Sstevel@tonic-gate * There is also a per-instance array of objects, which correspond
10730Sstevel@tonic-gate * to PKCS#11 token objects. These objects can be shared by multiple
10740Sstevel@tonic-gate * sesions.
10750Sstevel@tonic-gate *
10760Sstevel@tonic-gate * Token objects are identified by having a CKA_TOKEN attribute B_TRUE.
10770Sstevel@tonic-gate * Private objects are identified by having a CKA_PRIVATE attribute
10780Sstevel@tonic-gate * set to B_TRUE.
10790Sstevel@tonic-gate */
10800Sstevel@tonic-gate
10810Sstevel@tonic-gate #define DPROV_MAX_OBJECTS 128 /* max # of objects */
10820Sstevel@tonic-gate #define DPROV_MAX_ATTR 64 /* max # of attributes per object */
10830Sstevel@tonic-gate
10840Sstevel@tonic-gate /* object description */
10850Sstevel@tonic-gate typedef struct dprov_object {
10860Sstevel@tonic-gate crypto_object_attribute_t do_attr[DPROV_MAX_ATTR]; /* attributes */
10870Sstevel@tonic-gate uint_t do_token_idx; /* index in per-instance table */
10880Sstevel@tonic-gate /* for token objects. */
10890Sstevel@tonic-gate boolean_t do_destroyed; /* object has been destroyed. */
10900Sstevel@tonic-gate /* keep object around until all */
10910Sstevel@tonic-gate /* sessions that refer to it */
10920Sstevel@tonic-gate /* are closed, but mark it */
10930Sstevel@tonic-gate /* destroyed so that references */
10940Sstevel@tonic-gate /* to the object fail. */
10950Sstevel@tonic-gate /* used for token objects only */
10960Sstevel@tonic-gate uint_t do_refcnt;
10970Sstevel@tonic-gate } dprov_object_t;
10980Sstevel@tonic-gate
10990Sstevel@tonic-gate /*
11000Sstevel@tonic-gate * If a session has a reference to a dprov_object_t,
11010Sstevel@tonic-gate * it REFHOLD()s.
11020Sstevel@tonic-gate */
11030Sstevel@tonic-gate #define DPROV_OBJECT_REFHOLD(object) { \
11040Sstevel@tonic-gate atomic_add_32(&(object)->do_refcnt, 1); \
11050Sstevel@tonic-gate ASSERT((object)->do_refcnt != 0); \
11060Sstevel@tonic-gate }
11070Sstevel@tonic-gate
11080Sstevel@tonic-gate /*
11090Sstevel@tonic-gate * Releases a reference to an object. When the last
11100Sstevel@tonic-gate * reference is released, the object is freed.
11110Sstevel@tonic-gate */
11120Sstevel@tonic-gate #define DPROV_OBJECT_REFRELE(object) { \
11130Sstevel@tonic-gate ASSERT((object)->do_refcnt != 0); \
11140Sstevel@tonic-gate membar_exit(); \
11150Sstevel@tonic-gate if (atomic_add_32_nv(&(object)->do_refcnt, -1) == 0) \
11160Sstevel@tonic-gate dprov_free_object(object); \
11170Sstevel@tonic-gate }
11180Sstevel@tonic-gate
11190Sstevel@tonic-gate /*
11200Sstevel@tonic-gate * Object attributes are passed to the provider using crypto_object_attribute
11210Sstevel@tonic-gate * structures, which contain the type of the attribute, a pointer to
11220Sstevel@tonic-gate * it's value, and the length of its value. The attribute types values
11230Sstevel@tonic-gate * are defined by the PKCS#11 specification. This provider only cares
11240Sstevel@tonic-gate * about a subset of these attributes. In order to avoid having to
11250Sstevel@tonic-gate * include the PKCS#11 header files, we define here the attributes values
11260Sstevel@tonic-gate * which are used by the provider.
11270Sstevel@tonic-gate */
11280Sstevel@tonic-gate
11290Sstevel@tonic-gate #define DPROV_CKA_CLASS 0x00000000
11300Sstevel@tonic-gate #define DPROV_CKA_TOKEN 0x00000001
11310Sstevel@tonic-gate #define DPROV_CKA_PRIVATE 0x00000002
11320Sstevel@tonic-gate #define DPROV_CKA_VALUE 0x00000011
1133904Smcpowers #define DPROV_CKA_CERTIFICATE_TYPE 0x00000080
11340Sstevel@tonic-gate #define DPROV_CKA_KEY_TYPE 0x00000100
11354219Smcpowers #define DPROV_CKA_SENSITIVE 0x00000103
11360Sstevel@tonic-gate #define DPROV_CKA_ENCRYPT 0x00000104
11370Sstevel@tonic-gate #define DPROV_CKA_DECRYPT 0x00000105
11380Sstevel@tonic-gate #define DPROV_CKA_WRAP 0x00000106
11390Sstevel@tonic-gate #define DPROV_CKA_UNWRAP 0x00000107
11400Sstevel@tonic-gate #define DPROV_CKA_SIGN 0x00000108
11410Sstevel@tonic-gate #define DPROV_CKA_SIGN_RECOVER 0x00000109
11420Sstevel@tonic-gate #define DPROV_CKA_VERIFY 0x0000010A
11430Sstevel@tonic-gate #define DPROV_CKA_VERIFY_RECOVER 0x0000010B
11440Sstevel@tonic-gate #define DPROV_CKA_DERIVE 0x0000010C
11450Sstevel@tonic-gate #define DPROV_CKA_MODULUS 0x00000120
11460Sstevel@tonic-gate #define DPROV_CKA_MODULUS_BITS 0x00000121
11470Sstevel@tonic-gate #define DPROV_CKA_PUBLIC_EXPONENT 0x00000122
11480Sstevel@tonic-gate #define DPROV_CKA_PRIVATE_EXPONENT 0x00000123
11494424Sizick #define DPROV_CKA_PRIME 0x00000130
11504424Sizick #define DPROV_CKA_BASE 0x00000132
11510Sstevel@tonic-gate #define DPROV_CKA_VALUE_BITS 0x00000160
11520Sstevel@tonic-gate #define DPROV_CKA_VALUE_LEN 0x00000161
11530Sstevel@tonic-gate #define DPROV_CKA_EXTRACTABLE 0x00000162
11545697Smcpowers #define DPROV_CKA_EC_PARAMS 0x00000180
11555697Smcpowers #define DPROV_CKA_EC_POINT 0x00000181
1156904Smcpowers #define DPROV_HW_FEATURE_TYPE 0x00000300
11570Sstevel@tonic-gate
11580Sstevel@tonic-gate /*
11590Sstevel@tonic-gate * Object classes from PKCS#11
11600Sstevel@tonic-gate */
11610Sstevel@tonic-gate #define DPROV_CKO_DATA 0x00000000
11620Sstevel@tonic-gate #define DPROV_CKO_CERTIFICATE 0x00000001
11630Sstevel@tonic-gate #define DPROV_CKO_PUBLIC_KEY 0x00000002
11640Sstevel@tonic-gate #define DPROV_CKO_PRIVATE_KEY 0x00000003
11650Sstevel@tonic-gate #define DPROV_CKO_SECRET_KEY 0x00000004
11660Sstevel@tonic-gate #define DPROV_CKO_HW_FEATURE 0x00000005
11670Sstevel@tonic-gate #define DPROV_CKO_DOMAIN_PARAMETERS 0x00000006
11680Sstevel@tonic-gate #define DPROV_CKO_VENDOR_DEFINED 0x80000000
11690Sstevel@tonic-gate
11700Sstevel@tonic-gate /*
11710Sstevel@tonic-gate * A few key types from PKCS#11
11720Sstevel@tonic-gate */
11730Sstevel@tonic-gate #define DPROV_CKK_RSA 0x00000000
11740Sstevel@tonic-gate #define DPROV_CKK_GENERIC_SECRET 0x00000010
11750Sstevel@tonic-gate #define DPROV_CKK_RC4 0x00000012
11760Sstevel@tonic-gate #define DPROV_CKK_DES 0x00000013
11770Sstevel@tonic-gate #define DPROV_CKK_DES3 0x00000015
11780Sstevel@tonic-gate #define DPROV_CKK_AES 0x0000001F
1179676Sizick #define DPROV_CKK_BLOWFISH 0x00000020
11800Sstevel@tonic-gate
11810Sstevel@tonic-gate /*
11820Sstevel@tonic-gate * Find object context. Allows the find object init/find/final
11830Sstevel@tonic-gate * to store data persistent across calls.
11840Sstevel@tonic-gate */
11850Sstevel@tonic-gate typedef struct dprov_find_ctx {
11860Sstevel@tonic-gate crypto_object_id_t fc_ids[DPROV_MAX_OBJECTS]; /* object ids */
11870Sstevel@tonic-gate uint_t fc_nids; /* number of ids in fc_ids */
11880Sstevel@tonic-gate uint_t fc_next; /* next id to return */
11890Sstevel@tonic-gate } dprov_find_ctx_t;
11900Sstevel@tonic-gate
11910Sstevel@tonic-gate /*
11920Sstevel@tonic-gate * Session management: each instance is associated with an array
11930Sstevel@tonic-gate * of sessions. KEF providers sessions are always R/W the library and
11940Sstevel@tonic-gate * the ioctl maintain the PKCS#11 R/W attributes for the session.
11950Sstevel@tonic-gate */
11960Sstevel@tonic-gate
11970Sstevel@tonic-gate #define DPROV_MIN_SESSIONS 32 /* # of sessions to start with */
11980Sstevel@tonic-gate
11990Sstevel@tonic-gate typedef enum dprov_session_state {
12000Sstevel@tonic-gate DPROV_SESSION_STATE_PUBLIC, /* public (default) */
12010Sstevel@tonic-gate DPROV_SESSION_STATE_SO, /* SO logged in */
12020Sstevel@tonic-gate DPROV_SESSION_STATE_USER /* user logged in */
12030Sstevel@tonic-gate } dprov_session_state_t;
12040Sstevel@tonic-gate
12050Sstevel@tonic-gate /* session description */
12060Sstevel@tonic-gate typedef struct dprov_session {
12070Sstevel@tonic-gate dprov_session_state_t ds_state; /* session state */
12080Sstevel@tonic-gate dprov_object_t *ds_objects[DPROV_MAX_OBJECTS]; /* session objects */
12090Sstevel@tonic-gate } dprov_session_t;
12100Sstevel@tonic-gate
12110Sstevel@tonic-gate
12120Sstevel@tonic-gate static crypto_provider_info_t dprov_prov_info = {
1213904Smcpowers CRYPTO_SPI_VERSION_2,
12140Sstevel@tonic-gate "Dummy Pseudo HW Provider",
12150Sstevel@tonic-gate CRYPTO_HW_PROVIDER,
12160Sstevel@tonic-gate NULL, /* pi_provider_dev */
12170Sstevel@tonic-gate NULL, /* pi_provider_handle */
12180Sstevel@tonic-gate &dprov_crypto_ops,
12190Sstevel@tonic-gate sizeof (dprov_mech_info_tab)/sizeof (crypto_mech_info_t),
12200Sstevel@tonic-gate dprov_mech_info_tab,
12210Sstevel@tonic-gate 0, /* pi_logical_provider_count */
12224072Skrishna NULL, /* pi_logical_providers */
12234072Skrishna 0 /* pi_flags */
12240Sstevel@tonic-gate };
12250Sstevel@tonic-gate
12260Sstevel@tonic-gate /*
12270Sstevel@tonic-gate * Per-instance info.
12280Sstevel@tonic-gate */
12290Sstevel@tonic-gate typedef struct dprov_state {
12300Sstevel@tonic-gate kmutex_t ds_lock; /* per-instance lock */
12310Sstevel@tonic-gate dev_info_t *ds_dip; /* device info */
12320Sstevel@tonic-gate crypto_kcf_provider_handle_t ds_prov_handle; /* framework handle */
12330Sstevel@tonic-gate taskq_t *ds_taskq; /* taskq for async behavior */
12340Sstevel@tonic-gate char ds_user_pin[DPROV_MAX_PIN_LEN]; /* normal user PIN */
12350Sstevel@tonic-gate uint_t ds_user_pin_len;
12360Sstevel@tonic-gate char ds_so_pin[DPROV_MAX_PIN_LEN]; /* SO PIN */
12370Sstevel@tonic-gate uint_t ds_so_pin_len;
12380Sstevel@tonic-gate dprov_session_t **ds_sessions; /* sessions for this instance */
12390Sstevel@tonic-gate uint_t ds_sessions_slots; /* number of session slots */
12400Sstevel@tonic-gate uint_t ds_sessions_count; /* number of open sessions */
12410Sstevel@tonic-gate boolean_t ds_token_initialized; /* provider initialized? */
12420Sstevel@tonic-gate boolean_t ds_user_pin_set; /* user pin set? */
12430Sstevel@tonic-gate char ds_label[CRYPTO_EXT_SIZE_LABEL]; /* "token" label */
12440Sstevel@tonic-gate dprov_object_t *ds_objects[DPROV_MAX_OBJECTS]; /* "token" objects */
12450Sstevel@tonic-gate } dprov_state_t;
12460Sstevel@tonic-gate
12470Sstevel@tonic-gate
12480Sstevel@tonic-gate /*
12490Sstevel@tonic-gate * A taskq is associated with each instance of the pseudo driver in order
12500Sstevel@tonic-gate * to simulate the asynchronous execution of requests.
12510Sstevel@tonic-gate * The following defines the taskq request structures.
12520Sstevel@tonic-gate */
12530Sstevel@tonic-gate
12540Sstevel@tonic-gate /* request types */
12550Sstevel@tonic-gate typedef enum dprov_req_type {
12560Sstevel@tonic-gate /* digest requests */
12570Sstevel@tonic-gate DPROV_REQ_DIGEST_INIT = 1,
12580Sstevel@tonic-gate DPROV_REQ_DIGEST,
12590Sstevel@tonic-gate DPROV_REQ_DIGEST_UPDATE,
12600Sstevel@tonic-gate DPROV_REQ_DIGEST_KEY,
12610Sstevel@tonic-gate DPROV_REQ_DIGEST_FINAL,
12620Sstevel@tonic-gate DPROV_REQ_DIGEST_ATOMIC,
12630Sstevel@tonic-gate /* cipher requests */
12640Sstevel@tonic-gate DPROV_REQ_ENCRYPT_INIT,
12650Sstevel@tonic-gate DPROV_REQ_ENCRYPT,
12660Sstevel@tonic-gate DPROV_REQ_ENCRYPT_UPDATE,
12670Sstevel@tonic-gate DPROV_REQ_ENCRYPT_FINAL,
12680Sstevel@tonic-gate DPROV_REQ_ENCRYPT_ATOMIC,
12690Sstevel@tonic-gate DPROV_REQ_DECRYPT_INIT,
12700Sstevel@tonic-gate DPROV_REQ_DECRYPT,
12710Sstevel@tonic-gate DPROV_REQ_DECRYPT_UPDATE,
12720Sstevel@tonic-gate DPROV_REQ_DECRYPT_FINAL,
12730Sstevel@tonic-gate DPROV_REQ_DECRYPT_ATOMIC,
12740Sstevel@tonic-gate /* mac requests */
12750Sstevel@tonic-gate DPROV_REQ_MAC_INIT,
12760Sstevel@tonic-gate DPROV_REQ_MAC,
12770Sstevel@tonic-gate DPROV_REQ_MAC_UPDATE,
12780Sstevel@tonic-gate DPROV_REQ_MAC_FINAL,
12790Sstevel@tonic-gate DPROV_REQ_MAC_ATOMIC,
12800Sstevel@tonic-gate DPROV_REQ_MAC_VERIFY_ATOMIC,
12810Sstevel@tonic-gate /* sign requests */
12820Sstevel@tonic-gate DPROV_REQ_SIGN_INIT,
12830Sstevel@tonic-gate DPROV_REQ_SIGN,
12840Sstevel@tonic-gate DPROV_REQ_SIGN_UPDATE,
12850Sstevel@tonic-gate DPROV_REQ_SIGN_FINAL,
12860Sstevel@tonic-gate DPROV_REQ_SIGN_ATOMIC,
12870Sstevel@tonic-gate DPROV_REQ_SIGN_RECOVER_INIT,
12880Sstevel@tonic-gate DPROV_REQ_SIGN_RECOVER,
12890Sstevel@tonic-gate DPROV_REQ_SIGN_RECOVER_ATOMIC,
12900Sstevel@tonic-gate /* verify requests */
12910Sstevel@tonic-gate DPROV_REQ_VERIFY_INIT,
12920Sstevel@tonic-gate DPROV_REQ_VERIFY,
12930Sstevel@tonic-gate DPROV_REQ_VERIFY_UPDATE,
12940Sstevel@tonic-gate DPROV_REQ_VERIFY_FINAL,
12950Sstevel@tonic-gate DPROV_REQ_VERIFY_ATOMIC,
12960Sstevel@tonic-gate DPROV_REQ_VERIFY_RECOVER_INIT,
12970Sstevel@tonic-gate DPROV_REQ_VERIFY_RECOVER,
12980Sstevel@tonic-gate DPROV_REQ_VERIFY_RECOVER_ATOMIC,
12990Sstevel@tonic-gate /* dual ops requests */
13000Sstevel@tonic-gate DPROV_REQ_DIGEST_ENCRYPT_UPDATE,
13010Sstevel@tonic-gate DPROV_REQ_DECRYPT_DIGEST_UPDATE,
13020Sstevel@tonic-gate DPROV_REQ_SIGN_ENCRYPT_UPDATE,
13030Sstevel@tonic-gate DPROV_REQ_DECRYPT_VERIFY_UPDATE,
13040Sstevel@tonic-gate /* dual cipher/mac requests */
13050Sstevel@tonic-gate DPROV_REQ_ENCRYPT_MAC_INIT,
13060Sstevel@tonic-gate DPROV_REQ_ENCRYPT_MAC,
13070Sstevel@tonic-gate DPROV_REQ_ENCRYPT_MAC_UPDATE,
13080Sstevel@tonic-gate DPROV_REQ_ENCRYPT_MAC_FINAL,
13090Sstevel@tonic-gate DPROV_REQ_ENCRYPT_MAC_ATOMIC,
13100Sstevel@tonic-gate DPROV_REQ_MAC_DECRYPT_INIT,
13110Sstevel@tonic-gate DPROV_REQ_MAC_DECRYPT,
13120Sstevel@tonic-gate DPROV_REQ_MAC_DECRYPT_UPDATE,
13130Sstevel@tonic-gate DPROV_REQ_MAC_DECRYPT_FINAL,
13140Sstevel@tonic-gate DPROV_REQ_MAC_DECRYPT_ATOMIC,
13150Sstevel@tonic-gate DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC,
13160Sstevel@tonic-gate /* random number ops */
13170Sstevel@tonic-gate DPROV_REQ_RANDOM_SEED,
13180Sstevel@tonic-gate DPROV_REQ_RANDOM_GENERATE,
13190Sstevel@tonic-gate /* session management requests */
13200Sstevel@tonic-gate DPROV_REQ_SESSION_OPEN,
13210Sstevel@tonic-gate DPROV_REQ_SESSION_CLOSE,
13220Sstevel@tonic-gate DPROV_REQ_SESSION_LOGIN,
13230Sstevel@tonic-gate DPROV_REQ_SESSION_LOGOUT,
13240Sstevel@tonic-gate /* object management requests */
13250Sstevel@tonic-gate DPROV_REQ_OBJECT_CREATE,
13260Sstevel@tonic-gate DPROV_REQ_OBJECT_COPY,
13270Sstevel@tonic-gate DPROV_REQ_OBJECT_DESTROY,
13280Sstevel@tonic-gate DPROV_REQ_OBJECT_GET_SIZE,
13290Sstevel@tonic-gate DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE,
13300Sstevel@tonic-gate DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE,
13310Sstevel@tonic-gate DPROV_REQ_OBJECT_FIND_INIT,
13320Sstevel@tonic-gate DPROV_REQ_OBJECT_FIND,
13330Sstevel@tonic-gate DPROV_REQ_OBJECT_FIND_FINAL,
13340Sstevel@tonic-gate /* key management requests */
13350Sstevel@tonic-gate DPROV_REQ_KEY_GENERATE,
13360Sstevel@tonic-gate DPROV_REQ_KEY_GENERATE_PAIR,
13370Sstevel@tonic-gate DPROV_REQ_KEY_WRAP,
13380Sstevel@tonic-gate DPROV_REQ_KEY_UNWRAP,
13390Sstevel@tonic-gate DPROV_REQ_KEY_DERIVE,
13400Sstevel@tonic-gate /* provider management requests */
13410Sstevel@tonic-gate DPROV_REQ_MGMT_EXTINFO,
13420Sstevel@tonic-gate DPROV_REQ_MGMT_INITTOKEN,
13430Sstevel@tonic-gate DPROV_REQ_MGMT_INITPIN,
13444219Smcpowers DPROV_REQ_MGMT_SETPIN,
13454219Smcpowers /* no (key)store key management requests */
13464424Sizick DPROV_REQ_NOSTORE_KEY_GENERATE,
13474424Sizick DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR,
13484424Sizick DPROV_REQ_NOSTORE_KEY_DERIVE
13490Sstevel@tonic-gate } dprov_req_type_t;
13500Sstevel@tonic-gate
13510Sstevel@tonic-gate /* for DPROV_REQ_DIGEST requests */
13520Sstevel@tonic-gate typedef struct dprov_digest_req {
13530Sstevel@tonic-gate crypto_mechanism_t *dr_mechanism;
13540Sstevel@tonic-gate crypto_ctx_t *dr_ctx;
13550Sstevel@tonic-gate crypto_data_t *dr_data;
13560Sstevel@tonic-gate crypto_key_t *dr_key;
13570Sstevel@tonic-gate crypto_data_t *dr_digest;
13580Sstevel@tonic-gate } dprov_digest_req_t;
13590Sstevel@tonic-gate
13600Sstevel@tonic-gate /* for DPROV_REQ_MAC requests */
13610Sstevel@tonic-gate typedef struct dprov_mac_req {
13620Sstevel@tonic-gate crypto_mechanism_t *dr_mechanism;
13630Sstevel@tonic-gate crypto_ctx_t *dr_ctx;
13644072Skrishna crypto_key_t *dr_key;
13650Sstevel@tonic-gate crypto_data_t *dr_data;
13660Sstevel@tonic-gate crypto_data_t *dr_mac;
13670Sstevel@tonic-gate crypto_session_id_t dr_session_id;
13680Sstevel@tonic-gate } dprov_mac_req_t;
13690Sstevel@tonic-gate
13700Sstevel@tonic-gate /* for DPROV_REQ_ENCRYPT and DPROV_REQ_DECRYPT requests */
13710Sstevel@tonic-gate typedef struct dprov_cipher_req {
13720Sstevel@tonic-gate crypto_mechanism_t *dr_mechanism;
13730Sstevel@tonic-gate crypto_ctx_t *dr_ctx;
13740Sstevel@tonic-gate crypto_key_t *dr_key;
13750Sstevel@tonic-gate crypto_data_t *dr_plaintext;
13760Sstevel@tonic-gate crypto_data_t *dr_ciphertext;
13770Sstevel@tonic-gate crypto_session_id_t dr_session_id;
13780Sstevel@tonic-gate } dprov_cipher_req_t;
13790Sstevel@tonic-gate
13800Sstevel@tonic-gate /* for DPROV_REQ_SIGN requests */
13810Sstevel@tonic-gate typedef struct dprov_sign_req {
13820Sstevel@tonic-gate crypto_mechanism_t *sr_mechanism;
13830Sstevel@tonic-gate crypto_ctx_t *sr_ctx;
13840Sstevel@tonic-gate crypto_key_t *sr_key;
13850Sstevel@tonic-gate crypto_data_t *sr_data;
13860Sstevel@tonic-gate crypto_data_t *sr_signature;
13870Sstevel@tonic-gate crypto_session_id_t sr_session_id;
13880Sstevel@tonic-gate } dprov_sign_req_t;
13890Sstevel@tonic-gate
13900Sstevel@tonic-gate /* for DPROV_REQ_VERIFY requests */
13910Sstevel@tonic-gate typedef struct dprov_verify_req {
13920Sstevel@tonic-gate crypto_mechanism_t *vr_mechanism;
13930Sstevel@tonic-gate crypto_ctx_t *vr_ctx;
13940Sstevel@tonic-gate crypto_key_t *vr_key;
13950Sstevel@tonic-gate crypto_data_t *vr_data;
13960Sstevel@tonic-gate crypto_data_t *vr_signature;
13970Sstevel@tonic-gate crypto_session_id_t vr_session_id;
13980Sstevel@tonic-gate } dprov_verify_req_t;
13990Sstevel@tonic-gate
14000Sstevel@tonic-gate /* for dual ops requests */
14010Sstevel@tonic-gate typedef struct dprov_dual_req {
14020Sstevel@tonic-gate crypto_ctx_t *dr_signverify_ctx;
14030Sstevel@tonic-gate crypto_ctx_t *dr_cipher_ctx;
14040Sstevel@tonic-gate crypto_data_t *dr_plaintext;
14050Sstevel@tonic-gate crypto_data_t *dr_ciphertext;
14060Sstevel@tonic-gate } dprov_dual_req_t;
14070Sstevel@tonic-gate
14080Sstevel@tonic-gate /* for cipher/mac dual ops requests */
14090Sstevel@tonic-gate typedef struct dprov_cipher_mac_req {
14100Sstevel@tonic-gate crypto_session_id_t mr_session_id;
14110Sstevel@tonic-gate crypto_ctx_t *mr_ctx;
14120Sstevel@tonic-gate crypto_mechanism_t *mr_cipher_mech;
14130Sstevel@tonic-gate crypto_key_t *mr_cipher_key;
14140Sstevel@tonic-gate crypto_mechanism_t *mr_mac_mech;
14150Sstevel@tonic-gate crypto_key_t *mr_mac_key;
14160Sstevel@tonic-gate crypto_dual_data_t *mr_dual_data;
14170Sstevel@tonic-gate crypto_data_t *mr_data;
14180Sstevel@tonic-gate crypto_data_t *mr_mac;
14190Sstevel@tonic-gate } dprov_cipher_mac_req_t;
14200Sstevel@tonic-gate
14210Sstevel@tonic-gate /* for DPROV_REQ_RANDOM requests */
14220Sstevel@tonic-gate typedef struct dprov_random_req {
14230Sstevel@tonic-gate uchar_t *rr_buf;
14240Sstevel@tonic-gate size_t rr_len;
14250Sstevel@tonic-gate crypto_session_id_t rr_session_id;
14261920Smcpowers uint_t rr_entropy_est;
14271920Smcpowers uint32_t rr_flags;
14280Sstevel@tonic-gate } dprov_random_req_t;
14290Sstevel@tonic-gate
14300Sstevel@tonic-gate /* for DPROV_REQ_SESSION requests */
14310Sstevel@tonic-gate typedef struct dprov_session_req {
14320Sstevel@tonic-gate crypto_session_id_t *sr_session_id_ptr;
14330Sstevel@tonic-gate crypto_session_id_t sr_session_id;
14340Sstevel@tonic-gate crypto_user_type_t sr_user_type;
14350Sstevel@tonic-gate char *sr_pin;
14360Sstevel@tonic-gate size_t sr_pin_len;
14370Sstevel@tonic-gate } dprov_session_req_t;
14380Sstevel@tonic-gate
14390Sstevel@tonic-gate /* for DPROV_REQ_OBJECT requests */
14400Sstevel@tonic-gate typedef struct dprov_object_req {
14410Sstevel@tonic-gate crypto_session_id_t or_session_id;
14420Sstevel@tonic-gate crypto_object_id_t or_object_id;
14430Sstevel@tonic-gate crypto_object_attribute_t *or_template;
14440Sstevel@tonic-gate uint_t or_attribute_count;
14450Sstevel@tonic-gate crypto_object_id_t *or_object_id_ptr;
14460Sstevel@tonic-gate size_t *or_object_size;
14470Sstevel@tonic-gate void **or_find_pp;
14480Sstevel@tonic-gate void *or_find_p;
14490Sstevel@tonic-gate uint_t or_max_object_count;
14500Sstevel@tonic-gate uint_t *or_object_count_ptr;
14510Sstevel@tonic-gate } dprov_object_req_t;
14520Sstevel@tonic-gate
14530Sstevel@tonic-gate /* for DPROV_REQ_KEY requests */
14540Sstevel@tonic-gate typedef struct dprov_key_req {
14550Sstevel@tonic-gate crypto_session_id_t kr_session_id;
14560Sstevel@tonic-gate crypto_mechanism_t *kr_mechanism;
14570Sstevel@tonic-gate crypto_object_attribute_t *kr_template;
14580Sstevel@tonic-gate uint_t kr_attribute_count;
14590Sstevel@tonic-gate crypto_object_id_t *kr_object_id_ptr;
14600Sstevel@tonic-gate crypto_object_attribute_t *kr_private_key_template;
14610Sstevel@tonic-gate uint_t kr_private_key_attribute_count;
14620Sstevel@tonic-gate crypto_object_id_t *kr_private_key_object_id_ptr;
14630Sstevel@tonic-gate crypto_key_t *kr_key;
14640Sstevel@tonic-gate uchar_t *kr_wrapped_key;
14650Sstevel@tonic-gate size_t *kr_wrapped_key_len_ptr;
14664219Smcpowers crypto_object_attribute_t *kr_out_template1;
14674219Smcpowers crypto_object_attribute_t *kr_out_template2;
14684219Smcpowers uint_t kr_out_attribute_count1;
14694219Smcpowers uint_t kr_out_attribute_count2;
14700Sstevel@tonic-gate } dprov_key_req_t;
14710Sstevel@tonic-gate
14720Sstevel@tonic-gate /* for DPROV_REQ_MGMT requests */
14730Sstevel@tonic-gate typedef struct dprov_mgmt_req {
14740Sstevel@tonic-gate crypto_session_id_t mr_session_id;
14750Sstevel@tonic-gate char *mr_pin;
14760Sstevel@tonic-gate size_t mr_pin_len;
14770Sstevel@tonic-gate char *mr_old_pin;
14780Sstevel@tonic-gate size_t mr_old_pin_len;
14790Sstevel@tonic-gate char *mr_label;
14800Sstevel@tonic-gate crypto_provider_ext_info_t *mr_ext_info;
14810Sstevel@tonic-gate } dprov_mgmt_req_t;
14820Sstevel@tonic-gate
14830Sstevel@tonic-gate /* request, as queued on taskq */
14840Sstevel@tonic-gate typedef struct dprov_req {
14850Sstevel@tonic-gate dprov_req_type_t dr_type;
14860Sstevel@tonic-gate dprov_state_t *dr_softc;
14870Sstevel@tonic-gate crypto_req_handle_t dr_kcf_req;
14880Sstevel@tonic-gate union {
14890Sstevel@tonic-gate dprov_digest_req_t dru_digest_req;
14900Sstevel@tonic-gate dprov_mac_req_t dru_mac_req;
14910Sstevel@tonic-gate dprov_cipher_req_t dru_cipher_req;
14920Sstevel@tonic-gate dprov_sign_req_t dru_sign_req;
14930Sstevel@tonic-gate dprov_verify_req_t dru_verify_req;
14940Sstevel@tonic-gate dprov_dual_req_t dru_dual_req;
14950Sstevel@tonic-gate dprov_cipher_mac_req_t dru_cipher_mac_req;
14960Sstevel@tonic-gate dprov_random_req_t dru_random_req;
14970Sstevel@tonic-gate dprov_session_req_t dru_session_req;
14980Sstevel@tonic-gate dprov_object_req_t dru_object_req;
14990Sstevel@tonic-gate dprov_key_req_t dru_key_req;
15000Sstevel@tonic-gate dprov_mgmt_req_t dru_mgmt_req;
15010Sstevel@tonic-gate } dr_req;
15020Sstevel@tonic-gate } dprov_req_t;
15030Sstevel@tonic-gate
15040Sstevel@tonic-gate /* shortcuts for union fields */
15050Sstevel@tonic-gate #define dr_digest_req dr_req.dru_digest_req
15060Sstevel@tonic-gate #define dr_mac_req dr_req.dru_mac_req
15070Sstevel@tonic-gate #define dr_cipher_req dr_req.dru_cipher_req
15080Sstevel@tonic-gate #define dr_sign_req dr_req.dru_sign_req
15090Sstevel@tonic-gate #define dr_verify_req dr_req.dru_verify_req
15100Sstevel@tonic-gate #define dr_dual_req dr_req.dru_dual_req
15110Sstevel@tonic-gate #define dr_cipher_mac_req dr_req.dru_cipher_mac_req
15120Sstevel@tonic-gate #define dr_random_req dr_req.dru_random_req
15130Sstevel@tonic-gate #define dr_session_req dr_req.dru_session_req
15140Sstevel@tonic-gate #define dr_object_req dr_req.dru_object_req
15150Sstevel@tonic-gate #define dr_key_req dr_req.dru_key_req
15160Sstevel@tonic-gate #define dr_mgmt_req dr_req.dru_mgmt_req
15170Sstevel@tonic-gate
15180Sstevel@tonic-gate /* prototypes for the tasq dispatcher functions */
15190Sstevel@tonic-gate static void dprov_digest_task(dprov_req_t *);
15200Sstevel@tonic-gate static void dprov_mac_task(dprov_req_t *);
15210Sstevel@tonic-gate static void dprov_sign_task(dprov_req_t *);
15220Sstevel@tonic-gate static void dprov_verify_task(dprov_req_t *);
15230Sstevel@tonic-gate static void dprov_dual_task(dprov_req_t *);
15240Sstevel@tonic-gate static void dprov_cipher_task(dprov_req_t *);
15250Sstevel@tonic-gate static void dprov_cipher_mac_task(dprov_req_t *);
15260Sstevel@tonic-gate static void dprov_random_task(dprov_req_t *);
15270Sstevel@tonic-gate static void dprov_session_task(dprov_req_t *);
15280Sstevel@tonic-gate static void dprov_object_task(dprov_req_t *);
15290Sstevel@tonic-gate static void dprov_key_task(dprov_req_t *);
15300Sstevel@tonic-gate static void dprov_mgmt_task(dprov_req_t *);
15310Sstevel@tonic-gate
15320Sstevel@tonic-gate /* helper functions */
15330Sstevel@tonic-gate static int dprov_digest_submit_req(dprov_req_type_t, dprov_state_t *,
15340Sstevel@tonic-gate crypto_req_handle_t, crypto_mechanism_t *, crypto_data_t *, crypto_key_t *,
15350Sstevel@tonic-gate crypto_data_t *, crypto_ctx_t *, int);
15360Sstevel@tonic-gate static int dprov_cipher_submit_req(dprov_req_type_t, dprov_state_t *,
15370Sstevel@tonic-gate crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
15380Sstevel@tonic-gate crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
15390Sstevel@tonic-gate static int dprov_mac_submit_req(dprov_req_type_t, dprov_state_t *,
15400Sstevel@tonic-gate crypto_req_handle_t, crypto_mechanism_t *, crypto_data_t *,
15410Sstevel@tonic-gate crypto_key_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
15420Sstevel@tonic-gate static int dprov_sign_submit_req(dprov_req_type_t, dprov_state_t *,
15430Sstevel@tonic-gate crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *,
15440Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
15450Sstevel@tonic-gate static int dprov_verify_submit_req(dprov_req_type_t, dprov_state_t *,
15460Sstevel@tonic-gate crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *,
15470Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
15480Sstevel@tonic-gate static int dprov_dual_submit_req(dprov_req_type_t, dprov_state_t *,
15490Sstevel@tonic-gate crypto_req_handle_t, crypto_ctx_t *, crypto_ctx_t *, crypto_data_t *,
15500Sstevel@tonic-gate crypto_data_t *);
15510Sstevel@tonic-gate static int dprov_cipher_mac_submit_req(dprov_req_type_t, dprov_state_t *,
15520Sstevel@tonic-gate crypto_req_handle_t, crypto_ctx_t *, crypto_session_id_t,
15530Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *, crypto_key_t *,
15540Sstevel@tonic-gate crypto_dual_data_t *, crypto_data_t *, crypto_data_t *, int);
15550Sstevel@tonic-gate static int dprov_random_submit_req(dprov_req_type_t, dprov_state_t *,
15561920Smcpowers crypto_req_handle_t, uchar_t *, size_t, crypto_session_id_t, uint_t,
15571920Smcpowers uint32_t);
15580Sstevel@tonic-gate static int dprov_session_submit_req(dprov_req_type_t, dprov_state_t *,
15590Sstevel@tonic-gate crypto_req_handle_t, crypto_session_id_t *, crypto_session_id_t,
15600Sstevel@tonic-gate crypto_user_type_t, char *, size_t);
15610Sstevel@tonic-gate static int dprov_object_submit_req(dprov_req_type_t, dprov_state_t *,
15620Sstevel@tonic-gate crypto_req_handle_t, crypto_session_id_t, crypto_object_id_t,
15630Sstevel@tonic-gate crypto_object_attribute_t *, uint_t, crypto_object_id_t *, size_t *,
15640Sstevel@tonic-gate void **, void *, uint_t, uint_t *, int);
15650Sstevel@tonic-gate static int dprov_key_submit_req(dprov_req_type_t, dprov_state_t *,
15660Sstevel@tonic-gate crypto_req_handle_t, crypto_session_id_t, crypto_mechanism_t *,
15670Sstevel@tonic-gate crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
15680Sstevel@tonic-gate crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
15694219Smcpowers crypto_key_t *, uchar_t *, size_t *, crypto_object_attribute_t *,
15704219Smcpowers uint_t, crypto_object_attribute_t *, uint_t);
15710Sstevel@tonic-gate static int dprov_mgmt_submit_req(dprov_req_type_t, dprov_state_t *,
15720Sstevel@tonic-gate crypto_req_handle_t, crypto_session_id_t, char *, size_t, char *, size_t,
15730Sstevel@tonic-gate char *, crypto_provider_ext_info_t *);
15740Sstevel@tonic-gate static int dprov_get_sw_prov(crypto_mechanism_t *, kcf_provider_desc_t **,
15750Sstevel@tonic-gate crypto_mech_type_t *);
15760Sstevel@tonic-gate
15770Sstevel@tonic-gate /* object management helper functions */
15780Sstevel@tonic-gate static void dprov_free_object(dprov_object_t *);
15790Sstevel@tonic-gate static void dprov_release_session_objects(dprov_session_t *);
15805697Smcpowers static void dprov_adjust_attrs(crypto_object_attribute_t *, int);
15810Sstevel@tonic-gate static boolean_t dprov_object_is_private(dprov_object_t *);
15820Sstevel@tonic-gate static boolean_t dprov_object_is_token(dprov_object_t *);
15830Sstevel@tonic-gate static int dprov_key_value_secret(dprov_state_t *, crypto_session_id_t,
15840Sstevel@tonic-gate dprov_req_type_t, crypto_key_t *, crypto_key_t *);
15850Sstevel@tonic-gate static int dprov_key_attr_asymmetric(dprov_state_t *, crypto_session_id_t,
15860Sstevel@tonic-gate dprov_req_type_t, crypto_key_t *, crypto_key_t *);
15870Sstevel@tonic-gate static int dprov_get_object_attr_boolean(dprov_object_t *, uint64_t,
15880Sstevel@tonic-gate boolean_t *);
15890Sstevel@tonic-gate static int dprov_get_object_attr_ulong(dprov_object_t *, uint64_t, ulong_t *);
15900Sstevel@tonic-gate static int dprov_get_object_attr_array(dprov_object_t *, uint64_t, void **,
15910Sstevel@tonic-gate size_t *);
15920Sstevel@tonic-gate static int dprov_get_key_attr_ulong(crypto_key_t *, uint64_t, ulong_t *);
15930Sstevel@tonic-gate static int dprov_get_key_attr_array(crypto_key_t *, uint64_t, void **,
15940Sstevel@tonic-gate size_t *);
15950Sstevel@tonic-gate static int dprov_create_object_from_template(dprov_state_t *, dprov_session_t *,
15960Sstevel@tonic-gate crypto_object_attribute_t *, uint_t, crypto_object_id_t *, boolean_t,
15970Sstevel@tonic-gate boolean_t);
15980Sstevel@tonic-gate static int dprov_get_template_attr_scalar_common(crypto_object_attribute_t *,
15990Sstevel@tonic-gate uint_t, uint64_t, void *, size_t);
16000Sstevel@tonic-gate static int dprov_get_template_attr_boolean(crypto_object_attribute_t *,
16010Sstevel@tonic-gate uint_t, uint64_t, boolean_t *);
16020Sstevel@tonic-gate static int dprov_get_template_attr_ulong(crypto_object_attribute_t *, uint_t,
16030Sstevel@tonic-gate uint64_t, ulong_t *);
16040Sstevel@tonic-gate static int dprov_template_attr_present(crypto_object_attribute_t *, uint_t,
16050Sstevel@tonic-gate uint64_t);
16060Sstevel@tonic-gate static int dprov_get_template_attr_array(crypto_object_attribute_t *, uint_t,
16070Sstevel@tonic-gate uint64_t, void **, size_t *);
16080Sstevel@tonic-gate static int dprov_destroy_object(dprov_state_t *, dprov_session_t *,
16090Sstevel@tonic-gate crypto_object_id_t);
16100Sstevel@tonic-gate static int dprov_object_set_attr(dprov_session_t *, crypto_object_id_t,
16110Sstevel@tonic-gate crypto_object_attribute_t *, uint_t, boolean_t);
16120Sstevel@tonic-gate static int dprov_find_attr(crypto_object_attribute_t *, uint_t, uint64_t);
16130Sstevel@tonic-gate static boolean_t dprov_attributes_match(dprov_object_t *,
16140Sstevel@tonic-gate crypto_object_attribute_t *, uint_t);
16150Sstevel@tonic-gate
16160Sstevel@tonic-gate /* retrieve the softc and instance number from a SPI crypto context */
16170Sstevel@tonic-gate #define DPROV_SOFTC_FROM_CTX(ctx, softc, instance) { \
16180Sstevel@tonic-gate (softc) = (dprov_state_t *)(ctx)->cc_provider; \
16190Sstevel@tonic-gate (instance) = ddi_get_instance((softc)->ds_dip); \
16200Sstevel@tonic-gate }
16210Sstevel@tonic-gate
16220Sstevel@tonic-gate /* retrieve the softc and instance number from a taskq request */
16230Sstevel@tonic-gate #define DPROV_SOFTC_FROM_REQ(req, softc, instance) { \
16240Sstevel@tonic-gate (softc) = (req)->dr_softc; \
16250Sstevel@tonic-gate (instance) = ddi_get_instance((softc)->ds_dip); \
16260Sstevel@tonic-gate }
16270Sstevel@tonic-gate
16280Sstevel@tonic-gate /*
16290Sstevel@tonic-gate * The dprov private context most of the time contains a pointer to the
16300Sstevel@tonic-gate * crypto_context_t that was allocated when calling a KCF function.
16310Sstevel@tonic-gate * Dual cipher/mac operations however require the dprov driver
16320Sstevel@tonic-gate * to maintain the contexts associated with the separate cipher
16330Sstevel@tonic-gate * and mac operations. These two types of dprov contexts are
16340Sstevel@tonic-gate * defined below.
16350Sstevel@tonic-gate */
16360Sstevel@tonic-gate typedef enum dprov_ctx_type {
16370Sstevel@tonic-gate DPROV_CTX_SINGLE,
16380Sstevel@tonic-gate DPROV_CTX_DUAL
16390Sstevel@tonic-gate } dprov_ctx_type_t;
16400Sstevel@tonic-gate
16410Sstevel@tonic-gate /*
16420Sstevel@tonic-gate * When the context refers to a single KCF context, the
16430Sstevel@tonic-gate * cc_provider field of a crypto_ctx_t points to a structure of
16440Sstevel@tonic-gate * type dprov_ctx_single.
16450Sstevel@tonic-gate */
16460Sstevel@tonic-gate typedef struct dprov_ctx_single {
16470Sstevel@tonic-gate dprov_ctx_type_t dc_type;
16480Sstevel@tonic-gate crypto_context_t dc_ctx;
16494072Skrishna boolean_t dc_svrfy_to_mac;
16500Sstevel@tonic-gate } dprov_ctx_single_t;
16510Sstevel@tonic-gate
16520Sstevel@tonic-gate /*
16530Sstevel@tonic-gate * When the context is used for cipher/mac operations, it contains
16540Sstevel@tonic-gate * pointers to to KCF contexts, one for the cipher operation, the
16550Sstevel@tonic-gate * other for the mac operation.
16560Sstevel@tonic-gate */
16570Sstevel@tonic-gate typedef struct dprov_ctx_dual {
16580Sstevel@tonic-gate dprov_ctx_type_t cd_type;
16590Sstevel@tonic-gate crypto_context_t cd_cipher_ctx;
16600Sstevel@tonic-gate crypto_context_t cd_mac_ctx;
16610Sstevel@tonic-gate } dprov_ctx_dual_t;
16620Sstevel@tonic-gate
16630Sstevel@tonic-gate /*
16640Sstevel@tonic-gate * Helper macros for context accessors. These macros return the
16650Sstevel@tonic-gate * k-API context corresponding to the given SPI context for
16660Sstevel@tonic-gate * single and dual cipher/mac operations.
16670Sstevel@tonic-gate */
16680Sstevel@tonic-gate
16694072Skrishna #define DPROV_CTX_P(_ctx) \
16704072Skrishna ((dprov_ctx_single_t *)(_ctx)->cc_provider_private)
16714072Skrishna
16724072Skrishna #define DPROV_CTX_SINGLE(_ctx) ((DPROV_CTX_P(_ctx))->dc_ctx)
16730Sstevel@tonic-gate
16740Sstevel@tonic-gate #define DPROV_CTX_DUAL_CIPHER(_ctx) \
16750Sstevel@tonic-gate (((dprov_ctx_dual_t *)(_ctx)->cc_provider_private)->cd_cipher_ctx)
16760Sstevel@tonic-gate
16770Sstevel@tonic-gate #define DPROV_CTX_DUAL_MAC(_ctx) \
16780Sstevel@tonic-gate (((dprov_ctx_dual_t *)(_ctx)->cc_provider_private)->cd_mac_ctx)
16790Sstevel@tonic-gate
16800Sstevel@tonic-gate static int dprov_alloc_context(dprov_req_type_t, crypto_ctx_t *);
16810Sstevel@tonic-gate
16820Sstevel@tonic-gate
16830Sstevel@tonic-gate
16840Sstevel@tonic-gate static void *statep; /* state pointer */
16850Sstevel@tonic-gate
16860Sstevel@tonic-gate /*
16870Sstevel@tonic-gate * DDI entry points.
16880Sstevel@tonic-gate */
16890Sstevel@tonic-gate int
_init(void)16900Sstevel@tonic-gate _init(void)
16910Sstevel@tonic-gate {
16920Sstevel@tonic-gate int error;
16930Sstevel@tonic-gate
16940Sstevel@tonic-gate DPROV_DEBUG(D_INIT, ("dprov: in _init\n"));
16950Sstevel@tonic-gate
16960Sstevel@tonic-gate if ((error = ddi_soft_state_init(&statep, sizeof (dprov_state_t),
16970Sstevel@tonic-gate 0)) != 0)
16980Sstevel@tonic-gate return (error);
16990Sstevel@tonic-gate
17000Sstevel@tonic-gate return (mod_install(&modlinkage));
17010Sstevel@tonic-gate }
17020Sstevel@tonic-gate
17030Sstevel@tonic-gate int
_fini(void)17040Sstevel@tonic-gate _fini(void)
17050Sstevel@tonic-gate {
17060Sstevel@tonic-gate int error;
17070Sstevel@tonic-gate
17080Sstevel@tonic-gate DPROV_DEBUG(D_INIT, ("dprov: in _fini\n"));
17090Sstevel@tonic-gate
17100Sstevel@tonic-gate if ((error = mod_remove(&modlinkage)) != 0)
17110Sstevel@tonic-gate return (error);
17120Sstevel@tonic-gate
17130Sstevel@tonic-gate ddi_soft_state_fini(&statep);
17140Sstevel@tonic-gate
17150Sstevel@tonic-gate return (0);
17160Sstevel@tonic-gate }
17170Sstevel@tonic-gate
17180Sstevel@tonic-gate int
_info(struct modinfo * modinfop)17190Sstevel@tonic-gate _info(struct modinfo *modinfop)
17200Sstevel@tonic-gate {
17210Sstevel@tonic-gate DPROV_DEBUG(D_INIT, ("dprov: in _info\n"));
17220Sstevel@tonic-gate
17230Sstevel@tonic-gate return (mod_info(&modlinkage, modinfop));
17240Sstevel@tonic-gate }
17250Sstevel@tonic-gate
17260Sstevel@tonic-gate /* ARGSUSED */
17270Sstevel@tonic-gate static int
dprov_getinfo(dev_info_t * dip,ddi_info_cmd_t cmd,void * arg,void ** result)17280Sstevel@tonic-gate dprov_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
17290Sstevel@tonic-gate {
17300Sstevel@tonic-gate int instance = getminor((dev_t)arg);
17310Sstevel@tonic-gate dprov_state_t *softc;
17320Sstevel@tonic-gate
17330Sstevel@tonic-gate DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_getinfo() for %d\n",
17340Sstevel@tonic-gate instance));
17350Sstevel@tonic-gate
17360Sstevel@tonic-gate switch (cmd) {
17370Sstevel@tonic-gate case DDI_INFO_DEVT2DEVINFO:
17380Sstevel@tonic-gate softc = ddi_get_soft_state(statep, instance);
17390Sstevel@tonic-gate *result = softc->ds_dip;
17400Sstevel@tonic-gate return (DDI_SUCCESS);
17410Sstevel@tonic-gate
17420Sstevel@tonic-gate case DDI_INFO_DEVT2INSTANCE:
17430Sstevel@tonic-gate *result = (void *)(uintptr_t)instance;
17440Sstevel@tonic-gate return (DDI_SUCCESS);
17450Sstevel@tonic-gate }
17460Sstevel@tonic-gate return (DDI_FAILURE);
17470Sstevel@tonic-gate }
17480Sstevel@tonic-gate
17490Sstevel@tonic-gate static int
dprov_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)17500Sstevel@tonic-gate dprov_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
17510Sstevel@tonic-gate {
17520Sstevel@tonic-gate int instance = ddi_get_instance(dip);
17530Sstevel@tonic-gate dprov_state_t *softc;
17540Sstevel@tonic-gate char devname[256];
17550Sstevel@tonic-gate int ret;
17560Sstevel@tonic-gate
17570Sstevel@tonic-gate DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_attach() for %d\n",
17580Sstevel@tonic-gate instance));
17590Sstevel@tonic-gate
17600Sstevel@tonic-gate if (cmd != DDI_ATTACH) {
17610Sstevel@tonic-gate return (DDI_FAILURE);
17620Sstevel@tonic-gate }
17630Sstevel@tonic-gate
17640Sstevel@tonic-gate /* get new softc and initialize it */
17650Sstevel@tonic-gate if (ddi_soft_state_zalloc(statep, instance) != DDI_SUCCESS)
17660Sstevel@tonic-gate return (DDI_FAILURE);
17670Sstevel@tonic-gate
17680Sstevel@tonic-gate softc = ddi_get_soft_state(statep, instance);
17690Sstevel@tonic-gate mutex_init(&softc->ds_lock, NULL, MUTEX_DRIVER, NULL);
17700Sstevel@tonic-gate softc->ds_dip = dip;
17710Sstevel@tonic-gate softc->ds_prov_handle = NULL;
17720Sstevel@tonic-gate
17730Sstevel@tonic-gate /* create minor node */
17744427Sizick (void) sprintf(devname, "dprov%d", instance);
17750Sstevel@tonic-gate if (ddi_create_minor_node(dip, devname, S_IFCHR, instance,
17760Sstevel@tonic-gate DDI_PSEUDO, 0) != DDI_SUCCESS) {
17770Sstevel@tonic-gate cmn_err(CE_WARN, "attach: failed creating minor node");
17780Sstevel@tonic-gate mutex_destroy(&softc->ds_lock);
17790Sstevel@tonic-gate ddi_soft_state_free(statep, instance);
17800Sstevel@tonic-gate return (DDI_FAILURE);
17810Sstevel@tonic-gate }
17820Sstevel@tonic-gate
17834219Smcpowers nostore_key_gen = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
17844219Smcpowers DDI_PROP_DONTPASS, "nostore_key_gen", 0);
17854219Smcpowers if (nostore_key_gen != 0) {
17864219Smcpowers dprov_prov_info.pi_interface_version = CRYPTO_SPI_VERSION_3;
17874219Smcpowers dprov_crypto_ops.co_object_ops = NULL;
17884219Smcpowers dprov_crypto_ops.co_nostore_key_ops = &dprov_nostore_key_ops;
17894219Smcpowers }
17904219Smcpowers
17914072Skrishna dprov_max_digestsz = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
17924072Skrishna DDI_PROP_DONTPASS, "max_digest_sz", INT_MAX);
17934072Skrishna if (dprov_max_digestsz != INT_MAX && dprov_max_digestsz != 0 &&
17944072Skrishna dprov_max_digestsz != DDI_PROP_NOT_FOUND) {
17954072Skrishna dprov_no_multipart = B_TRUE;
179611304SJanie.Lu@Sun.COM dprov_prov_info.pi_flags |=
179711304SJanie.Lu@Sun.COM (CRYPTO_HASH_NO_UPDATE | CRYPTO_HMAC_NO_UPDATE);
17984072Skrishna }
17994072Skrishna
18000Sstevel@tonic-gate /* create taskq */
18010Sstevel@tonic-gate softc->ds_taskq = taskq_create(devname, 1, minclsyspri,
18020Sstevel@tonic-gate crypto_taskq_minalloc, crypto_taskq_maxalloc, TASKQ_PREPOPULATE);
18030Sstevel@tonic-gate
18040Sstevel@tonic-gate /* initialize table of sessions */
18050Sstevel@tonic-gate softc->ds_sessions = kmem_zalloc(DPROV_MIN_SESSIONS *
18060Sstevel@tonic-gate sizeof (dprov_session_t *), KM_SLEEP);
18070Sstevel@tonic-gate softc->ds_sessions_slots = DPROV_MIN_SESSIONS;
18080Sstevel@tonic-gate softc->ds_sessions_count = 0;
18090Sstevel@tonic-gate
18100Sstevel@tonic-gate /* initialized done by init_token entry point */
18110Sstevel@tonic-gate softc->ds_token_initialized = B_TRUE;
18120Sstevel@tonic-gate
1813904Smcpowers (void) memset(softc->ds_label, ' ', CRYPTO_EXT_SIZE_LABEL);
1814904Smcpowers bcopy("Dummy Pseudo HW Provider", softc->ds_label, 24);
1815904Smcpowers
18160Sstevel@tonic-gate bcopy("changeme", softc->ds_user_pin, 8);
18170Sstevel@tonic-gate softc->ds_user_pin_len = 8;
18180Sstevel@tonic-gate softc->ds_user_pin_set = B_TRUE;
18190Sstevel@tonic-gate
18200Sstevel@tonic-gate /* register with the crypto framework */
18210Sstevel@tonic-gate dprov_prov_info.pi_provider_dev.pd_hw = dip;
18220Sstevel@tonic-gate dprov_prov_info.pi_provider_handle = softc;
18234072Skrishna
18244072Skrishna if (dprov_no_multipart) { /* Export only single part */
18254072Skrishna dprov_digest_ops.digest_update = NULL;
18264072Skrishna dprov_digest_ops.digest_key = NULL;
18274072Skrishna dprov_digest_ops.digest_final = NULL;
18284072Skrishna dprov_object_ops.object_create = NULL;
18294072Skrishna }
18304072Skrishna
18310Sstevel@tonic-gate if ((ret = crypto_register_provider(&dprov_prov_info,
18320Sstevel@tonic-gate &softc->ds_prov_handle)) != CRYPTO_SUCCESS) {
18330Sstevel@tonic-gate cmn_err(CE_WARN,
18340Sstevel@tonic-gate "dprov crypto_register_provider() failed (0x%x)", ret);
18350Sstevel@tonic-gate taskq_destroy(softc->ds_taskq);
18360Sstevel@tonic-gate kmem_free(softc->ds_sessions, softc->ds_sessions_slots *
18370Sstevel@tonic-gate sizeof (dprov_session_t *));
18380Sstevel@tonic-gate mutex_destroy(&softc->ds_lock);
18390Sstevel@tonic-gate ddi_soft_state_free(statep, instance);
18400Sstevel@tonic-gate ddi_remove_minor_node(dip, NULL);
18410Sstevel@tonic-gate return (DDI_FAILURE);
18420Sstevel@tonic-gate }
18430Sstevel@tonic-gate
18440Sstevel@tonic-gate /*
18450Sstevel@tonic-gate * This call is for testing only; it is not required by the SPI.
18460Sstevel@tonic-gate */
18470Sstevel@tonic-gate crypto_provider_notification(softc->ds_prov_handle,
18480Sstevel@tonic-gate CRYPTO_PROVIDER_READY);
18490Sstevel@tonic-gate
18500Sstevel@tonic-gate return (DDI_SUCCESS);
18510Sstevel@tonic-gate }
18520Sstevel@tonic-gate
18530Sstevel@tonic-gate static int
dprov_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)18540Sstevel@tonic-gate dprov_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
18550Sstevel@tonic-gate {
18560Sstevel@tonic-gate int instance = ddi_get_instance(dip);
18570Sstevel@tonic-gate dprov_state_t *softc = ddi_get_soft_state(statep, instance);
18580Sstevel@tonic-gate dprov_session_t *session;
18590Sstevel@tonic-gate int i, ret;
18600Sstevel@tonic-gate
18610Sstevel@tonic-gate DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_detach() for %d\n",
18620Sstevel@tonic-gate instance));
18630Sstevel@tonic-gate
18640Sstevel@tonic-gate if (cmd != DDI_DETACH)
18650Sstevel@tonic-gate return (DDI_FAILURE);
18660Sstevel@tonic-gate
18670Sstevel@tonic-gate /* unregister from the crypto framework */
18680Sstevel@tonic-gate if (softc->ds_prov_handle != NULL)
18690Sstevel@tonic-gate if ((ret = crypto_unregister_provider(
18700Sstevel@tonic-gate softc->ds_prov_handle)) != CRYPTO_SUCCESS) {
18710Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_detach: "
18720Sstevel@tonic-gate "crypto_unregister_provider() "
18730Sstevel@tonic-gate "failed (0x%x)", ret);
18740Sstevel@tonic-gate return (DDI_FAILURE);
18750Sstevel@tonic-gate }
18760Sstevel@tonic-gate
18770Sstevel@tonic-gate
18780Sstevel@tonic-gate taskq_destroy(softc->ds_taskq);
18790Sstevel@tonic-gate
18800Sstevel@tonic-gate for (i = 0; i < softc->ds_sessions_slots; i++) {
18810Sstevel@tonic-gate if ((session = softc->ds_sessions[i]) == NULL)
18820Sstevel@tonic-gate continue;
18830Sstevel@tonic-gate
18840Sstevel@tonic-gate dprov_release_session_objects(session);
18850Sstevel@tonic-gate
18860Sstevel@tonic-gate kmem_free(session, sizeof (dprov_session_t));
18870Sstevel@tonic-gate softc->ds_sessions_count--;
18880Sstevel@tonic-gate
18890Sstevel@tonic-gate }
18900Sstevel@tonic-gate
18910Sstevel@tonic-gate kmem_free(softc->ds_sessions, softc->ds_sessions_slots *
18920Sstevel@tonic-gate sizeof (dprov_session_t *));
18930Sstevel@tonic-gate /* free token objects */
18940Sstevel@tonic-gate for (i = 0; i < DPROV_MAX_OBJECTS; i++)
18950Sstevel@tonic-gate if (softc->ds_objects[i] != NULL)
18960Sstevel@tonic-gate dprov_free_object(softc->ds_objects[i]);
18970Sstevel@tonic-gate
18980Sstevel@tonic-gate mutex_destroy(&softc->ds_lock);
18990Sstevel@tonic-gate ddi_soft_state_free(statep, instance);
19000Sstevel@tonic-gate
19010Sstevel@tonic-gate ddi_remove_minor_node(dip, NULL);
19020Sstevel@tonic-gate
19030Sstevel@tonic-gate return (DDI_SUCCESS);
19040Sstevel@tonic-gate }
19050Sstevel@tonic-gate
19060Sstevel@tonic-gate /*
19070Sstevel@tonic-gate * Control entry points.
19080Sstevel@tonic-gate */
19090Sstevel@tonic-gate static void
dprov_provider_status(crypto_provider_handle_t provider,uint_t * status)19100Sstevel@tonic-gate dprov_provider_status(crypto_provider_handle_t provider, uint_t *status)
19110Sstevel@tonic-gate {
19120Sstevel@tonic-gate _NOTE(ARGUNUSED(provider))
19130Sstevel@tonic-gate
19140Sstevel@tonic-gate *status = CRYPTO_PROVIDER_READY;
19150Sstevel@tonic-gate }
19160Sstevel@tonic-gate
19170Sstevel@tonic-gate /*
19180Sstevel@tonic-gate * Digest entry points.
19190Sstevel@tonic-gate */
19200Sstevel@tonic-gate
19210Sstevel@tonic-gate static int
dprov_digest_init(crypto_ctx_t * ctx,crypto_mechanism_t * mechanism,crypto_req_handle_t req)19220Sstevel@tonic-gate dprov_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
19230Sstevel@tonic-gate crypto_req_handle_t req)
19240Sstevel@tonic-gate {
19250Sstevel@tonic-gate int error = CRYPTO_FAILED;
19260Sstevel@tonic-gate dprov_state_t *softc;
19270Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
19280Sstevel@tonic-gate int instance;
19290Sstevel@tonic-gate
19300Sstevel@tonic-gate /* extract softc and instance number from context */
19310Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
19320Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_init: started\n", instance));
19330Sstevel@tonic-gate
19340Sstevel@tonic-gate /* check mechanism */
19354002Sdarrenm if (mechanism->cm_type != MD4_MECH_INFO_TYPE &&
19364002Sdarrenm mechanism->cm_type != MD5_MECH_INFO_TYPE &&
19370Sstevel@tonic-gate mechanism->cm_type != SHA1_MECH_INFO_TYPE &&
19380Sstevel@tonic-gate mechanism->cm_type != SHA256_MECH_INFO_TYPE &&
19390Sstevel@tonic-gate mechanism->cm_type != SHA384_MECH_INFO_TYPE &&
19400Sstevel@tonic-gate mechanism->cm_type != SHA512_MECH_INFO_TYPE) {
19410Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_digest_init: unexpected mech type "
19420Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type);
19430Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
19440Sstevel@tonic-gate }
19450Sstevel@tonic-gate
19460Sstevel@tonic-gate /* submit request to the taskq */
19470Sstevel@tonic-gate error = dprov_digest_submit_req(DPROV_REQ_DIGEST_INIT, softc, req,
19480Sstevel@tonic-gate mechanism, NULL, NULL, NULL, ctx, KM_SLEEP);
19490Sstevel@tonic-gate
19500Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_init: done err = 0x%x\n",
19510Sstevel@tonic-gate instance, error));
19520Sstevel@tonic-gate
19530Sstevel@tonic-gate return (error);
19540Sstevel@tonic-gate }
19550Sstevel@tonic-gate
19560Sstevel@tonic-gate static int
dprov_digest(crypto_ctx_t * ctx,crypto_data_t * data,crypto_data_t * digest,crypto_req_handle_t req)19570Sstevel@tonic-gate dprov_digest(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *digest,
19580Sstevel@tonic-gate crypto_req_handle_t req)
19590Sstevel@tonic-gate {
19600Sstevel@tonic-gate int error = CRYPTO_FAILED;
19610Sstevel@tonic-gate dprov_state_t *softc;
19620Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
19630Sstevel@tonic-gate int instance;
19640Sstevel@tonic-gate
19654072Skrishna if (dprov_no_multipart && data->cd_length > dprov_max_digestsz)
19664072Skrishna return (CRYPTO_BUFFER_TOO_BIG);
19674072Skrishna
19680Sstevel@tonic-gate /* extract softc and instance number from context */
19690Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
19700Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest: started\n", instance));
19710Sstevel@tonic-gate
19720Sstevel@tonic-gate /* submit request to the taskq */
19730Sstevel@tonic-gate error = dprov_digest_submit_req(DPROV_REQ_DIGEST, softc, req,
19740Sstevel@tonic-gate NULL, data, NULL, digest, ctx, KM_NOSLEEP);
19750Sstevel@tonic-gate
19760Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest: done, err = 0x%x\n",
19770Sstevel@tonic-gate instance, error));
19780Sstevel@tonic-gate
19790Sstevel@tonic-gate return (error);
19800Sstevel@tonic-gate }
19810Sstevel@tonic-gate
19820Sstevel@tonic-gate static int
dprov_digest_update(crypto_ctx_t * ctx,crypto_data_t * data,crypto_req_handle_t req)19830Sstevel@tonic-gate dprov_digest_update(crypto_ctx_t *ctx, crypto_data_t *data,
19840Sstevel@tonic-gate crypto_req_handle_t req)
19850Sstevel@tonic-gate {
19860Sstevel@tonic-gate int error = CRYPTO_FAILED;
19870Sstevel@tonic-gate dprov_state_t *softc;
19880Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
19890Sstevel@tonic-gate int instance;
19900Sstevel@tonic-gate
19910Sstevel@tonic-gate /* extract softc and instance number from context */
19920Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
19930Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_update: started\n",
19940Sstevel@tonic-gate instance));
19950Sstevel@tonic-gate
19960Sstevel@tonic-gate /* submit request to the taskq */
19970Sstevel@tonic-gate error = dprov_digest_submit_req(DPROV_REQ_DIGEST_UPDATE, softc,
19980Sstevel@tonic-gate req, NULL, data, NULL, NULL, ctx, KM_NOSLEEP);
19990Sstevel@tonic-gate
20000Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_update: done err = 0x0%x\n",
20010Sstevel@tonic-gate instance, error));
20020Sstevel@tonic-gate
20030Sstevel@tonic-gate return (error);
20040Sstevel@tonic-gate }
20050Sstevel@tonic-gate
20060Sstevel@tonic-gate static int
dprov_digest_key(crypto_ctx_t * ctx,crypto_key_t * key,crypto_req_handle_t req)20070Sstevel@tonic-gate dprov_digest_key(crypto_ctx_t *ctx, crypto_key_t *key, crypto_req_handle_t req)
20080Sstevel@tonic-gate {
20090Sstevel@tonic-gate int error = CRYPTO_FAILED;
20100Sstevel@tonic-gate dprov_state_t *softc;
20110Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
20120Sstevel@tonic-gate int instance;
20130Sstevel@tonic-gate
20140Sstevel@tonic-gate /* extract softc and instance number from context */
20150Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
20160Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_key: started\n", instance));
20170Sstevel@tonic-gate
20180Sstevel@tonic-gate /* submit request to the taskq */
20190Sstevel@tonic-gate error = dprov_digest_submit_req(DPROV_REQ_DIGEST_KEY, softc, req, NULL,
20200Sstevel@tonic-gate NULL, key, NULL, ctx, KM_NOSLEEP);
20210Sstevel@tonic-gate
20220Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_key: done err = 0x0%x\n",
20230Sstevel@tonic-gate instance, error));
20240Sstevel@tonic-gate
20250Sstevel@tonic-gate return (error);
20260Sstevel@tonic-gate }
20270Sstevel@tonic-gate
20280Sstevel@tonic-gate static int
dprov_digest_final(crypto_ctx_t * ctx,crypto_data_t * digest,crypto_req_handle_t req)20290Sstevel@tonic-gate dprov_digest_final(crypto_ctx_t *ctx, crypto_data_t *digest,
20300Sstevel@tonic-gate crypto_req_handle_t req)
20310Sstevel@tonic-gate {
20320Sstevel@tonic-gate int error = CRYPTO_FAILED;
20330Sstevel@tonic-gate dprov_state_t *softc;
20340Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
20350Sstevel@tonic-gate int instance;
20360Sstevel@tonic-gate
20370Sstevel@tonic-gate /* extract softc and instance number from context */
20380Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
20390Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_final: started\n", instance));
20400Sstevel@tonic-gate
20410Sstevel@tonic-gate /* submit request to the taskq */
20420Sstevel@tonic-gate error = dprov_digest_submit_req(DPROV_REQ_DIGEST_FINAL, softc, req,
20430Sstevel@tonic-gate NULL, NULL, NULL, digest, ctx, KM_NOSLEEP);
20440Sstevel@tonic-gate
20450Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_final: done err = 0x0%x\n",
20460Sstevel@tonic-gate instance, error));
20470Sstevel@tonic-gate
20480Sstevel@tonic-gate return (error);
20490Sstevel@tonic-gate }
20500Sstevel@tonic-gate
20510Sstevel@tonic-gate /* ARGSUSED */
20520Sstevel@tonic-gate static int
dprov_digest_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_data_t * data,crypto_data_t * digest,crypto_req_handle_t req)20530Sstevel@tonic-gate dprov_digest_atomic(crypto_provider_handle_t provider,
20540Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
20550Sstevel@tonic-gate crypto_data_t *data, crypto_data_t *digest,
20560Sstevel@tonic-gate crypto_req_handle_t req)
20570Sstevel@tonic-gate {
20580Sstevel@tonic-gate int error = CRYPTO_FAILED;
20590Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
20600Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
20610Sstevel@tonic-gate int instance;
20620Sstevel@tonic-gate
20634072Skrishna if (dprov_no_multipart && data->cd_length > dprov_max_digestsz)
20644072Skrishna return (CRYPTO_BUFFER_TOO_BIG);
20654072Skrishna
20660Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
20670Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_atomic: started\n",
20680Sstevel@tonic-gate instance));
20690Sstevel@tonic-gate
20700Sstevel@tonic-gate /* check mechanism */
20714002Sdarrenm if (mechanism->cm_type != MD4_MECH_INFO_TYPE &&
20724002Sdarrenm mechanism->cm_type != MD5_MECH_INFO_TYPE &&
20730Sstevel@tonic-gate mechanism->cm_type != SHA1_MECH_INFO_TYPE &&
20740Sstevel@tonic-gate mechanism->cm_type != SHA256_MECH_INFO_TYPE &&
20750Sstevel@tonic-gate mechanism->cm_type != SHA384_MECH_INFO_TYPE &&
20760Sstevel@tonic-gate mechanism->cm_type != SHA512_MECH_INFO_TYPE) {
20770Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_digest_atomic: unexpected mech type "
20780Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type);
20790Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
20800Sstevel@tonic-gate }
20810Sstevel@tonic-gate
20820Sstevel@tonic-gate /* submit request to the taskq */
20830Sstevel@tonic-gate error = dprov_digest_submit_req(DPROV_REQ_DIGEST_ATOMIC, softc, req,
20840Sstevel@tonic-gate mechanism, data, NULL, digest, NULL, KM_SLEEP);
20850Sstevel@tonic-gate
20860Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_atomic: done err = 0x0%x\n",
20870Sstevel@tonic-gate instance, error));
20880Sstevel@tonic-gate
20890Sstevel@tonic-gate return (error);
20900Sstevel@tonic-gate }
20910Sstevel@tonic-gate
20920Sstevel@tonic-gate /*
20930Sstevel@tonic-gate * MAC entry points.
20940Sstevel@tonic-gate */
20950Sstevel@tonic-gate
20960Sstevel@tonic-gate /*
20970Sstevel@tonic-gate * Checks whether the specified mech_type is supported by mac
20980Sstevel@tonic-gate * entry points.
20990Sstevel@tonic-gate */
21000Sstevel@tonic-gate static boolean_t
dprov_valid_mac_mech(crypto_mech_type_t mech_type)21010Sstevel@tonic-gate dprov_valid_mac_mech(crypto_mech_type_t mech_type)
21020Sstevel@tonic-gate {
21030Sstevel@tonic-gate return (mech_type == MD5_HMAC_MECH_INFO_TYPE ||
21040Sstevel@tonic-gate mech_type == MD5_HMAC_GEN_MECH_INFO_TYPE ||
21050Sstevel@tonic-gate mech_type == SHA1_HMAC_MECH_INFO_TYPE ||
21060Sstevel@tonic-gate mech_type == SHA1_HMAC_GEN_MECH_INFO_TYPE ||
21070Sstevel@tonic-gate mech_type == SHA256_HMAC_MECH_INFO_TYPE ||
21080Sstevel@tonic-gate mech_type == SHA256_HMAC_GEN_MECH_INFO_TYPE ||
21090Sstevel@tonic-gate mech_type == SHA384_HMAC_MECH_INFO_TYPE ||
21100Sstevel@tonic-gate mech_type == SHA384_HMAC_GEN_MECH_INFO_TYPE ||
21110Sstevel@tonic-gate mech_type == SHA512_HMAC_MECH_INFO_TYPE ||
21129339SMark.Powers@Sun.COM mech_type == SHA512_HMAC_GEN_MECH_INFO_TYPE ||
21139339SMark.Powers@Sun.COM mech_type == AES_GMAC_MECH_INFO_TYPE);
21140Sstevel@tonic-gate }
21150Sstevel@tonic-gate
21160Sstevel@tonic-gate static int
dprov_mac_init(crypto_ctx_t * ctx,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)21170Sstevel@tonic-gate dprov_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
21180Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
21190Sstevel@tonic-gate crypto_req_handle_t req)
21200Sstevel@tonic-gate {
21210Sstevel@tonic-gate int error = CRYPTO_FAILED;
21220Sstevel@tonic-gate dprov_state_t *softc;
21230Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
21240Sstevel@tonic-gate int instance;
21250Sstevel@tonic-gate
21260Sstevel@tonic-gate /* extract softc and instance number from context */
21270Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
21280Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_init: started\n", instance));
21290Sstevel@tonic-gate
21300Sstevel@tonic-gate /* check mechanism */
21310Sstevel@tonic-gate if (!dprov_valid_mac_mech(mechanism->cm_type)) {
21320Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_mac_init: unexpected mech type "
21330Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type);
21340Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
21350Sstevel@tonic-gate }
21360Sstevel@tonic-gate
21370Sstevel@tonic-gate if (ctx_template != NULL)
21380Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
21390Sstevel@tonic-gate
21400Sstevel@tonic-gate /* submit request to the taskq */
21410Sstevel@tonic-gate error = dprov_mac_submit_req(DPROV_REQ_MAC_INIT, softc, req,
21420Sstevel@tonic-gate mechanism, NULL, key, NULL, ctx, 0, KM_SLEEP);
21430Sstevel@tonic-gate
21440Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_init: done err = 0x%x\n",
21450Sstevel@tonic-gate instance, error));
21460Sstevel@tonic-gate
21470Sstevel@tonic-gate return (error);
21480Sstevel@tonic-gate }
21490Sstevel@tonic-gate
21500Sstevel@tonic-gate static int
dprov_mac(crypto_ctx_t * ctx,crypto_data_t * data,crypto_data_t * mac,crypto_req_handle_t req)21510Sstevel@tonic-gate dprov_mac(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *mac,
21520Sstevel@tonic-gate crypto_req_handle_t req)
21530Sstevel@tonic-gate {
21540Sstevel@tonic-gate int error = CRYPTO_FAILED;
21550Sstevel@tonic-gate dprov_state_t *softc;
21560Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
21570Sstevel@tonic-gate int instance;
21580Sstevel@tonic-gate
21590Sstevel@tonic-gate /* extract softc and instance number from context */
21600Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
21610Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac: started\n", instance));
21620Sstevel@tonic-gate
21630Sstevel@tonic-gate /* submit request to the taskq */
21640Sstevel@tonic-gate error = dprov_mac_submit_req(DPROV_REQ_MAC, softc, req,
21650Sstevel@tonic-gate NULL, data, NULL, mac, ctx, 0, KM_NOSLEEP);
21660Sstevel@tonic-gate
21670Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac: done, err = 0x%x\n", instance,
21680Sstevel@tonic-gate error));
21690Sstevel@tonic-gate
21700Sstevel@tonic-gate return (error);
21710Sstevel@tonic-gate }
21720Sstevel@tonic-gate
21730Sstevel@tonic-gate static int
dprov_mac_update(crypto_ctx_t * ctx,crypto_data_t * data,crypto_req_handle_t req)21740Sstevel@tonic-gate dprov_mac_update(crypto_ctx_t *ctx, crypto_data_t *data,
21750Sstevel@tonic-gate crypto_req_handle_t req)
21760Sstevel@tonic-gate {
21770Sstevel@tonic-gate int error = CRYPTO_FAILED;
21780Sstevel@tonic-gate dprov_state_t *softc;
21790Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
21800Sstevel@tonic-gate int instance;
21810Sstevel@tonic-gate
21820Sstevel@tonic-gate /* extract softc and instance number from context */
21830Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
21840Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_update: started\n", instance));
21850Sstevel@tonic-gate
21860Sstevel@tonic-gate /* submit request to the taskq */
21870Sstevel@tonic-gate error = dprov_mac_submit_req(DPROV_REQ_MAC_UPDATE, softc,
21880Sstevel@tonic-gate req, NULL, data, NULL, NULL, ctx, 0, KM_NOSLEEP);
21890Sstevel@tonic-gate
21900Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_update: done err = 0x0%x\n",
21910Sstevel@tonic-gate instance, error));
21920Sstevel@tonic-gate
21930Sstevel@tonic-gate return (error);
21940Sstevel@tonic-gate }
21950Sstevel@tonic-gate
21960Sstevel@tonic-gate static int
dprov_mac_final(crypto_ctx_t * ctx,crypto_data_t * mac,crypto_req_handle_t req)21970Sstevel@tonic-gate dprov_mac_final(crypto_ctx_t *ctx, crypto_data_t *mac, crypto_req_handle_t req)
21980Sstevel@tonic-gate {
21990Sstevel@tonic-gate int error = CRYPTO_FAILED;
22000Sstevel@tonic-gate dprov_state_t *softc;
22010Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
22020Sstevel@tonic-gate int instance;
22030Sstevel@tonic-gate
22040Sstevel@tonic-gate /* extract softc and instance number from context */
22050Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
22060Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_final: started\n", instance));
22070Sstevel@tonic-gate
22080Sstevel@tonic-gate /* submit request to the taskq */
22090Sstevel@tonic-gate error = dprov_mac_submit_req(DPROV_REQ_MAC_FINAL, softc, req,
22100Sstevel@tonic-gate NULL, NULL, NULL, mac, ctx, 0, KM_NOSLEEP);
22110Sstevel@tonic-gate
22120Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_final: done err = 0x0%x\n",
22130Sstevel@tonic-gate instance, error));
22140Sstevel@tonic-gate
22150Sstevel@tonic-gate return (error);
22160Sstevel@tonic-gate }
22170Sstevel@tonic-gate
22180Sstevel@tonic-gate static int
dprov_mac_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * data,crypto_data_t * mac,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)22190Sstevel@tonic-gate dprov_mac_atomic(crypto_provider_handle_t provider,
22200Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
22210Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
22220Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
22230Sstevel@tonic-gate {
22240Sstevel@tonic-gate int error = CRYPTO_FAILED;
22250Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
22260Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
22270Sstevel@tonic-gate int instance;
22280Sstevel@tonic-gate
22290Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
22300Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_atomic: started\n", instance));
22310Sstevel@tonic-gate
22320Sstevel@tonic-gate if (ctx_template != NULL)
22330Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
22340Sstevel@tonic-gate
22350Sstevel@tonic-gate /* check mechanism */
22360Sstevel@tonic-gate if (!dprov_valid_mac_mech(mechanism->cm_type)) {
22370Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_mac_atomic: unexpected mech type "
22380Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type);
22390Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
22400Sstevel@tonic-gate }
22410Sstevel@tonic-gate
22420Sstevel@tonic-gate /* submit request to the taskq */
22430Sstevel@tonic-gate error = dprov_mac_submit_req(DPROV_REQ_MAC_ATOMIC, softc, req,
22440Sstevel@tonic-gate mechanism, data, key, mac, NULL, session_id, KM_SLEEP);
22450Sstevel@tonic-gate
22460Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_atomic: done err = 0x0%x\n",
22470Sstevel@tonic-gate instance, error));
22480Sstevel@tonic-gate
22490Sstevel@tonic-gate return (error);
22500Sstevel@tonic-gate }
22510Sstevel@tonic-gate
22520Sstevel@tonic-gate static int
dprov_mac_verify_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * data,crypto_data_t * mac,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)22530Sstevel@tonic-gate dprov_mac_verify_atomic(crypto_provider_handle_t provider,
22540Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
22550Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
22560Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
22570Sstevel@tonic-gate {
22580Sstevel@tonic-gate int error = CRYPTO_FAILED;
22590Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
22600Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
22610Sstevel@tonic-gate int instance;
22620Sstevel@tonic-gate
22630Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
22640Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_verify_atomic: started\n",
22650Sstevel@tonic-gate instance));
22660Sstevel@tonic-gate
22670Sstevel@tonic-gate if (ctx_template != NULL)
22680Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
22690Sstevel@tonic-gate
22700Sstevel@tonic-gate /* check mechanism */
22710Sstevel@tonic-gate if (!dprov_valid_mac_mech(mechanism->cm_type)) {
22720Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_mac_verify_atomic: unexpected mech "
22730Sstevel@tonic-gate "type 0x%llx\n", (unsigned long long)mechanism->cm_type);
22740Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
22750Sstevel@tonic-gate }
22760Sstevel@tonic-gate
22770Sstevel@tonic-gate /* submit request to the taskq */
22780Sstevel@tonic-gate error = dprov_mac_submit_req(DPROV_REQ_MAC_VERIFY_ATOMIC, softc, req,
22790Sstevel@tonic-gate mechanism, data, key, mac, NULL, session_id, KM_SLEEP);
22800Sstevel@tonic-gate
22810Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_verify_atomic: done err = 0x0%x\n",
22820Sstevel@tonic-gate instance, error));
22830Sstevel@tonic-gate
22840Sstevel@tonic-gate return (error);
22850Sstevel@tonic-gate }
22860Sstevel@tonic-gate
22870Sstevel@tonic-gate /*
22880Sstevel@tonic-gate * Cipher (encrypt/decrypt) entry points.
22890Sstevel@tonic-gate */
22900Sstevel@tonic-gate
22910Sstevel@tonic-gate /*
22920Sstevel@tonic-gate * Checks whether the specified mech_type is supported by cipher entry
22930Sstevel@tonic-gate * points.
22940Sstevel@tonic-gate */
22950Sstevel@tonic-gate static boolean_t
dprov_valid_cipher_mech(crypto_mech_type_t mech_type)22960Sstevel@tonic-gate dprov_valid_cipher_mech(crypto_mech_type_t mech_type)
22970Sstevel@tonic-gate {
22980Sstevel@tonic-gate return (mech_type == DES_CBC_MECH_INFO_TYPE ||
22994424Sizick mech_type == DES3_CBC_MECH_INFO_TYPE ||
23004424Sizick mech_type == DES_ECB_MECH_INFO_TYPE ||
23014424Sizick mech_type == DES3_ECB_MECH_INFO_TYPE ||
23024424Sizick mech_type == BLOWFISH_CBC_MECH_INFO_TYPE ||
23034424Sizick mech_type == BLOWFISH_ECB_MECH_INFO_TYPE ||
23044424Sizick mech_type == AES_CBC_MECH_INFO_TYPE ||
23054424Sizick mech_type == AES_ECB_MECH_INFO_TYPE ||
23064424Sizick mech_type == AES_CTR_MECH_INFO_TYPE ||
23075413Sdinak mech_type == AES_CCM_MECH_INFO_TYPE ||
23088005SMark.Powers@Sun.COM mech_type == AES_GCM_MECH_INFO_TYPE ||
23099339SMark.Powers@Sun.COM mech_type == AES_GMAC_MECH_INFO_TYPE ||
23104424Sizick mech_type == RC4_MECH_INFO_TYPE ||
23114424Sizick mech_type == RSA_PKCS_MECH_INFO_TYPE ||
23124424Sizick mech_type == RSA_X_509_MECH_INFO_TYPE ||
23134424Sizick mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE ||
23144424Sizick mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE ||
23154424Sizick mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE ||
23164424Sizick mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE ||
23174424Sizick mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE);
23180Sstevel@tonic-gate }
23190Sstevel@tonic-gate
23200Sstevel@tonic-gate static boolean_t
is_publickey_mech(crypto_mech_type_t mech_type)23210Sstevel@tonic-gate is_publickey_mech(crypto_mech_type_t mech_type)
23220Sstevel@tonic-gate {
23230Sstevel@tonic-gate return (mech_type == RSA_PKCS_MECH_INFO_TYPE ||
23244424Sizick mech_type == RSA_X_509_MECH_INFO_TYPE ||
23254424Sizick mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE ||
23264424Sizick mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE ||
23274424Sizick mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE ||
23284424Sizick mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE ||
23295697Smcpowers mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE ||
23305697Smcpowers mech_type == ECDSA_SHA1_MECH_INFO_TYPE ||
23315697Smcpowers mech_type == ECDSA_MECH_INFO_TYPE);
23320Sstevel@tonic-gate }
23330Sstevel@tonic-gate
23340Sstevel@tonic-gate
23350Sstevel@tonic-gate /* ARGSUSED */
23360Sstevel@tonic-gate static int
dprov_encrypt_init(crypto_ctx_t * ctx,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)23370Sstevel@tonic-gate dprov_encrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
23380Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
23390Sstevel@tonic-gate crypto_req_handle_t req)
23400Sstevel@tonic-gate {
23410Sstevel@tonic-gate int error = CRYPTO_FAILED;
23420Sstevel@tonic-gate dprov_state_t *softc;
23430Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
23440Sstevel@tonic-gate int instance;
23450Sstevel@tonic-gate
23460Sstevel@tonic-gate /* extract softc and instance number from context */
23470Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
23480Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_init: started\n",
23490Sstevel@tonic-gate instance));
23500Sstevel@tonic-gate
23510Sstevel@tonic-gate /* check mechanism */
23520Sstevel@tonic-gate if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
23530Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_encrypt_init: unexpected mech type "
23540Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type);
23550Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
23560Sstevel@tonic-gate }
23570Sstevel@tonic-gate
23580Sstevel@tonic-gate /* submit request to the taskq */
23590Sstevel@tonic-gate error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_INIT, softc,
23600Sstevel@tonic-gate req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
23610Sstevel@tonic-gate
23620Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_init: done err = 0x0%x\n",
23630Sstevel@tonic-gate instance, error));
23640Sstevel@tonic-gate
23650Sstevel@tonic-gate return (error);
23660Sstevel@tonic-gate }
23670Sstevel@tonic-gate
23680Sstevel@tonic-gate /* ARGSUSED */
23690Sstevel@tonic-gate static int
dprov_encrypt(crypto_ctx_t * ctx,crypto_data_t * plaintext,crypto_data_t * ciphertext,crypto_req_handle_t req)23700Sstevel@tonic-gate dprov_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
23710Sstevel@tonic-gate crypto_data_t *ciphertext, crypto_req_handle_t req)
23720Sstevel@tonic-gate {
23730Sstevel@tonic-gate int error = CRYPTO_FAILED;
23740Sstevel@tonic-gate dprov_state_t *softc;
23750Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
23760Sstevel@tonic-gate int instance;
23770Sstevel@tonic-gate
23780Sstevel@tonic-gate /* extract softc and instance number from context */
23790Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
23800Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt: started\n", instance));
23810Sstevel@tonic-gate
23820Sstevel@tonic-gate /* submit request to the taskq */
23830Sstevel@tonic-gate error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT, softc,
23840Sstevel@tonic-gate req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
23850Sstevel@tonic-gate
23860Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt: done err = 0x0%x\n",
23870Sstevel@tonic-gate instance, error));
23880Sstevel@tonic-gate
23890Sstevel@tonic-gate return (error);
23900Sstevel@tonic-gate }
23910Sstevel@tonic-gate
23920Sstevel@tonic-gate /* ARGSUSED */
23930Sstevel@tonic-gate static int
dprov_encrypt_update(crypto_ctx_t * ctx,crypto_data_t * plaintext,crypto_data_t * ciphertext,crypto_req_handle_t req)23940Sstevel@tonic-gate dprov_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
23950Sstevel@tonic-gate crypto_data_t *ciphertext, crypto_req_handle_t req)
23960Sstevel@tonic-gate {
23970Sstevel@tonic-gate int error = CRYPTO_FAILED;
23980Sstevel@tonic-gate dprov_state_t *softc;
23990Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
24000Sstevel@tonic-gate int instance;
24010Sstevel@tonic-gate
24020Sstevel@tonic-gate /* extract softc and instance number from context */
24030Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
24040Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_update: started\n",
24050Sstevel@tonic-gate instance));
24060Sstevel@tonic-gate
24070Sstevel@tonic-gate /* submit request to the taskq */
24080Sstevel@tonic-gate error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_UPDATE, softc,
24090Sstevel@tonic-gate req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
24100Sstevel@tonic-gate
24110Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_update: done err = 0x0%x\n",
24120Sstevel@tonic-gate instance, error));
24130Sstevel@tonic-gate
24140Sstevel@tonic-gate return (error);
24150Sstevel@tonic-gate }
24160Sstevel@tonic-gate
24170Sstevel@tonic-gate /* ARGSUSED */
24180Sstevel@tonic-gate static int
dprov_encrypt_final(crypto_ctx_t * ctx,crypto_data_t * ciphertext,crypto_req_handle_t req)24190Sstevel@tonic-gate dprov_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
24200Sstevel@tonic-gate crypto_req_handle_t req)
24210Sstevel@tonic-gate {
24220Sstevel@tonic-gate int error = CRYPTO_FAILED;
24230Sstevel@tonic-gate dprov_state_t *softc;
24240Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
24250Sstevel@tonic-gate int instance;
24260Sstevel@tonic-gate
24270Sstevel@tonic-gate /* extract softc and instance number from context */
24280Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
24290Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_final: started\n",
24300Sstevel@tonic-gate instance));
24310Sstevel@tonic-gate
24320Sstevel@tonic-gate /* submit request to the taskq */
24330Sstevel@tonic-gate error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_FINAL, softc,
24340Sstevel@tonic-gate req, NULL, NULL, NULL, ciphertext, ctx, 0, KM_NOSLEEP);
24350Sstevel@tonic-gate
24360Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_final: done err = 0x0%x\n",
24370Sstevel@tonic-gate instance, error));
24380Sstevel@tonic-gate
24390Sstevel@tonic-gate return (error);
24400Sstevel@tonic-gate }
24410Sstevel@tonic-gate
24420Sstevel@tonic-gate static int
dprov_encrypt_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * plaintext,crypto_data_t * ciphertext,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)24430Sstevel@tonic-gate dprov_encrypt_atomic(crypto_provider_handle_t provider,
24440Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
24450Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext,
24460Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
24470Sstevel@tonic-gate {
24480Sstevel@tonic-gate int error = CRYPTO_FAILED;
24490Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
24500Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
24510Sstevel@tonic-gate int instance;
24520Sstevel@tonic-gate
24530Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
24540Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_encrypt_atomic: started\n", instance));
24550Sstevel@tonic-gate
24560Sstevel@tonic-gate if (ctx_template != NULL)
24570Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
24580Sstevel@tonic-gate
24590Sstevel@tonic-gate /* check mechanism */
24600Sstevel@tonic-gate if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
24610Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_encrypt_atomic: unexpected mech type "
24620Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type);
24630Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
24640Sstevel@tonic-gate }
24650Sstevel@tonic-gate
24660Sstevel@tonic-gate error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_ATOMIC, softc,
24670Sstevel@tonic-gate req, mechanism, key, plaintext, ciphertext, NULL, session_id,
24680Sstevel@tonic-gate KM_SLEEP);
24690Sstevel@tonic-gate
24700Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_encrypt_atomic: done err = 0x0%x\n",
24710Sstevel@tonic-gate instance, error));
24720Sstevel@tonic-gate
24730Sstevel@tonic-gate return (error);
24740Sstevel@tonic-gate }
24750Sstevel@tonic-gate
24760Sstevel@tonic-gate /* ARGSUSED */
24770Sstevel@tonic-gate static int
dprov_decrypt_init(crypto_ctx_t * ctx,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)24780Sstevel@tonic-gate dprov_decrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
24790Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
24800Sstevel@tonic-gate crypto_req_handle_t req)
24810Sstevel@tonic-gate {
24820Sstevel@tonic-gate int error = CRYPTO_FAILED;
24830Sstevel@tonic-gate dprov_state_t *softc;
24840Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
24850Sstevel@tonic-gate int instance;
24860Sstevel@tonic-gate
24870Sstevel@tonic-gate /* extract softc and instance number from context */
24880Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
24890Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_init: started\n",
24900Sstevel@tonic-gate instance));
24910Sstevel@tonic-gate
24920Sstevel@tonic-gate /* check mechanism */
24930Sstevel@tonic-gate if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
24940Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_decrypt_init: unexpected mech type "
24950Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type);
24960Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
24970Sstevel@tonic-gate }
24980Sstevel@tonic-gate
24990Sstevel@tonic-gate /* submit request to the taskq */
25000Sstevel@tonic-gate error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_INIT, softc,
25010Sstevel@tonic-gate req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
25020Sstevel@tonic-gate
25030Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_init: done err = 0x0%x\n",
25040Sstevel@tonic-gate instance, error));
25050Sstevel@tonic-gate
25060Sstevel@tonic-gate return (error);
25070Sstevel@tonic-gate }
25080Sstevel@tonic-gate
25090Sstevel@tonic-gate /* ARGSUSED */
25100Sstevel@tonic-gate static int
dprov_decrypt(crypto_ctx_t * ctx,crypto_data_t * ciphertext,crypto_data_t * plaintext,crypto_req_handle_t req)25110Sstevel@tonic-gate dprov_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
25120Sstevel@tonic-gate crypto_data_t *plaintext, crypto_req_handle_t req)
25130Sstevel@tonic-gate {
25140Sstevel@tonic-gate int error = CRYPTO_FAILED;
25150Sstevel@tonic-gate
25160Sstevel@tonic-gate dprov_state_t *softc;
25170Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
25180Sstevel@tonic-gate int instance;
25190Sstevel@tonic-gate
25200Sstevel@tonic-gate /* extract softc and instance number from context */
25210Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
25220Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt: started\n", instance));
25230Sstevel@tonic-gate
25240Sstevel@tonic-gate /* submit request to the taskq */
25250Sstevel@tonic-gate error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT, softc,
25260Sstevel@tonic-gate req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
25270Sstevel@tonic-gate
25280Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt: done err = 0x0%x\n",
25290Sstevel@tonic-gate instance, error));
25300Sstevel@tonic-gate
25310Sstevel@tonic-gate return (error);
25320Sstevel@tonic-gate }
25330Sstevel@tonic-gate
25340Sstevel@tonic-gate /* ARGSUSED */
25350Sstevel@tonic-gate static int
dprov_decrypt_update(crypto_ctx_t * ctx,crypto_data_t * ciphertext,crypto_data_t * plaintext,crypto_req_handle_t req)25360Sstevel@tonic-gate dprov_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
25370Sstevel@tonic-gate crypto_data_t *plaintext, crypto_req_handle_t req)
25380Sstevel@tonic-gate {
25390Sstevel@tonic-gate int error = CRYPTO_FAILED;
25400Sstevel@tonic-gate dprov_state_t *softc;
25410Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
25420Sstevel@tonic-gate int instance;
25430Sstevel@tonic-gate
25440Sstevel@tonic-gate /* extract softc and instance number from context */
25450Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
25460Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_update: started\n",
25470Sstevel@tonic-gate instance));
25480Sstevel@tonic-gate
25490Sstevel@tonic-gate /* submit request to the taskq */
25500Sstevel@tonic-gate error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_UPDATE, softc,
25510Sstevel@tonic-gate req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
25520Sstevel@tonic-gate
25530Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_update: done err = 0x0%x\n",
25540Sstevel@tonic-gate instance, error));
25550Sstevel@tonic-gate
25560Sstevel@tonic-gate return (error);
25570Sstevel@tonic-gate }
25580Sstevel@tonic-gate
25590Sstevel@tonic-gate /* ARGSUSED */
25600Sstevel@tonic-gate static int
dprov_decrypt_final(crypto_ctx_t * ctx,crypto_data_t * plaintext,crypto_req_handle_t req)25610Sstevel@tonic-gate dprov_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *plaintext,
25620Sstevel@tonic-gate crypto_req_handle_t req)
25630Sstevel@tonic-gate {
25640Sstevel@tonic-gate int error = CRYPTO_FAILED;
25650Sstevel@tonic-gate dprov_state_t *softc;
25660Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
25670Sstevel@tonic-gate int instance;
25680Sstevel@tonic-gate
25690Sstevel@tonic-gate /* extract softc and instance number from context */
25700Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
25710Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_final: started\n",
25720Sstevel@tonic-gate instance));
25730Sstevel@tonic-gate
25740Sstevel@tonic-gate /* submit request to the taskq */
25750Sstevel@tonic-gate error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_FINAL, softc,
25760Sstevel@tonic-gate req, NULL, NULL, plaintext, NULL, ctx, 0, KM_NOSLEEP);
25770Sstevel@tonic-gate
25780Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_final: done err = 0x0%x\n",
25790Sstevel@tonic-gate instance, error));
25800Sstevel@tonic-gate
25810Sstevel@tonic-gate return (error);
25820Sstevel@tonic-gate }
25830Sstevel@tonic-gate
25840Sstevel@tonic-gate static int
dprov_decrypt_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * ciphertext,crypto_data_t * plaintext,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)25850Sstevel@tonic-gate dprov_decrypt_atomic(crypto_provider_handle_t provider,
25860Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
25870Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext,
25880Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
25890Sstevel@tonic-gate {
25900Sstevel@tonic-gate int error = CRYPTO_FAILED;
25910Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
25920Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
25930Sstevel@tonic-gate int instance;
25940Sstevel@tonic-gate
25950Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
25960Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_decrypt_atomic: started\n", instance));
25970Sstevel@tonic-gate
25980Sstevel@tonic-gate if (ctx_template != NULL)
25990Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
26000Sstevel@tonic-gate
26010Sstevel@tonic-gate /* check mechanism */
26020Sstevel@tonic-gate if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
26030Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_atomic_init: unexpected mech type "
26040Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type);
26050Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
26060Sstevel@tonic-gate }
26070Sstevel@tonic-gate
26080Sstevel@tonic-gate error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_ATOMIC, softc,
26090Sstevel@tonic-gate req, mechanism, key, plaintext, ciphertext, NULL, session_id,
26100Sstevel@tonic-gate KM_SLEEP);
26110Sstevel@tonic-gate
26120Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_decrypt_atomic: done err = 0x0%x\n",
26130Sstevel@tonic-gate instance, error));
26140Sstevel@tonic-gate
26150Sstevel@tonic-gate return (error);
26160Sstevel@tonic-gate }
26170Sstevel@tonic-gate
26180Sstevel@tonic-gate /*
26190Sstevel@tonic-gate * Sign entry points.
26200Sstevel@tonic-gate */
26210Sstevel@tonic-gate
26220Sstevel@tonic-gate /*
26230Sstevel@tonic-gate * Checks whether the specified mech_type is supported by sign/verify
26240Sstevel@tonic-gate * entry points.
26250Sstevel@tonic-gate */
26260Sstevel@tonic-gate static boolean_t
dprov_valid_sign_verif_mech(crypto_mech_type_t mech_type)26270Sstevel@tonic-gate dprov_valid_sign_verif_mech(crypto_mech_type_t mech_type)
26280Sstevel@tonic-gate {
26290Sstevel@tonic-gate return (mech_type == MD5_HMAC_MECH_INFO_TYPE ||
26304424Sizick mech_type == MD5_HMAC_GEN_MECH_INFO_TYPE ||
26314424Sizick mech_type == SHA1_HMAC_MECH_INFO_TYPE ||
26324424Sizick mech_type == SHA1_HMAC_GEN_MECH_INFO_TYPE ||
26334424Sizick mech_type == SHA256_HMAC_MECH_INFO_TYPE ||
26344424Sizick mech_type == SHA256_HMAC_GEN_MECH_INFO_TYPE ||
26354424Sizick mech_type == SHA384_HMAC_MECH_INFO_TYPE ||
26364424Sizick mech_type == SHA384_HMAC_GEN_MECH_INFO_TYPE ||
26374424Sizick mech_type == SHA512_HMAC_MECH_INFO_TYPE ||
26384424Sizick mech_type == SHA512_HMAC_GEN_MECH_INFO_TYPE ||
26394424Sizick mech_type == RSA_PKCS_MECH_INFO_TYPE ||
26404424Sizick mech_type == RSA_X_509_MECH_INFO_TYPE ||
26414424Sizick mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE ||
26424424Sizick mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE ||
26434424Sizick mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE ||
26444424Sizick mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE ||
26455697Smcpowers mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE ||
26465697Smcpowers mech_type == ECDSA_SHA1_MECH_INFO_TYPE ||
26475697Smcpowers mech_type == ECDSA_MECH_INFO_TYPE);
26480Sstevel@tonic-gate }
26490Sstevel@tonic-gate
26500Sstevel@tonic-gate static int
dprov_sign_init(crypto_ctx_t * ctx,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)26510Sstevel@tonic-gate dprov_sign_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
26520Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
26530Sstevel@tonic-gate crypto_req_handle_t req)
26540Sstevel@tonic-gate {
26550Sstevel@tonic-gate int error = CRYPTO_FAILED;
26560Sstevel@tonic-gate dprov_state_t *softc;
26570Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
26580Sstevel@tonic-gate int instance;
26590Sstevel@tonic-gate
26600Sstevel@tonic-gate /* extract softc and instance number from context */
26610Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
26620Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_init: started\n", instance));
26630Sstevel@tonic-gate
26640Sstevel@tonic-gate /* check mechanism */
26650Sstevel@tonic-gate if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
26660Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_sign_init: unexpected mech type "
26670Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type);
26680Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
26690Sstevel@tonic-gate }
26700Sstevel@tonic-gate
26710Sstevel@tonic-gate if (ctx_template != NULL)
26720Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
26730Sstevel@tonic-gate
26740Sstevel@tonic-gate /* submit request to the taskq */
26750Sstevel@tonic-gate error = dprov_sign_submit_req(DPROV_REQ_SIGN_INIT, softc, req,
26760Sstevel@tonic-gate mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
26770Sstevel@tonic-gate
26780Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_init: done err = 0x%x\n",
26790Sstevel@tonic-gate instance, error));
26800Sstevel@tonic-gate
26810Sstevel@tonic-gate return (error);
26820Sstevel@tonic-gate }
26830Sstevel@tonic-gate
26840Sstevel@tonic-gate static int
dprov_sign(crypto_ctx_t * ctx,crypto_data_t * data,crypto_data_t * signature,crypto_req_handle_t req)26850Sstevel@tonic-gate dprov_sign(crypto_ctx_t *ctx, crypto_data_t *data,
26860Sstevel@tonic-gate crypto_data_t *signature, crypto_req_handle_t req)
26870Sstevel@tonic-gate {
26880Sstevel@tonic-gate int error = CRYPTO_FAILED;
26890Sstevel@tonic-gate dprov_state_t *softc;
26900Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
26910Sstevel@tonic-gate int instance;
26920Sstevel@tonic-gate
26930Sstevel@tonic-gate /* extract softc and instance number from context */
26940Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
26950Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign: started\n", instance));
26960Sstevel@tonic-gate
26970Sstevel@tonic-gate /* submit request to the taskq */
26980Sstevel@tonic-gate error = dprov_sign_submit_req(DPROV_REQ_SIGN, softc, req,
26990Sstevel@tonic-gate NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
27000Sstevel@tonic-gate
27010Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign: done err = 0x%x\n",
27020Sstevel@tonic-gate instance, error));
27030Sstevel@tonic-gate
27040Sstevel@tonic-gate return (error);
27050Sstevel@tonic-gate }
27060Sstevel@tonic-gate
27070Sstevel@tonic-gate static int
dprov_sign_update(crypto_ctx_t * ctx,crypto_data_t * data,crypto_req_handle_t req)27080Sstevel@tonic-gate dprov_sign_update(crypto_ctx_t *ctx, crypto_data_t *data,
27090Sstevel@tonic-gate crypto_req_handle_t req)
27100Sstevel@tonic-gate {
27110Sstevel@tonic-gate int error = CRYPTO_FAILED;
27120Sstevel@tonic-gate dprov_state_t *softc;
27130Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
27140Sstevel@tonic-gate int instance;
27150Sstevel@tonic-gate
27160Sstevel@tonic-gate /* extract softc and instance number from context */
27170Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
27180Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_update: started\n", instance));
27190Sstevel@tonic-gate
27200Sstevel@tonic-gate /* submit request to the taskq */
27210Sstevel@tonic-gate error = dprov_sign_submit_req(DPROV_REQ_SIGN_UPDATE, softc, req,
27220Sstevel@tonic-gate NULL, NULL, data, NULL, ctx, 0, KM_NOSLEEP);
27230Sstevel@tonic-gate
27240Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_update: done err = 0x%x\n",
27250Sstevel@tonic-gate instance, error));
27260Sstevel@tonic-gate
27270Sstevel@tonic-gate return (error);
27280Sstevel@tonic-gate }
27290Sstevel@tonic-gate
27300Sstevel@tonic-gate static int
dprov_sign_final(crypto_ctx_t * ctx,crypto_data_t * signature,crypto_req_handle_t req)27310Sstevel@tonic-gate dprov_sign_final(crypto_ctx_t *ctx, crypto_data_t *signature,
27320Sstevel@tonic-gate crypto_req_handle_t req)
27330Sstevel@tonic-gate {
27340Sstevel@tonic-gate int error = CRYPTO_FAILED;
27350Sstevel@tonic-gate dprov_state_t *softc;
27360Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
27370Sstevel@tonic-gate int instance;
27380Sstevel@tonic-gate
27390Sstevel@tonic-gate /* extract softc and instance number from context */
27400Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
27410Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_final: started\n", instance));
27420Sstevel@tonic-gate
27430Sstevel@tonic-gate /* submit request to the taskq */
27440Sstevel@tonic-gate error = dprov_sign_submit_req(DPROV_REQ_SIGN_FINAL, softc, req,
27450Sstevel@tonic-gate NULL, NULL, NULL, signature, ctx, 0, KM_NOSLEEP);
27460Sstevel@tonic-gate
27470Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_final: done err = 0x%x\n",
27480Sstevel@tonic-gate instance, error));
27490Sstevel@tonic-gate
27500Sstevel@tonic-gate return (error);
27510Sstevel@tonic-gate }
27520Sstevel@tonic-gate
27530Sstevel@tonic-gate static int
dprov_sign_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * data,crypto_data_t * signature,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)27540Sstevel@tonic-gate dprov_sign_atomic(crypto_provider_handle_t provider,
27550Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
27560Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature,
27570Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
27580Sstevel@tonic-gate {
27590Sstevel@tonic-gate int error = CRYPTO_FAILED;
27600Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
27610Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
27620Sstevel@tonic-gate int instance;
27630Sstevel@tonic-gate
27640Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
27650Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_atomic: started\n", instance));
27660Sstevel@tonic-gate
27670Sstevel@tonic-gate /* check mechanism */
27680Sstevel@tonic-gate if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
27690Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_sign_atomic: unexpected mech type "
27700Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type);
27710Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
27720Sstevel@tonic-gate }
27730Sstevel@tonic-gate
27740Sstevel@tonic-gate if (ctx_template != NULL)
27750Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
27760Sstevel@tonic-gate
27770Sstevel@tonic-gate /* submit request to the taskq */
27780Sstevel@tonic-gate error = dprov_sign_submit_req(DPROV_REQ_SIGN_ATOMIC, softc, req,
27790Sstevel@tonic-gate mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
27800Sstevel@tonic-gate
27810Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_atomic: done err = 0x%x\n",
27820Sstevel@tonic-gate instance, error));
27830Sstevel@tonic-gate
27840Sstevel@tonic-gate return (error);
27850Sstevel@tonic-gate }
27860Sstevel@tonic-gate
27870Sstevel@tonic-gate static int
dprov_sign_recover_init(crypto_ctx_t * ctx,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)27880Sstevel@tonic-gate dprov_sign_recover_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
27890Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
27900Sstevel@tonic-gate crypto_req_handle_t req)
27910Sstevel@tonic-gate {
27920Sstevel@tonic-gate int error = CRYPTO_FAILED;
27930Sstevel@tonic-gate dprov_state_t *softc;
27940Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
27950Sstevel@tonic-gate int instance;
27960Sstevel@tonic-gate
27970Sstevel@tonic-gate /* extract softc and instance number from context */
27980Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
27990Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_init: started\n",
28000Sstevel@tonic-gate instance));
28010Sstevel@tonic-gate
28020Sstevel@tonic-gate if (ctx_template != NULL)
28030Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
28040Sstevel@tonic-gate
28050Sstevel@tonic-gate /* submit request to the taskq */
28060Sstevel@tonic-gate error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER_INIT, softc, req,
28070Sstevel@tonic-gate mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
28080Sstevel@tonic-gate
28090Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_init: done err = 0x%x\n",
28100Sstevel@tonic-gate instance, error));
28110Sstevel@tonic-gate
28120Sstevel@tonic-gate return (error);
28130Sstevel@tonic-gate }
28140Sstevel@tonic-gate
28150Sstevel@tonic-gate static int
dprov_sign_recover(crypto_ctx_t * ctx,crypto_data_t * data,crypto_data_t * signature,crypto_req_handle_t req)28160Sstevel@tonic-gate dprov_sign_recover(crypto_ctx_t *ctx, crypto_data_t *data,
28170Sstevel@tonic-gate crypto_data_t *signature, crypto_req_handle_t req)
28180Sstevel@tonic-gate {
28190Sstevel@tonic-gate int error = CRYPTO_FAILED;
28200Sstevel@tonic-gate dprov_state_t *softc;
28210Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
28220Sstevel@tonic-gate int instance;
28230Sstevel@tonic-gate
28240Sstevel@tonic-gate /* extract softc and instance number from context */
28250Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
28260Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover: started\n", instance));
28270Sstevel@tonic-gate
28280Sstevel@tonic-gate /* submit request to the taskq */
28290Sstevel@tonic-gate error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER, softc, req,
28300Sstevel@tonic-gate NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
28310Sstevel@tonic-gate
28320Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover: done err = 0x%x\n",
28330Sstevel@tonic-gate instance, error));
28340Sstevel@tonic-gate
28350Sstevel@tonic-gate return (error);
28360Sstevel@tonic-gate }
28370Sstevel@tonic-gate
28380Sstevel@tonic-gate static int
dprov_sign_recover_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * data,crypto_data_t * signature,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)28390Sstevel@tonic-gate dprov_sign_recover_atomic(crypto_provider_handle_t provider,
28400Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
28410Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature,
28420Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
28430Sstevel@tonic-gate {
28440Sstevel@tonic-gate int error = CRYPTO_FAILED;
28450Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
28460Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
28470Sstevel@tonic-gate int instance;
28480Sstevel@tonic-gate
28490Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
28500Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_atomic: started\n",
28510Sstevel@tonic-gate instance));
28520Sstevel@tonic-gate
28530Sstevel@tonic-gate if (ctx_template != NULL)
28540Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
28550Sstevel@tonic-gate
28560Sstevel@tonic-gate /* submit request to the taskq */
28570Sstevel@tonic-gate error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER_ATOMIC, softc, req,
28580Sstevel@tonic-gate mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
28590Sstevel@tonic-gate
28600Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_atomic: done "
28610Sstevel@tonic-gate "err = 0x%x\n", instance, error));
28620Sstevel@tonic-gate
28630Sstevel@tonic-gate return (error);
28640Sstevel@tonic-gate }
28650Sstevel@tonic-gate
28660Sstevel@tonic-gate /*
28670Sstevel@tonic-gate * Verify entry points.
28680Sstevel@tonic-gate */
28690Sstevel@tonic-gate
28700Sstevel@tonic-gate static int
dprov_verify_init(crypto_ctx_t * ctx,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)28710Sstevel@tonic-gate dprov_verify_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
28720Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
28730Sstevel@tonic-gate crypto_req_handle_t req)
28740Sstevel@tonic-gate {
28750Sstevel@tonic-gate int error = CRYPTO_FAILED;
28760Sstevel@tonic-gate dprov_state_t *softc;
28770Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
28780Sstevel@tonic-gate int instance;
28790Sstevel@tonic-gate
28800Sstevel@tonic-gate /* extract softc and instance number from context */
28810Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
28820Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_init: started\n", instance));
28830Sstevel@tonic-gate
28840Sstevel@tonic-gate /* check mechanism */
28850Sstevel@tonic-gate if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
28860Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_verify_init: unexpected mech type "
28870Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type);
28880Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
28890Sstevel@tonic-gate }
28900Sstevel@tonic-gate
28910Sstevel@tonic-gate if (ctx_template != NULL)
28920Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
28930Sstevel@tonic-gate
28940Sstevel@tonic-gate error = dprov_verify_submit_req(DPROV_REQ_VERIFY_INIT, softc, req,
28950Sstevel@tonic-gate mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
28960Sstevel@tonic-gate
28970Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_init: done err = 0x%x\n",
28980Sstevel@tonic-gate instance, error));
28990Sstevel@tonic-gate
29000Sstevel@tonic-gate return (error);
29010Sstevel@tonic-gate }
29020Sstevel@tonic-gate
29030Sstevel@tonic-gate static int
dprov_verify(crypto_ctx_t * ctx,crypto_data_t * data,crypto_data_t * signature,crypto_req_handle_t req)29040Sstevel@tonic-gate dprov_verify(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature,
29050Sstevel@tonic-gate crypto_req_handle_t req)
29060Sstevel@tonic-gate {
29070Sstevel@tonic-gate int error = CRYPTO_FAILED;
29080Sstevel@tonic-gate dprov_state_t *softc;
29090Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
29100Sstevel@tonic-gate int instance;
29110Sstevel@tonic-gate
29120Sstevel@tonic-gate /* extract softc and instance number from context */
29130Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
29140Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify: started\n", instance));
29150Sstevel@tonic-gate
29160Sstevel@tonic-gate /* submit request to the taskq */
29170Sstevel@tonic-gate error = dprov_verify_submit_req(DPROV_REQ_VERIFY, softc, req,
29180Sstevel@tonic-gate NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
29190Sstevel@tonic-gate
29200Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify: done err = 0x%x\n",
29210Sstevel@tonic-gate instance, error));
29220Sstevel@tonic-gate
29230Sstevel@tonic-gate return (error);
29240Sstevel@tonic-gate }
29250Sstevel@tonic-gate
29260Sstevel@tonic-gate static int
dprov_verify_update(crypto_ctx_t * ctx,crypto_data_t * data,crypto_req_handle_t req)29270Sstevel@tonic-gate dprov_verify_update(crypto_ctx_t *ctx, crypto_data_t *data,
29280Sstevel@tonic-gate crypto_req_handle_t req)
29290Sstevel@tonic-gate {
29300Sstevel@tonic-gate int error = CRYPTO_FAILED;
29310Sstevel@tonic-gate dprov_state_t *softc;
29320Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
29330Sstevel@tonic-gate int instance;
29340Sstevel@tonic-gate
29350Sstevel@tonic-gate /* extract softc and instance number from context */
29360Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
29370Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_update: started\n",
29380Sstevel@tonic-gate instance));
29390Sstevel@tonic-gate
29400Sstevel@tonic-gate /* submit request to the taskq */
29410Sstevel@tonic-gate error = dprov_verify_submit_req(DPROV_REQ_VERIFY_UPDATE, softc, req,
29420Sstevel@tonic-gate NULL, NULL, data, NULL, ctx, 0, KM_NOSLEEP);
29430Sstevel@tonic-gate
29440Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_update: done err = 0x%x\n",
29450Sstevel@tonic-gate instance, error));
29460Sstevel@tonic-gate
29470Sstevel@tonic-gate return (error);
29480Sstevel@tonic-gate }
29490Sstevel@tonic-gate
29500Sstevel@tonic-gate static int
dprov_verify_final(crypto_ctx_t * ctx,crypto_data_t * signature,crypto_req_handle_t req)29510Sstevel@tonic-gate dprov_verify_final(crypto_ctx_t *ctx, crypto_data_t *signature,
29520Sstevel@tonic-gate crypto_req_handle_t req)
29530Sstevel@tonic-gate {
29540Sstevel@tonic-gate int error = CRYPTO_FAILED;
29550Sstevel@tonic-gate dprov_state_t *softc;
29560Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
29570Sstevel@tonic-gate int instance;
29580Sstevel@tonic-gate
29590Sstevel@tonic-gate /* extract softc and instance number from context */
29600Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
29610Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_final: started\n", instance));
29620Sstevel@tonic-gate
29630Sstevel@tonic-gate /* submit request to the taskq */
29640Sstevel@tonic-gate error = dprov_verify_submit_req(DPROV_REQ_VERIFY_FINAL, softc, req,
29650Sstevel@tonic-gate NULL, NULL, NULL, signature, ctx, 0, KM_NOSLEEP);
29660Sstevel@tonic-gate
29670Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_final: done err = 0x%x\n",
29680Sstevel@tonic-gate instance, error));
29690Sstevel@tonic-gate
29700Sstevel@tonic-gate return (error);
29710Sstevel@tonic-gate }
29720Sstevel@tonic-gate
29730Sstevel@tonic-gate static int
dprov_verify_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * data,crypto_data_t * signature,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)29740Sstevel@tonic-gate dprov_verify_atomic(crypto_provider_handle_t provider,
29750Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
29760Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature,
29770Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
29780Sstevel@tonic-gate {
29790Sstevel@tonic-gate int error = CRYPTO_FAILED;
29800Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
29810Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
29820Sstevel@tonic-gate int instance;
29830Sstevel@tonic-gate
29840Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
29850Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_atomic: started\n",
29860Sstevel@tonic-gate instance));
29870Sstevel@tonic-gate
29880Sstevel@tonic-gate /* check mechanism */
29890Sstevel@tonic-gate if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
29900Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_verify_atomic: unexpected mech type "
29910Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type);
29920Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
29930Sstevel@tonic-gate }
29940Sstevel@tonic-gate
29950Sstevel@tonic-gate if (ctx_template != NULL)
29960Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
29970Sstevel@tonic-gate
29980Sstevel@tonic-gate /* submit request to the taskq */
29990Sstevel@tonic-gate error = dprov_verify_submit_req(DPROV_REQ_VERIFY_ATOMIC, softc, req,
30000Sstevel@tonic-gate mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
30010Sstevel@tonic-gate
30020Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_atomic: done err = 0x%x\n",
30030Sstevel@tonic-gate instance, error));
30040Sstevel@tonic-gate
30050Sstevel@tonic-gate return (error);
30060Sstevel@tonic-gate }
30070Sstevel@tonic-gate
30080Sstevel@tonic-gate static int
dprov_verify_recover_init(crypto_ctx_t * ctx,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)30090Sstevel@tonic-gate dprov_verify_recover_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
30100Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
30110Sstevel@tonic-gate crypto_req_handle_t req)
30120Sstevel@tonic-gate {
30130Sstevel@tonic-gate int error = CRYPTO_FAILED;
30140Sstevel@tonic-gate dprov_state_t *softc;
30150Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
30160Sstevel@tonic-gate int instance;
30170Sstevel@tonic-gate
30180Sstevel@tonic-gate /* extract softc and instance number from context */
30190Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
30200Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_init: started\n",
30210Sstevel@tonic-gate instance));
30220Sstevel@tonic-gate
30230Sstevel@tonic-gate if (ctx_template != NULL)
30240Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
30250Sstevel@tonic-gate
30260Sstevel@tonic-gate /* submit request to the taskq */
30270Sstevel@tonic-gate error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER_INIT, softc,
30280Sstevel@tonic-gate req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
30290Sstevel@tonic-gate
30300Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_init: done "
30310Sstevel@tonic-gate "err = 0x%x\n", instance, error));
30320Sstevel@tonic-gate
30330Sstevel@tonic-gate return (error);
30340Sstevel@tonic-gate }
30350Sstevel@tonic-gate
30360Sstevel@tonic-gate static int
dprov_verify_recover(crypto_ctx_t * ctx,crypto_data_t * signature,crypto_data_t * data,crypto_req_handle_t req)30370Sstevel@tonic-gate dprov_verify_recover(crypto_ctx_t *ctx, crypto_data_t *signature,
30380Sstevel@tonic-gate crypto_data_t *data, crypto_req_handle_t req)
30390Sstevel@tonic-gate {
30400Sstevel@tonic-gate int error = CRYPTO_FAILED;
30410Sstevel@tonic-gate dprov_state_t *softc;
30420Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
30430Sstevel@tonic-gate int instance;
30440Sstevel@tonic-gate
30450Sstevel@tonic-gate /* extract softc and instance number from context */
30460Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
30470Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover: started\n",
30480Sstevel@tonic-gate instance));
30490Sstevel@tonic-gate
30500Sstevel@tonic-gate /* submit request to the taskq */
30510Sstevel@tonic-gate error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER, softc, req,
30520Sstevel@tonic-gate NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
30530Sstevel@tonic-gate
30540Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover: done err = 0x%x\n",
30550Sstevel@tonic-gate instance, error));
30560Sstevel@tonic-gate
30570Sstevel@tonic-gate return (error);
30580Sstevel@tonic-gate }
30590Sstevel@tonic-gate
30600Sstevel@tonic-gate static int
dprov_verify_recover_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * signature,crypto_data_t * data,crypto_spi_ctx_template_t ctx_template,crypto_req_handle_t req)30610Sstevel@tonic-gate dprov_verify_recover_atomic(crypto_provider_handle_t provider,
30620Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
30630Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *signature, crypto_data_t *data,
30640Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
30650Sstevel@tonic-gate {
30660Sstevel@tonic-gate int error = CRYPTO_FAILED;
30670Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
30680Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
30690Sstevel@tonic-gate int instance;
30700Sstevel@tonic-gate
30710Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
30720Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_atomic: started\n",
30730Sstevel@tonic-gate instance));
30740Sstevel@tonic-gate
30750Sstevel@tonic-gate if (ctx_template != NULL)
30760Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
30770Sstevel@tonic-gate
30780Sstevel@tonic-gate /* submit request to the taskq */
30790Sstevel@tonic-gate error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER_ATOMIC, softc,
30800Sstevel@tonic-gate req, mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
30810Sstevel@tonic-gate
30820Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_atomic: done "
30830Sstevel@tonic-gate "err = 0x%x\n", instance, error));
30840Sstevel@tonic-gate
30850Sstevel@tonic-gate return (error);
30860Sstevel@tonic-gate }
30870Sstevel@tonic-gate
30880Sstevel@tonic-gate /*
30890Sstevel@tonic-gate * Dual operations entry points.
30900Sstevel@tonic-gate */
30910Sstevel@tonic-gate
30920Sstevel@tonic-gate static int
dprov_digest_encrypt_update(crypto_ctx_t * digest_ctx,crypto_ctx_t * encrypt_ctx,crypto_data_t * plaintext,crypto_data_t * ciphertext,crypto_req_handle_t req)30930Sstevel@tonic-gate dprov_digest_encrypt_update(crypto_ctx_t *digest_ctx,
30940Sstevel@tonic-gate crypto_ctx_t *encrypt_ctx, crypto_data_t *plaintext,
30950Sstevel@tonic-gate crypto_data_t *ciphertext, crypto_req_handle_t req)
30960Sstevel@tonic-gate {
30970Sstevel@tonic-gate int error = CRYPTO_FAILED;
30980Sstevel@tonic-gate dprov_state_t *softc;
30990Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
31000Sstevel@tonic-gate int instance;
31010Sstevel@tonic-gate
31020Sstevel@tonic-gate /* extract softc and instance number from context */
31030Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(digest_ctx, softc, instance);
31040Sstevel@tonic-gate DPROV_DEBUG(D_DUAL, ("(%d) dprov_digest_encrypt_update: started\n",
31050Sstevel@tonic-gate instance));
31060Sstevel@tonic-gate
31070Sstevel@tonic-gate if (digest_ctx->cc_provider != encrypt_ctx->cc_provider)
31080Sstevel@tonic-gate return (CRYPTO_INVALID_CONTEXT);
31090Sstevel@tonic-gate
31100Sstevel@tonic-gate /* submit request to the taskq */
31110Sstevel@tonic-gate error = dprov_dual_submit_req(DPROV_REQ_DIGEST_ENCRYPT_UPDATE,
31120Sstevel@tonic-gate softc, req, digest_ctx, encrypt_ctx, plaintext, ciphertext);
31130Sstevel@tonic-gate
31140Sstevel@tonic-gate DPROV_DEBUG(D_DUAL, ("(%d) dprov_digest_encrypt_update: done "
31150Sstevel@tonic-gate "err = 0x%x\n", instance, error));
31160Sstevel@tonic-gate
31170Sstevel@tonic-gate return (error);
31180Sstevel@tonic-gate }
31190Sstevel@tonic-gate
31200Sstevel@tonic-gate static int
dprov_decrypt_digest_update(crypto_ctx_t * decrypt_ctx,crypto_ctx_t * digest_ctx,crypto_data_t * ciphertext,crypto_data_t * plaintext,crypto_req_handle_t req)31210Sstevel@tonic-gate dprov_decrypt_digest_update(crypto_ctx_t *decrypt_ctx, crypto_ctx_t *digest_ctx,
31220Sstevel@tonic-gate crypto_data_t *ciphertext, crypto_data_t *plaintext,
31230Sstevel@tonic-gate crypto_req_handle_t req)
31240Sstevel@tonic-gate {
31250Sstevel@tonic-gate int error = CRYPTO_FAILED;
31260Sstevel@tonic-gate dprov_state_t *softc;
31270Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
31280Sstevel@tonic-gate int instance;
31290Sstevel@tonic-gate
31300Sstevel@tonic-gate /* extract softc and instance number from context */
31310Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(decrypt_ctx, softc, instance);
31320Sstevel@tonic-gate DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_digest_update: started\n",
31330Sstevel@tonic-gate instance));
31340Sstevel@tonic-gate
31350Sstevel@tonic-gate if (decrypt_ctx->cc_provider != digest_ctx->cc_provider)
31360Sstevel@tonic-gate return (CRYPTO_INVALID_CONTEXT);
31370Sstevel@tonic-gate
31380Sstevel@tonic-gate /* submit request to the taskq */
31390Sstevel@tonic-gate error = dprov_dual_submit_req(DPROV_REQ_DECRYPT_DIGEST_UPDATE,
31400Sstevel@tonic-gate softc, req, digest_ctx, decrypt_ctx, plaintext, ciphertext);
31410Sstevel@tonic-gate
31420Sstevel@tonic-gate DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_digest_update: done "
31430Sstevel@tonic-gate "err = 0x%x\n", instance, error));
31440Sstevel@tonic-gate
31450Sstevel@tonic-gate return (error);
31460Sstevel@tonic-gate }
31470Sstevel@tonic-gate
31480Sstevel@tonic-gate static int
dprov_sign_encrypt_update(crypto_ctx_t * sign_ctx,crypto_ctx_t * encrypt_ctx,crypto_data_t * plaintext,crypto_data_t * ciphertext,crypto_req_handle_t req)31490Sstevel@tonic-gate dprov_sign_encrypt_update(crypto_ctx_t *sign_ctx, crypto_ctx_t *encrypt_ctx,
31500Sstevel@tonic-gate crypto_data_t *plaintext, crypto_data_t *ciphertext,
31510Sstevel@tonic-gate crypto_req_handle_t req)
31520Sstevel@tonic-gate {
31530Sstevel@tonic-gate int error = CRYPTO_FAILED;
31540Sstevel@tonic-gate dprov_state_t *softc;
31550Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
31560Sstevel@tonic-gate int instance;
31570Sstevel@tonic-gate
31580Sstevel@tonic-gate /* extract softc and instance number from context */
31590Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(sign_ctx, softc, instance);
31600Sstevel@tonic-gate DPROV_DEBUG(D_DUAL, ("(%d) dprov_sign_encrypt_update: started\n",
31610Sstevel@tonic-gate instance));
31620Sstevel@tonic-gate
31630Sstevel@tonic-gate if (sign_ctx->cc_provider != encrypt_ctx->cc_provider)
31640Sstevel@tonic-gate return (CRYPTO_INVALID_CONTEXT);
31650Sstevel@tonic-gate
31660Sstevel@tonic-gate /* submit request to the taskq */
31670Sstevel@tonic-gate error = dprov_dual_submit_req(DPROV_REQ_SIGN_ENCRYPT_UPDATE,
31680Sstevel@tonic-gate softc, req, sign_ctx, encrypt_ctx, plaintext, ciphertext);
31690Sstevel@tonic-gate
31700Sstevel@tonic-gate DPROV_DEBUG(D_DUAL, ("(%d) dprov_sign_encrypt_update: done "
31710Sstevel@tonic-gate "err = 0x%x\n", instance, error));
31720Sstevel@tonic-gate
31730Sstevel@tonic-gate return (error);
31740Sstevel@tonic-gate }
31750Sstevel@tonic-gate
31760Sstevel@tonic-gate static int
dprov_decrypt_verify_update(crypto_ctx_t * decrypt_ctx,crypto_ctx_t * verify_ctx,crypto_data_t * ciphertext,crypto_data_t * plaintext,crypto_req_handle_t req)31770Sstevel@tonic-gate dprov_decrypt_verify_update(crypto_ctx_t *decrypt_ctx, crypto_ctx_t *verify_ctx,
31780Sstevel@tonic-gate crypto_data_t *ciphertext, crypto_data_t *plaintext,
31790Sstevel@tonic-gate crypto_req_handle_t req)
31800Sstevel@tonic-gate {
31810Sstevel@tonic-gate int error = CRYPTO_FAILED;
31820Sstevel@tonic-gate dprov_state_t *softc;
31830Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
31840Sstevel@tonic-gate int instance;
31850Sstevel@tonic-gate
31860Sstevel@tonic-gate /* extract softc and instance number from context */
31870Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(decrypt_ctx, softc, instance);
31880Sstevel@tonic-gate DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_verify_update: started\n",
31890Sstevel@tonic-gate instance));
31900Sstevel@tonic-gate
31910Sstevel@tonic-gate if (decrypt_ctx->cc_provider != verify_ctx->cc_provider)
31920Sstevel@tonic-gate return (CRYPTO_INVALID_CONTEXT);
31930Sstevel@tonic-gate
31940Sstevel@tonic-gate /* submit request to the taskq */
31950Sstevel@tonic-gate error = dprov_dual_submit_req(DPROV_REQ_DECRYPT_VERIFY_UPDATE,
31960Sstevel@tonic-gate softc, req, verify_ctx, decrypt_ctx, plaintext, ciphertext);
31970Sstevel@tonic-gate
31980Sstevel@tonic-gate DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_verify_update: done "
31990Sstevel@tonic-gate "err = 0x%x\n", instance, error));
32000Sstevel@tonic-gate
32010Sstevel@tonic-gate return (error);
32020Sstevel@tonic-gate }
32030Sstevel@tonic-gate
32040Sstevel@tonic-gate /*
32050Sstevel@tonic-gate * Dual cipher-mac entry points.
32060Sstevel@tonic-gate */
32070Sstevel@tonic-gate
32080Sstevel@tonic-gate static int
dprov_encrypt_mac_init(crypto_ctx_t * ctx,crypto_mechanism_t * encrypt_mech,crypto_key_t * encrypt_key,crypto_mechanism_t * mac_mech,crypto_key_t * mac_key,crypto_spi_ctx_template_t encr_ctx_template,crypto_spi_ctx_template_t mac_ctx_template,crypto_req_handle_t req)32090Sstevel@tonic-gate dprov_encrypt_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *encrypt_mech,
32100Sstevel@tonic-gate crypto_key_t *encrypt_key, crypto_mechanism_t *mac_mech,
32110Sstevel@tonic-gate crypto_key_t *mac_key, crypto_spi_ctx_template_t encr_ctx_template,
32120Sstevel@tonic-gate crypto_spi_ctx_template_t mac_ctx_template,
32130Sstevel@tonic-gate crypto_req_handle_t req)
32140Sstevel@tonic-gate {
32150Sstevel@tonic-gate int error = CRYPTO_FAILED;
32160Sstevel@tonic-gate dprov_state_t *softc;
32170Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
32180Sstevel@tonic-gate int instance;
32190Sstevel@tonic-gate
32200Sstevel@tonic-gate /* extract softc and instance number from context */
32210Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
32220Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_init: started\n",
32230Sstevel@tonic-gate instance));
32240Sstevel@tonic-gate
32250Sstevel@tonic-gate /* check mechanisms */
32260Sstevel@tonic-gate if (!dprov_valid_cipher_mech(encrypt_mech->cm_type)) {
32270Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_encrypt_mac_init: unexpected encrypt "
32280Sstevel@tonic-gate "mech type 0x%llx\n",
32290Sstevel@tonic-gate (unsigned long long)encrypt_mech->cm_type);
32300Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
32310Sstevel@tonic-gate }
32320Sstevel@tonic-gate if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
32330Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_encrypt_mac_init: unexpected mac "
32340Sstevel@tonic-gate "mech type 0x%llx\n",
32350Sstevel@tonic-gate (unsigned long long)mac_mech->cm_type);
32360Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
32370Sstevel@tonic-gate }
32380Sstevel@tonic-gate
32390Sstevel@tonic-gate if (encr_ctx_template != NULL || mac_ctx_template != NULL)
32400Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
32410Sstevel@tonic-gate
32420Sstevel@tonic-gate /* submit request to the taskq */
32430Sstevel@tonic-gate error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_INIT,
32440Sstevel@tonic-gate softc, req, ctx, 0, encrypt_mech, encrypt_key, mac_mech, mac_key,
32450Sstevel@tonic-gate NULL, NULL, NULL, KM_SLEEP);
32460Sstevel@tonic-gate
32470Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_init: done "
32480Sstevel@tonic-gate "err = 0x%x\n", instance, error));
32490Sstevel@tonic-gate
32500Sstevel@tonic-gate return (error);
32510Sstevel@tonic-gate }
32520Sstevel@tonic-gate
32530Sstevel@tonic-gate static int
dprov_encrypt_mac(crypto_ctx_t * ctx,crypto_data_t * plaintext,crypto_dual_data_t * ciphertext,crypto_data_t * mac,crypto_req_handle_t req)32540Sstevel@tonic-gate dprov_encrypt_mac(crypto_ctx_t *ctx, crypto_data_t *plaintext,
32550Sstevel@tonic-gate crypto_dual_data_t *ciphertext, crypto_data_t *mac, crypto_req_handle_t req)
32560Sstevel@tonic-gate {
32570Sstevel@tonic-gate int error = CRYPTO_FAILED;
32580Sstevel@tonic-gate dprov_state_t *softc;
32590Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
32600Sstevel@tonic-gate int instance;
32610Sstevel@tonic-gate
32620Sstevel@tonic-gate /* extract softc and instance number from context */
32630Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
32640Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac: started\n",
32650Sstevel@tonic-gate instance));
32660Sstevel@tonic-gate
32670Sstevel@tonic-gate /*
32680Sstevel@tonic-gate * submit request to the taskq
32690Sstevel@tonic-gate * Careful! cihertext/plaintext order inversion
32700Sstevel@tonic-gate */
32710Sstevel@tonic-gate error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC,
32720Sstevel@tonic-gate softc, req, ctx, 0, NULL, NULL, NULL, NULL,
32730Sstevel@tonic-gate ciphertext, plaintext, mac, KM_NOSLEEP);
32740Sstevel@tonic-gate
32750Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac: done "
32760Sstevel@tonic-gate "err = 0x%x\n", instance, error));
32770Sstevel@tonic-gate
32780Sstevel@tonic-gate return (error);
32790Sstevel@tonic-gate }
32800Sstevel@tonic-gate
32810Sstevel@tonic-gate static int
dprov_encrypt_mac_update(crypto_ctx_t * ctx,crypto_data_t * plaintext,crypto_dual_data_t * ciphertext,crypto_req_handle_t req)32820Sstevel@tonic-gate dprov_encrypt_mac_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
32830Sstevel@tonic-gate crypto_dual_data_t *ciphertext, crypto_req_handle_t req)
32840Sstevel@tonic-gate {
32850Sstevel@tonic-gate int error = CRYPTO_FAILED;
32860Sstevel@tonic-gate dprov_state_t *softc;
32870Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
32880Sstevel@tonic-gate int instance;
32890Sstevel@tonic-gate
32900Sstevel@tonic-gate /* extract softc and instance number from context */
32910Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
32920Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_update: started\n",
32930Sstevel@tonic-gate instance));
32940Sstevel@tonic-gate
32950Sstevel@tonic-gate /* submit request to the taskq */
32960Sstevel@tonic-gate error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_UPDATE,
32970Sstevel@tonic-gate softc, req, ctx, 0, NULL, NULL, NULL, NULL,
32980Sstevel@tonic-gate ciphertext, plaintext, NULL, KM_NOSLEEP);
32990Sstevel@tonic-gate
33000Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_update: done "
33010Sstevel@tonic-gate "err = 0x%x\n", instance, error));
33020Sstevel@tonic-gate
33030Sstevel@tonic-gate return (error);
33040Sstevel@tonic-gate }
33050Sstevel@tonic-gate
33060Sstevel@tonic-gate static int
dprov_encrypt_mac_final(crypto_ctx_t * ctx,crypto_dual_data_t * ciphertext,crypto_data_t * mac,crypto_req_handle_t req)33070Sstevel@tonic-gate dprov_encrypt_mac_final(crypto_ctx_t *ctx,
33080Sstevel@tonic-gate crypto_dual_data_t *ciphertext, crypto_data_t *mac,
33090Sstevel@tonic-gate crypto_req_handle_t req)
33100Sstevel@tonic-gate {
33110Sstevel@tonic-gate int error = CRYPTO_FAILED;
33120Sstevel@tonic-gate dprov_state_t *softc;
33130Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
33140Sstevel@tonic-gate int instance;
33150Sstevel@tonic-gate
33160Sstevel@tonic-gate /* extract softc and instance number from context */
33170Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
33180Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_final: started\n",
33190Sstevel@tonic-gate instance));
33200Sstevel@tonic-gate
33210Sstevel@tonic-gate /* submit request to the taskq */
33220Sstevel@tonic-gate error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_FINAL,
33230Sstevel@tonic-gate softc, req, ctx, 0, NULL, NULL, NULL, NULL,
33240Sstevel@tonic-gate ciphertext, NULL, mac, KM_NOSLEEP);
33250Sstevel@tonic-gate
33260Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_final: done "
33270Sstevel@tonic-gate "err = 0x%x\n", instance, error));
33280Sstevel@tonic-gate
33290Sstevel@tonic-gate return (error);
33300Sstevel@tonic-gate }
33310Sstevel@tonic-gate
33320Sstevel@tonic-gate static int
dprov_encrypt_mac_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * encrypt_mech,crypto_key_t * encrypt_key,crypto_mechanism_t * mac_mech,crypto_key_t * mac_key,crypto_data_t * plaintext,crypto_dual_data_t * ciphertext,crypto_data_t * mac,crypto_spi_ctx_template_t encr_ctx_template,crypto_spi_ctx_template_t mac_ctx_template,crypto_req_handle_t req)33330Sstevel@tonic-gate dprov_encrypt_mac_atomic(crypto_provider_handle_t provider,
33340Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *encrypt_mech,
33350Sstevel@tonic-gate crypto_key_t *encrypt_key, crypto_mechanism_t *mac_mech,
33360Sstevel@tonic-gate crypto_key_t *mac_key, crypto_data_t *plaintext,
33370Sstevel@tonic-gate crypto_dual_data_t *ciphertext, crypto_data_t *mac,
33380Sstevel@tonic-gate crypto_spi_ctx_template_t encr_ctx_template,
33390Sstevel@tonic-gate crypto_spi_ctx_template_t mac_ctx_template,
33400Sstevel@tonic-gate crypto_req_handle_t req)
33410Sstevel@tonic-gate {
33420Sstevel@tonic-gate int error = CRYPTO_FAILED;
33430Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
33440Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
33450Sstevel@tonic-gate int instance;
33460Sstevel@tonic-gate
33470Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
33480Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_atomic: started\n",
33490Sstevel@tonic-gate instance));
33500Sstevel@tonic-gate
33510Sstevel@tonic-gate /* check mechanisms */
33520Sstevel@tonic-gate if (!dprov_valid_cipher_mech(encrypt_mech->cm_type)) {
33530Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_encrypt_mac_atomic: unexpected encrypt "
33540Sstevel@tonic-gate "mech type 0x%llx\n",
33550Sstevel@tonic-gate (unsigned long long)encrypt_mech->cm_type);
33560Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
33570Sstevel@tonic-gate }
33580Sstevel@tonic-gate if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
33590Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_encrypt_mac_atomic: unexpected mac "
33600Sstevel@tonic-gate "mech type 0x%llx\n",
33610Sstevel@tonic-gate (unsigned long long)mac_mech->cm_type);
33620Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
33630Sstevel@tonic-gate }
33640Sstevel@tonic-gate
33650Sstevel@tonic-gate if (encr_ctx_template != NULL || mac_ctx_template != NULL)
33660Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
33670Sstevel@tonic-gate
33680Sstevel@tonic-gate /* submit request to the taskq */
33690Sstevel@tonic-gate error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_ATOMIC,
33700Sstevel@tonic-gate softc, req, NULL, session_id, encrypt_mech, encrypt_key, mac_mech,
33710Sstevel@tonic-gate mac_key, ciphertext, plaintext, mac, KM_SLEEP);
33720Sstevel@tonic-gate
33730Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_atomic: done "
33740Sstevel@tonic-gate "err = 0x%x\n", instance, error));
33750Sstevel@tonic-gate
33760Sstevel@tonic-gate return (error);
33770Sstevel@tonic-gate }
33780Sstevel@tonic-gate
33790Sstevel@tonic-gate static int
dprov_mac_decrypt_init(crypto_ctx_t * ctx,crypto_mechanism_t * mac_mech,crypto_key_t * mac_key,crypto_mechanism_t * decrypt_mech,crypto_key_t * decrypt_key,crypto_spi_ctx_template_t mac_ctx_template,crypto_spi_ctx_template_t decr_ctx_template,crypto_req_handle_t req)33800Sstevel@tonic-gate dprov_mac_decrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mac_mech,
33810Sstevel@tonic-gate crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech,
33820Sstevel@tonic-gate crypto_key_t *decrypt_key, crypto_spi_ctx_template_t mac_ctx_template,
33830Sstevel@tonic-gate crypto_spi_ctx_template_t decr_ctx_template,
33840Sstevel@tonic-gate crypto_req_handle_t req)
33850Sstevel@tonic-gate {
33860Sstevel@tonic-gate int error = CRYPTO_FAILED;
33870Sstevel@tonic-gate dprov_state_t *softc;
33880Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
33890Sstevel@tonic-gate int instance;
33900Sstevel@tonic-gate
33910Sstevel@tonic-gate /* extract softc and instance number from context */
33920Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
33930Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_init: started\n",
33940Sstevel@tonic-gate instance));
33950Sstevel@tonic-gate
33960Sstevel@tonic-gate /* check mechanisms */
33970Sstevel@tonic-gate if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) {
33980Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_mac_decrypt_init: unexpected decrypt "
33990Sstevel@tonic-gate "mech type 0x%llx\n",
34000Sstevel@tonic-gate (unsigned long long)decrypt_mech->cm_type);
34010Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
34020Sstevel@tonic-gate }
34030Sstevel@tonic-gate if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
34040Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_mac_decrypt_init: unexpected mac "
34050Sstevel@tonic-gate "mech type 0x%llx\n",
34060Sstevel@tonic-gate (unsigned long long)mac_mech->cm_type);
34070Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
34080Sstevel@tonic-gate }
34090Sstevel@tonic-gate
34100Sstevel@tonic-gate if (decr_ctx_template != NULL || mac_ctx_template != NULL)
34110Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
34120Sstevel@tonic-gate
34130Sstevel@tonic-gate /* submit request to the taskq */
34140Sstevel@tonic-gate error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_INIT,
34150Sstevel@tonic-gate softc, req, ctx, 0, decrypt_mech, decrypt_key, mac_mech, mac_key,
34160Sstevel@tonic-gate NULL, NULL, NULL, KM_SLEEP);
34170Sstevel@tonic-gate
34180Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_init: done "
34190Sstevel@tonic-gate "err = 0x%x\n", instance, error));
34200Sstevel@tonic-gate
34210Sstevel@tonic-gate return (error);
34220Sstevel@tonic-gate }
34230Sstevel@tonic-gate
34240Sstevel@tonic-gate static int
dprov_mac_decrypt(crypto_ctx_t * ctx,crypto_dual_data_t * ciphertext,crypto_data_t * mac,crypto_data_t * plaintext,crypto_req_handle_t req)34250Sstevel@tonic-gate dprov_mac_decrypt(crypto_ctx_t *ctx, crypto_dual_data_t *ciphertext,
34260Sstevel@tonic-gate crypto_data_t *mac, crypto_data_t *plaintext, crypto_req_handle_t req)
34270Sstevel@tonic-gate {
34280Sstevel@tonic-gate int error = CRYPTO_FAILED;
34290Sstevel@tonic-gate dprov_state_t *softc;
34300Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
34310Sstevel@tonic-gate int instance;
34320Sstevel@tonic-gate
34330Sstevel@tonic-gate /* extract softc and instance number from context */
34340Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
34350Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt: started\n",
34360Sstevel@tonic-gate instance));
34370Sstevel@tonic-gate
34380Sstevel@tonic-gate /* submit request to the taskq */
34390Sstevel@tonic-gate error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT,
34400Sstevel@tonic-gate softc, req, ctx, 0, NULL, NULL, NULL, NULL,
34410Sstevel@tonic-gate ciphertext, plaintext, mac, KM_NOSLEEP);
34420Sstevel@tonic-gate
34430Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt: done "
34440Sstevel@tonic-gate "err = 0x%x\n", instance, error));
34450Sstevel@tonic-gate
34460Sstevel@tonic-gate return (error);
34470Sstevel@tonic-gate }
34480Sstevel@tonic-gate
34490Sstevel@tonic-gate static int
dprov_mac_decrypt_update(crypto_ctx_t * ctx,crypto_dual_data_t * ciphertext,crypto_data_t * plaintext,crypto_req_handle_t req)34500Sstevel@tonic-gate dprov_mac_decrypt_update(crypto_ctx_t *ctx, crypto_dual_data_t *ciphertext,
34510Sstevel@tonic-gate crypto_data_t *plaintext, crypto_req_handle_t req)
34520Sstevel@tonic-gate {
34530Sstevel@tonic-gate int error = CRYPTO_FAILED;
34540Sstevel@tonic-gate dprov_state_t *softc;
34550Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
34560Sstevel@tonic-gate int instance;
34570Sstevel@tonic-gate
34580Sstevel@tonic-gate /* extract softc and instance number from context */
34590Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
34600Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_update: started\n",
34610Sstevel@tonic-gate instance));
34620Sstevel@tonic-gate
34630Sstevel@tonic-gate /* submit request to the taskq */
34640Sstevel@tonic-gate error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_UPDATE,
34650Sstevel@tonic-gate softc, req, ctx, 0, NULL, NULL, NULL, NULL,
34660Sstevel@tonic-gate ciphertext, plaintext, NULL, KM_NOSLEEP);
34670Sstevel@tonic-gate
34680Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_update: done "
34690Sstevel@tonic-gate "err = 0x%x\n", instance, error));
34700Sstevel@tonic-gate
34710Sstevel@tonic-gate return (error);
34720Sstevel@tonic-gate }
34730Sstevel@tonic-gate
34740Sstevel@tonic-gate static int
dprov_mac_decrypt_final(crypto_ctx_t * ctx,crypto_data_t * mac,crypto_data_t * plaintext,crypto_req_handle_t req)34750Sstevel@tonic-gate dprov_mac_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *mac,
34760Sstevel@tonic-gate crypto_data_t *plaintext, crypto_req_handle_t req)
34770Sstevel@tonic-gate {
34780Sstevel@tonic-gate int error = CRYPTO_FAILED;
34790Sstevel@tonic-gate dprov_state_t *softc;
34800Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
34810Sstevel@tonic-gate int instance;
34820Sstevel@tonic-gate
34830Sstevel@tonic-gate /* extract softc and instance number from context */
34840Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
34850Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_final: started\n",
34860Sstevel@tonic-gate instance));
34870Sstevel@tonic-gate
34880Sstevel@tonic-gate /* submit request to the taskq */
34890Sstevel@tonic-gate error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_FINAL,
34900Sstevel@tonic-gate softc, req, ctx, 0, NULL, NULL, NULL, NULL,
34910Sstevel@tonic-gate NULL, plaintext, mac, KM_NOSLEEP);
34920Sstevel@tonic-gate
34930Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_final: done "
34940Sstevel@tonic-gate "err = 0x%x\n", instance, error));
34950Sstevel@tonic-gate
34960Sstevel@tonic-gate return (error);
34970Sstevel@tonic-gate }
34980Sstevel@tonic-gate
34990Sstevel@tonic-gate static int
dprov_mac_decrypt_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mac_mech,crypto_key_t * mac_key,crypto_mechanism_t * decrypt_mech,crypto_key_t * decrypt_key,crypto_dual_data_t * ciphertext,crypto_data_t * mac,crypto_data_t * plaintext,crypto_spi_ctx_template_t mac_ctx_template,crypto_spi_ctx_template_t decr_ctx_template,crypto_req_handle_t req)35000Sstevel@tonic-gate dprov_mac_decrypt_atomic(crypto_provider_handle_t provider,
35010Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mac_mech,
35020Sstevel@tonic-gate crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech,
35030Sstevel@tonic-gate crypto_key_t *decrypt_key, crypto_dual_data_t *ciphertext,
35040Sstevel@tonic-gate crypto_data_t *mac, crypto_data_t *plaintext,
35050Sstevel@tonic-gate crypto_spi_ctx_template_t mac_ctx_template,
35060Sstevel@tonic-gate crypto_spi_ctx_template_t decr_ctx_template,
35070Sstevel@tonic-gate crypto_req_handle_t req)
35080Sstevel@tonic-gate {
35090Sstevel@tonic-gate int error = CRYPTO_FAILED;
35100Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
35110Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
35120Sstevel@tonic-gate int instance;
35130Sstevel@tonic-gate
35140Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
35150Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_atomic: started\n",
35160Sstevel@tonic-gate instance));
35170Sstevel@tonic-gate
35180Sstevel@tonic-gate /* check mechanisms */
35190Sstevel@tonic-gate if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) {
35200Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_mac_decrypt_atomic: unexpected encrypt "
35210Sstevel@tonic-gate "mech type 0x%llx\n",
35220Sstevel@tonic-gate (unsigned long long)decrypt_mech->cm_type);
35230Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
35240Sstevel@tonic-gate }
35250Sstevel@tonic-gate if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
35260Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_mac_decrypt_atomic: unexpected mac "
35270Sstevel@tonic-gate "mech type 0x%llx\n",
35280Sstevel@tonic-gate (unsigned long long)mac_mech->cm_type);
35290Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
35300Sstevel@tonic-gate }
35310Sstevel@tonic-gate
35320Sstevel@tonic-gate if (decr_ctx_template != NULL || mac_ctx_template != NULL)
35330Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
35340Sstevel@tonic-gate
35350Sstevel@tonic-gate /* submit request to the taskq */
35360Sstevel@tonic-gate error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_ATOMIC,
35370Sstevel@tonic-gate softc, req, NULL, session_id, decrypt_mech, decrypt_key, mac_mech,
35380Sstevel@tonic-gate mac_key, ciphertext, plaintext, mac, KM_SLEEP);
35390Sstevel@tonic-gate
35400Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_atomic: done "
35410Sstevel@tonic-gate "err = 0x%x\n", instance, error));
35420Sstevel@tonic-gate
35430Sstevel@tonic-gate return (error);
35440Sstevel@tonic-gate }
35450Sstevel@tonic-gate
35460Sstevel@tonic-gate static int
dprov_mac_verify_decrypt_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mac_mech,crypto_key_t * mac_key,crypto_mechanism_t * decrypt_mech,crypto_key_t * decrypt_key,crypto_dual_data_t * ciphertext,crypto_data_t * mac,crypto_data_t * plaintext,crypto_spi_ctx_template_t mac_ctx_template,crypto_spi_ctx_template_t decr_ctx_template,crypto_req_handle_t req)35470Sstevel@tonic-gate dprov_mac_verify_decrypt_atomic(crypto_provider_handle_t provider,
35480Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mac_mech,
35490Sstevel@tonic-gate crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech,
35500Sstevel@tonic-gate crypto_key_t *decrypt_key, crypto_dual_data_t *ciphertext,
35510Sstevel@tonic-gate crypto_data_t *mac, crypto_data_t *plaintext,
35520Sstevel@tonic-gate crypto_spi_ctx_template_t mac_ctx_template,
35530Sstevel@tonic-gate crypto_spi_ctx_template_t decr_ctx_template,
35540Sstevel@tonic-gate crypto_req_handle_t req)
35550Sstevel@tonic-gate {
35560Sstevel@tonic-gate int error = CRYPTO_FAILED;
35570Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
35580Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
35590Sstevel@tonic-gate int instance;
35600Sstevel@tonic-gate
35610Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
35620Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_verify_decrypt_atomic:"
35630Sstevel@tonic-gate "started\n", instance));
35640Sstevel@tonic-gate
35650Sstevel@tonic-gate /* check mechanisms */
35660Sstevel@tonic-gate if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) {
35670Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_mac_verify_decrypt_atomic: "
35680Sstevel@tonic-gate "unexpected encrypt mech type 0x%llx\n",
35690Sstevel@tonic-gate (unsigned long long)decrypt_mech->cm_type);
35700Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
35710Sstevel@tonic-gate }
35720Sstevel@tonic-gate if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
35730Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_mac_verify_decrypt_atomic: "
35740Sstevel@tonic-gate "unexpected mac mech type 0x%llx\n",
35750Sstevel@tonic-gate (unsigned long long)mac_mech->cm_type);
35760Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID);
35770Sstevel@tonic-gate }
35780Sstevel@tonic-gate
35790Sstevel@tonic-gate if (decr_ctx_template != NULL || mac_ctx_template != NULL)
35800Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
35810Sstevel@tonic-gate
35820Sstevel@tonic-gate /* submit request to the taskq */
35830Sstevel@tonic-gate error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC,
35840Sstevel@tonic-gate softc, req, NULL, session_id, decrypt_mech, decrypt_key, mac_mech,
35850Sstevel@tonic-gate mac_key, ciphertext, plaintext, mac, KM_SLEEP);
35860Sstevel@tonic-gate
35870Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_verify_decrypt_atomic: done "
35880Sstevel@tonic-gate "err = 0x%x\n", instance, error));
35890Sstevel@tonic-gate
35900Sstevel@tonic-gate return (error);
35910Sstevel@tonic-gate }
35920Sstevel@tonic-gate
35930Sstevel@tonic-gate /*
35940Sstevel@tonic-gate * Random number entry points.
35950Sstevel@tonic-gate */
35960Sstevel@tonic-gate
35970Sstevel@tonic-gate static int
dprov_seed_random(crypto_provider_handle_t provider,crypto_session_id_t sid,uchar_t * buf,size_t len,uint_t entropy_est,uint32_t flags,crypto_req_handle_t req)35980Sstevel@tonic-gate dprov_seed_random(crypto_provider_handle_t provider, crypto_session_id_t sid,
35991920Smcpowers uchar_t *buf, size_t len, uint_t entropy_est, uint32_t flags,
36001920Smcpowers crypto_req_handle_t req)
36010Sstevel@tonic-gate {
36020Sstevel@tonic-gate int error = CRYPTO_FAILED;
36030Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
36040Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
36050Sstevel@tonic-gate int instance;
36060Sstevel@tonic-gate
36070Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
36080Sstevel@tonic-gate DPROV_DEBUG(D_RANDOM, ("(%d) dprov_seed_random: started\n",
36090Sstevel@tonic-gate instance));
36100Sstevel@tonic-gate
36110Sstevel@tonic-gate error = dprov_random_submit_req(DPROV_REQ_RANDOM_SEED, softc,
36121920Smcpowers req, buf, len, sid, entropy_est, flags);
36130Sstevel@tonic-gate
36140Sstevel@tonic-gate DPROV_DEBUG(D_RANDOM, ("(%d) dprov_seed_random: done err = 0x0%x\n",
36150Sstevel@tonic-gate instance, error));
36160Sstevel@tonic-gate
36170Sstevel@tonic-gate return (error);
36180Sstevel@tonic-gate }
36190Sstevel@tonic-gate
36200Sstevel@tonic-gate static int
dprov_generate_random(crypto_provider_handle_t provider,crypto_session_id_t sid,uchar_t * buf,size_t len,crypto_req_handle_t req)36210Sstevel@tonic-gate dprov_generate_random(crypto_provider_handle_t provider,
36220Sstevel@tonic-gate crypto_session_id_t sid, uchar_t *buf, size_t len, crypto_req_handle_t req)
36230Sstevel@tonic-gate {
36240Sstevel@tonic-gate int error = CRYPTO_FAILED;
36250Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
36260Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
36270Sstevel@tonic-gate int instance;
36280Sstevel@tonic-gate
36290Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
36300Sstevel@tonic-gate DPROV_DEBUG(D_RANDOM, ("(%d) dprov_generate_random: started\n",
36310Sstevel@tonic-gate instance));
36320Sstevel@tonic-gate
36330Sstevel@tonic-gate error = dprov_random_submit_req(DPROV_REQ_RANDOM_GENERATE, softc,
36341920Smcpowers req, buf, len, sid, 0, 0);
36350Sstevel@tonic-gate
36360Sstevel@tonic-gate DPROV_DEBUG(D_RANDOM, ("(%d) dprov_generate_random: done "
36370Sstevel@tonic-gate "err = 0x0%x\n", instance, error));
36380Sstevel@tonic-gate
36390Sstevel@tonic-gate return (error);
36400Sstevel@tonic-gate }
36410Sstevel@tonic-gate
36420Sstevel@tonic-gate /*
36430Sstevel@tonic-gate * Session Management entry points.
36440Sstevel@tonic-gate */
36450Sstevel@tonic-gate
36460Sstevel@tonic-gate static int
dprov_session_open(crypto_provider_handle_t provider,crypto_session_id_t * session_id,crypto_req_handle_t req)36470Sstevel@tonic-gate dprov_session_open(crypto_provider_handle_t provider,
36480Sstevel@tonic-gate crypto_session_id_t *session_id, crypto_req_handle_t req)
36490Sstevel@tonic-gate {
36500Sstevel@tonic-gate int error = CRYPTO_FAILED;
36510Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
36520Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
36530Sstevel@tonic-gate int instance;
36540Sstevel@tonic-gate
36550Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
36560Sstevel@tonic-gate DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_open: started\n",
36570Sstevel@tonic-gate instance));
36580Sstevel@tonic-gate
36590Sstevel@tonic-gate error = dprov_session_submit_req(DPROV_REQ_SESSION_OPEN, softc,
36600Sstevel@tonic-gate req, session_id, 0, 0, NULL, 0);
36610Sstevel@tonic-gate
36620Sstevel@tonic-gate DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_open: done err = 0x0%x\n",
36630Sstevel@tonic-gate instance, error));
36640Sstevel@tonic-gate
36650Sstevel@tonic-gate return (error);
36660Sstevel@tonic-gate }
36670Sstevel@tonic-gate
36680Sstevel@tonic-gate static int
dprov_session_close(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_req_handle_t req)36690Sstevel@tonic-gate dprov_session_close(crypto_provider_handle_t provider,
36700Sstevel@tonic-gate crypto_session_id_t session_id, crypto_req_handle_t req)
36710Sstevel@tonic-gate {
36720Sstevel@tonic-gate int error = CRYPTO_FAILED;
36730Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
36740Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
36750Sstevel@tonic-gate int instance;
36760Sstevel@tonic-gate
36770Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
36780Sstevel@tonic-gate DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_close: started\n",
36790Sstevel@tonic-gate instance));
36800Sstevel@tonic-gate
36810Sstevel@tonic-gate error = dprov_session_submit_req(DPROV_REQ_SESSION_CLOSE, softc,
36820Sstevel@tonic-gate req, 0, session_id, 0, NULL, 0);
36830Sstevel@tonic-gate
36840Sstevel@tonic-gate DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_close: done err = 0x0%x\n",
36850Sstevel@tonic-gate instance, error));
36860Sstevel@tonic-gate
36870Sstevel@tonic-gate return (error);
36880Sstevel@tonic-gate }
36890Sstevel@tonic-gate
36900Sstevel@tonic-gate static int
dprov_session_login(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_user_type_t user_type,char * pin,size_t pin_len,crypto_req_handle_t req)36910Sstevel@tonic-gate dprov_session_login(crypto_provider_handle_t provider,
36920Sstevel@tonic-gate crypto_session_id_t session_id, crypto_user_type_t user_type,
36930Sstevel@tonic-gate char *pin, size_t pin_len, crypto_req_handle_t req)
36940Sstevel@tonic-gate {
36950Sstevel@tonic-gate int error = CRYPTO_FAILED;
36960Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
36970Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
36980Sstevel@tonic-gate int instance;
36990Sstevel@tonic-gate
37000Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
37010Sstevel@tonic-gate DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_login: started\n",
37020Sstevel@tonic-gate instance));
37030Sstevel@tonic-gate
37040Sstevel@tonic-gate error = dprov_session_submit_req(DPROV_REQ_SESSION_LOGIN, softc,
37050Sstevel@tonic-gate req, 0, session_id, user_type, pin, pin_len);
37060Sstevel@tonic-gate
37070Sstevel@tonic-gate DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_login: done err = 0x0%x\n",
37080Sstevel@tonic-gate instance, error));
37090Sstevel@tonic-gate
37100Sstevel@tonic-gate return (error);
37110Sstevel@tonic-gate }
37120Sstevel@tonic-gate
37130Sstevel@tonic-gate static int
dprov_session_logout(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_req_handle_t req)37140Sstevel@tonic-gate dprov_session_logout(crypto_provider_handle_t provider,
37150Sstevel@tonic-gate crypto_session_id_t session_id, crypto_req_handle_t req)
37160Sstevel@tonic-gate {
37170Sstevel@tonic-gate int error = CRYPTO_FAILED;
37180Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
37190Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
37200Sstevel@tonic-gate int instance;
37210Sstevel@tonic-gate
37220Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
37230Sstevel@tonic-gate DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_logout: started\n",
37240Sstevel@tonic-gate instance));
37250Sstevel@tonic-gate
37260Sstevel@tonic-gate error = dprov_session_submit_req(DPROV_REQ_SESSION_LOGOUT, softc,
37270Sstevel@tonic-gate req, 0, session_id, 0, NULL, 0);
37280Sstevel@tonic-gate
37290Sstevel@tonic-gate DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_logout: done err = 0x0%x\n",
37300Sstevel@tonic-gate instance, error));
37310Sstevel@tonic-gate
37320Sstevel@tonic-gate return (error);
37330Sstevel@tonic-gate }
37340Sstevel@tonic-gate
37350Sstevel@tonic-gate /*
37360Sstevel@tonic-gate * Object management entry points.
37370Sstevel@tonic-gate */
37380Sstevel@tonic-gate
37390Sstevel@tonic-gate static int
dprov_object_create(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_object_attribute_t * template,uint_t attribute_count,crypto_object_id_t * object,crypto_req_handle_t req)37400Sstevel@tonic-gate dprov_object_create(crypto_provider_handle_t provider,
37410Sstevel@tonic-gate crypto_session_id_t session_id, crypto_object_attribute_t *template,
37420Sstevel@tonic-gate uint_t attribute_count, crypto_object_id_t *object,
37430Sstevel@tonic-gate crypto_req_handle_t req)
37440Sstevel@tonic-gate {
37450Sstevel@tonic-gate int error = CRYPTO_FAILED;
37460Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
37470Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
37480Sstevel@tonic-gate int instance;
37490Sstevel@tonic-gate
37500Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
37510Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_create: started\n",
37520Sstevel@tonic-gate instance));
37530Sstevel@tonic-gate
37540Sstevel@tonic-gate /* submit request to the taskq */
37550Sstevel@tonic-gate error = dprov_object_submit_req(DPROV_REQ_OBJECT_CREATE, softc, req,
37560Sstevel@tonic-gate session_id, 0, template, attribute_count, object, NULL, NULL,
37570Sstevel@tonic-gate NULL, 0, NULL, KM_NOSLEEP);
37580Sstevel@tonic-gate
37590Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_create: done err = 0x0%x\n",
37600Sstevel@tonic-gate instance, error));
37610Sstevel@tonic-gate
37620Sstevel@tonic-gate return (error);
37630Sstevel@tonic-gate }
37640Sstevel@tonic-gate
37650Sstevel@tonic-gate static int
dprov_object_copy(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_object_id_t object,crypto_object_attribute_t * template,uint_t attribute_count,crypto_object_id_t * new_object,crypto_req_handle_t req)37660Sstevel@tonic-gate dprov_object_copy(crypto_provider_handle_t provider,
37670Sstevel@tonic-gate crypto_session_id_t session_id, crypto_object_id_t object,
37680Sstevel@tonic-gate crypto_object_attribute_t *template, uint_t attribute_count,
37690Sstevel@tonic-gate crypto_object_id_t *new_object, crypto_req_handle_t req)
37700Sstevel@tonic-gate {
37710Sstevel@tonic-gate int error = CRYPTO_FAILED;
37720Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
37730Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
37740Sstevel@tonic-gate int instance;
37750Sstevel@tonic-gate
37760Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
37770Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_copy: started\n",
37780Sstevel@tonic-gate instance));
37790Sstevel@tonic-gate
37800Sstevel@tonic-gate /* submit request to the taskq */
37810Sstevel@tonic-gate error = dprov_object_submit_req(DPROV_REQ_OBJECT_COPY, softc, req,
37820Sstevel@tonic-gate session_id, object, template, attribute_count, new_object,
37830Sstevel@tonic-gate NULL, NULL, NULL, 0, NULL, KM_NOSLEEP);
37840Sstevel@tonic-gate
37850Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_copy: done err = 0x0%x\n",
37860Sstevel@tonic-gate instance, error));
37870Sstevel@tonic-gate
37880Sstevel@tonic-gate return (error);
37890Sstevel@tonic-gate }
37900Sstevel@tonic-gate
37910Sstevel@tonic-gate static int
dprov_object_destroy(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_object_id_t object,crypto_req_handle_t req)37920Sstevel@tonic-gate dprov_object_destroy(crypto_provider_handle_t provider,
37930Sstevel@tonic-gate crypto_session_id_t session_id, crypto_object_id_t object,
37940Sstevel@tonic-gate crypto_req_handle_t req)
37950Sstevel@tonic-gate {
37960Sstevel@tonic-gate int error = CRYPTO_FAILED;
37970Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
37980Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
37990Sstevel@tonic-gate int instance;
38000Sstevel@tonic-gate
38010Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
38020Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_destroy: started\n",
38030Sstevel@tonic-gate instance));
38040Sstevel@tonic-gate
38050Sstevel@tonic-gate /* submit request to the taskq */
38060Sstevel@tonic-gate error = dprov_object_submit_req(DPROV_REQ_OBJECT_DESTROY, softc, req,
38070Sstevel@tonic-gate session_id, object, NULL, 0, NULL, NULL, NULL, NULL, 0, NULL,
38080Sstevel@tonic-gate KM_NOSLEEP);
38090Sstevel@tonic-gate
38100Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_destroy: done err = 0x0%x\n",
38110Sstevel@tonic-gate instance, error));
38120Sstevel@tonic-gate
38130Sstevel@tonic-gate return (error);
38140Sstevel@tonic-gate }
38150Sstevel@tonic-gate
38160Sstevel@tonic-gate static int
dprov_object_get_size(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_object_id_t object,size_t * size,crypto_req_handle_t req)38170Sstevel@tonic-gate dprov_object_get_size(crypto_provider_handle_t provider,
38180Sstevel@tonic-gate crypto_session_id_t session_id, crypto_object_id_t object,
38190Sstevel@tonic-gate size_t *size, crypto_req_handle_t req)
38200Sstevel@tonic-gate {
38210Sstevel@tonic-gate int error = CRYPTO_FAILED;
38220Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
38230Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
38240Sstevel@tonic-gate int instance;
38250Sstevel@tonic-gate
38260Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
38270Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_size: started\n",
38280Sstevel@tonic-gate instance));
38290Sstevel@tonic-gate
38300Sstevel@tonic-gate /* submit request to the taskq */
38310Sstevel@tonic-gate error = dprov_object_submit_req(DPROV_REQ_OBJECT_GET_SIZE, softc, req,
38320Sstevel@tonic-gate session_id, object, NULL, 0, NULL, size, NULL, NULL, 0, NULL,
38330Sstevel@tonic-gate KM_NOSLEEP);
38340Sstevel@tonic-gate
38350Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_size: done err = 0x0%x\n",
38360Sstevel@tonic-gate instance, error));
38370Sstevel@tonic-gate
38380Sstevel@tonic-gate return (error);
38390Sstevel@tonic-gate }
38400Sstevel@tonic-gate
38410Sstevel@tonic-gate static int
dprov_object_get_attribute_value(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_object_id_t object,crypto_object_attribute_t * template,uint_t attribute_count,crypto_req_handle_t req)38420Sstevel@tonic-gate dprov_object_get_attribute_value(crypto_provider_handle_t provider,
38430Sstevel@tonic-gate crypto_session_id_t session_id, crypto_object_id_t object,
38440Sstevel@tonic-gate crypto_object_attribute_t *template, uint_t attribute_count,
38450Sstevel@tonic-gate crypto_req_handle_t req)
38460Sstevel@tonic-gate {
38470Sstevel@tonic-gate int error = CRYPTO_FAILED;
38480Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
38490Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
38500Sstevel@tonic-gate int instance;
38510Sstevel@tonic-gate
38520Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
38530Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_attribute_value: "
38540Sstevel@tonic-gate "started\n", instance));
38550Sstevel@tonic-gate
38560Sstevel@tonic-gate /* submit request to the taskq */
38570Sstevel@tonic-gate error = dprov_object_submit_req(DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE,
38580Sstevel@tonic-gate softc, req, session_id, object, template, attribute_count,
38590Sstevel@tonic-gate NULL, NULL, NULL, NULL, 0, NULL, KM_NOSLEEP);
38600Sstevel@tonic-gate
38610Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_attribute_value: "
38620Sstevel@tonic-gate "done err = 0x0%x\n", instance, error));
38630Sstevel@tonic-gate
38640Sstevel@tonic-gate return (error);
38650Sstevel@tonic-gate }
38660Sstevel@tonic-gate
38670Sstevel@tonic-gate static int
dprov_object_set_attribute_value(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_object_id_t object,crypto_object_attribute_t * template,uint_t attribute_count,crypto_req_handle_t req)38680Sstevel@tonic-gate dprov_object_set_attribute_value(crypto_provider_handle_t provider,
38690Sstevel@tonic-gate crypto_session_id_t session_id, crypto_object_id_t object,
38700Sstevel@tonic-gate crypto_object_attribute_t *template, uint_t attribute_count,
38710Sstevel@tonic-gate crypto_req_handle_t req)
38720Sstevel@tonic-gate {
38730Sstevel@tonic-gate int error = CRYPTO_FAILED;
38740Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
38750Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
38760Sstevel@tonic-gate int instance;
38770Sstevel@tonic-gate
38780Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
38790Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_set_attribute_value: "
38800Sstevel@tonic-gate "started\n", instance));
38810Sstevel@tonic-gate
38820Sstevel@tonic-gate /* submit request to the taskq */
38830Sstevel@tonic-gate error = dprov_object_submit_req(DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE,
38840Sstevel@tonic-gate softc, req, session_id, object, template, attribute_count,
38850Sstevel@tonic-gate NULL, NULL, NULL, NULL, 0, NULL, KM_NOSLEEP);
38860Sstevel@tonic-gate
38870Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_set_attribute_value: "
38880Sstevel@tonic-gate "done err = 0x0%x\n", instance, error));
38890Sstevel@tonic-gate
38900Sstevel@tonic-gate return (error);
38910Sstevel@tonic-gate }
38920Sstevel@tonic-gate
38930Sstevel@tonic-gate static int
dprov_object_find_init(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_object_attribute_t * template,uint_t attribute_count,void ** provider_private,crypto_req_handle_t req)38940Sstevel@tonic-gate dprov_object_find_init(crypto_provider_handle_t provider,
38950Sstevel@tonic-gate crypto_session_id_t session_id, crypto_object_attribute_t *template,
38960Sstevel@tonic-gate uint_t attribute_count, void **provider_private,
38970Sstevel@tonic-gate crypto_req_handle_t req)
38980Sstevel@tonic-gate {
38990Sstevel@tonic-gate int error = CRYPTO_FAILED;
39000Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
39010Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
39020Sstevel@tonic-gate int instance;
39030Sstevel@tonic-gate
39040Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
39050Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_init: started\n",
39060Sstevel@tonic-gate instance));
39070Sstevel@tonic-gate
39080Sstevel@tonic-gate /* submit request to the taskq */
39090Sstevel@tonic-gate error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND_INIT, softc, req,
39100Sstevel@tonic-gate session_id, 0, template, attribute_count, NULL, NULL,
39110Sstevel@tonic-gate provider_private, NULL, 0, NULL, KM_SLEEP);
39120Sstevel@tonic-gate
39130Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_init: done "
39140Sstevel@tonic-gate "err = 0x0%x\n", instance, error));
39150Sstevel@tonic-gate
39160Sstevel@tonic-gate return (error);
39170Sstevel@tonic-gate }
39180Sstevel@tonic-gate
39190Sstevel@tonic-gate static int
dprov_object_find(crypto_provider_handle_t provider,void * provider_private,crypto_object_id_t * objects,uint_t max_object_count,uint_t * object_count,crypto_req_handle_t req)39200Sstevel@tonic-gate dprov_object_find(crypto_provider_handle_t provider, void *provider_private,
39210Sstevel@tonic-gate crypto_object_id_t *objects, uint_t max_object_count,
39220Sstevel@tonic-gate uint_t *object_count, crypto_req_handle_t req)
39230Sstevel@tonic-gate {
39240Sstevel@tonic-gate int error = CRYPTO_FAILED;
39250Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
39260Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
39270Sstevel@tonic-gate int instance;
39280Sstevel@tonic-gate
39290Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
39300Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find: started\n",
39310Sstevel@tonic-gate instance));
39320Sstevel@tonic-gate
39330Sstevel@tonic-gate /* submit request to the taskq */
39340Sstevel@tonic-gate error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND, softc, req,
39350Sstevel@tonic-gate 0, 0, NULL, 0, objects, NULL, NULL, provider_private,
39360Sstevel@tonic-gate max_object_count, object_count, KM_NOSLEEP);
39370Sstevel@tonic-gate
39380Sstevel@tonic-gate
39390Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find: done err = 0x0%x\n",
39400Sstevel@tonic-gate instance, error));
39410Sstevel@tonic-gate
39420Sstevel@tonic-gate return (error);
39430Sstevel@tonic-gate }
39440Sstevel@tonic-gate
39450Sstevel@tonic-gate static int
dprov_object_find_final(crypto_provider_handle_t provider,void * provider_private,crypto_req_handle_t req)39460Sstevel@tonic-gate dprov_object_find_final(crypto_provider_handle_t provider,
39470Sstevel@tonic-gate void *provider_private, crypto_req_handle_t req)
39480Sstevel@tonic-gate {
39490Sstevel@tonic-gate int error = CRYPTO_FAILED;
39500Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
39510Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
39520Sstevel@tonic-gate int instance;
39530Sstevel@tonic-gate
39540Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
39550Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_final: started\n",
39560Sstevel@tonic-gate instance));
39570Sstevel@tonic-gate
39580Sstevel@tonic-gate /* submit request to the taskq */
39590Sstevel@tonic-gate error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND_FINAL, softc, req,
39600Sstevel@tonic-gate 0, 0, NULL, 0, NULL, NULL, NULL, provider_private,
39610Sstevel@tonic-gate 0, NULL, KM_NOSLEEP);
39620Sstevel@tonic-gate
39630Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_final: done "
39640Sstevel@tonic-gate "err = 0x0%x\n", instance, error));
39650Sstevel@tonic-gate
39660Sstevel@tonic-gate return (error);
39670Sstevel@tonic-gate }
39680Sstevel@tonic-gate
39690Sstevel@tonic-gate /*
39700Sstevel@tonic-gate * Key management entry points.
39710Sstevel@tonic-gate */
39720Sstevel@tonic-gate
39730Sstevel@tonic-gate static int
dprov_key_generate(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_object_attribute_t * template,uint_t attribute_count,crypto_object_id_t * object,crypto_req_handle_t req)39740Sstevel@tonic-gate dprov_key_generate(crypto_provider_handle_t provider,
39750Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
39760Sstevel@tonic-gate crypto_object_attribute_t *template, uint_t attribute_count,
39770Sstevel@tonic-gate crypto_object_id_t *object, crypto_req_handle_t req)
39780Sstevel@tonic-gate {
39790Sstevel@tonic-gate int error = CRYPTO_FAILED;
39800Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
39810Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
39820Sstevel@tonic-gate int instance;
39830Sstevel@tonic-gate
39840Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
39850Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate: started\n",
39860Sstevel@tonic-gate instance));
39870Sstevel@tonic-gate
39880Sstevel@tonic-gate /* submit request to the taskq */
39890Sstevel@tonic-gate error = dprov_key_submit_req(DPROV_REQ_KEY_GENERATE, softc, req,
39900Sstevel@tonic-gate session_id, mechanism, template, attribute_count, object, NULL,
39914219Smcpowers 0, NULL, NULL, NULL, 0, NULL, 0, NULL, 0);
39920Sstevel@tonic-gate
39930Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate: done err = 0x0%x\n",
39940Sstevel@tonic-gate instance, error));
39950Sstevel@tonic-gate
39960Sstevel@tonic-gate return (error);
39970Sstevel@tonic-gate }
39980Sstevel@tonic-gate
39990Sstevel@tonic-gate static int
dprov_key_generate_pair(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_object_attribute_t * public_key_template,uint_t public_key_attribute_count,crypto_object_attribute_t * private_key_template,uint_t private_key_attribute_count,crypto_object_id_t * public_key,crypto_object_id_t * private_key,crypto_req_handle_t req)40000Sstevel@tonic-gate dprov_key_generate_pair(crypto_provider_handle_t provider,
40010Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
40020Sstevel@tonic-gate crypto_object_attribute_t *public_key_template,
40030Sstevel@tonic-gate uint_t public_key_attribute_count,
40040Sstevel@tonic-gate crypto_object_attribute_t *private_key_template,
40050Sstevel@tonic-gate uint_t private_key_attribute_count,
40060Sstevel@tonic-gate crypto_object_id_t *public_key, crypto_object_id_t *private_key,
40070Sstevel@tonic-gate crypto_req_handle_t req)
40080Sstevel@tonic-gate {
40090Sstevel@tonic-gate int error = CRYPTO_FAILED;
40100Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
40110Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
40120Sstevel@tonic-gate int instance;
40130Sstevel@tonic-gate
40140Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
40150Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate_pair: started\n",
40160Sstevel@tonic-gate instance));
40170Sstevel@tonic-gate
40180Sstevel@tonic-gate /* submit request to the taskq */
40190Sstevel@tonic-gate error = dprov_key_submit_req(DPROV_REQ_KEY_GENERATE_PAIR, softc, req,
40200Sstevel@tonic-gate session_id, mechanism, public_key_template,
40210Sstevel@tonic-gate public_key_attribute_count, public_key, private_key_template,
40224219Smcpowers private_key_attribute_count, private_key, NULL, NULL, 0, NULL, 0,
40234219Smcpowers NULL, 0);
40240Sstevel@tonic-gate
40250Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate_pair: done err = 0x0%x\n",
40260Sstevel@tonic-gate instance, error));
40270Sstevel@tonic-gate
40280Sstevel@tonic-gate return (error);
40290Sstevel@tonic-gate }
40300Sstevel@tonic-gate
40310Sstevel@tonic-gate static int
dprov_key_wrap(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * wrapping_key,crypto_object_id_t * key,uchar_t * wrapped_key,size_t * wrapped_key_len_ptr,crypto_req_handle_t req)40320Sstevel@tonic-gate dprov_key_wrap(crypto_provider_handle_t provider,
40330Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
40340Sstevel@tonic-gate crypto_key_t *wrapping_key, crypto_object_id_t *key,
40350Sstevel@tonic-gate uchar_t *wrapped_key, size_t *wrapped_key_len_ptr, crypto_req_handle_t req)
40360Sstevel@tonic-gate {
40370Sstevel@tonic-gate int error = CRYPTO_FAILED;
40380Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
40390Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
40400Sstevel@tonic-gate int instance;
40410Sstevel@tonic-gate
40420Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
40430Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_wrap: started\n",
40440Sstevel@tonic-gate instance));
40450Sstevel@tonic-gate
40460Sstevel@tonic-gate /* submit request to the taskq */
40470Sstevel@tonic-gate error = dprov_key_submit_req(DPROV_REQ_KEY_WRAP, softc, req,
40480Sstevel@tonic-gate session_id, mechanism, NULL, 0, key, NULL,
40494219Smcpowers 0, NULL, wrapping_key, wrapped_key, wrapped_key_len_ptr,
40504219Smcpowers NULL, 0, NULL, 0);
40510Sstevel@tonic-gate
40520Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_wrap: done err = 0x0%x\n",
40530Sstevel@tonic-gate instance, error));
40540Sstevel@tonic-gate
40550Sstevel@tonic-gate return (error);
40560Sstevel@tonic-gate }
40570Sstevel@tonic-gate
40580Sstevel@tonic-gate static int
dprov_key_unwrap(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * unwrapping_key,uchar_t * wrapped_key,size_t * wrapped_key_len_ptr,crypto_object_attribute_t * template,uint_t attribute_count,crypto_object_id_t * key,crypto_req_handle_t req)40590Sstevel@tonic-gate dprov_key_unwrap(crypto_provider_handle_t provider,
40600Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
40610Sstevel@tonic-gate crypto_key_t *unwrapping_key, uchar_t *wrapped_key,
40620Sstevel@tonic-gate size_t *wrapped_key_len_ptr, crypto_object_attribute_t *template,
40630Sstevel@tonic-gate uint_t attribute_count, crypto_object_id_t *key, crypto_req_handle_t req)
40640Sstevel@tonic-gate {
40650Sstevel@tonic-gate int error = CRYPTO_FAILED;
40660Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
40670Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
40680Sstevel@tonic-gate int instance;
40690Sstevel@tonic-gate
40700Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
40710Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_unwrap: started\n",
40720Sstevel@tonic-gate instance));
40730Sstevel@tonic-gate
40740Sstevel@tonic-gate /* submit request to the taskq */
40750Sstevel@tonic-gate error = dprov_key_submit_req(DPROV_REQ_KEY_UNWRAP, softc, req,
40760Sstevel@tonic-gate session_id, mechanism, template, attribute_count, key, NULL,
40774219Smcpowers 0, NULL, unwrapping_key, wrapped_key, wrapped_key_len_ptr,
40784219Smcpowers NULL, 0, NULL, 0);
40790Sstevel@tonic-gate
40800Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_unwrap: done err = 0x0%x\n",
40810Sstevel@tonic-gate instance, error));
40820Sstevel@tonic-gate
40830Sstevel@tonic-gate return (error);
40840Sstevel@tonic-gate }
40850Sstevel@tonic-gate
40860Sstevel@tonic-gate static int
dprov_key_derive(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * base_key,crypto_object_attribute_t * template,uint_t attribute_count,crypto_object_id_t * key,crypto_req_handle_t req)40870Sstevel@tonic-gate dprov_key_derive(crypto_provider_handle_t provider,
40880Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
40890Sstevel@tonic-gate crypto_key_t *base_key, crypto_object_attribute_t *template,
40900Sstevel@tonic-gate uint_t attribute_count, crypto_object_id_t *key, crypto_req_handle_t req)
40910Sstevel@tonic-gate {
40920Sstevel@tonic-gate int error = CRYPTO_FAILED;
40930Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
40940Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
40950Sstevel@tonic-gate int instance;
40960Sstevel@tonic-gate
40970Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
40980Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_derive: started\n",
40990Sstevel@tonic-gate instance));
41000Sstevel@tonic-gate
41010Sstevel@tonic-gate /* submit request to the taskq */
41020Sstevel@tonic-gate error = dprov_key_submit_req(DPROV_REQ_KEY_DERIVE, softc, req,
41030Sstevel@tonic-gate session_id, mechanism, template, attribute_count, key, NULL,
41044219Smcpowers 0, NULL, base_key, NULL, 0, NULL, 0, NULL, 0);
41050Sstevel@tonic-gate
41060Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_derive: done err = 0x0%x\n",
41070Sstevel@tonic-gate instance, error));
41080Sstevel@tonic-gate
41090Sstevel@tonic-gate return (error);
41100Sstevel@tonic-gate }
41110Sstevel@tonic-gate
41120Sstevel@tonic-gate /*
41130Sstevel@tonic-gate * Provider management entry points.
41140Sstevel@tonic-gate */
41150Sstevel@tonic-gate
41160Sstevel@tonic-gate static int
dprov_ext_info(crypto_provider_handle_t provider,crypto_provider_ext_info_t * ext_info,crypto_req_handle_t req)41170Sstevel@tonic-gate dprov_ext_info(crypto_provider_handle_t provider,
41180Sstevel@tonic-gate crypto_provider_ext_info_t *ext_info, crypto_req_handle_t req)
41190Sstevel@tonic-gate {
41200Sstevel@tonic-gate int error = CRYPTO_FAILED;
41210Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
41220Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
41230Sstevel@tonic-gate int instance;
41240Sstevel@tonic-gate
41250Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
41260Sstevel@tonic-gate DPROV_DEBUG(D_MGMT, ("(%d) dprov_ext_info: started\n",
41270Sstevel@tonic-gate instance));
41280Sstevel@tonic-gate
41290Sstevel@tonic-gate error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_EXTINFO, softc, req,
41300Sstevel@tonic-gate 0, NULL, 0, NULL, 0, NULL, ext_info);
41310Sstevel@tonic-gate
41320Sstevel@tonic-gate DPROV_DEBUG(D_MGMT, ("(%d) dprov_ext_info: done err = 0x0%x\n",
41330Sstevel@tonic-gate instance, error));
41340Sstevel@tonic-gate
41350Sstevel@tonic-gate return (error);
41360Sstevel@tonic-gate }
41370Sstevel@tonic-gate
41380Sstevel@tonic-gate static int
dprov_init_token(crypto_provider_handle_t provider,char * pin,size_t pin_len,char * label,crypto_req_handle_t req)41390Sstevel@tonic-gate dprov_init_token(crypto_provider_handle_t provider, char *pin, size_t pin_len,
41400Sstevel@tonic-gate char *label, crypto_req_handle_t req)
41410Sstevel@tonic-gate {
41420Sstevel@tonic-gate int error = CRYPTO_FAILED;
41430Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
41440Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
41450Sstevel@tonic-gate int instance;
41460Sstevel@tonic-gate
41470Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
41480Sstevel@tonic-gate DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_token: started\n",
41490Sstevel@tonic-gate instance));
41500Sstevel@tonic-gate
41510Sstevel@tonic-gate error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_INITTOKEN, softc, req,
41520Sstevel@tonic-gate 0, pin, pin_len, NULL, 0, label, NULL);
41530Sstevel@tonic-gate
41540Sstevel@tonic-gate DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_token: done err = 0x0%x\n",
41550Sstevel@tonic-gate instance, error));
41560Sstevel@tonic-gate
41570Sstevel@tonic-gate return (error);
41580Sstevel@tonic-gate }
41590Sstevel@tonic-gate
41600Sstevel@tonic-gate static int
dprov_init_pin(crypto_provider_handle_t provider,crypto_session_id_t session_id,char * pin,size_t pin_len,crypto_req_handle_t req)41610Sstevel@tonic-gate dprov_init_pin(crypto_provider_handle_t provider,
41620Sstevel@tonic-gate crypto_session_id_t session_id, char *pin, size_t pin_len,
41630Sstevel@tonic-gate crypto_req_handle_t req)
41640Sstevel@tonic-gate {
41650Sstevel@tonic-gate int error = CRYPTO_FAILED;
41660Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
41670Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
41680Sstevel@tonic-gate int instance;
41690Sstevel@tonic-gate
41700Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
41710Sstevel@tonic-gate DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_pin: started\n",
41720Sstevel@tonic-gate instance));
41730Sstevel@tonic-gate
41740Sstevel@tonic-gate error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_INITPIN, softc, req,
41750Sstevel@tonic-gate session_id, pin, pin_len, NULL, 0, NULL, NULL);
41760Sstevel@tonic-gate
41770Sstevel@tonic-gate DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_pin: done err = 0x0%x\n",
41780Sstevel@tonic-gate instance, error));
41790Sstevel@tonic-gate
41800Sstevel@tonic-gate return (error);
41810Sstevel@tonic-gate }
41820Sstevel@tonic-gate
41830Sstevel@tonic-gate static int
dprov_set_pin(crypto_provider_handle_t provider,crypto_session_id_t session_id,char * old_pin,size_t old_pin_len,char * new_pin,size_t new_pin_len,crypto_req_handle_t req)41840Sstevel@tonic-gate dprov_set_pin(crypto_provider_handle_t provider, crypto_session_id_t session_id,
41850Sstevel@tonic-gate char *old_pin, size_t old_pin_len, char *new_pin, size_t new_pin_len,
41860Sstevel@tonic-gate crypto_req_handle_t req)
41870Sstevel@tonic-gate {
41880Sstevel@tonic-gate int error = CRYPTO_FAILED;
41890Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider;
41900Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
41910Sstevel@tonic-gate int instance;
41920Sstevel@tonic-gate
41930Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip);
41940Sstevel@tonic-gate DPROV_DEBUG(D_MGMT, ("(%d) dprov_set_pin: started\n",
41950Sstevel@tonic-gate instance));
41960Sstevel@tonic-gate
41970Sstevel@tonic-gate error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_SETPIN, softc, req,
41980Sstevel@tonic-gate session_id, new_pin, new_pin_len, old_pin, old_pin_len, NULL, NULL);
41990Sstevel@tonic-gate
42000Sstevel@tonic-gate DPROV_DEBUG(D_MGMT, ("(%d) dprov_set_pin: done err = 0x0%x\n",
42010Sstevel@tonic-gate instance, error));
42020Sstevel@tonic-gate
42030Sstevel@tonic-gate return (error);
42040Sstevel@tonic-gate }
42050Sstevel@tonic-gate
42060Sstevel@tonic-gate
42070Sstevel@tonic-gate /*
42080Sstevel@tonic-gate * Context management entry points.
42090Sstevel@tonic-gate */
42100Sstevel@tonic-gate
42110Sstevel@tonic-gate /*
42120Sstevel@tonic-gate * Allocate a dprov-private context based on the specified dprov request.
42130Sstevel@tonic-gate * For dual cipher/mac requests, the allocated context will
42140Sstevel@tonic-gate * contain a structure dprov_ctx_dual_t, for other request types,
42150Sstevel@tonic-gate * it will contain a dprov_ctx_single.
42160Sstevel@tonic-gate * Returns one of the CRYPTO_ status codes.
42170Sstevel@tonic-gate */
42180Sstevel@tonic-gate static int
dprov_alloc_context(dprov_req_type_t req_type,crypto_ctx_t * spi_ctx)42190Sstevel@tonic-gate dprov_alloc_context(dprov_req_type_t req_type, crypto_ctx_t *spi_ctx)
42200Sstevel@tonic-gate {
42210Sstevel@tonic-gate dprov_ctx_single_t *dprov_private;
42220Sstevel@tonic-gate
42230Sstevel@tonic-gate switch (req_type) {
42240Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_MAC_INIT:
42250Sstevel@tonic-gate case DPROV_REQ_MAC_DECRYPT_INIT:
42260Sstevel@tonic-gate dprov_private = kmem_zalloc(sizeof (dprov_ctx_dual_t),
42270Sstevel@tonic-gate KM_NOSLEEP);
42280Sstevel@tonic-gate if (dprov_private == NULL)
42290Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY);
42300Sstevel@tonic-gate dprov_private->dc_type = DPROV_CTX_DUAL;
42310Sstevel@tonic-gate break;
42320Sstevel@tonic-gate default:
42330Sstevel@tonic-gate dprov_private = kmem_zalloc(sizeof (dprov_ctx_single_t),
42340Sstevel@tonic-gate KM_NOSLEEP);
42350Sstevel@tonic-gate if (dprov_private == NULL)
42360Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY);
42370Sstevel@tonic-gate dprov_private->dc_type = DPROV_CTX_SINGLE;
42384072Skrishna dprov_private->dc_svrfy_to_mac = B_FALSE;
42390Sstevel@tonic-gate break;
42400Sstevel@tonic-gate }
42410Sstevel@tonic-gate
42420Sstevel@tonic-gate spi_ctx->cc_provider_private = (void *)dprov_private;
42430Sstevel@tonic-gate
42440Sstevel@tonic-gate return (CRYPTO_SUCCESS);
42450Sstevel@tonic-gate }
42460Sstevel@tonic-gate
42470Sstevel@tonic-gate static int
dprov_free_context(crypto_ctx_t * ctx)42480Sstevel@tonic-gate dprov_free_context(crypto_ctx_t *ctx)
42490Sstevel@tonic-gate {
42500Sstevel@tonic-gate if (ctx->cc_provider_private == NULL)
42510Sstevel@tonic-gate return (CRYPTO_SUCCESS);
42520Sstevel@tonic-gate
42530Sstevel@tonic-gate DPROV_DEBUG(D_CONTEXT, ("dprov_free_context\n"));
42540Sstevel@tonic-gate
42550Sstevel@tonic-gate {
42560Sstevel@tonic-gate /*
42570Sstevel@tonic-gate * The dprov private context could contain either
42580Sstevel@tonic-gate * a dprov_ctx_single_t or a dprov_ctx_dual_t. Free
42590Sstevel@tonic-gate * the context based on its type. The k-API contexts
42600Sstevel@tonic-gate * that were attached to the dprov private context
42610Sstevel@tonic-gate * are freed by the framework.
42620Sstevel@tonic-gate */
42630Sstevel@tonic-gate dprov_ctx_single_t *ctx_single =
42640Sstevel@tonic-gate (dprov_ctx_single_t *)(ctx->cc_provider_private);
42650Sstevel@tonic-gate
42660Sstevel@tonic-gate if (ctx_single->dc_type == DPROV_CTX_SINGLE) {
42670Sstevel@tonic-gate crypto_context_t context = DPROV_CTX_SINGLE(ctx);
42680Sstevel@tonic-gate
42690Sstevel@tonic-gate /*
42700Sstevel@tonic-gate * This case happens for the crypto_cancel_ctx() case.
42710Sstevel@tonic-gate * We have to cancel the SW provider context also.
42720Sstevel@tonic-gate */
42730Sstevel@tonic-gate if (context != NULL)
42740Sstevel@tonic-gate crypto_cancel_ctx(context);
42750Sstevel@tonic-gate
42760Sstevel@tonic-gate kmem_free(ctx_single, sizeof (dprov_ctx_single_t));
42770Sstevel@tonic-gate } else {
42780Sstevel@tonic-gate crypto_context_t cipher_context =
42790Sstevel@tonic-gate DPROV_CTX_DUAL_CIPHER(ctx);
42800Sstevel@tonic-gate crypto_context_t mac_context = DPROV_CTX_DUAL_MAC(ctx);
42810Sstevel@tonic-gate
42820Sstevel@tonic-gate /* See comments above. */
42830Sstevel@tonic-gate if (cipher_context != NULL)
42840Sstevel@tonic-gate crypto_cancel_ctx(cipher_context);
42850Sstevel@tonic-gate if (mac_context != NULL)
42860Sstevel@tonic-gate crypto_cancel_ctx(mac_context);
42870Sstevel@tonic-gate
42880Sstevel@tonic-gate ASSERT(ctx_single->dc_type == DPROV_CTX_DUAL);
42890Sstevel@tonic-gate kmem_free(ctx_single, sizeof (dprov_ctx_dual_t));
42900Sstevel@tonic-gate }
42910Sstevel@tonic-gate ctx->cc_provider_private = NULL;
42920Sstevel@tonic-gate }
42930Sstevel@tonic-gate
42940Sstevel@tonic-gate return (CRYPTO_SUCCESS);
42950Sstevel@tonic-gate }
42960Sstevel@tonic-gate
4297904Smcpowers /*
4298904Smcpowers * Resource control checks don't need to be done. Why? Because this routine
4299904Smcpowers * knows the size of the structure, and it can't be overridden by a user.
4300904Smcpowers * This is different from the crypto module, which has no knowledge of
4301904Smcpowers * specific mechanisms, and therefore has to trust specified size of the
4302904Smcpowers * parameter. This trust, or lack of trust, is why the size of the
4303904Smcpowers * parameter has to be charged against the project resource control.
4304904Smcpowers */
4305904Smcpowers static int
copyin_aes_ccm_mech(crypto_mechanism_t * in_mech,crypto_mechanism_t * out_mech,int * out_error,int mode)43065413Sdinak copyin_aes_ccm_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
43075413Sdinak int *out_error, int mode)
43085413Sdinak {
43095413Sdinak STRUCT_DECL(crypto_mechanism, mech);
43105413Sdinak STRUCT_DECL(CK_AES_CCM_PARAMS, params);
43115413Sdinak CK_AES_CCM_PARAMS *aes_ccm_params;
43125413Sdinak caddr_t pp;
43135413Sdinak size_t param_len;
43145413Sdinak int error = 0;
43155413Sdinak int rv = 0;
43165413Sdinak
43175413Sdinak STRUCT_INIT(mech, mode);
43185413Sdinak STRUCT_INIT(params, mode);
43195413Sdinak bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
43205413Sdinak pp = STRUCT_FGETP(mech, cm_param);
43215413Sdinak param_len = STRUCT_FGET(mech, cm_param_len);
43225413Sdinak
43235413Sdinak if (param_len != STRUCT_SIZE(params)) {
43245413Sdinak rv = CRYPTO_ARGUMENTS_BAD;
43255413Sdinak goto out;
43265413Sdinak }
43275413Sdinak
43285413Sdinak out_mech->cm_type = STRUCT_FGET(mech, cm_type);
43295413Sdinak out_mech->cm_param = NULL;
43305413Sdinak out_mech->cm_param_len = 0;
43315413Sdinak if (pp != NULL) {
43325413Sdinak size_t nonce_len, auth_data_len, total_param_len;
43335413Sdinak
43345413Sdinak if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
43355413Sdinak out_mech->cm_param = NULL;
43365413Sdinak error = EFAULT;
43375413Sdinak goto out;
43385413Sdinak }
43395413Sdinak
43405413Sdinak nonce_len = STRUCT_FGET(params, ulNonceSize);
43415413Sdinak auth_data_len = STRUCT_FGET(params, ulAuthDataSize);
43425413Sdinak
43435413Sdinak /* allocate param structure */
43445413Sdinak total_param_len =
43455413Sdinak sizeof (CK_AES_CCM_PARAMS) + nonce_len + auth_data_len;
43465413Sdinak aes_ccm_params = kmem_alloc(total_param_len, KM_NOSLEEP);
43475413Sdinak if (aes_ccm_params == NULL) {
43485413Sdinak rv = CRYPTO_HOST_MEMORY;
43495413Sdinak goto out;
43505413Sdinak }
43515413Sdinak aes_ccm_params->ulMACSize = STRUCT_FGET(params, ulMACSize);
43525413Sdinak aes_ccm_params->ulNonceSize = nonce_len;
43535413Sdinak aes_ccm_params->ulAuthDataSize = auth_data_len;
43545413Sdinak aes_ccm_params->ulDataSize
43555413Sdinak = STRUCT_FGET(params, ulDataSize);
43565413Sdinak aes_ccm_params->nonce
43575413Sdinak = (uchar_t *)aes_ccm_params + sizeof (CK_AES_CCM_PARAMS);
43585413Sdinak aes_ccm_params->authData
43595413Sdinak = aes_ccm_params->nonce + nonce_len;
43605413Sdinak
43615413Sdinak if (copyin((char *)STRUCT_FGETP(params, nonce),
43625413Sdinak aes_ccm_params->nonce, nonce_len) != 0) {
43635413Sdinak kmem_free(aes_ccm_params, total_param_len);
43645413Sdinak out_mech->cm_param = NULL;
43655413Sdinak error = EFAULT;
43665413Sdinak goto out;
43675413Sdinak }
43685413Sdinak if (copyin((char *)STRUCT_FGETP(params, authData),
43695413Sdinak aes_ccm_params->authData, auth_data_len) != 0) {
43705413Sdinak kmem_free(aes_ccm_params, total_param_len);
43715413Sdinak out_mech->cm_param = NULL;
43725413Sdinak error = EFAULT;
43735413Sdinak goto out;
43745413Sdinak }
43755413Sdinak out_mech->cm_param = (char *)aes_ccm_params;
43765413Sdinak out_mech->cm_param_len = sizeof (CK_AES_CCM_PARAMS);
43775413Sdinak }
43785413Sdinak out:
43795413Sdinak *out_error = error;
43805413Sdinak return (rv);
43815413Sdinak }
43825413Sdinak
43838005SMark.Powers@Sun.COM /*
43848005SMark.Powers@Sun.COM * Resource control checks don't need to be done. Why? Because this routine
43858005SMark.Powers@Sun.COM * knows the size of the structure, and it can't be overridden by a user.
43868005SMark.Powers@Sun.COM * This is different from the crypto module, which has no knowledge of
43878005SMark.Powers@Sun.COM * specific mechanisms, and therefore has to trust specified size of the
43888005SMark.Powers@Sun.COM * parameter. This trust, or lack of trust, is why the size of the
43898005SMark.Powers@Sun.COM * parameter has to be charged against the project resource control.
43908005SMark.Powers@Sun.COM */
43918005SMark.Powers@Sun.COM static int
copyin_aes_gcm_mech(crypto_mechanism_t * in_mech,crypto_mechanism_t * out_mech,int * out_error,int mode)43928005SMark.Powers@Sun.COM copyin_aes_gcm_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
43938005SMark.Powers@Sun.COM int *out_error, int mode)
43948005SMark.Powers@Sun.COM {
43958005SMark.Powers@Sun.COM STRUCT_DECL(crypto_mechanism, mech);
43968005SMark.Powers@Sun.COM STRUCT_DECL(CK_AES_GCM_PARAMS, params);
43978005SMark.Powers@Sun.COM CK_AES_GCM_PARAMS *aes_gcm_params;
43988005SMark.Powers@Sun.COM caddr_t pp;
43998005SMark.Powers@Sun.COM size_t param_len;
44008005SMark.Powers@Sun.COM int error = 0;
44018005SMark.Powers@Sun.COM int rv = 0;
44028005SMark.Powers@Sun.COM
44038005SMark.Powers@Sun.COM STRUCT_INIT(mech, mode);
44048005SMark.Powers@Sun.COM STRUCT_INIT(params, mode);
44058005SMark.Powers@Sun.COM bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
44068005SMark.Powers@Sun.COM pp = STRUCT_FGETP(mech, cm_param);
44078005SMark.Powers@Sun.COM param_len = STRUCT_FGET(mech, cm_param_len);
44088005SMark.Powers@Sun.COM
44098005SMark.Powers@Sun.COM if (param_len != STRUCT_SIZE(params)) {
44108005SMark.Powers@Sun.COM rv = CRYPTO_ARGUMENTS_BAD;
44118005SMark.Powers@Sun.COM goto out;
44128005SMark.Powers@Sun.COM }
44138005SMark.Powers@Sun.COM
44148005SMark.Powers@Sun.COM out_mech->cm_type = STRUCT_FGET(mech, cm_type);
44158005SMark.Powers@Sun.COM out_mech->cm_param = NULL;
44168005SMark.Powers@Sun.COM out_mech->cm_param_len = 0;
44178005SMark.Powers@Sun.COM if (pp != NULL) {
44188005SMark.Powers@Sun.COM size_t nonce_len, auth_data_len, total_param_len;
44198005SMark.Powers@Sun.COM
44208005SMark.Powers@Sun.COM if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
44218005SMark.Powers@Sun.COM out_mech->cm_param = NULL;
44228005SMark.Powers@Sun.COM error = EFAULT;
44238005SMark.Powers@Sun.COM goto out;
44248005SMark.Powers@Sun.COM }
44258005SMark.Powers@Sun.COM
44268005SMark.Powers@Sun.COM nonce_len = STRUCT_FGET(params, ulIvLen);
44278005SMark.Powers@Sun.COM auth_data_len = STRUCT_FGET(params, ulAADLen);
44288005SMark.Powers@Sun.COM
44298005SMark.Powers@Sun.COM /* allocate param structure */
44308005SMark.Powers@Sun.COM total_param_len =
44318005SMark.Powers@Sun.COM sizeof (CK_AES_GCM_PARAMS) + nonce_len + auth_data_len;
44328005SMark.Powers@Sun.COM aes_gcm_params = kmem_alloc(total_param_len, KM_NOSLEEP);
44338005SMark.Powers@Sun.COM if (aes_gcm_params == NULL) {
44348005SMark.Powers@Sun.COM rv = CRYPTO_HOST_MEMORY;
44358005SMark.Powers@Sun.COM goto out;
44368005SMark.Powers@Sun.COM }
44378005SMark.Powers@Sun.COM aes_gcm_params->ulTagBits = STRUCT_FGET(params, ulTagBits);
44388005SMark.Powers@Sun.COM aes_gcm_params->ulIvLen = nonce_len;
44398005SMark.Powers@Sun.COM aes_gcm_params->ulAADLen = auth_data_len;
44408005SMark.Powers@Sun.COM aes_gcm_params->pIv
44418005SMark.Powers@Sun.COM = (uchar_t *)aes_gcm_params + sizeof (CK_AES_GCM_PARAMS);
44428005SMark.Powers@Sun.COM aes_gcm_params->pAAD = aes_gcm_params->pIv + nonce_len;
44438005SMark.Powers@Sun.COM
44448005SMark.Powers@Sun.COM if (copyin((char *)STRUCT_FGETP(params, pIv),
44458005SMark.Powers@Sun.COM aes_gcm_params->pIv, nonce_len) != 0) {
44468005SMark.Powers@Sun.COM kmem_free(aes_gcm_params, total_param_len);
44478005SMark.Powers@Sun.COM out_mech->cm_param = NULL;
44488005SMark.Powers@Sun.COM error = EFAULT;
44498005SMark.Powers@Sun.COM goto out;
44508005SMark.Powers@Sun.COM }
44518005SMark.Powers@Sun.COM if (copyin((char *)STRUCT_FGETP(params, pAAD),
44528005SMark.Powers@Sun.COM aes_gcm_params->pAAD, auth_data_len) != 0) {
44538005SMark.Powers@Sun.COM kmem_free(aes_gcm_params, total_param_len);
44548005SMark.Powers@Sun.COM out_mech->cm_param = NULL;
44558005SMark.Powers@Sun.COM error = EFAULT;
44568005SMark.Powers@Sun.COM goto out;
44578005SMark.Powers@Sun.COM }
44588005SMark.Powers@Sun.COM out_mech->cm_param = (char *)aes_gcm_params;
44598005SMark.Powers@Sun.COM out_mech->cm_param_len = sizeof (CK_AES_GCM_PARAMS);
44608005SMark.Powers@Sun.COM }
44618005SMark.Powers@Sun.COM out:
44628005SMark.Powers@Sun.COM *out_error = error;
44638005SMark.Powers@Sun.COM return (rv);
44648005SMark.Powers@Sun.COM }
44655413Sdinak
44669339SMark.Powers@Sun.COM static int
copyin_aes_gmac_mech(crypto_mechanism_t * in_mech,crypto_mechanism_t * out_mech,int * out_error,int mode)44679339SMark.Powers@Sun.COM copyin_aes_gmac_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
44689339SMark.Powers@Sun.COM int *out_error, int mode)
44699339SMark.Powers@Sun.COM {
44709339SMark.Powers@Sun.COM STRUCT_DECL(crypto_mechanism, mech);
44719339SMark.Powers@Sun.COM STRUCT_DECL(CK_AES_GMAC_PARAMS, params);
44729339SMark.Powers@Sun.COM CK_AES_GMAC_PARAMS *aes_gmac_params;
44739339SMark.Powers@Sun.COM caddr_t pp;
44749339SMark.Powers@Sun.COM size_t param_len;
44759339SMark.Powers@Sun.COM int error = 0;
44769339SMark.Powers@Sun.COM int rv = 0;
44779339SMark.Powers@Sun.COM
44789339SMark.Powers@Sun.COM STRUCT_INIT(mech, mode);
44799339SMark.Powers@Sun.COM STRUCT_INIT(params, mode);
44809339SMark.Powers@Sun.COM bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
44819339SMark.Powers@Sun.COM pp = STRUCT_FGETP(mech, cm_param);
44829339SMark.Powers@Sun.COM param_len = STRUCT_FGET(mech, cm_param_len);
44839339SMark.Powers@Sun.COM
44849339SMark.Powers@Sun.COM if (param_len != STRUCT_SIZE(params)) {
44859339SMark.Powers@Sun.COM rv = CRYPTO_ARGUMENTS_BAD;
44869339SMark.Powers@Sun.COM goto out;
44879339SMark.Powers@Sun.COM }
44889339SMark.Powers@Sun.COM
44899339SMark.Powers@Sun.COM out_mech->cm_type = STRUCT_FGET(mech, cm_type);
44909339SMark.Powers@Sun.COM out_mech->cm_param = NULL;
44919339SMark.Powers@Sun.COM out_mech->cm_param_len = 0;
44929339SMark.Powers@Sun.COM if (pp != NULL) {
44939339SMark.Powers@Sun.COM size_t auth_data_len, total_param_len;
44949339SMark.Powers@Sun.COM
44959339SMark.Powers@Sun.COM if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
44969339SMark.Powers@Sun.COM out_mech->cm_param = NULL;
44979339SMark.Powers@Sun.COM error = EFAULT;
44989339SMark.Powers@Sun.COM goto out;
44999339SMark.Powers@Sun.COM }
45009339SMark.Powers@Sun.COM
45019339SMark.Powers@Sun.COM auth_data_len = STRUCT_FGET(params, ulAADLen);
45029339SMark.Powers@Sun.COM
45039339SMark.Powers@Sun.COM /* allocate param structure */
45049339SMark.Powers@Sun.COM total_param_len = sizeof (CK_AES_GMAC_PARAMS) +
45059339SMark.Powers@Sun.COM AES_GMAC_IV_LEN + auth_data_len;
45069339SMark.Powers@Sun.COM aes_gmac_params = kmem_alloc(total_param_len, KM_NOSLEEP);
45079339SMark.Powers@Sun.COM if (aes_gmac_params == NULL) {
45089339SMark.Powers@Sun.COM rv = CRYPTO_HOST_MEMORY;
45099339SMark.Powers@Sun.COM goto out;
45109339SMark.Powers@Sun.COM }
45119339SMark.Powers@Sun.COM aes_gmac_params->ulAADLen = auth_data_len;
45129339SMark.Powers@Sun.COM aes_gmac_params->pIv
45139339SMark.Powers@Sun.COM = (uchar_t *)aes_gmac_params + sizeof (CK_AES_GMAC_PARAMS);
45149339SMark.Powers@Sun.COM aes_gmac_params->pAAD = aes_gmac_params->pIv + AES_GMAC_IV_LEN;
45159339SMark.Powers@Sun.COM
45169339SMark.Powers@Sun.COM if (copyin((char *)STRUCT_FGETP(params, pIv),
45179339SMark.Powers@Sun.COM aes_gmac_params->pIv, AES_GMAC_IV_LEN) != 0) {
45189339SMark.Powers@Sun.COM kmem_free(aes_gmac_params, total_param_len);
45199339SMark.Powers@Sun.COM out_mech->cm_param = NULL;
45209339SMark.Powers@Sun.COM error = EFAULT;
45219339SMark.Powers@Sun.COM goto out;
45229339SMark.Powers@Sun.COM }
45239339SMark.Powers@Sun.COM if (copyin((char *)STRUCT_FGETP(params, pAAD),
45249339SMark.Powers@Sun.COM aes_gmac_params->pAAD, auth_data_len) != 0) {
45259339SMark.Powers@Sun.COM kmem_free(aes_gmac_params, total_param_len);
45269339SMark.Powers@Sun.COM out_mech->cm_param = NULL;
45279339SMark.Powers@Sun.COM error = EFAULT;
45289339SMark.Powers@Sun.COM goto out;
45299339SMark.Powers@Sun.COM }
45309339SMark.Powers@Sun.COM out_mech->cm_param = (char *)aes_gmac_params;
45319339SMark.Powers@Sun.COM out_mech->cm_param_len = sizeof (CK_AES_GMAC_PARAMS);
45329339SMark.Powers@Sun.COM }
45339339SMark.Powers@Sun.COM out:
45349339SMark.Powers@Sun.COM *out_error = error;
45359339SMark.Powers@Sun.COM return (rv);
45369339SMark.Powers@Sun.COM }
45379339SMark.Powers@Sun.COM
45385413Sdinak /*
45395413Sdinak * Resource control checks don't need to be done. Why? Because this routine
45405413Sdinak * knows the size of the structure, and it can't be overridden by a user.
45415413Sdinak * This is different from the crypto module, which has no knowledge of
45425413Sdinak * specific mechanisms, and therefore has to trust specified size of the
45435413Sdinak * parameter. This trust, or lack of trust, is why the size of the
45445413Sdinak * parameter has to be charged against the project resource control.
45455413Sdinak */
45465413Sdinak static int
copyin_aes_ctr_mech(crypto_mechanism_t * in_mech,crypto_mechanism_t * out_mech,int * out_error,int mode)4547904Smcpowers copyin_aes_ctr_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
4548904Smcpowers int *out_error, int mode)
4549904Smcpowers {
4550904Smcpowers STRUCT_DECL(crypto_mechanism, mech);
4551904Smcpowers STRUCT_DECL(CK_AES_CTR_PARAMS, params);
4552904Smcpowers CK_AES_CTR_PARAMS *aes_ctr_params;
4553904Smcpowers caddr_t pp;
4554904Smcpowers size_t param_len;
4555904Smcpowers int error = 0;
4556904Smcpowers int rv = 0;
4557904Smcpowers
4558904Smcpowers STRUCT_INIT(mech, mode);
4559904Smcpowers STRUCT_INIT(params, mode);
4560904Smcpowers bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4561904Smcpowers pp = STRUCT_FGETP(mech, cm_param);
4562904Smcpowers param_len = STRUCT_FGET(mech, cm_param_len);
4563904Smcpowers
4564904Smcpowers if (param_len != STRUCT_SIZE(params)) {
4565904Smcpowers rv = CRYPTO_ARGUMENTS_BAD;
4566904Smcpowers goto out;
4567904Smcpowers }
4568904Smcpowers
4569904Smcpowers out_mech->cm_type = STRUCT_FGET(mech, cm_type);
4570904Smcpowers out_mech->cm_param = NULL;
4571904Smcpowers out_mech->cm_param_len = 0;
4572904Smcpowers if (pp != NULL) {
4573904Smcpowers if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
4574904Smcpowers out_mech->cm_param = NULL;
4575904Smcpowers error = EFAULT;
4576904Smcpowers goto out;
4577904Smcpowers }
4578904Smcpowers /* allocate param structure and counter block */
45795072Smcpowers aes_ctr_params = kmem_alloc(sizeof (CK_AES_CTR_PARAMS),
4580904Smcpowers KM_NOSLEEP);
4581904Smcpowers if (aes_ctr_params == NULL) {
4582904Smcpowers rv = CRYPTO_HOST_MEMORY;
4583904Smcpowers goto out;
4584904Smcpowers }
4585904Smcpowers aes_ctr_params->ulCounterBits = STRUCT_FGET(params,
4586904Smcpowers ulCounterBits);
45875072Smcpowers bcopy(STRUCT_FGETP(params, cb), aes_ctr_params->cb, 16);
4588904Smcpowers out_mech->cm_param = (char *)aes_ctr_params;
4589904Smcpowers out_mech->cm_param_len = sizeof (CK_AES_CTR_PARAMS);
4590904Smcpowers }
4591904Smcpowers out:
4592904Smcpowers *out_error = error;
4593904Smcpowers return (rv);
4594904Smcpowers }
4595904Smcpowers
45965697Smcpowers static int
copyin_ecc_mech(crypto_mechanism_t * in_mech,crypto_mechanism_t * out_mech,int * out_error,int mode)45975697Smcpowers copyin_ecc_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
45985697Smcpowers int *out_error, int mode)
45995697Smcpowers {
46005697Smcpowers STRUCT_DECL(crypto_mechanism, mech);
46015697Smcpowers STRUCT_DECL(CK_ECDH1_DERIVE_PARAMS, params);
46025697Smcpowers CK_ECDH1_DERIVE_PARAMS *ecc_params;
46035697Smcpowers caddr_t pp;
46045697Smcpowers size_t param_len, shared_data_len, public_data_len;
46055697Smcpowers int error = 0;
46065697Smcpowers int rv = 0;
46075697Smcpowers
46085697Smcpowers STRUCT_INIT(mech, mode);
46095697Smcpowers STRUCT_INIT(params, mode);
46105697Smcpowers bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
46115697Smcpowers pp = STRUCT_FGETP(mech, cm_param);
46125697Smcpowers param_len = STRUCT_FGET(mech, cm_param_len);
46135697Smcpowers
46145697Smcpowers if (param_len != STRUCT_SIZE(params)) {
46155697Smcpowers rv = CRYPTO_ARGUMENTS_BAD;
46165697Smcpowers goto out;
46175697Smcpowers }
46185697Smcpowers
46195697Smcpowers out_mech->cm_type = STRUCT_FGET(mech, cm_type);
46205697Smcpowers out_mech->cm_param = NULL;
46215697Smcpowers out_mech->cm_param_len = 0;
46225697Smcpowers if (pp != NULL) {
46235697Smcpowers if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
46245697Smcpowers out_mech->cm_param = NULL;
46255697Smcpowers error = EFAULT;
46265697Smcpowers goto out;
46275697Smcpowers }
46285697Smcpowers shared_data_len = STRUCT_FGET(params, ulSharedDataLen);
46295697Smcpowers public_data_len = STRUCT_FGET(params, ulPublicDataLen);
46305697Smcpowers /* allocate param structure and buffers */
46315697Smcpowers ecc_params = kmem_alloc(sizeof (CK_ECDH1_DERIVE_PARAMS) +
46325697Smcpowers roundup(shared_data_len, sizeof (caddr_t)) +
46335697Smcpowers roundup(public_data_len, sizeof (caddr_t)), KM_NOSLEEP);
46345697Smcpowers if (ecc_params == NULL) {
46355697Smcpowers rv = CRYPTO_HOST_MEMORY;
46365697Smcpowers goto out;
46375697Smcpowers }
46385697Smcpowers ecc_params->pSharedData = (uchar_t *)ecc_params +
46395697Smcpowers sizeof (CK_ECDH1_DERIVE_PARAMS);
46405697Smcpowers ecc_params->pPublicData = (uchar_t *)ecc_params->pSharedData +
46415697Smcpowers roundup(shared_data_len, sizeof (caddr_t));
46425697Smcpowers if (copyin((char *)STRUCT_FGETP(params, pSharedData),
46435697Smcpowers ecc_params->pSharedData, shared_data_len) != 0) {
46445697Smcpowers kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) +
46455697Smcpowers roundup(shared_data_len, sizeof (caddr_t)) +
46465697Smcpowers roundup(public_data_len, sizeof (caddr_t)));
46475697Smcpowers out_mech->cm_param = NULL;
46485697Smcpowers error = EFAULT;
46495697Smcpowers goto out;
46505697Smcpowers }
46515697Smcpowers ecc_params->ulSharedDataLen = shared_data_len;
46525697Smcpowers
46535697Smcpowers if (copyin((char *)STRUCT_FGETP(params, pPublicData),
46545697Smcpowers ecc_params->pPublicData, public_data_len) != 0) {
46555697Smcpowers kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) +
46565697Smcpowers roundup(shared_data_len, sizeof (caddr_t)) +
46575697Smcpowers roundup(public_data_len, sizeof (caddr_t)));
46585697Smcpowers out_mech->cm_param = NULL;
46595697Smcpowers error = EFAULT;
46605697Smcpowers goto out;
46615697Smcpowers }
46625697Smcpowers ecc_params->ulPublicDataLen = public_data_len;
46635697Smcpowers ecc_params->kdf = STRUCT_FGET(params, kdf);
46645697Smcpowers out_mech->cm_param = (char *)ecc_params;
46655697Smcpowers out_mech->cm_param_len = sizeof (CK_ECDH1_DERIVE_PARAMS);
46665697Smcpowers }
46675697Smcpowers out:
46685697Smcpowers *out_error = error;
46695697Smcpowers return (rv);
46705697Smcpowers }
46715697Smcpowers
4672904Smcpowers /* ARGSUSED */
4673904Smcpowers static int
copyout_aes_ctr_mech(crypto_mechanism_t * in_mech,crypto_mechanism_t * out_mech,int * out_error,int mode)4674904Smcpowers copyout_aes_ctr_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
4675904Smcpowers int *out_error, int mode)
4676904Smcpowers {
4677904Smcpowers STRUCT_DECL(crypto_mechanism, mech);
4678904Smcpowers STRUCT_DECL(CK_AES_CTR_PARAMS, params);
4679904Smcpowers caddr_t pp;
4680904Smcpowers size_t param_len;
4681904Smcpowers int error = 0;
4682904Smcpowers int rv = 0;
4683904Smcpowers
4684904Smcpowers STRUCT_INIT(mech, mode);
4685904Smcpowers STRUCT_INIT(params, mode);
4686904Smcpowers bcopy(out_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4687904Smcpowers pp = STRUCT_FGETP(mech, cm_param);
4688904Smcpowers param_len = STRUCT_FGET(mech, cm_param_len);
4689904Smcpowers if (param_len != STRUCT_SIZE(params)) {
4690904Smcpowers rv = CRYPTO_ARGUMENTS_BAD;
4691904Smcpowers goto out;
4692904Smcpowers }
4693904Smcpowers
4694904Smcpowers if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
4695904Smcpowers error = EFAULT;
4696904Smcpowers goto out;
4697904Smcpowers }
4698904Smcpowers
4699904Smcpowers /* for testing, overwrite the iv with 16 X 'A' */
47005072Smcpowers (void) memset(STRUCT_FGETP(params, cb), 'A', 16);
47015413Sdinak if (copyout((char *)pp, STRUCT_BUF(params), param_len) != 0) {
47025072Smcpowers error = EFAULT;
47035072Smcpowers goto out;
4704904Smcpowers }
4705904Smcpowers out:
4706904Smcpowers *out_error = error;
4707904Smcpowers return (rv);
4708904Smcpowers }
4709904Smcpowers
4710904Smcpowers /* ARGSUSED */
4711904Smcpowers static int
dprov_copyin_mechanism(crypto_provider_handle_t provider,crypto_mechanism_t * umech,crypto_mechanism_t * kmech,int * out_error,int mode)4712904Smcpowers dprov_copyin_mechanism(crypto_provider_handle_t provider,
4713904Smcpowers crypto_mechanism_t *umech, crypto_mechanism_t *kmech,
4714904Smcpowers int *out_error, int mode)
4715904Smcpowers {
4716904Smcpowers STRUCT_DECL(crypto_mechanism, mech);
4717904Smcpowers size_t param_len, expected_param_len;
4718904Smcpowers caddr_t pp;
4719904Smcpowers char *param;
4720904Smcpowers int rv;
4721904Smcpowers int error = 0;
4722904Smcpowers
4723904Smcpowers ASSERT(!servicing_interrupt());
4724904Smcpowers
4725904Smcpowers STRUCT_INIT(mech, mode);
4726904Smcpowers bcopy(umech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4727904Smcpowers pp = STRUCT_FGETP(mech, cm_param);
4728904Smcpowers param_len = STRUCT_FGET(mech, cm_param_len);
4729904Smcpowers
4730904Smcpowers kmech->cm_param = NULL;
4731904Smcpowers kmech->cm_param_len = 0;
4732904Smcpowers
4733904Smcpowers switch (kmech->cm_type) {
4734904Smcpowers case DES_CBC_MECH_INFO_TYPE:
4735904Smcpowers case DES3_CBC_MECH_INFO_TYPE:
4736904Smcpowers expected_param_len = DES_BLOCK_LEN;
4737904Smcpowers break;
4738904Smcpowers
4739904Smcpowers case BLOWFISH_CBC_MECH_INFO_TYPE:
4740904Smcpowers expected_param_len = BLOWFISH_BLOCK_LEN;
4741904Smcpowers break;
4742904Smcpowers
4743904Smcpowers case AES_CBC_MECH_INFO_TYPE:
4744904Smcpowers expected_param_len = AES_BLOCK_LEN;
4745904Smcpowers break;
4746904Smcpowers
4747904Smcpowers case AES_CTR_MECH_INFO_TYPE:
4748904Smcpowers case SHA1_KEY_DERIVATION_MECH_INFO_TYPE: /* for testing only */
4749904Smcpowers rv = copyin_aes_ctr_mech(umech, kmech, &error, mode);
4750904Smcpowers goto out;
4751904Smcpowers
47525697Smcpowers case ECDH1_DERIVE_MECH_INFO_TYPE:
47535697Smcpowers rv = copyin_ecc_mech(umech, kmech, &error, mode);
47545697Smcpowers goto out;
47555697Smcpowers
47565413Sdinak case AES_CCM_MECH_INFO_TYPE:
47575413Sdinak rv = copyin_aes_ccm_mech(umech, kmech, &error, mode);
47585413Sdinak goto out;
47595413Sdinak
47608005SMark.Powers@Sun.COM case AES_GCM_MECH_INFO_TYPE:
47618005SMark.Powers@Sun.COM rv = copyin_aes_gcm_mech(umech, kmech, &error, mode);
47628005SMark.Powers@Sun.COM goto out;
47638005SMark.Powers@Sun.COM
47649339SMark.Powers@Sun.COM case AES_GMAC_MECH_INFO_TYPE:
47659339SMark.Powers@Sun.COM rv = copyin_aes_gmac_mech(umech, kmech, &error, mode);
47669339SMark.Powers@Sun.COM goto out;
47679339SMark.Powers@Sun.COM
47684424Sizick case DH_PKCS_DERIVE_MECH_INFO_TYPE:
47694424Sizick expected_param_len = param_len;
47704424Sizick break;
47714424Sizick
47722938Smcpowers default:
47732938Smcpowers /* nothing to do - mechanism has no parameters */
4774904Smcpowers rv = CRYPTO_SUCCESS;
4775904Smcpowers goto out;
4776904Smcpowers }
4777904Smcpowers
4778904Smcpowers if (param_len != expected_param_len) {
4779904Smcpowers rv = CRYPTO_MECHANISM_PARAM_INVALID;
4780904Smcpowers goto out;
4781904Smcpowers }
4782904Smcpowers if (pp == NULL) {
4783904Smcpowers rv = CRYPTO_MECHANISM_PARAM_INVALID;
4784904Smcpowers goto out;
4785904Smcpowers }
4786904Smcpowers if ((param = kmem_alloc(param_len, KM_NOSLEEP)) == NULL) {
4787904Smcpowers rv = CRYPTO_HOST_MEMORY;
4788904Smcpowers goto out;
4789904Smcpowers }
4790904Smcpowers if (copyin((char *)pp, param, param_len) != 0) {
4791904Smcpowers kmem_free(param, param_len);
4792904Smcpowers error = EFAULT;
4793904Smcpowers rv = CRYPTO_FAILED;
4794904Smcpowers goto out;
4795904Smcpowers }
4796904Smcpowers kmech->cm_param = (char *)param;
4797904Smcpowers kmech->cm_param_len = param_len;
4798904Smcpowers rv = CRYPTO_SUCCESS;
4799904Smcpowers out:
4800904Smcpowers *out_error = error;
4801904Smcpowers return (rv);
4802904Smcpowers }
4803904Smcpowers
4804904Smcpowers /* ARGSUSED */
4805904Smcpowers static int
dprov_copyout_mechanism(crypto_provider_handle_t provider,crypto_mechanism_t * kmech,crypto_mechanism_t * umech,int * out_error,int mode)4806904Smcpowers dprov_copyout_mechanism(crypto_provider_handle_t provider,
4807904Smcpowers crypto_mechanism_t *kmech, crypto_mechanism_t *umech,
4808904Smcpowers int *out_error, int mode)
4809904Smcpowers {
4810904Smcpowers ASSERT(!servicing_interrupt());
4811904Smcpowers
4812904Smcpowers switch (kmech->cm_type) {
4813904Smcpowers case AES_CTR_MECH_INFO_TYPE:
4814904Smcpowers case SHA1_KEY_DERIVATION_MECH_INFO_TYPE: /* for testing only */
4815904Smcpowers return (copyout_aes_ctr_mech(kmech, umech, out_error, mode));
48165697Smcpowers case ECDH1_DERIVE_MECH_INFO_TYPE:
48175697Smcpowers return (CRYPTO_SUCCESS);
4818904Smcpowers default:
4819904Smcpowers return (CRYPTO_MECHANISM_INVALID);
4820904Smcpowers }
4821904Smcpowers }
4822904Smcpowers
4823904Smcpowers /*
4824904Smcpowers * Free mechanism parameter that was allocated by the provider.
4825904Smcpowers */
4826904Smcpowers /* ARGSUSED */
4827904Smcpowers static int
dprov_free_mechanism(crypto_provider_handle_t provider,crypto_mechanism_t * mech)4828904Smcpowers dprov_free_mechanism(crypto_provider_handle_t provider,
4829904Smcpowers crypto_mechanism_t *mech)
4830904Smcpowers {
4831904Smcpowers size_t len;
4832904Smcpowers
4833904Smcpowers if (mech->cm_param == NULL || mech->cm_param_len == 0)
4834904Smcpowers return (CRYPTO_SUCCESS);
4835904Smcpowers
48365697Smcpowers switch (mech->cm_type) {
48375697Smcpowers case AES_CTR_MECH_INFO_TYPE:
48385697Smcpowers case SHA1_KEY_DERIVATION_MECH_INFO_TYPE:
48395072Smcpowers len = sizeof (CK_AES_CTR_PARAMS);
48405697Smcpowers break;
48415697Smcpowers case ECDH1_DERIVE_MECH_INFO_TYPE: {
48425697Smcpowers CK_ECDH1_DERIVE_PARAMS *ecc_params;
48435697Smcpowers
48445697Smcpowers /* LINTED: pointer alignment */
48455697Smcpowers ecc_params = (CK_ECDH1_DERIVE_PARAMS *)mech->cm_param;
48465697Smcpowers kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) +
48475697Smcpowers roundup(ecc_params->ulSharedDataLen, sizeof (caddr_t)) +
48485697Smcpowers roundup(ecc_params->ulPublicDataLen, sizeof (caddr_t)));
48495697Smcpowers return (CRYPTO_SUCCESS);
48505697Smcpowers }
48517188Smcpowers case AES_CCM_MECH_INFO_TYPE: {
48527188Smcpowers CK_AES_CCM_PARAMS *params;
48537188Smcpowers size_t total_param_len;
48547188Smcpowers
48557188Smcpowers if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) {
48567188Smcpowers /* LINTED: pointer alignment */
48577188Smcpowers params = (CK_AES_CCM_PARAMS *)mech->cm_param;
48587188Smcpowers total_param_len = mech->cm_param_len +
48597188Smcpowers params->ulNonceSize + params->ulAuthDataSize;
48607188Smcpowers kmem_free(params, total_param_len);
48617188Smcpowers mech->cm_param = NULL;
48627188Smcpowers mech->cm_param_len = 0;
48637188Smcpowers }
48648005SMark.Powers@Sun.COM return (CRYPTO_SUCCESS);
48658005SMark.Powers@Sun.COM }
48669339SMark.Powers@Sun.COM case AES_GMAC_MECH_INFO_TYPE: {
48679339SMark.Powers@Sun.COM CK_AES_GMAC_PARAMS *params;
48689339SMark.Powers@Sun.COM size_t total_param_len;
48699339SMark.Powers@Sun.COM
48709339SMark.Powers@Sun.COM if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) {
48719339SMark.Powers@Sun.COM /* LINTED: pointer alignment */
48729339SMark.Powers@Sun.COM params = (CK_AES_GMAC_PARAMS *)mech->cm_param;
48739339SMark.Powers@Sun.COM total_param_len = mech->cm_param_len +
48749339SMark.Powers@Sun.COM AES_GMAC_IV_LEN + params->ulAADLen;
48759339SMark.Powers@Sun.COM kmem_free(params, total_param_len);
48769339SMark.Powers@Sun.COM mech->cm_param = NULL;
48779339SMark.Powers@Sun.COM mech->cm_param_len = 0;
48789339SMark.Powers@Sun.COM }
48799339SMark.Powers@Sun.COM return (CRYPTO_SUCCESS);
48809339SMark.Powers@Sun.COM }
48818005SMark.Powers@Sun.COM case AES_GCM_MECH_INFO_TYPE: {
48828005SMark.Powers@Sun.COM CK_AES_GCM_PARAMS *params;
48838005SMark.Powers@Sun.COM size_t total_param_len;
48848005SMark.Powers@Sun.COM
48858005SMark.Powers@Sun.COM if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) {
48868005SMark.Powers@Sun.COM /* LINTED: pointer alignment */
48878005SMark.Powers@Sun.COM params = (CK_AES_GCM_PARAMS *)mech->cm_param;
48888005SMark.Powers@Sun.COM total_param_len = mech->cm_param_len +
48898005SMark.Powers@Sun.COM params->ulIvLen + params->ulAADLen;
48908005SMark.Powers@Sun.COM kmem_free(params, total_param_len);
48918005SMark.Powers@Sun.COM mech->cm_param = NULL;
48928005SMark.Powers@Sun.COM mech->cm_param_len = 0;
48938005SMark.Powers@Sun.COM }
48948005SMark.Powers@Sun.COM return (CRYPTO_SUCCESS);
48957188Smcpowers }
48967188Smcpowers
48975697Smcpowers default:
4898904Smcpowers len = mech->cm_param_len;
4899904Smcpowers }
4900904Smcpowers kmem_free(mech->cm_param, len);
4901904Smcpowers return (CRYPTO_SUCCESS);
4902904Smcpowers }
49030Sstevel@tonic-gate
49040Sstevel@tonic-gate /*
49054219Smcpowers * No (Key)Store Key management entry point.
49064219Smcpowers */
49074219Smcpowers static int
dprov_nostore_key_generate(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_object_attribute_t * template,uint_t attribute_count,crypto_object_attribute_t * out_template,uint_t out_attribute_count,crypto_req_handle_t req)49084219Smcpowers dprov_nostore_key_generate(crypto_provider_handle_t provider,
49094219Smcpowers crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
49104219Smcpowers crypto_object_attribute_t *template, uint_t attribute_count,
49114219Smcpowers crypto_object_attribute_t *out_template, uint_t out_attribute_count,
49124219Smcpowers crypto_req_handle_t req)
49134219Smcpowers {
49144219Smcpowers int error = CRYPTO_FAILED;
49154219Smcpowers dprov_state_t *softc = (dprov_state_t *)provider;
49164219Smcpowers /* LINTED E_FUNC_SET_NOT_USED */
49174219Smcpowers int instance;
49184219Smcpowers
49194219Smcpowers instance = ddi_get_instance(softc->ds_dip);
49204219Smcpowers DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate: started\n",
49214219Smcpowers instance));
49224219Smcpowers
49234219Smcpowers /* submit request to the taskq */
49244219Smcpowers error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_GENERATE,
49254219Smcpowers softc, req, session_id, mechanism, template, attribute_count,
49264219Smcpowers NULL, NULL, 0, NULL, NULL, NULL, 0, out_template,
49274219Smcpowers out_attribute_count, NULL, 0);
49284219Smcpowers
49294219Smcpowers DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate: "
49304219Smcpowers "done err = 0x0%x\n", instance, error));
49314219Smcpowers
49324219Smcpowers return (error);
49334219Smcpowers }
49344219Smcpowers
49354424Sizick static int
dprov_nostore_key_generate_pair(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_object_attribute_t * public_key_template,uint_t public_key_attribute_count,crypto_object_attribute_t * private_key_template,uint_t private_key_attribute_count,crypto_object_attribute_t * out_public_key_template,uint_t out_public_key_attribute_count,crypto_object_attribute_t * out_private_key_template,uint_t out_private_key_attribute_count,crypto_req_handle_t req)49364424Sizick dprov_nostore_key_generate_pair(crypto_provider_handle_t provider,
49374424Sizick crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
49384424Sizick crypto_object_attribute_t *public_key_template,
49394424Sizick uint_t public_key_attribute_count,
49404424Sizick crypto_object_attribute_t *private_key_template,
49414424Sizick uint_t private_key_attribute_count,
49424424Sizick crypto_object_attribute_t *out_public_key_template,
49434424Sizick uint_t out_public_key_attribute_count,
49444424Sizick crypto_object_attribute_t *out_private_key_template,
49454424Sizick uint_t out_private_key_attribute_count,
49464424Sizick crypto_req_handle_t req)
49474424Sizick {
49484424Sizick int error = CRYPTO_FAILED;
49494424Sizick dprov_state_t *softc = (dprov_state_t *)provider;
49504424Sizick /* LINTED E_FUNC_SET_NOT_USED */
49514424Sizick int instance;
49524424Sizick
49534424Sizick instance = ddi_get_instance(softc->ds_dip);
49544424Sizick DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate_pair: started\n",
49554424Sizick instance));
49564424Sizick
49574424Sizick /* submit request to the taskq */
49584424Sizick error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR,
49594424Sizick softc, req, session_id, mechanism, public_key_template,
49604424Sizick public_key_attribute_count, NULL, private_key_template,
49614424Sizick private_key_attribute_count, NULL, NULL, NULL, 0,
49624424Sizick out_public_key_template, out_public_key_attribute_count,
49634424Sizick out_private_key_template, out_private_key_attribute_count);
49644424Sizick
49654424Sizick DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate_pair: "
49664424Sizick "done err = 0x0%x\n", instance, error));
49674424Sizick
49684424Sizick return (error);
49694424Sizick }
49704424Sizick
49714424Sizick static int
dprov_nostore_key_derive(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * base_key,crypto_object_attribute_t * template,uint_t attribute_count,crypto_object_attribute_t * out_template,uint_t out_attribute_count,crypto_req_handle_t req)49724424Sizick dprov_nostore_key_derive(crypto_provider_handle_t provider,
49734424Sizick crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
49744424Sizick crypto_key_t *base_key, crypto_object_attribute_t *template,
49754424Sizick uint_t attribute_count, crypto_object_attribute_t *out_template,
49764424Sizick uint_t out_attribute_count, crypto_req_handle_t req)
49774424Sizick {
49784424Sizick int error = CRYPTO_FAILED;
49794424Sizick dprov_state_t *softc = (dprov_state_t *)provider;
49804424Sizick /* LINTED E_FUNC_SET_NOT_USED */
49814424Sizick int instance;
49824424Sizick
49834424Sizick instance = ddi_get_instance(softc->ds_dip);
49844424Sizick DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_derive: started\n",
49854424Sizick instance));
49864424Sizick
49874424Sizick /* submit request to the taskq */
49884424Sizick error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_DERIVE, softc, req,
49894424Sizick session_id, mechanism, template, attribute_count, NULL, NULL,
49904424Sizick 0, NULL, base_key, NULL, 0, out_template, out_attribute_count,
49914424Sizick NULL, 0);
49924424Sizick
49934424Sizick DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_derive: "
49944424Sizick "done err = 0x0%x\n", instance, error));
49954424Sizick
49964424Sizick return (error);
49974424Sizick }
49984424Sizick
49994219Smcpowers /*
50000Sstevel@tonic-gate * Allocate a dprov taskq request and initialize the common fields.
50010Sstevel@tonic-gate * Return NULL if the memory allocation failed.
50020Sstevel@tonic-gate */
50030Sstevel@tonic-gate static dprov_req_t *
dprov_alloc_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t kcf_req,int kmflag)50040Sstevel@tonic-gate dprov_alloc_req(dprov_req_type_t req_type, dprov_state_t *softc,
50050Sstevel@tonic-gate crypto_req_handle_t kcf_req, int kmflag)
50060Sstevel@tonic-gate {
50070Sstevel@tonic-gate dprov_req_t *taskq_req;
50080Sstevel@tonic-gate
50090Sstevel@tonic-gate if ((taskq_req = kmem_alloc(sizeof (dprov_req_t), kmflag)) == NULL)
50100Sstevel@tonic-gate return (NULL);
50110Sstevel@tonic-gate
50120Sstevel@tonic-gate taskq_req->dr_type = req_type;
50130Sstevel@tonic-gate taskq_req->dr_softc = softc;
50140Sstevel@tonic-gate taskq_req->dr_kcf_req = kcf_req;
50150Sstevel@tonic-gate
50160Sstevel@tonic-gate return (taskq_req);
50170Sstevel@tonic-gate }
50180Sstevel@tonic-gate
50190Sstevel@tonic-gate /*
50200Sstevel@tonic-gate * Dispatch a dprov request on the taskq associated with a softc.
50210Sstevel@tonic-gate * Returns CRYPTO_HOST_MEMORY if the request cannot be queued,
50220Sstevel@tonic-gate * CRYPTO_QUEUED on success.
50230Sstevel@tonic-gate */
50240Sstevel@tonic-gate static int
dprov_taskq_dispatch(dprov_state_t * softc,dprov_req_t * taskq_req,task_func_t * func,int kmflag)50250Sstevel@tonic-gate dprov_taskq_dispatch(dprov_state_t *softc, dprov_req_t *taskq_req,
50260Sstevel@tonic-gate task_func_t *func, int kmflag)
50270Sstevel@tonic-gate {
50280Sstevel@tonic-gate if (taskq_dispatch(softc->ds_taskq, func, taskq_req,
50290Sstevel@tonic-gate kmflag == KM_NOSLEEP ? TQ_NOSLEEP : TQ_SLEEP) == (taskqid_t)0) {
50300Sstevel@tonic-gate kmem_free(taskq_req, sizeof (dprov_req_t));
50310Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY);
50320Sstevel@tonic-gate } else
50330Sstevel@tonic-gate return (CRYPTO_QUEUED);
50340Sstevel@tonic-gate }
50350Sstevel@tonic-gate
50360Sstevel@tonic-gate /*
50370Sstevel@tonic-gate * Helper function to submit digest operations to the taskq.
50380Sstevel@tonic-gate * Returns one of the CRYPTO_ errors.
50390Sstevel@tonic-gate */
50400Sstevel@tonic-gate static int
dprov_digest_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,crypto_mechanism_t * mechanism,crypto_data_t * data,crypto_key_t * key,crypto_data_t * digest,crypto_ctx_t * ctx,int kmflag)50410Sstevel@tonic-gate dprov_digest_submit_req(dprov_req_type_t req_type,
50420Sstevel@tonic-gate dprov_state_t *softc, crypto_req_handle_t req,
50430Sstevel@tonic-gate crypto_mechanism_t *mechanism, crypto_data_t *data, crypto_key_t *key,
50440Sstevel@tonic-gate crypto_data_t *digest, crypto_ctx_t *ctx, int kmflag)
50450Sstevel@tonic-gate {
50460Sstevel@tonic-gate dprov_req_t *taskq_req;
50470Sstevel@tonic-gate
50480Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
50490Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY);
50500Sstevel@tonic-gate
50510Sstevel@tonic-gate taskq_req->dr_digest_req.dr_mechanism = mechanism;
50520Sstevel@tonic-gate taskq_req->dr_digest_req.dr_ctx = ctx;
50530Sstevel@tonic-gate taskq_req->dr_digest_req.dr_data = data;
50540Sstevel@tonic-gate taskq_req->dr_digest_req.dr_key = key;
50550Sstevel@tonic-gate taskq_req->dr_digest_req.dr_digest = digest;
50560Sstevel@tonic-gate
50570Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req,
50580Sstevel@tonic-gate (task_func_t *)dprov_digest_task, kmflag));
50590Sstevel@tonic-gate }
50600Sstevel@tonic-gate
50610Sstevel@tonic-gate /*
50620Sstevel@tonic-gate * Helper function to submit mac operations to the taskq.
50630Sstevel@tonic-gate * Returns one of the CRYPTO_ errors.
50640Sstevel@tonic-gate */
50650Sstevel@tonic-gate static int
dprov_mac_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,crypto_mechanism_t * mechanism,crypto_data_t * data,crypto_key_t * key,crypto_data_t * mac,crypto_ctx_t * ctx,crypto_session_id_t sid,int kmflag)50660Sstevel@tonic-gate dprov_mac_submit_req(dprov_req_type_t req_type,
50670Sstevel@tonic-gate dprov_state_t *softc, crypto_req_handle_t req,
50680Sstevel@tonic-gate crypto_mechanism_t *mechanism, crypto_data_t *data, crypto_key_t *key,
50690Sstevel@tonic-gate crypto_data_t *mac, crypto_ctx_t *ctx, crypto_session_id_t sid, int kmflag)
50700Sstevel@tonic-gate {
50710Sstevel@tonic-gate dprov_req_t *taskq_req;
50720Sstevel@tonic-gate
50730Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
50740Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY);
50750Sstevel@tonic-gate
50760Sstevel@tonic-gate taskq_req->dr_mac_req.dr_mechanism = mechanism;
50770Sstevel@tonic-gate taskq_req->dr_mac_req.dr_ctx = ctx;
50780Sstevel@tonic-gate taskq_req->dr_mac_req.dr_data = data;
50790Sstevel@tonic-gate taskq_req->dr_mac_req.dr_key = key;
50800Sstevel@tonic-gate taskq_req->dr_mac_req.dr_mac = mac;
50810Sstevel@tonic-gate taskq_req->dr_mac_req.dr_session_id = sid;
50820Sstevel@tonic-gate
50830Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req,
50840Sstevel@tonic-gate (task_func_t *)dprov_mac_task, kmflag));
50850Sstevel@tonic-gate }
50860Sstevel@tonic-gate
50870Sstevel@tonic-gate /*
50880Sstevel@tonic-gate * Helper function to submit sign operations to the taskq.
50890Sstevel@tonic-gate * Returns one of the CRYPTO_ errors.
50900Sstevel@tonic-gate */
50910Sstevel@tonic-gate static int
dprov_sign_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * data,crypto_data_t * signature,crypto_ctx_t * ctx,crypto_session_id_t sid,int kmflag)50920Sstevel@tonic-gate dprov_sign_submit_req(dprov_req_type_t req_type,
50930Sstevel@tonic-gate dprov_state_t *softc, crypto_req_handle_t req,
50940Sstevel@tonic-gate crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data,
50950Sstevel@tonic-gate crypto_data_t *signature, crypto_ctx_t *ctx, crypto_session_id_t sid,
50960Sstevel@tonic-gate int kmflag)
50970Sstevel@tonic-gate {
50980Sstevel@tonic-gate dprov_req_t *taskq_req;
50990Sstevel@tonic-gate
51000Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
51010Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY);
51020Sstevel@tonic-gate
51030Sstevel@tonic-gate taskq_req->dr_sign_req.sr_mechanism = mechanism;
51040Sstevel@tonic-gate taskq_req->dr_sign_req.sr_ctx = ctx;
51050Sstevel@tonic-gate taskq_req->dr_sign_req.sr_key = key;
51060Sstevel@tonic-gate taskq_req->dr_sign_req.sr_data = data;
51070Sstevel@tonic-gate taskq_req->dr_sign_req.sr_signature = signature;
51080Sstevel@tonic-gate taskq_req->dr_sign_req.sr_session_id = sid;
51090Sstevel@tonic-gate
51100Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req,
51110Sstevel@tonic-gate (task_func_t *)dprov_sign_task, kmflag));
51120Sstevel@tonic-gate }
51130Sstevel@tonic-gate
51140Sstevel@tonic-gate /*
51150Sstevel@tonic-gate * Helper function to submit verify operations to the taskq.
51160Sstevel@tonic-gate * Returns one of the CRYPTO_ errors.
51170Sstevel@tonic-gate */
51180Sstevel@tonic-gate static int
dprov_verify_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * data,crypto_data_t * signature,crypto_ctx_t * ctx,crypto_session_id_t sid,int kmflag)51190Sstevel@tonic-gate dprov_verify_submit_req(dprov_req_type_t req_type,
51200Sstevel@tonic-gate dprov_state_t *softc, crypto_req_handle_t req,
51210Sstevel@tonic-gate crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data,
51220Sstevel@tonic-gate crypto_data_t *signature, crypto_ctx_t *ctx, crypto_session_id_t sid,
51230Sstevel@tonic-gate int kmflag)
51240Sstevel@tonic-gate {
51250Sstevel@tonic-gate dprov_req_t *taskq_req;
51260Sstevel@tonic-gate
51270Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
51280Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY);
51290Sstevel@tonic-gate
51300Sstevel@tonic-gate taskq_req->dr_verify_req.vr_mechanism = mechanism;
51310Sstevel@tonic-gate taskq_req->dr_verify_req.vr_ctx = ctx;
51320Sstevel@tonic-gate taskq_req->dr_verify_req.vr_key = key;
51330Sstevel@tonic-gate taskq_req->dr_verify_req.vr_data = data;
51340Sstevel@tonic-gate taskq_req->dr_verify_req.vr_signature = signature;
51350Sstevel@tonic-gate taskq_req->dr_verify_req.vr_session_id = sid;
51360Sstevel@tonic-gate
51370Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req,
51380Sstevel@tonic-gate (task_func_t *)dprov_verify_task, kmflag));
51390Sstevel@tonic-gate }
51400Sstevel@tonic-gate
51410Sstevel@tonic-gate /*
51420Sstevel@tonic-gate * Helper function to submit dual operations to the taskq.
51430Sstevel@tonic-gate * Returns one of the CRYPTO_ errors.
51440Sstevel@tonic-gate */
51450Sstevel@tonic-gate static int
dprov_dual_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,crypto_ctx_t * signverify_ctx,crypto_ctx_t * cipher_ctx,crypto_data_t * plaintext,crypto_data_t * ciphertext)51460Sstevel@tonic-gate dprov_dual_submit_req(dprov_req_type_t req_type, dprov_state_t *softc,
51470Sstevel@tonic-gate crypto_req_handle_t req, crypto_ctx_t *signverify_ctx,
51480Sstevel@tonic-gate crypto_ctx_t *cipher_ctx, crypto_data_t *plaintext,
51490Sstevel@tonic-gate crypto_data_t *ciphertext)
51500Sstevel@tonic-gate {
51510Sstevel@tonic-gate dprov_req_t *taskq_req;
51520Sstevel@tonic-gate
51530Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req,
51540Sstevel@tonic-gate KM_NOSLEEP)) == NULL)
51550Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY);
51560Sstevel@tonic-gate
51570Sstevel@tonic-gate taskq_req->dr_dual_req.dr_signverify_ctx = signverify_ctx;
51580Sstevel@tonic-gate taskq_req->dr_dual_req.dr_cipher_ctx = cipher_ctx;
51590Sstevel@tonic-gate taskq_req->dr_dual_req.dr_plaintext = plaintext;
51600Sstevel@tonic-gate taskq_req->dr_dual_req.dr_ciphertext = ciphertext;
51610Sstevel@tonic-gate
51620Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req,
51630Sstevel@tonic-gate (task_func_t *)dprov_dual_task, KM_NOSLEEP));
51640Sstevel@tonic-gate }
51650Sstevel@tonic-gate
51660Sstevel@tonic-gate /*
51670Sstevel@tonic-gate * Helper function to submit dual cipher/mac operations to the taskq.
51680Sstevel@tonic-gate * Returns one of the CRYPTO_ errors.
51690Sstevel@tonic-gate */
51700Sstevel@tonic-gate static int
dprov_cipher_mac_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,crypto_ctx_t * ctx,crypto_session_id_t sid,crypto_mechanism_t * cipher_mech,crypto_key_t * cipher_key,crypto_mechanism_t * mac_mech,crypto_key_t * mac_key,crypto_dual_data_t * dual_data,crypto_data_t * data,crypto_data_t * mac,int kmflag)51710Sstevel@tonic-gate dprov_cipher_mac_submit_req(dprov_req_type_t req_type,
51720Sstevel@tonic-gate dprov_state_t *softc, crypto_req_handle_t req, crypto_ctx_t *ctx,
51730Sstevel@tonic-gate crypto_session_id_t sid, crypto_mechanism_t *cipher_mech,
51740Sstevel@tonic-gate crypto_key_t *cipher_key, crypto_mechanism_t *mac_mech,
51750Sstevel@tonic-gate crypto_key_t *mac_key, crypto_dual_data_t *dual_data,
51760Sstevel@tonic-gate crypto_data_t *data, crypto_data_t *mac, int kmflag)
51770Sstevel@tonic-gate {
51780Sstevel@tonic-gate dprov_req_t *taskq_req;
51790Sstevel@tonic-gate
51800Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
51810Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY);
51820Sstevel@tonic-gate
51830Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_session_id = sid;
51840Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_ctx = ctx;
51850Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_cipher_mech = cipher_mech;
51860Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_cipher_key = cipher_key;
51870Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_mac_mech = mac_mech;
51880Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_mac_key = mac_key;
51890Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_dual_data = dual_data;
51900Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_data = data;
51910Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_mac = mac;
51920Sstevel@tonic-gate
51930Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req,
51940Sstevel@tonic-gate (task_func_t *)dprov_cipher_mac_task, kmflag));
51950Sstevel@tonic-gate }
51960Sstevel@tonic-gate
51970Sstevel@tonic-gate /*
51980Sstevel@tonic-gate * Helper function to submit cipher operations to the taskq.
51990Sstevel@tonic-gate * Returns one of the CRYPTO_ errors.
52000Sstevel@tonic-gate */
52010Sstevel@tonic-gate static int
dprov_cipher_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * plaintext,crypto_data_t * ciphertext,crypto_ctx_t * ctx,crypto_session_id_t sid,int kmflag)52020Sstevel@tonic-gate dprov_cipher_submit_req(dprov_req_type_t req_type,
52030Sstevel@tonic-gate dprov_state_t *softc, crypto_req_handle_t req,
52040Sstevel@tonic-gate crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *plaintext,
52050Sstevel@tonic-gate crypto_data_t *ciphertext, crypto_ctx_t *ctx, crypto_session_id_t sid,
52060Sstevel@tonic-gate int kmflag)
52070Sstevel@tonic-gate {
52080Sstevel@tonic-gate dprov_req_t *taskq_req;
52090Sstevel@tonic-gate
52100Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
52110Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY);
52120Sstevel@tonic-gate
52130Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_mechanism = mechanism;
52140Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_ctx = ctx;
52150Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_key = key;
52160Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_plaintext = plaintext;
52170Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_ciphertext = ciphertext;
52180Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_session_id = sid;
52190Sstevel@tonic-gate
52200Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req,
52210Sstevel@tonic-gate (task_func_t *)dprov_cipher_task, kmflag));
52220Sstevel@tonic-gate }
52230Sstevel@tonic-gate
52240Sstevel@tonic-gate /*
52250Sstevel@tonic-gate * Helper function to submit random number operations to the taskq.
52260Sstevel@tonic-gate * Returns one of the CRYPTO_ errors.
52270Sstevel@tonic-gate */
52280Sstevel@tonic-gate static int
dprov_random_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,uchar_t * buf,size_t len,crypto_session_id_t sid,uint_t entropy_est,uint32_t flags)52290Sstevel@tonic-gate dprov_random_submit_req(dprov_req_type_t req_type,
52300Sstevel@tonic-gate dprov_state_t *softc, crypto_req_handle_t req, uchar_t *buf, size_t len,
52311920Smcpowers crypto_session_id_t sid, uint_t entropy_est, uint32_t flags)
52320Sstevel@tonic-gate {
52330Sstevel@tonic-gate dprov_req_t *taskq_req;
52340Sstevel@tonic-gate
52350Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req,
52360Sstevel@tonic-gate KM_NOSLEEP)) == NULL)
52370Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY);
52380Sstevel@tonic-gate
52390Sstevel@tonic-gate taskq_req->dr_random_req.rr_buf = buf;
52400Sstevel@tonic-gate taskq_req->dr_random_req.rr_len = len;
52410Sstevel@tonic-gate taskq_req->dr_random_req.rr_session_id = sid;
52421920Smcpowers taskq_req->dr_random_req.rr_entropy_est = entropy_est;
52431920Smcpowers taskq_req->dr_random_req.rr_flags = flags;
52440Sstevel@tonic-gate
52450Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req,
52460Sstevel@tonic-gate (task_func_t *)dprov_random_task, KM_NOSLEEP));
52470Sstevel@tonic-gate }
52480Sstevel@tonic-gate
52490Sstevel@tonic-gate
52500Sstevel@tonic-gate /*
52510Sstevel@tonic-gate * Helper function to submit session management operations to the taskq.
52520Sstevel@tonic-gate * Returns one of the CRYPTO_ errors.
52530Sstevel@tonic-gate */
52540Sstevel@tonic-gate static int
dprov_session_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,crypto_session_id_t * session_id_ptr,crypto_session_id_t session_id,crypto_user_type_t user_type,char * pin,size_t pin_len)52550Sstevel@tonic-gate dprov_session_submit_req(dprov_req_type_t req_type,
52560Sstevel@tonic-gate dprov_state_t *softc, crypto_req_handle_t req,
52570Sstevel@tonic-gate crypto_session_id_t *session_id_ptr, crypto_session_id_t session_id,
52580Sstevel@tonic-gate crypto_user_type_t user_type, char *pin, size_t pin_len)
52590Sstevel@tonic-gate {
52600Sstevel@tonic-gate dprov_req_t *taskq_req;
52610Sstevel@tonic-gate
52620Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req,
52630Sstevel@tonic-gate KM_NOSLEEP)) == NULL)
52640Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY);
52650Sstevel@tonic-gate
52660Sstevel@tonic-gate taskq_req->dr_session_req.sr_session_id_ptr = session_id_ptr;
52670Sstevel@tonic-gate taskq_req->dr_session_req.sr_session_id = session_id;
52680Sstevel@tonic-gate taskq_req->dr_session_req.sr_user_type = user_type;
52690Sstevel@tonic-gate taskq_req->dr_session_req.sr_pin = pin;
52700Sstevel@tonic-gate taskq_req->dr_session_req.sr_pin_len = pin_len;
52710Sstevel@tonic-gate
52720Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req,
52730Sstevel@tonic-gate (task_func_t *)dprov_session_task, KM_NOSLEEP));
52740Sstevel@tonic-gate }
52750Sstevel@tonic-gate
52760Sstevel@tonic-gate /*
52770Sstevel@tonic-gate * Helper function to submit object management operations to the taskq.
52780Sstevel@tonic-gate * Returns one of the CRYPTO_ errors.
52790Sstevel@tonic-gate */
52800Sstevel@tonic-gate static int
dprov_object_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,crypto_session_id_t session_id,crypto_object_id_t object_id,crypto_object_attribute_t * template,uint_t attribute_count,crypto_object_id_t * object_id_ptr,size_t * object_size,void ** find_pp,void * find_p,uint_t max_object_count,uint_t * object_count_ptr,int kmflag)52810Sstevel@tonic-gate dprov_object_submit_req(dprov_req_type_t req_type,
52820Sstevel@tonic-gate dprov_state_t *softc, crypto_req_handle_t req,
52830Sstevel@tonic-gate crypto_session_id_t session_id, crypto_object_id_t object_id,
52840Sstevel@tonic-gate crypto_object_attribute_t *template, uint_t attribute_count,
52850Sstevel@tonic-gate crypto_object_id_t *object_id_ptr, size_t *object_size,
52860Sstevel@tonic-gate void **find_pp, void *find_p, uint_t max_object_count,
52870Sstevel@tonic-gate uint_t *object_count_ptr, int kmflag)
52880Sstevel@tonic-gate {
52890Sstevel@tonic-gate dprov_req_t *taskq_req;
52900Sstevel@tonic-gate
52910Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req,
52920Sstevel@tonic-gate kmflag)) == NULL)
52930Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY);
52940Sstevel@tonic-gate
52950Sstevel@tonic-gate taskq_req->dr_object_req.or_session_id = session_id;
52960Sstevel@tonic-gate taskq_req->dr_object_req.or_object_id = object_id;
52970Sstevel@tonic-gate taskq_req->dr_object_req.or_template = template;
52980Sstevel@tonic-gate taskq_req->dr_object_req.or_attribute_count = attribute_count;
52990Sstevel@tonic-gate taskq_req->dr_object_req.or_object_id_ptr = object_id_ptr;
53000Sstevel@tonic-gate taskq_req->dr_object_req.or_object_size = object_size;
53010Sstevel@tonic-gate taskq_req->dr_object_req.or_find_pp = find_pp;
53020Sstevel@tonic-gate taskq_req->dr_object_req.or_find_p = find_p;
53030Sstevel@tonic-gate taskq_req->dr_object_req.or_max_object_count = max_object_count;
53040Sstevel@tonic-gate taskq_req->dr_object_req.or_object_count_ptr = object_count_ptr;
53050Sstevel@tonic-gate
53060Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req,
53070Sstevel@tonic-gate (task_func_t *)dprov_object_task, KM_NOSLEEP));
53080Sstevel@tonic-gate }
53090Sstevel@tonic-gate
53100Sstevel@tonic-gate /*
53110Sstevel@tonic-gate * Helper function to submit key management operations to the taskq.
53120Sstevel@tonic-gate * Returns one of the CRYPTO_ errors.
53130Sstevel@tonic-gate */
53140Sstevel@tonic-gate static int
dprov_key_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_object_attribute_t * template,uint_t attribute_count,crypto_object_id_t * object_id_ptr,crypto_object_attribute_t * private_key_template,uint_t private_key_attribute_count,crypto_object_id_t * private_key_object_id_ptr,crypto_key_t * key,uchar_t * wrapped_key,size_t * wrapped_key_len_ptr,crypto_object_attribute_t * out_template1,uint_t out_attribute_count1,crypto_object_attribute_t * out_template2,uint_t out_attribute_count2)53150Sstevel@tonic-gate dprov_key_submit_req(dprov_req_type_t req_type,
53160Sstevel@tonic-gate dprov_state_t *softc, crypto_req_handle_t req,
53170Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
53180Sstevel@tonic-gate crypto_object_attribute_t *template, uint_t attribute_count,
53190Sstevel@tonic-gate crypto_object_id_t *object_id_ptr,
53200Sstevel@tonic-gate crypto_object_attribute_t *private_key_template,
53210Sstevel@tonic-gate uint_t private_key_attribute_count,
53220Sstevel@tonic-gate crypto_object_id_t *private_key_object_id_ptr, crypto_key_t *key,
53234219Smcpowers uchar_t *wrapped_key, size_t *wrapped_key_len_ptr,
53244219Smcpowers crypto_object_attribute_t *out_template1, uint_t out_attribute_count1,
53254219Smcpowers crypto_object_attribute_t *out_template2, uint_t out_attribute_count2)
53260Sstevel@tonic-gate {
53270Sstevel@tonic-gate dprov_req_t *taskq_req;
53280Sstevel@tonic-gate
53290Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req,
53300Sstevel@tonic-gate KM_NOSLEEP)) == NULL)
53310Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY);
53320Sstevel@tonic-gate
53330Sstevel@tonic-gate taskq_req->dr_key_req.kr_session_id = session_id;
53340Sstevel@tonic-gate taskq_req->dr_key_req.kr_mechanism = mechanism;
53350Sstevel@tonic-gate taskq_req->dr_key_req.kr_template = template;
53360Sstevel@tonic-gate taskq_req->dr_key_req.kr_attribute_count = attribute_count;
53370Sstevel@tonic-gate taskq_req->dr_key_req.kr_object_id_ptr = object_id_ptr;
53380Sstevel@tonic-gate taskq_req->dr_key_req.kr_private_key_template = private_key_template;
53390Sstevel@tonic-gate taskq_req->dr_key_req.kr_private_key_attribute_count =
53400Sstevel@tonic-gate private_key_attribute_count;
53410Sstevel@tonic-gate taskq_req->dr_key_req.kr_private_key_object_id_ptr =
53420Sstevel@tonic-gate private_key_object_id_ptr;
53430Sstevel@tonic-gate taskq_req->dr_key_req.kr_key = key;
53440Sstevel@tonic-gate taskq_req->dr_key_req.kr_wrapped_key = wrapped_key;
53450Sstevel@tonic-gate taskq_req->dr_key_req.kr_wrapped_key_len_ptr = wrapped_key_len_ptr;
53464219Smcpowers taskq_req->dr_key_req.kr_out_template1 = out_template1;
53474219Smcpowers taskq_req->dr_key_req.kr_out_attribute_count1 = out_attribute_count1;
53484219Smcpowers taskq_req->dr_key_req.kr_out_template2 = out_template2;
53494219Smcpowers taskq_req->dr_key_req.kr_out_attribute_count2 = out_attribute_count2;
53500Sstevel@tonic-gate
53510Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req,
53520Sstevel@tonic-gate (task_func_t *)dprov_key_task, KM_NOSLEEP));
53530Sstevel@tonic-gate }
53540Sstevel@tonic-gate
53550Sstevel@tonic-gate /*
53560Sstevel@tonic-gate * Helper function to submit provider management operations to the taskq.
53570Sstevel@tonic-gate * Returns one of the CRYPTO_ errors.
53580Sstevel@tonic-gate */
53590Sstevel@tonic-gate static int
dprov_mgmt_submit_req(dprov_req_type_t req_type,dprov_state_t * softc,crypto_req_handle_t req,crypto_session_id_t session_id,char * pin,size_t pin_len,char * old_pin,size_t old_pin_len,char * label,crypto_provider_ext_info_t * ext_info)53600Sstevel@tonic-gate dprov_mgmt_submit_req(dprov_req_type_t req_type,
53610Sstevel@tonic-gate dprov_state_t *softc, crypto_req_handle_t req,
53620Sstevel@tonic-gate crypto_session_id_t session_id, char *pin, size_t pin_len,
53630Sstevel@tonic-gate char *old_pin, size_t old_pin_len, char *label,
53640Sstevel@tonic-gate crypto_provider_ext_info_t *ext_info)
53650Sstevel@tonic-gate {
53660Sstevel@tonic-gate dprov_req_t *taskq_req;
53670Sstevel@tonic-gate
53680Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req,
53690Sstevel@tonic-gate KM_NOSLEEP)) == NULL)
53700Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY);
53710Sstevel@tonic-gate
53720Sstevel@tonic-gate taskq_req->dr_mgmt_req.mr_session_id = session_id;
53730Sstevel@tonic-gate taskq_req->dr_mgmt_req.mr_pin = pin;
53740Sstevel@tonic-gate taskq_req->dr_mgmt_req.mr_pin_len = pin_len;
53750Sstevel@tonic-gate taskq_req->dr_mgmt_req.mr_old_pin = old_pin;
53760Sstevel@tonic-gate taskq_req->dr_mgmt_req.mr_old_pin_len = old_pin_len;
53770Sstevel@tonic-gate taskq_req->dr_mgmt_req.mr_label = label;
53780Sstevel@tonic-gate taskq_req->dr_mgmt_req.mr_ext_info = ext_info;
53790Sstevel@tonic-gate
53800Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req,
53810Sstevel@tonic-gate (task_func_t *)dprov_mgmt_task, KM_NOSLEEP));
53820Sstevel@tonic-gate }
53830Sstevel@tonic-gate
53840Sstevel@tonic-gate /*
53850Sstevel@tonic-gate * Helper function for taskq dispatcher routines. Notify the framework
53860Sstevel@tonic-gate * that the operation corresponding to the specified request is done,
53870Sstevel@tonic-gate * and pass it the error code. Finally, free the taskq_req.
53880Sstevel@tonic-gate */
53890Sstevel@tonic-gate static void
dprov_op_done(dprov_req_t * taskq_req,int error)53900Sstevel@tonic-gate dprov_op_done(dprov_req_t *taskq_req, int error)
53910Sstevel@tonic-gate {
53920Sstevel@tonic-gate /* notify framework that request is completed */
53930Sstevel@tonic-gate crypto_op_notification(taskq_req->dr_kcf_req, error);
53940Sstevel@tonic-gate
53950Sstevel@tonic-gate /* free taskq request structure */
53960Sstevel@tonic-gate kmem_free(taskq_req, sizeof (dprov_req_t));
53970Sstevel@tonic-gate }
53980Sstevel@tonic-gate
53990Sstevel@tonic-gate /*
54000Sstevel@tonic-gate * taskq dispatcher function for digest operations.
54010Sstevel@tonic-gate */
54020Sstevel@tonic-gate static void
dprov_digest_task(dprov_req_t * taskq_req)54030Sstevel@tonic-gate dprov_digest_task(dprov_req_t *taskq_req)
54040Sstevel@tonic-gate {
54050Sstevel@tonic-gate kcf_provider_desc_t *pd;
54060Sstevel@tonic-gate dprov_state_t *softc;
54070Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
54080Sstevel@tonic-gate int instance;
54090Sstevel@tonic-gate int error = CRYPTO_NOT_SUPPORTED;
54100Sstevel@tonic-gate crypto_ctx_t *ctx = taskq_req->dr_digest_req.dr_ctx;
54110Sstevel@tonic-gate crypto_mechanism_t mech;
54120Sstevel@tonic-gate
54130Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
54140Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_task: started\n", instance));
54150Sstevel@tonic-gate
54160Sstevel@tonic-gate switch (taskq_req->dr_type) {
54170Sstevel@tonic-gate
54180Sstevel@tonic-gate case DPROV_REQ_DIGEST_INIT:
54190Sstevel@tonic-gate /* allocate a dprov-private context */
54200Sstevel@tonic-gate if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
54210Sstevel@tonic-gate CRYPTO_SUCCESS)
54220Sstevel@tonic-gate break;
54230Sstevel@tonic-gate
54240Sstevel@tonic-gate /* structure assignment */
54250Sstevel@tonic-gate mech = *taskq_req->dr_digest_req.dr_mechanism;
54260Sstevel@tonic-gate
54270Sstevel@tonic-gate /* get the software provider for this mechanism */
54280Sstevel@tonic-gate if ((error = dprov_get_sw_prov(
54290Sstevel@tonic-gate taskq_req->dr_digest_req.dr_mechanism, &pd,
54300Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS)
54310Sstevel@tonic-gate break;
54320Sstevel@tonic-gate
54330Sstevel@tonic-gate /* Use a session id of zero since we use a software provider */
54340Sstevel@tonic-gate error = crypto_digest_init_prov(pd, 0, &mech,
54350Sstevel@tonic-gate &DPROV_CTX_SINGLE(ctx), NULL);
54360Sstevel@tonic-gate
54370Sstevel@tonic-gate /* release provider reference */
54380Sstevel@tonic-gate KCF_PROV_REFRELE(pd);
54390Sstevel@tonic-gate break;
54400Sstevel@tonic-gate
54410Sstevel@tonic-gate case DPROV_REQ_DIGEST:
54420Sstevel@tonic-gate error = crypto_digest_single(DPROV_CTX_SINGLE(ctx),
54430Sstevel@tonic-gate taskq_req->dr_digest_req.dr_data,
54440Sstevel@tonic-gate taskq_req->dr_digest_req.dr_digest, NULL);
54450Sstevel@tonic-gate
54460Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) {
54470Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL;
54480Sstevel@tonic-gate (void) dprov_free_context(ctx);
54490Sstevel@tonic-gate }
54500Sstevel@tonic-gate break;
54510Sstevel@tonic-gate
54520Sstevel@tonic-gate case DPROV_REQ_DIGEST_UPDATE:
54530Sstevel@tonic-gate error = crypto_digest_update(DPROV_CTX_SINGLE(ctx),
54540Sstevel@tonic-gate taskq_req->dr_digest_req.dr_data, NULL);
54550Sstevel@tonic-gate break;
54560Sstevel@tonic-gate
54570Sstevel@tonic-gate case DPROV_REQ_DIGEST_KEY: {
54580Sstevel@tonic-gate crypto_data_t data;
54590Sstevel@tonic-gate crypto_key_t key;
54600Sstevel@tonic-gate size_t len;
54610Sstevel@tonic-gate
54620Sstevel@tonic-gate mutex_enter(&softc->ds_lock);
54630Sstevel@tonic-gate error = dprov_key_value_secret(softc, ctx->cc_session,
54640Sstevel@tonic-gate taskq_req->dr_type, taskq_req->dr_digest_req.dr_key, &key);
54650Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
54660Sstevel@tonic-gate if (error != CRYPTO_SUCCESS)
54670Sstevel@tonic-gate break;
54680Sstevel@tonic-gate
54690Sstevel@tonic-gate /* key lengths are specified in bits */
54700Sstevel@tonic-gate len = CRYPTO_BITS2BYTES(key.ck_length);
54710Sstevel@tonic-gate data.cd_format = CRYPTO_DATA_RAW;
54720Sstevel@tonic-gate data.cd_offset = 0;
54730Sstevel@tonic-gate data.cd_length = len;
54740Sstevel@tonic-gate data.cd_raw.iov_base = key.ck_data;
54750Sstevel@tonic-gate data.cd_raw.iov_len = len;
54760Sstevel@tonic-gate error = crypto_digest_update(DPROV_CTX_SINGLE(ctx),
54770Sstevel@tonic-gate &data, NULL);
54780Sstevel@tonic-gate break;
54790Sstevel@tonic-gate }
54800Sstevel@tonic-gate
54810Sstevel@tonic-gate case DPROV_REQ_DIGEST_FINAL:
54820Sstevel@tonic-gate error = crypto_digest_final(DPROV_CTX_SINGLE(ctx),
54830Sstevel@tonic-gate taskq_req->dr_digest_req.dr_digest, NULL);
54840Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) {
54850Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL;
54860Sstevel@tonic-gate (void) dprov_free_context(ctx);
54870Sstevel@tonic-gate }
54880Sstevel@tonic-gate break;
54890Sstevel@tonic-gate
54900Sstevel@tonic-gate case DPROV_REQ_DIGEST_ATOMIC:
54910Sstevel@tonic-gate /* structure assignment */
54920Sstevel@tonic-gate mech = *taskq_req->dr_digest_req.dr_mechanism;
54930Sstevel@tonic-gate
54940Sstevel@tonic-gate /* get the software provider for this mechanism */
54950Sstevel@tonic-gate if ((error = dprov_get_sw_prov(
54960Sstevel@tonic-gate taskq_req->dr_digest_req.dr_mechanism, &pd,
54970Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS)
54980Sstevel@tonic-gate break;
54990Sstevel@tonic-gate
55000Sstevel@tonic-gate /* use a session id of zero since we use a software provider */
5501904Smcpowers error = crypto_digest_prov(pd, 0, &mech,
55020Sstevel@tonic-gate taskq_req->dr_digest_req.dr_data,
5503904Smcpowers taskq_req->dr_digest_req.dr_digest, NULL);
55040Sstevel@tonic-gate
55050Sstevel@tonic-gate /* release provider reference */
55060Sstevel@tonic-gate KCF_PROV_REFRELE(pd);
55070Sstevel@tonic-gate
55080Sstevel@tonic-gate break;
55090Sstevel@tonic-gate }
55100Sstevel@tonic-gate
55110Sstevel@tonic-gate dprov_op_done(taskq_req, error);
55120Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_task: end\n", instance));
55130Sstevel@tonic-gate }
55140Sstevel@tonic-gate
55150Sstevel@tonic-gate /*
55160Sstevel@tonic-gate * taskq dispatcher function for mac operations.
55170Sstevel@tonic-gate */
55180Sstevel@tonic-gate static void
dprov_mac_task(dprov_req_t * taskq_req)55190Sstevel@tonic-gate dprov_mac_task(dprov_req_t *taskq_req)
55200Sstevel@tonic-gate {
55210Sstevel@tonic-gate kcf_provider_desc_t *pd;
55220Sstevel@tonic-gate dprov_state_t *softc;
55230Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
55240Sstevel@tonic-gate int instance;
55250Sstevel@tonic-gate int error = CRYPTO_NOT_SUPPORTED;
55260Sstevel@tonic-gate crypto_ctx_t *ctx = taskq_req->dr_mac_req.dr_ctx;
55270Sstevel@tonic-gate crypto_key_t key;
55280Sstevel@tonic-gate crypto_mechanism_t mech;
55290Sstevel@tonic-gate
55300Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
55310Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: started\n", instance));
55320Sstevel@tonic-gate
55330Sstevel@tonic-gate switch (taskq_req->dr_type) {
55340Sstevel@tonic-gate
55350Sstevel@tonic-gate case DPROV_REQ_MAC_INIT:
55360Sstevel@tonic-gate /* allocate a dprov-private context */
55370Sstevel@tonic-gate if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
55380Sstevel@tonic-gate CRYPTO_SUCCESS)
55390Sstevel@tonic-gate break;
55400Sstevel@tonic-gate
55410Sstevel@tonic-gate /* get key value */
55420Sstevel@tonic-gate mutex_enter(&softc->ds_lock);
55430Sstevel@tonic-gate error = dprov_key_value_secret(softc, ctx->cc_session,
55440Sstevel@tonic-gate taskq_req->dr_type, taskq_req->dr_mac_req.dr_key, &key);
55450Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
55460Sstevel@tonic-gate if (error != CRYPTO_SUCCESS)
55470Sstevel@tonic-gate break;
55480Sstevel@tonic-gate
55490Sstevel@tonic-gate /* structure assignment */
55500Sstevel@tonic-gate mech = *taskq_req->dr_mac_req.dr_mechanism;
55510Sstevel@tonic-gate
55520Sstevel@tonic-gate /* get the software provider for this mechanism */
55530Sstevel@tonic-gate if ((error = dprov_get_sw_prov(
55540Sstevel@tonic-gate taskq_req->dr_mac_req.dr_mechanism, &pd,
55550Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS)
55560Sstevel@tonic-gate break;
55570Sstevel@tonic-gate
55580Sstevel@tonic-gate /* Use a session id of zero since we use a software provider */
55590Sstevel@tonic-gate error = crypto_mac_init_prov(pd, 0, &mech, &key, NULL,
55600Sstevel@tonic-gate &DPROV_CTX_SINGLE(ctx), NULL);
55610Sstevel@tonic-gate
55620Sstevel@tonic-gate /* release provider reference */
55630Sstevel@tonic-gate KCF_PROV_REFRELE(pd);
55640Sstevel@tonic-gate break;
55650Sstevel@tonic-gate
55660Sstevel@tonic-gate case DPROV_REQ_MAC:
55670Sstevel@tonic-gate error = crypto_mac_single(DPROV_CTX_SINGLE(ctx),
55680Sstevel@tonic-gate taskq_req->dr_mac_req.dr_data,
55690Sstevel@tonic-gate taskq_req->dr_mac_req.dr_mac, NULL);
55700Sstevel@tonic-gate
55710Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) {
55720Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL;
55730Sstevel@tonic-gate (void) dprov_free_context(ctx);
55740Sstevel@tonic-gate }
55750Sstevel@tonic-gate break;
55760Sstevel@tonic-gate
55770Sstevel@tonic-gate case DPROV_REQ_MAC_UPDATE:
55780Sstevel@tonic-gate error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
55790Sstevel@tonic-gate taskq_req->dr_mac_req.dr_data, NULL);
55800Sstevel@tonic-gate break;
55810Sstevel@tonic-gate
55820Sstevel@tonic-gate case DPROV_REQ_MAC_FINAL:
55830Sstevel@tonic-gate error = crypto_mac_final(DPROV_CTX_SINGLE(ctx),
55840Sstevel@tonic-gate taskq_req->dr_mac_req.dr_mac, NULL);
55850Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) {
55860Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL;
55870Sstevel@tonic-gate (void) dprov_free_context(ctx);
55880Sstevel@tonic-gate }
55890Sstevel@tonic-gate break;
55900Sstevel@tonic-gate
55910Sstevel@tonic-gate case DPROV_REQ_MAC_ATOMIC:
55920Sstevel@tonic-gate case DPROV_REQ_MAC_VERIFY_ATOMIC:
55930Sstevel@tonic-gate /* get key value */
55940Sstevel@tonic-gate mutex_enter(&softc->ds_lock);
55950Sstevel@tonic-gate error = dprov_key_value_secret(softc,
55960Sstevel@tonic-gate taskq_req->dr_mac_req.dr_session_id,
55970Sstevel@tonic-gate taskq_req->dr_type, taskq_req->dr_mac_req.dr_key, &key);
55980Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
55990Sstevel@tonic-gate if (error != CRYPTO_SUCCESS)
56000Sstevel@tonic-gate break;
56010Sstevel@tonic-gate
56020Sstevel@tonic-gate /* structure assignment */
56030Sstevel@tonic-gate mech = *taskq_req->dr_mac_req.dr_mechanism;
56040Sstevel@tonic-gate
56050Sstevel@tonic-gate /* get the software provider for this mechanism */
56060Sstevel@tonic-gate if ((error = dprov_get_sw_prov(
56070Sstevel@tonic-gate taskq_req->dr_mac_req.dr_mechanism, &pd,
56080Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS)
56090Sstevel@tonic-gate break;
56100Sstevel@tonic-gate
56110Sstevel@tonic-gate /* use a session id of zero since we use a software provider */
56120Sstevel@tonic-gate if (taskq_req->dr_type == DPROV_REQ_MAC_ATOMIC)
5613904Smcpowers error = crypto_mac_prov(pd, 0, &mech,
56140Sstevel@tonic-gate taskq_req->dr_mac_req.dr_data,
5615904Smcpowers &key, NULL, taskq_req->dr_mac_req.dr_mac, NULL);
56160Sstevel@tonic-gate else
5617904Smcpowers error = crypto_mac_verify_prov(pd, 0, &mech,
56180Sstevel@tonic-gate taskq_req->dr_mac_req.dr_data,
5619904Smcpowers &key, NULL, taskq_req->dr_mac_req.dr_mac, NULL);
56200Sstevel@tonic-gate
56210Sstevel@tonic-gate /* release provider reference */
56220Sstevel@tonic-gate KCF_PROV_REFRELE(pd);
56230Sstevel@tonic-gate
56240Sstevel@tonic-gate break;
56250Sstevel@tonic-gate }
56260Sstevel@tonic-gate
56270Sstevel@tonic-gate dprov_op_done(taskq_req, error);
56280Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: end\n", instance));
56290Sstevel@tonic-gate }
56300Sstevel@tonic-gate
56310Sstevel@tonic-gate /*
56320Sstevel@tonic-gate * taskq dispatcher function for sign operations.
56330Sstevel@tonic-gate */
56340Sstevel@tonic-gate static void
dprov_sign_task(dprov_req_t * taskq_req)56350Sstevel@tonic-gate dprov_sign_task(dprov_req_t *taskq_req)
56360Sstevel@tonic-gate {
56370Sstevel@tonic-gate kcf_provider_desc_t *pd;
56380Sstevel@tonic-gate dprov_state_t *softc;
56390Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
56400Sstevel@tonic-gate int instance;
56410Sstevel@tonic-gate int error = CRYPTO_NOT_SUPPORTED;
56424072Skrishna crypto_ctx_t *ctx = taskq_req->dr_sign_req.sr_ctx;
56430Sstevel@tonic-gate crypto_key_t key, *keyp;
56440Sstevel@tonic-gate crypto_mechanism_t mech;
56450Sstevel@tonic-gate
56460Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
56470Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_task: started\n", instance));
56480Sstevel@tonic-gate
56490Sstevel@tonic-gate switch (taskq_req->dr_type) {
56500Sstevel@tonic-gate
56510Sstevel@tonic-gate case DPROV_REQ_SIGN_INIT:
56520Sstevel@tonic-gate case DPROV_REQ_SIGN_RECOVER_INIT:
56530Sstevel@tonic-gate /* allocate a dprov-private context */
56540Sstevel@tonic-gate if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
56550Sstevel@tonic-gate CRYPTO_SUCCESS)
56560Sstevel@tonic-gate break;
56570Sstevel@tonic-gate
56580Sstevel@tonic-gate /* structure assignment */
56590Sstevel@tonic-gate mech = *taskq_req->dr_sign_req.sr_mechanism;
56604072Skrishna if (dprov_valid_mac_mech(mech.cm_type)) {
56614072Skrishna DPROV_CTX_P(ctx)->dc_svrfy_to_mac = B_TRUE;
56624072Skrishna }
56630Sstevel@tonic-gate
56640Sstevel@tonic-gate mutex_enter(&softc->ds_lock);
56650Sstevel@tonic-gate if (is_publickey_mech(mech.cm_type)) {
56660Sstevel@tonic-gate if ((error = dprov_key_attr_asymmetric(softc,
56670Sstevel@tonic-gate ctx->cc_session, taskq_req->dr_type,
56680Sstevel@tonic-gate taskq_req->dr_sign_req.sr_key, &key))
56690Sstevel@tonic-gate != CRYPTO_SUCCESS) {
56700Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
56710Sstevel@tonic-gate break;
56720Sstevel@tonic-gate }
56730Sstevel@tonic-gate keyp = &key;
56740Sstevel@tonic-gate } else {
56750Sstevel@tonic-gate if ((error = dprov_key_value_secret(softc,
56760Sstevel@tonic-gate ctx->cc_session, taskq_req->dr_type,
56770Sstevel@tonic-gate taskq_req->dr_sign_req.sr_key, &key))
56780Sstevel@tonic-gate != CRYPTO_SUCCESS) {
56790Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
56800Sstevel@tonic-gate break;
56810Sstevel@tonic-gate }
56820Sstevel@tonic-gate keyp = &key;
56830Sstevel@tonic-gate }
56840Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
56850Sstevel@tonic-gate
56860Sstevel@tonic-gate /* get the software provider for this mechanism */
56870Sstevel@tonic-gate if ((error = dprov_get_sw_prov(
56880Sstevel@tonic-gate taskq_req->dr_sign_req.sr_mechanism, &pd,
56890Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS)
56900Sstevel@tonic-gate break;
56910Sstevel@tonic-gate
56924072Skrishna if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
56934072Skrishna error = crypto_mac_init_prov(pd, 0, &mech, keyp, NULL,
56944072Skrishna &DPROV_CTX_SINGLE(ctx), NULL);
56954072Skrishna
56964072Skrishna /* release provider reference */
56974072Skrishna KCF_PROV_REFRELE(pd);
56984072Skrishna break;
56994072Skrishna }
57004072Skrishna
57010Sstevel@tonic-gate /* Use a session id of zero since we use a software provider */
57020Sstevel@tonic-gate if (taskq_req->dr_type == DPROV_REQ_SIGN_INIT)
57030Sstevel@tonic-gate error = crypto_sign_init_prov(pd, 0, &mech, keyp,
57040Sstevel@tonic-gate NULL, &DPROV_CTX_SINGLE(ctx), NULL);
57050Sstevel@tonic-gate else
57060Sstevel@tonic-gate error = crypto_sign_recover_init_prov(pd, 0, &mech,
57070Sstevel@tonic-gate keyp, NULL, &DPROV_CTX_SINGLE(ctx), NULL);
57080Sstevel@tonic-gate
57090Sstevel@tonic-gate /* release provider reference */
57100Sstevel@tonic-gate KCF_PROV_REFRELE(pd);
57110Sstevel@tonic-gate
57120Sstevel@tonic-gate break;
57130Sstevel@tonic-gate
57140Sstevel@tonic-gate case DPROV_REQ_SIGN:
57154072Skrishna if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
57164072Skrishna /* Emulate using update and final */
57174072Skrishna error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
57184072Skrishna taskq_req->dr_mac_req.dr_data, NULL);
57194072Skrishna if (error == CRYPTO_SUCCESS) {
57204072Skrishna error = crypto_mac_final(DPROV_CTX_SINGLE(ctx),
57214072Skrishna taskq_req->dr_mac_req.dr_mac, NULL);
57224072Skrishna }
57234072Skrishna } else {
57244072Skrishna error = crypto_sign_single(DPROV_CTX_SINGLE(ctx),
57254072Skrishna taskq_req->dr_sign_req.sr_data,
57264072Skrishna taskq_req->dr_sign_req.sr_signature, NULL);
57274072Skrishna }
57280Sstevel@tonic-gate
57290Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) {
57300Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL;
57310Sstevel@tonic-gate (void) dprov_free_context(ctx);
57320Sstevel@tonic-gate }
57330Sstevel@tonic-gate break;
57340Sstevel@tonic-gate
57350Sstevel@tonic-gate case DPROV_REQ_SIGN_UPDATE:
57364072Skrishna if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
57374072Skrishna error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
57384072Skrishna taskq_req->dr_mac_req.dr_data, NULL);
57394072Skrishna } else {
57404072Skrishna error = crypto_sign_update(DPROV_CTX_SINGLE(ctx),
57414072Skrishna taskq_req->dr_sign_req.sr_data, NULL);
57424072Skrishna }
57430Sstevel@tonic-gate break;
57440Sstevel@tonic-gate
57450Sstevel@tonic-gate case DPROV_REQ_SIGN_FINAL:
57464072Skrishna if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
57474072Skrishna error = crypto_mac_final(DPROV_CTX_SINGLE(ctx),
57484072Skrishna taskq_req->dr_mac_req.dr_mac, NULL);
57494072Skrishna } else {
57504072Skrishna error = crypto_sign_final(DPROV_CTX_SINGLE(ctx),
57514072Skrishna taskq_req->dr_sign_req.sr_signature, NULL);
57524072Skrishna }
57530Sstevel@tonic-gate
57540Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) {
57550Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL;
57560Sstevel@tonic-gate (void) dprov_free_context(ctx);
57570Sstevel@tonic-gate }
57580Sstevel@tonic-gate break;
57590Sstevel@tonic-gate
57600Sstevel@tonic-gate case DPROV_REQ_SIGN_ATOMIC:
57610Sstevel@tonic-gate case DPROV_REQ_SIGN_RECOVER_ATOMIC:
57620Sstevel@tonic-gate /* structure assignment */
57630Sstevel@tonic-gate mech = *taskq_req->dr_sign_req.sr_mechanism;
57640Sstevel@tonic-gate
57650Sstevel@tonic-gate mutex_enter(&softc->ds_lock);
57660Sstevel@tonic-gate /* get key value for secret key algorithms */
57670Sstevel@tonic-gate if (is_publickey_mech(mech.cm_type)) {
57680Sstevel@tonic-gate if ((error = dprov_key_attr_asymmetric(softc,
57690Sstevel@tonic-gate taskq_req->dr_sign_req.sr_session_id,
57700Sstevel@tonic-gate taskq_req->dr_type,
57710Sstevel@tonic-gate taskq_req->dr_sign_req.sr_key, &key))
57720Sstevel@tonic-gate != CRYPTO_SUCCESS) {
57730Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
57740Sstevel@tonic-gate break;
57750Sstevel@tonic-gate }
57760Sstevel@tonic-gate keyp = &key;
57770Sstevel@tonic-gate } else {
57780Sstevel@tonic-gate if ((error = dprov_key_value_secret(softc,
57790Sstevel@tonic-gate taskq_req->dr_sign_req.sr_session_id,
57800Sstevel@tonic-gate taskq_req->dr_type,
57810Sstevel@tonic-gate taskq_req->dr_sign_req.sr_key, &key))
57820Sstevel@tonic-gate != CRYPTO_SUCCESS) {
57830Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
57840Sstevel@tonic-gate break;
57850Sstevel@tonic-gate }
57860Sstevel@tonic-gate keyp = &key;
57870Sstevel@tonic-gate }
57880Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
57890Sstevel@tonic-gate
57900Sstevel@tonic-gate /* get the software provider for this mechanism */
57910Sstevel@tonic-gate if ((error = dprov_get_sw_prov(
57920Sstevel@tonic-gate taskq_req->dr_sign_req.sr_mechanism, &pd,
57930Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS)
57940Sstevel@tonic-gate break;
57950Sstevel@tonic-gate
57960Sstevel@tonic-gate /* Use a session id of zero since we use a software provider */
57970Sstevel@tonic-gate if (taskq_req->dr_type == DPROV_REQ_SIGN_ATOMIC)
57980Sstevel@tonic-gate error = crypto_sign_prov(pd, 0, &mech, keyp,
57990Sstevel@tonic-gate taskq_req->dr_sign_req.sr_data,
58000Sstevel@tonic-gate NULL, taskq_req->dr_sign_req.sr_signature, NULL);
58010Sstevel@tonic-gate else
58020Sstevel@tonic-gate error = crypto_sign_recover_prov(pd, 0, &mech, keyp,
58030Sstevel@tonic-gate taskq_req->dr_sign_req.sr_data,
58040Sstevel@tonic-gate NULL, taskq_req->dr_sign_req.sr_signature, NULL);
58050Sstevel@tonic-gate
58060Sstevel@tonic-gate /* release provider reference */
58070Sstevel@tonic-gate KCF_PROV_REFRELE(pd);
58080Sstevel@tonic-gate break;
58090Sstevel@tonic-gate
58100Sstevel@tonic-gate case DPROV_REQ_SIGN_RECOVER:
58110Sstevel@tonic-gate error = crypto_sign_recover_single(DPROV_CTX_SINGLE(ctx),
58120Sstevel@tonic-gate taskq_req->dr_sign_req.sr_data,
58130Sstevel@tonic-gate taskq_req->dr_sign_req.sr_signature, NULL);
58140Sstevel@tonic-gate
58150Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) {
58160Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL;
58170Sstevel@tonic-gate (void) dprov_free_context(ctx);
58180Sstevel@tonic-gate }
58190Sstevel@tonic-gate break;
58200Sstevel@tonic-gate }
58210Sstevel@tonic-gate
58220Sstevel@tonic-gate dprov_op_done(taskq_req, error);
58230Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_task: end\n", instance));
58240Sstevel@tonic-gate }
58250Sstevel@tonic-gate
58264072Skrishna static int
emulate_verify_with_mac(crypto_ctx_t * ctx,crypto_data_t * in_mac)58274072Skrishna emulate_verify_with_mac(crypto_ctx_t *ctx, crypto_data_t *in_mac)
58284072Skrishna {
58294072Skrishna int error;
58304072Skrishna crypto_data_t tmpd;
58314072Skrishna crypto_data_t *out_mac;
58324072Skrishna char digest[SHA512_DIGEST_LENGTH];
58334072Skrishna
58344072Skrishna bzero(&tmpd, sizeof (crypto_data_t));
58354072Skrishna tmpd.cd_format = CRYPTO_DATA_RAW;
58364072Skrishna tmpd.cd_length = SHA512_DIGEST_LENGTH;
58374072Skrishna tmpd.cd_raw.iov_base = digest;
58384072Skrishna tmpd.cd_raw.iov_len = SHA512_DIGEST_LENGTH;
58394072Skrishna out_mac = &tmpd;
58404072Skrishna
58414072Skrishna error = crypto_mac_final(DPROV_CTX_SINGLE(ctx), out_mac, NULL);
58424072Skrishna if (in_mac->cd_length != out_mac->cd_length ||
58434072Skrishna (bcmp(digest, (unsigned char *)in_mac->cd_raw.iov_base +
58444072Skrishna in_mac->cd_offset, out_mac->cd_length) != 0)) {
58454072Skrishna error = CRYPTO_INVALID_MAC;
58464072Skrishna }
58474072Skrishna
58484072Skrishna return (error);
58494072Skrishna }
58504072Skrishna
58510Sstevel@tonic-gate /*
58520Sstevel@tonic-gate * taskq dispatcher function for verify operations.
58530Sstevel@tonic-gate */
58540Sstevel@tonic-gate static void
dprov_verify_task(dprov_req_t * taskq_req)58550Sstevel@tonic-gate dprov_verify_task(dprov_req_t *taskq_req)
58560Sstevel@tonic-gate {
58570Sstevel@tonic-gate kcf_provider_desc_t *pd;
58580Sstevel@tonic-gate dprov_state_t *softc;
58590Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
58600Sstevel@tonic-gate int instance;
58610Sstevel@tonic-gate int error = CRYPTO_NOT_SUPPORTED;
58620Sstevel@tonic-gate crypto_ctx_t *ctx = taskq_req->dr_verify_req.vr_ctx;
58630Sstevel@tonic-gate crypto_key_t key, *keyp;
58640Sstevel@tonic-gate crypto_mechanism_t mech;
58650Sstevel@tonic-gate
58660Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
58670Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_task: started\n", instance));
58680Sstevel@tonic-gate
58690Sstevel@tonic-gate switch (taskq_req->dr_type) {
58700Sstevel@tonic-gate
58710Sstevel@tonic-gate case DPROV_REQ_VERIFY_INIT:
58720Sstevel@tonic-gate case DPROV_REQ_VERIFY_RECOVER_INIT:
58730Sstevel@tonic-gate /* allocate a dprov-private context */
58740Sstevel@tonic-gate if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
58750Sstevel@tonic-gate CRYPTO_SUCCESS)
58760Sstevel@tonic-gate break;
58770Sstevel@tonic-gate
58780Sstevel@tonic-gate /* structure assignment */
58790Sstevel@tonic-gate mech = *taskq_req->dr_verify_req.vr_mechanism;
58804072Skrishna if (dprov_valid_mac_mech(mech.cm_type)) {
58814072Skrishna DPROV_CTX_P(ctx)->dc_svrfy_to_mac = B_TRUE;
58824072Skrishna }
58830Sstevel@tonic-gate
58840Sstevel@tonic-gate mutex_enter(&softc->ds_lock);
58850Sstevel@tonic-gate /* get key value for secret key algorithms */
58860Sstevel@tonic-gate if (is_publickey_mech(mech.cm_type)) {
58870Sstevel@tonic-gate if ((error = dprov_key_attr_asymmetric(softc,
58880Sstevel@tonic-gate ctx->cc_session, taskq_req->dr_type,
58890Sstevel@tonic-gate taskq_req->dr_verify_req.vr_key, &key))
58900Sstevel@tonic-gate != CRYPTO_SUCCESS) {
58910Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
58920Sstevel@tonic-gate break;
58930Sstevel@tonic-gate }
58940Sstevel@tonic-gate keyp = &key;
58950Sstevel@tonic-gate } else {
58960Sstevel@tonic-gate if ((error = dprov_key_value_secret(softc,
58970Sstevel@tonic-gate ctx->cc_session, taskq_req->dr_type,
58980Sstevel@tonic-gate taskq_req->dr_verify_req.vr_key, &key))
58990Sstevel@tonic-gate != CRYPTO_SUCCESS) {
59000Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
59010Sstevel@tonic-gate break;
59020Sstevel@tonic-gate }
59030Sstevel@tonic-gate keyp = &key;
59040Sstevel@tonic-gate }
59050Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
59060Sstevel@tonic-gate
59070Sstevel@tonic-gate /* get the software provider for this mechanism */
59080Sstevel@tonic-gate if ((error = dprov_get_sw_prov(
59090Sstevel@tonic-gate taskq_req->dr_verify_req.vr_mechanism, &pd,
59100Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS)
59110Sstevel@tonic-gate break;
59120Sstevel@tonic-gate
59134072Skrishna
59144072Skrishna if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
59154072Skrishna error = crypto_mac_init_prov(pd, 0, &mech, keyp, NULL,
59164072Skrishna &DPROV_CTX_SINGLE(ctx), NULL);
59174072Skrishna
59184072Skrishna /* release provider reference */
59194072Skrishna KCF_PROV_REFRELE(pd);
59204072Skrishna break;
59214072Skrishna }
59224072Skrishna
59230Sstevel@tonic-gate /* Use a session id of zero since we use a software provider */
59240Sstevel@tonic-gate if (taskq_req->dr_type == DPROV_REQ_VERIFY_INIT)
59250Sstevel@tonic-gate error = crypto_verify_init_prov(pd, 0, &mech, keyp,
59260Sstevel@tonic-gate NULL, &DPROV_CTX_SINGLE(ctx), NULL);
59270Sstevel@tonic-gate else
59280Sstevel@tonic-gate error = crypto_verify_recover_init_prov(pd, 0, &mech,
59290Sstevel@tonic-gate keyp, NULL, &DPROV_CTX_SINGLE(ctx), NULL);
59300Sstevel@tonic-gate
59310Sstevel@tonic-gate /* release provider reference */
59320Sstevel@tonic-gate KCF_PROV_REFRELE(pd);
59330Sstevel@tonic-gate
59340Sstevel@tonic-gate break;
59350Sstevel@tonic-gate
59360Sstevel@tonic-gate case DPROV_REQ_VERIFY:
59374072Skrishna if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
59384072Skrishna /* Emulate using update and final */
59394072Skrishna error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
59404072Skrishna taskq_req->dr_mac_req.dr_data, NULL);
59414072Skrishna if (error == CRYPTO_SUCCESS) {
59424072Skrishna error = emulate_verify_with_mac(ctx,
59434072Skrishna taskq_req->dr_mac_req.dr_mac);
59444072Skrishna }
59454072Skrishna } else {
59464072Skrishna error = crypto_verify_single(DPROV_CTX_SINGLE(ctx),
59474072Skrishna taskq_req->dr_verify_req.vr_data,
59484072Skrishna taskq_req->dr_verify_req.vr_signature, NULL);
59494072Skrishna }
59500Sstevel@tonic-gate
59510Sstevel@tonic-gate ASSERT(error != CRYPTO_BUFFER_TOO_SMALL);
59520Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL;
59530Sstevel@tonic-gate (void) dprov_free_context(ctx);
59540Sstevel@tonic-gate break;
59550Sstevel@tonic-gate
59560Sstevel@tonic-gate case DPROV_REQ_VERIFY_UPDATE:
59574072Skrishna if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
59584072Skrishna error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
59594072Skrishna taskq_req->dr_mac_req.dr_data, NULL);
59604072Skrishna } else {
59614072Skrishna error = crypto_verify_update(DPROV_CTX_SINGLE(ctx),
59624072Skrishna taskq_req->dr_verify_req.vr_data, NULL);
59634072Skrishna }
59640Sstevel@tonic-gate break;
59650Sstevel@tonic-gate
59660Sstevel@tonic-gate case DPROV_REQ_VERIFY_FINAL:
59674072Skrishna if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
59684072Skrishna error = emulate_verify_with_mac(ctx,
59694072Skrishna taskq_req->dr_mac_req.dr_mac);
59704072Skrishna } else {
59714072Skrishna error = crypto_verify_final(DPROV_CTX_SINGLE(ctx),
59724072Skrishna taskq_req->dr_verify_req.vr_signature, NULL);
59734072Skrishna }
59740Sstevel@tonic-gate
59750Sstevel@tonic-gate ASSERT(error != CRYPTO_BUFFER_TOO_SMALL);
59760Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL;
59770Sstevel@tonic-gate (void) dprov_free_context(ctx);
59780Sstevel@tonic-gate break;
59790Sstevel@tonic-gate
59800Sstevel@tonic-gate case DPROV_REQ_VERIFY_ATOMIC:
59810Sstevel@tonic-gate case DPROV_REQ_VERIFY_RECOVER_ATOMIC:
59820Sstevel@tonic-gate /* structure assignment */
59830Sstevel@tonic-gate mech = *taskq_req->dr_verify_req.vr_mechanism;
59840Sstevel@tonic-gate
59850Sstevel@tonic-gate mutex_enter(&softc->ds_lock);
59860Sstevel@tonic-gate /* get key value for secret key algorithms */
59870Sstevel@tonic-gate if (is_publickey_mech(mech.cm_type)) {
59880Sstevel@tonic-gate if ((error = dprov_key_attr_asymmetric(softc,
59890Sstevel@tonic-gate taskq_req->dr_verify_req.vr_session_id,
59900Sstevel@tonic-gate taskq_req->dr_type,
59910Sstevel@tonic-gate taskq_req->dr_verify_req.vr_key, &key))
59920Sstevel@tonic-gate != CRYPTO_SUCCESS) {
59930Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
59940Sstevel@tonic-gate break;
59950Sstevel@tonic-gate }
59960Sstevel@tonic-gate keyp = &key;
59970Sstevel@tonic-gate } else {
59980Sstevel@tonic-gate if ((error = dprov_key_value_secret(softc,
59990Sstevel@tonic-gate taskq_req->dr_verify_req.vr_session_id,
60000Sstevel@tonic-gate taskq_req->dr_type,
60010Sstevel@tonic-gate taskq_req->dr_verify_req.vr_key, &key))
60020Sstevel@tonic-gate != CRYPTO_SUCCESS) {
60030Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
60040Sstevel@tonic-gate break;
60050Sstevel@tonic-gate }
60060Sstevel@tonic-gate keyp = &key;
60070Sstevel@tonic-gate }
60080Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
60090Sstevel@tonic-gate
60100Sstevel@tonic-gate /* get the software provider for this mechanism */
60110Sstevel@tonic-gate if ((error = dprov_get_sw_prov(
60120Sstevel@tonic-gate taskq_req->dr_verify_req.vr_mechanism, &pd,
60130Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS)
60140Sstevel@tonic-gate break;
60150Sstevel@tonic-gate
60160Sstevel@tonic-gate /* Use a session id of zero since we use a software provider */
60170Sstevel@tonic-gate if (taskq_req->dr_type == DPROV_REQ_VERIFY_ATOMIC)
60180Sstevel@tonic-gate error = crypto_verify_prov(pd, 0, &mech, keyp,
60190Sstevel@tonic-gate taskq_req->dr_verify_req.vr_data,
60200Sstevel@tonic-gate NULL, taskq_req->dr_verify_req.vr_signature, NULL);
60210Sstevel@tonic-gate else
60220Sstevel@tonic-gate /*
60230Sstevel@tonic-gate * crypto_verify_recover_prov() has different argument
60240Sstevel@tonic-gate * order than crypto_verify_prov().
60250Sstevel@tonic-gate */
60260Sstevel@tonic-gate error = crypto_verify_recover_prov(pd, 0, &mech, keyp,
60270Sstevel@tonic-gate taskq_req->dr_verify_req.vr_signature,
60280Sstevel@tonic-gate NULL, taskq_req->dr_verify_req.vr_data, NULL);
60290Sstevel@tonic-gate
60300Sstevel@tonic-gate /* release provider reference */
60310Sstevel@tonic-gate KCF_PROV_REFRELE(pd);
60320Sstevel@tonic-gate break;
60330Sstevel@tonic-gate
60340Sstevel@tonic-gate case DPROV_REQ_VERIFY_RECOVER:
60350Sstevel@tonic-gate /*
60360Sstevel@tonic-gate * crypto_verify_recover_single() has different argument
60370Sstevel@tonic-gate * order than crypto_verify_single().
60380Sstevel@tonic-gate */
60390Sstevel@tonic-gate error = crypto_verify_recover_single(DPROV_CTX_SINGLE(ctx),
60400Sstevel@tonic-gate taskq_req->dr_verify_req.vr_signature,
60410Sstevel@tonic-gate taskq_req->dr_verify_req.vr_data, NULL);
60420Sstevel@tonic-gate
60430Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) {
60440Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL;
60450Sstevel@tonic-gate (void) dprov_free_context(ctx);
60460Sstevel@tonic-gate }
60470Sstevel@tonic-gate break;
60480Sstevel@tonic-gate }
60490Sstevel@tonic-gate
60500Sstevel@tonic-gate dprov_op_done(taskq_req, error);
60510Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_task: end\n", instance));
60520Sstevel@tonic-gate }
60530Sstevel@tonic-gate
60540Sstevel@tonic-gate /*
60550Sstevel@tonic-gate * taskq dispatcher function for dual operations.
60560Sstevel@tonic-gate */
60570Sstevel@tonic-gate static void
dprov_dual_task(dprov_req_t * taskq_req)60580Sstevel@tonic-gate dprov_dual_task(dprov_req_t *taskq_req)
60590Sstevel@tonic-gate {
60600Sstevel@tonic-gate dprov_state_t *softc;
60610Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
60620Sstevel@tonic-gate int instance;
60630Sstevel@tonic-gate int error = CRYPTO_NOT_SUPPORTED;
60640Sstevel@tonic-gate crypto_ctx_t *signverify_ctx = taskq_req->dr_dual_req.dr_signverify_ctx;
60650Sstevel@tonic-gate crypto_ctx_t *cipher_ctx = taskq_req->dr_dual_req.dr_cipher_ctx;
60660Sstevel@tonic-gate
60670Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
60680Sstevel@tonic-gate DPROV_DEBUG(D_DUAL, ("(%d) dprov_dual_task: started\n", instance));
60690Sstevel@tonic-gate
60700Sstevel@tonic-gate switch (taskq_req->dr_type) {
60710Sstevel@tonic-gate
60720Sstevel@tonic-gate case DPROV_REQ_DIGEST_ENCRYPT_UPDATE:
60730Sstevel@tonic-gate error = crypto_digest_encrypt_update(
60740Sstevel@tonic-gate DPROV_CTX_SINGLE(signverify_ctx),
60750Sstevel@tonic-gate DPROV_CTX_SINGLE(cipher_ctx),
60760Sstevel@tonic-gate taskq_req->dr_dual_req.dr_plaintext,
60770Sstevel@tonic-gate taskq_req->dr_dual_req.dr_ciphertext, NULL);
60780Sstevel@tonic-gate break;
60790Sstevel@tonic-gate
60800Sstevel@tonic-gate case DPROV_REQ_DECRYPT_DIGEST_UPDATE:
60810Sstevel@tonic-gate error = crypto_decrypt_digest_update(
60820Sstevel@tonic-gate DPROV_CTX_SINGLE(cipher_ctx),
60830Sstevel@tonic-gate DPROV_CTX_SINGLE(signverify_ctx),
60840Sstevel@tonic-gate taskq_req->dr_dual_req.dr_ciphertext,
60850Sstevel@tonic-gate taskq_req->dr_dual_req.dr_plaintext, NULL);
60860Sstevel@tonic-gate break;
60870Sstevel@tonic-gate
60880Sstevel@tonic-gate case DPROV_REQ_SIGN_ENCRYPT_UPDATE:
60890Sstevel@tonic-gate error = crypto_sign_encrypt_update(
60900Sstevel@tonic-gate DPROV_CTX_SINGLE(signverify_ctx),
60910Sstevel@tonic-gate DPROV_CTX_SINGLE(cipher_ctx),
60920Sstevel@tonic-gate taskq_req->dr_dual_req.dr_plaintext,
60930Sstevel@tonic-gate taskq_req->dr_dual_req.dr_ciphertext, NULL);
60940Sstevel@tonic-gate break;
60950Sstevel@tonic-gate
60960Sstevel@tonic-gate case DPROV_REQ_DECRYPT_VERIFY_UPDATE:
60970Sstevel@tonic-gate error = crypto_decrypt_verify_update(
60980Sstevel@tonic-gate DPROV_CTX_SINGLE(cipher_ctx),
60990Sstevel@tonic-gate DPROV_CTX_SINGLE(signverify_ctx),
61000Sstevel@tonic-gate taskq_req->dr_dual_req.dr_ciphertext,
61010Sstevel@tonic-gate taskq_req->dr_dual_req.dr_plaintext, NULL);
61020Sstevel@tonic-gate break;
61030Sstevel@tonic-gate }
61040Sstevel@tonic-gate
61050Sstevel@tonic-gate dprov_op_done(taskq_req, error);
61060Sstevel@tonic-gate DPROV_DEBUG(D_DUAL, ("(%d) dprov_dual_task: end\n", instance));
61070Sstevel@tonic-gate }
61080Sstevel@tonic-gate
61090Sstevel@tonic-gate /*
61100Sstevel@tonic-gate * taskq dispatcher function for cipher operations.
61110Sstevel@tonic-gate */
61120Sstevel@tonic-gate static void
dprov_cipher_task(dprov_req_t * taskq_req)61130Sstevel@tonic-gate dprov_cipher_task(dprov_req_t *taskq_req)
61140Sstevel@tonic-gate {
61150Sstevel@tonic-gate kcf_provider_desc_t *pd;
61160Sstevel@tonic-gate dprov_state_t *softc;
61170Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
61180Sstevel@tonic-gate int instance;
61190Sstevel@tonic-gate int error = CRYPTO_NOT_SUPPORTED;
61200Sstevel@tonic-gate crypto_ctx_t *ctx = taskq_req->dr_cipher_req.dr_ctx;
61210Sstevel@tonic-gate crypto_key_t key, *keyp;
61220Sstevel@tonic-gate crypto_mechanism_t mech;
61230Sstevel@tonic-gate
61240Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
61250Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_cipher_task: started\n", instance));
61260Sstevel@tonic-gate
61270Sstevel@tonic-gate switch (taskq_req->dr_type) {
61280Sstevel@tonic-gate
61290Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_INIT:
61300Sstevel@tonic-gate case DPROV_REQ_DECRYPT_INIT:
61310Sstevel@tonic-gate /* allocate a dprov-private context */
61320Sstevel@tonic-gate if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
61330Sstevel@tonic-gate CRYPTO_SUCCESS)
61340Sstevel@tonic-gate break;
61350Sstevel@tonic-gate
61360Sstevel@tonic-gate /* structure assignment */
61370Sstevel@tonic-gate mech = *taskq_req->dr_cipher_req.dr_mechanism;
61380Sstevel@tonic-gate
61390Sstevel@tonic-gate mutex_enter(&softc->ds_lock);
61400Sstevel@tonic-gate /* get key value for secret key algorithms */
61410Sstevel@tonic-gate if (is_publickey_mech(mech.cm_type)) {
61420Sstevel@tonic-gate if ((error = dprov_key_attr_asymmetric(softc,
61430Sstevel@tonic-gate ctx->cc_session, taskq_req->dr_type,
61440Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_key, &key))
61450Sstevel@tonic-gate != CRYPTO_SUCCESS) {
61460Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
61470Sstevel@tonic-gate break;
61480Sstevel@tonic-gate }
61490Sstevel@tonic-gate keyp = &key;
61500Sstevel@tonic-gate } else {
61510Sstevel@tonic-gate if ((error = dprov_key_value_secret(softc,
61520Sstevel@tonic-gate ctx->cc_session, taskq_req->dr_type,
61530Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_key, &key))
61540Sstevel@tonic-gate != CRYPTO_SUCCESS) {
61550Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
61560Sstevel@tonic-gate break;
61570Sstevel@tonic-gate }
61580Sstevel@tonic-gate keyp = &key;
61590Sstevel@tonic-gate }
61600Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
61610Sstevel@tonic-gate
61620Sstevel@tonic-gate /* get the software provider for this mechanism */
61630Sstevel@tonic-gate if ((error = dprov_get_sw_prov(
61640Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_mechanism, &pd,
61650Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS)
61660Sstevel@tonic-gate break;
61670Sstevel@tonic-gate
61680Sstevel@tonic-gate /* Use a session id of zero since we use a software provider */
61690Sstevel@tonic-gate if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_INIT)
61700Sstevel@tonic-gate error = crypto_encrypt_init_prov(pd, 0, &mech, keyp,
61710Sstevel@tonic-gate NULL, &DPROV_CTX_SINGLE(ctx), NULL);
61720Sstevel@tonic-gate else
61730Sstevel@tonic-gate error = crypto_decrypt_init_prov(pd, 0, &mech, keyp,
61740Sstevel@tonic-gate NULL, &DPROV_CTX_SINGLE(ctx), NULL);
61750Sstevel@tonic-gate
61763708Skrishna if (ctx->cc_flags & CRYPTO_INIT_OPSTATE) {
61773708Skrishna crypto_ctx_t *lctx =
61783708Skrishna (crypto_ctx_t *)(DPROV_CTX_SINGLE(ctx));
61793708Skrishna
61803708Skrishna ctx->cc_opstate = lctx->cc_provider_private;
61813708Skrishna ctx->cc_flags |= CRYPTO_USE_OPSTATE;
61823708Skrishna }
61833708Skrishna
61840Sstevel@tonic-gate /* release provider reference */
61850Sstevel@tonic-gate KCF_PROV_REFRELE(pd);
61860Sstevel@tonic-gate break;
61870Sstevel@tonic-gate
61880Sstevel@tonic-gate case DPROV_REQ_ENCRYPT:
61890Sstevel@tonic-gate error = crypto_encrypt_single(DPROV_CTX_SINGLE(ctx),
61900Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_plaintext,
61910Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_ciphertext, NULL);
61920Sstevel@tonic-gate
61930Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) {
61940Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL;
61950Sstevel@tonic-gate (void) dprov_free_context(ctx);
61960Sstevel@tonic-gate }
61970Sstevel@tonic-gate break;
61980Sstevel@tonic-gate
61990Sstevel@tonic-gate case DPROV_REQ_DECRYPT:
62000Sstevel@tonic-gate error = crypto_decrypt_single(DPROV_CTX_SINGLE(ctx),
62010Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_ciphertext,
62020Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_plaintext, NULL);
62030Sstevel@tonic-gate
62040Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) {
62050Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL;
62060Sstevel@tonic-gate (void) dprov_free_context(ctx);
62070Sstevel@tonic-gate }
62080Sstevel@tonic-gate break;
62090Sstevel@tonic-gate
62100Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_UPDATE:
62113708Skrishna ASSERT(!(ctx->cc_flags & CRYPTO_INIT_OPSTATE) ||
62123708Skrishna (ctx->cc_flags & CRYPTO_USE_OPSTATE));
62130Sstevel@tonic-gate error = crypto_encrypt_update(DPROV_CTX_SINGLE(ctx),
62140Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_plaintext,
62150Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_ciphertext, NULL);
62160Sstevel@tonic-gate break;
62170Sstevel@tonic-gate
62180Sstevel@tonic-gate case DPROV_REQ_DECRYPT_UPDATE:
62193708Skrishna ASSERT(!(ctx->cc_flags & CRYPTO_INIT_OPSTATE) ||
62203708Skrishna (ctx->cc_flags & CRYPTO_USE_OPSTATE));
62210Sstevel@tonic-gate error = crypto_decrypt_update(DPROV_CTX_SINGLE(ctx),
62220Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_ciphertext,
62230Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_plaintext, NULL);
62240Sstevel@tonic-gate break;
62250Sstevel@tonic-gate
62260Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_FINAL:
62270Sstevel@tonic-gate error = crypto_encrypt_final(DPROV_CTX_SINGLE(ctx),
62280Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_ciphertext, NULL);
62290Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) {
62300Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL;
62310Sstevel@tonic-gate (void) dprov_free_context(ctx);
62320Sstevel@tonic-gate }
62330Sstevel@tonic-gate break;
62340Sstevel@tonic-gate
62350Sstevel@tonic-gate case DPROV_REQ_DECRYPT_FINAL:
62360Sstevel@tonic-gate error = crypto_decrypt_final(DPROV_CTX_SINGLE(ctx),
62370Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_plaintext, NULL);
62380Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) {
62390Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL;
62400Sstevel@tonic-gate (void) dprov_free_context(ctx);
62410Sstevel@tonic-gate }
62420Sstevel@tonic-gate break;
62430Sstevel@tonic-gate
62440Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_ATOMIC:
62450Sstevel@tonic-gate case DPROV_REQ_DECRYPT_ATOMIC:
62460Sstevel@tonic-gate /* structure assignment */
62470Sstevel@tonic-gate mech = *taskq_req->dr_cipher_req.dr_mechanism;
62480Sstevel@tonic-gate
62490Sstevel@tonic-gate mutex_enter(&softc->ds_lock);
62500Sstevel@tonic-gate /* get key value for secret key algorithms */
62510Sstevel@tonic-gate if (is_publickey_mech(mech.cm_type)) {
62520Sstevel@tonic-gate if ((error = dprov_key_attr_asymmetric(softc,
62530Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_session_id,
62540Sstevel@tonic-gate taskq_req->dr_type,
62550Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_key,
62560Sstevel@tonic-gate &key)) != CRYPTO_SUCCESS) {
62570Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
62580Sstevel@tonic-gate break;
62590Sstevel@tonic-gate }
62600Sstevel@tonic-gate keyp = &key;
62610Sstevel@tonic-gate } else {
62620Sstevel@tonic-gate if ((error = dprov_key_value_secret(softc,
62630Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_session_id,
62640Sstevel@tonic-gate taskq_req->dr_type, taskq_req->dr_cipher_req.dr_key,
62650Sstevel@tonic-gate &key))
62660Sstevel@tonic-gate != CRYPTO_SUCCESS) {
62670Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
62680Sstevel@tonic-gate break;
62690Sstevel@tonic-gate }
62700Sstevel@tonic-gate keyp = &key;
62710Sstevel@tonic-gate }
62720Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
62730Sstevel@tonic-gate
62740Sstevel@tonic-gate /* get the software provider for this mechanism */
62750Sstevel@tonic-gate if ((error = dprov_get_sw_prov(
62760Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_mechanism, &pd,
62770Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS)
62780Sstevel@tonic-gate break;
62790Sstevel@tonic-gate
62800Sstevel@tonic-gate /* use a session id of zero since we use a software provider */
62810Sstevel@tonic-gate if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_ATOMIC)
6282904Smcpowers error = crypto_encrypt_prov(pd, 0, &mech,
62830Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_plaintext,
62840Sstevel@tonic-gate keyp, NULL,
6285904Smcpowers taskq_req->dr_cipher_req.dr_ciphertext, NULL);
62860Sstevel@tonic-gate else
6287904Smcpowers error = crypto_decrypt_prov(pd, 0, &mech,
62880Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_ciphertext,
62890Sstevel@tonic-gate keyp, NULL,
6290904Smcpowers taskq_req->dr_cipher_req.dr_plaintext, NULL);
62910Sstevel@tonic-gate
62920Sstevel@tonic-gate /* release provider reference */
62930Sstevel@tonic-gate KCF_PROV_REFRELE(pd);
62940Sstevel@tonic-gate
62950Sstevel@tonic-gate break;
62960Sstevel@tonic-gate }
62970Sstevel@tonic-gate
62980Sstevel@tonic-gate dprov_op_done(taskq_req, error);
62990Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: end\n", instance));
63000Sstevel@tonic-gate }
63010Sstevel@tonic-gate
63020Sstevel@tonic-gate /*
63030Sstevel@tonic-gate * Helper function for the cipher/mac dual operation taskq dispatch
63040Sstevel@tonic-gate * function. Initialize the cipher and mac key values and find the
63050Sstevel@tonic-gate * providers that can process the request for the specified mechanisms.
63060Sstevel@tonic-gate */
63070Sstevel@tonic-gate static int
dprov_cipher_mac_key_pd(dprov_state_t * softc,crypto_session_id_t sid,dprov_req_t * taskq_req,crypto_key_t * cipher_key,crypto_key_t * mac_key,kcf_provider_desc_t ** cipher_pd,kcf_provider_desc_t ** mac_pd,crypto_mech_type_t * cipher_mech_type,crypto_mech_type_t * mac_mech_type)63080Sstevel@tonic-gate dprov_cipher_mac_key_pd(dprov_state_t *softc, crypto_session_id_t sid,
63090Sstevel@tonic-gate dprov_req_t *taskq_req, crypto_key_t *cipher_key, crypto_key_t *mac_key,
63100Sstevel@tonic-gate kcf_provider_desc_t **cipher_pd, kcf_provider_desc_t **mac_pd,
63110Sstevel@tonic-gate crypto_mech_type_t *cipher_mech_type, crypto_mech_type_t *mac_mech_type)
63120Sstevel@tonic-gate {
63130Sstevel@tonic-gate int error;
63140Sstevel@tonic-gate
63150Sstevel@tonic-gate /* get the cipher key value */
63160Sstevel@tonic-gate mutex_enter(&softc->ds_lock);
6317904Smcpowers error = dprov_key_value_secret(softc, sid, DPROV_REQ_ENCRYPT_ATOMIC,
63180Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_cipher_key, cipher_key);
63190Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) {
63200Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
63210Sstevel@tonic-gate return (error);
63220Sstevel@tonic-gate }
63230Sstevel@tonic-gate
63240Sstevel@tonic-gate /* get the mac key value */
6325904Smcpowers error = dprov_key_value_secret(softc, sid, DPROV_REQ_MAC_ATOMIC,
63260Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_mac_key, mac_key);
63270Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
63280Sstevel@tonic-gate if (error != CRYPTO_SUCCESS)
63290Sstevel@tonic-gate return (error);
63300Sstevel@tonic-gate
63310Sstevel@tonic-gate /* get the SW provider to perform the cipher operation */
63320Sstevel@tonic-gate if ((error = dprov_get_sw_prov(
63330Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_cipher_mech, cipher_pd,
63340Sstevel@tonic-gate cipher_mech_type)) != CRYPTO_SUCCESS)
63350Sstevel@tonic-gate return (error);
63360Sstevel@tonic-gate
63370Sstevel@tonic-gate /* get the SW provider to perform the mac operation */
63380Sstevel@tonic-gate error = dprov_get_sw_prov(taskq_req->dr_cipher_mac_req.mr_mac_mech,
63390Sstevel@tonic-gate mac_pd, mac_mech_type);
63400Sstevel@tonic-gate
63410Sstevel@tonic-gate return (error);
63420Sstevel@tonic-gate }
63430Sstevel@tonic-gate
63440Sstevel@tonic-gate /*
63450Sstevel@tonic-gate * taskq dispatcher function for cipher/mac dual operations.
63460Sstevel@tonic-gate */
63470Sstevel@tonic-gate static void
dprov_cipher_mac_task(dprov_req_t * taskq_req)63480Sstevel@tonic-gate dprov_cipher_mac_task(dprov_req_t *taskq_req)
63490Sstevel@tonic-gate {
63500Sstevel@tonic-gate dprov_state_t *softc;
63510Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
63520Sstevel@tonic-gate int instance;
63530Sstevel@tonic-gate int error = CRYPTO_NOT_SUPPORTED;
63540Sstevel@tonic-gate crypto_ctx_t *ctx = taskq_req->dr_cipher_mac_req.mr_ctx;
63550Sstevel@tonic-gate kcf_provider_desc_t *cipher_pd;
63560Sstevel@tonic-gate kcf_provider_desc_t *mac_pd;
63570Sstevel@tonic-gate crypto_key_t cipher_key;
63580Sstevel@tonic-gate crypto_key_t mac_key;
63590Sstevel@tonic-gate crypto_dual_data_t *dual_data =
63600Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_dual_data;
63610Sstevel@tonic-gate crypto_data_t cipher_data;
63620Sstevel@tonic-gate crypto_data_t mac_data;
63630Sstevel@tonic-gate crypto_mechanism_t cipher_mech, mac_mech;
63640Sstevel@tonic-gate crypto_session_id_t session_id;
63650Sstevel@tonic-gate
63660Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
63670Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_cipher_mac_task: started\n",
63680Sstevel@tonic-gate instance));
63690Sstevel@tonic-gate
63700Sstevel@tonic-gate switch (taskq_req->dr_type) {
63710Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_MAC_INIT:
63720Sstevel@tonic-gate case DPROV_REQ_MAC_DECRYPT_INIT:
63730Sstevel@tonic-gate /* structure assignment */
63740Sstevel@tonic-gate cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech;
63750Sstevel@tonic-gate mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech;
63760Sstevel@tonic-gate
63770Sstevel@tonic-gate /* get the keys values and providers to use for operations */
63780Sstevel@tonic-gate if ((error = dprov_cipher_mac_key_pd(softc, ctx->cc_session,
63790Sstevel@tonic-gate taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd,
63800Sstevel@tonic-gate &cipher_mech.cm_type, &mac_mech.cm_type)) != CRYPTO_SUCCESS)
63810Sstevel@tonic-gate break;
63820Sstevel@tonic-gate
63830Sstevel@tonic-gate /* allocate a dprov-private context */
63840Sstevel@tonic-gate if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
63850Sstevel@tonic-gate CRYPTO_SUCCESS)
63860Sstevel@tonic-gate break;
63870Sstevel@tonic-gate
63880Sstevel@tonic-gate if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_MAC_INIT)
63890Sstevel@tonic-gate /* do the encryption initialization */
63900Sstevel@tonic-gate error = crypto_encrypt_init_prov(cipher_pd, 0,
63910Sstevel@tonic-gate &cipher_mech, &cipher_key, NULL,
63920Sstevel@tonic-gate &DPROV_CTX_DUAL_CIPHER(ctx), NULL);
63930Sstevel@tonic-gate else
63940Sstevel@tonic-gate /* do the decryption initialization */
63950Sstevel@tonic-gate error = crypto_decrypt_init_prov(cipher_pd, 0,
63960Sstevel@tonic-gate &cipher_mech, &cipher_key, NULL,
63970Sstevel@tonic-gate &DPROV_CTX_DUAL_CIPHER(ctx), NULL);
63980Sstevel@tonic-gate if (error != CRYPTO_SUCCESS)
63990Sstevel@tonic-gate break;
64000Sstevel@tonic-gate
64010Sstevel@tonic-gate /* do the mac initialization */
64020Sstevel@tonic-gate if ((error = crypto_mac_init_prov(mac_pd, 0,
64030Sstevel@tonic-gate &mac_mech, &mac_key, NULL, &DPROV_CTX_DUAL_MAC(ctx),
64040Sstevel@tonic-gate NULL)) != CRYPTO_SUCCESS)
64050Sstevel@tonic-gate break;
64060Sstevel@tonic-gate
64070Sstevel@tonic-gate /* release references to providers */
64080Sstevel@tonic-gate KCF_PROV_REFRELE(cipher_pd);
64090Sstevel@tonic-gate KCF_PROV_REFRELE(mac_pd);
64100Sstevel@tonic-gate
64110Sstevel@tonic-gate break;
64120Sstevel@tonic-gate
64130Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_MAC: {
64140Sstevel@tonic-gate size_t encrypted;
64150Sstevel@tonic-gate boolean_t inplace;
64160Sstevel@tonic-gate
64170Sstevel@tonic-gate crypto_data_t *plaintext_tmp, *ciphertext_tmp;
64180Sstevel@tonic-gate
64190Sstevel@tonic-gate cipher_data = *((crypto_data_t *)dual_data);
64200Sstevel@tonic-gate
64210Sstevel@tonic-gate /* do an encrypt update */
64220Sstevel@tonic-gate inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL);
64230Sstevel@tonic-gate if (inplace) {
64240Sstevel@tonic-gate plaintext_tmp = &cipher_data;
64250Sstevel@tonic-gate ciphertext_tmp = NULL;
64260Sstevel@tonic-gate } else {
64270Sstevel@tonic-gate plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data;
64280Sstevel@tonic-gate ciphertext_tmp = &cipher_data;
64290Sstevel@tonic-gate }
64300Sstevel@tonic-gate if ((error = crypto_encrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
64310Sstevel@tonic-gate plaintext_tmp, ciphertext_tmp, NULL)) != CRYPTO_SUCCESS)
64320Sstevel@tonic-gate break;
64330Sstevel@tonic-gate
64340Sstevel@tonic-gate /* do an encrypt final */
64350Sstevel@tonic-gate encrypted = cipher_data.cd_length;
64360Sstevel@tonic-gate
64370Sstevel@tonic-gate cipher_data.cd_offset += encrypted;
64380Sstevel@tonic-gate cipher_data.cd_length = dual_data->dd_len1 - encrypted;
64390Sstevel@tonic-gate
64400Sstevel@tonic-gate if ((error = crypto_encrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
64410Sstevel@tonic-gate &cipher_data, NULL)) != CRYPTO_SUCCESS)
64420Sstevel@tonic-gate break;
64430Sstevel@tonic-gate
64440Sstevel@tonic-gate /*
64450Sstevel@tonic-gate * Do a mac update on the resulting ciphertext, but with no
64460Sstevel@tonic-gate * more bytes than specified by dual_data, and starting at
64470Sstevel@tonic-gate * offset specified by dual_data. For in-place operations,
64480Sstevel@tonic-gate * we use the length specified by the dual_data.
64490Sstevel@tonic-gate */
64500Sstevel@tonic-gate mac_data = cipher_data;
64510Sstevel@tonic-gate mac_data.cd_offset = dual_data->dd_offset2;
64520Sstevel@tonic-gate mac_data.cd_length = dual_data->dd_len2;
64530Sstevel@tonic-gate if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
64540Sstevel@tonic-gate &mac_data, NULL)) != CRYPTO_SUCCESS)
64550Sstevel@tonic-gate break;
64560Sstevel@tonic-gate
64570Sstevel@tonic-gate /* do a mac final */
64580Sstevel@tonic-gate error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
64590Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_mac, NULL);
64600Sstevel@tonic-gate
64610Sstevel@tonic-gate /* Set the total size of the ciphertext, when successful */
64620Sstevel@tonic-gate if (error == CRYPTO_SUCCESS)
64630Sstevel@tonic-gate dual_data->dd_len1 = encrypted + cipher_data.cd_length;
64640Sstevel@tonic-gate
64650Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) {
64660Sstevel@tonic-gate DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
64670Sstevel@tonic-gate DPROV_CTX_DUAL_MAC(ctx) = NULL;
64680Sstevel@tonic-gate (void) dprov_free_context(ctx);
64690Sstevel@tonic-gate }
64700Sstevel@tonic-gate break;
64710Sstevel@tonic-gate }
64720Sstevel@tonic-gate
64730Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_MAC_UPDATE: {
64740Sstevel@tonic-gate crypto_data_t *plaintext_tmp, *ciphertext_tmp;
64750Sstevel@tonic-gate size_t encrypted;
64760Sstevel@tonic-gate ssize_t maclen;
64770Sstevel@tonic-gate boolean_t inplace;
64780Sstevel@tonic-gate
64790Sstevel@tonic-gate cipher_data = *((crypto_data_t *)dual_data);
64800Sstevel@tonic-gate
64810Sstevel@tonic-gate /* do an encrypt update */
64820Sstevel@tonic-gate inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL);
64830Sstevel@tonic-gate if (inplace) {
64840Sstevel@tonic-gate plaintext_tmp = &cipher_data;
64850Sstevel@tonic-gate ciphertext_tmp = NULL;
64860Sstevel@tonic-gate } else {
64870Sstevel@tonic-gate plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data;
64880Sstevel@tonic-gate ciphertext_tmp = &cipher_data;
64890Sstevel@tonic-gate }
64900Sstevel@tonic-gate if ((error = crypto_encrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
64910Sstevel@tonic-gate plaintext_tmp, ciphertext_tmp, NULL)) != CRYPTO_SUCCESS)
64920Sstevel@tonic-gate break;
64930Sstevel@tonic-gate
64940Sstevel@tonic-gate encrypted = cipher_data.cd_length;
64950Sstevel@tonic-gate
64960Sstevel@tonic-gate /*
64970Sstevel@tonic-gate * Do a mac update on the resulting ciphertext, but with no
64980Sstevel@tonic-gate * more bytes than specified by dual_data, and starting at
64990Sstevel@tonic-gate * offset specified by dual_data. For in-place operations,
65000Sstevel@tonic-gate * we use the length specified by the dual_data.
65010Sstevel@tonic-gate * There is an edge case, when the encryption step produced
65020Sstevel@tonic-gate * zero bytes in the ciphertext. Only the portion between
65030Sstevel@tonic-gate * offset2 and offset1 is then thrown in the MAC mix.
65040Sstevel@tonic-gate */
65050Sstevel@tonic-gate maclen = dual_data->dd_offset1 - dual_data->dd_offset2 +
65060Sstevel@tonic-gate encrypted;
65070Sstevel@tonic-gate if (maclen > 0) {
65080Sstevel@tonic-gate mac_data = cipher_data;
65090Sstevel@tonic-gate mac_data.cd_offset = dual_data->dd_offset2;
65100Sstevel@tonic-gate mac_data.cd_length = min(dual_data->dd_len2, maclen);
65110Sstevel@tonic-gate if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
65120Sstevel@tonic-gate &mac_data, NULL)) != CRYPTO_SUCCESS)
65130Sstevel@tonic-gate break;
65140Sstevel@tonic-gate }
65150Sstevel@tonic-gate /* Set the total size of the ciphertext, when successful */
65160Sstevel@tonic-gate if (error == CRYPTO_SUCCESS)
65170Sstevel@tonic-gate dual_data->dd_len1 = encrypted;
65180Sstevel@tonic-gate
65190Sstevel@tonic-gate break;
65200Sstevel@tonic-gate }
65210Sstevel@tonic-gate
65220Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_MAC_FINAL:
65230Sstevel@tonic-gate cipher_data = *((crypto_data_t *)dual_data);
65240Sstevel@tonic-gate
65250Sstevel@tonic-gate /* do an encrypt final */
65260Sstevel@tonic-gate if ((error = crypto_encrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
65270Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_data == NULL ?
65280Sstevel@tonic-gate &cipher_data : taskq_req->dr_cipher_mac_req.mr_data,
65290Sstevel@tonic-gate NULL)) != CRYPTO_SUCCESS)
65300Sstevel@tonic-gate break;
65310Sstevel@tonic-gate
65320Sstevel@tonic-gate /*
65330Sstevel@tonic-gate * If ciphertext length is different from zero, do a mac
65340Sstevel@tonic-gate * update on it. This does not apply to in-place since we
65350Sstevel@tonic-gate * do not allow partial updates, hence no final residual.
65360Sstevel@tonic-gate */
65370Sstevel@tonic-gate if (taskq_req->dr_cipher_mac_req.mr_data != NULL &&
65380Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_data->cd_length > 0)
65390Sstevel@tonic-gate if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
65400Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_data, NULL)) !=
65410Sstevel@tonic-gate CRYPTO_SUCCESS)
65420Sstevel@tonic-gate break;
65430Sstevel@tonic-gate
65440Sstevel@tonic-gate /* do a mac final */
65450Sstevel@tonic-gate error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
65460Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_mac, NULL);
65470Sstevel@tonic-gate
65480Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) {
65490Sstevel@tonic-gate DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
65500Sstevel@tonic-gate DPROV_CTX_DUAL_MAC(ctx) = NULL;
65510Sstevel@tonic-gate (void) dprov_free_context(ctx);
65520Sstevel@tonic-gate }
65530Sstevel@tonic-gate break;
65540Sstevel@tonic-gate
65550Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_MAC_ATOMIC: {
65560Sstevel@tonic-gate crypto_data_t *plaintext_tmp, *ciphertext_tmp;
65570Sstevel@tonic-gate boolean_t inplace;
65580Sstevel@tonic-gate
65590Sstevel@tonic-gate cipher_data = *((crypto_data_t *)dual_data);
65600Sstevel@tonic-gate
65610Sstevel@tonic-gate /* do an encrypt atomic */
65620Sstevel@tonic-gate inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL);
65630Sstevel@tonic-gate if (inplace) {
65640Sstevel@tonic-gate plaintext_tmp = &cipher_data;
65650Sstevel@tonic-gate ciphertext_tmp = NULL;
65660Sstevel@tonic-gate } else {
65670Sstevel@tonic-gate plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data;
65680Sstevel@tonic-gate ciphertext_tmp = &cipher_data;
65690Sstevel@tonic-gate }
65700Sstevel@tonic-gate
65710Sstevel@tonic-gate /* structure assignment */
65720Sstevel@tonic-gate cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech;
65730Sstevel@tonic-gate mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech;
65740Sstevel@tonic-gate session_id = taskq_req->dr_cipher_mac_req.mr_session_id;
65750Sstevel@tonic-gate
65760Sstevel@tonic-gate /* get the keys values and providers to use for operations */
65770Sstevel@tonic-gate if ((error = dprov_cipher_mac_key_pd(softc, session_id,
65780Sstevel@tonic-gate taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd,
65790Sstevel@tonic-gate &cipher_mech.cm_type, &mac_mech.cm_type)) !=
65800Sstevel@tonic-gate CRYPTO_SUCCESS)
65810Sstevel@tonic-gate break;
65820Sstevel@tonic-gate
65830Sstevel@tonic-gate /* do the atomic encrypt */
6584904Smcpowers if ((error = crypto_encrypt_prov(cipher_pd, 0,
65850Sstevel@tonic-gate &cipher_mech, plaintext_tmp, &cipher_key, NULL,
6586904Smcpowers ciphertext_tmp, NULL)) != CRYPTO_SUCCESS)
65870Sstevel@tonic-gate break;
65880Sstevel@tonic-gate
65890Sstevel@tonic-gate /* do the atomic mac */
65900Sstevel@tonic-gate mac_data = cipher_data;
65910Sstevel@tonic-gate mac_data.cd_length = dual_data->dd_len2;
65920Sstevel@tonic-gate mac_data.cd_offset = dual_data->dd_offset2;
6593904Smcpowers error = crypto_mac_prov(mac_pd, 0, &mac_mech, &mac_data,
6594904Smcpowers &mac_key, NULL, taskq_req->dr_cipher_mac_req.mr_mac, NULL);
65950Sstevel@tonic-gate
65960Sstevel@tonic-gate dual_data->dd_len1 = cipher_data.cd_length;
65970Sstevel@tonic-gate
65980Sstevel@tonic-gate break;
65990Sstevel@tonic-gate }
66000Sstevel@tonic-gate
66010Sstevel@tonic-gate case DPROV_REQ_MAC_DECRYPT: {
66020Sstevel@tonic-gate uint_t decrypted;
66030Sstevel@tonic-gate crypto_data_t plaintext_tmp;
66040Sstevel@tonic-gate
66050Sstevel@tonic-gate cipher_data = *((crypto_data_t *)dual_data);
66060Sstevel@tonic-gate
66070Sstevel@tonic-gate /* do a mac update and final on the ciphertext */
66080Sstevel@tonic-gate if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
66090Sstevel@tonic-gate &mac_data, NULL)) != CRYPTO_SUCCESS)
66100Sstevel@tonic-gate break;
66110Sstevel@tonic-gate
66120Sstevel@tonic-gate /* do a mac final */
66130Sstevel@tonic-gate if ((error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
66140Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_mac, NULL)) !=
66150Sstevel@tonic-gate CRYPTO_SUCCESS)
66160Sstevel@tonic-gate break;
66170Sstevel@tonic-gate
66180Sstevel@tonic-gate /* do an decrypt update */
66190Sstevel@tonic-gate cipher_data = mac_data;
66200Sstevel@tonic-gate cipher_data.cd_length = dual_data->dd_len2;
66210Sstevel@tonic-gate cipher_data.cd_offset = dual_data->dd_offset2;
66220Sstevel@tonic-gate if (taskq_req->dr_cipher_mac_req.mr_data == NULL)
66230Sstevel@tonic-gate /* in-place */
66240Sstevel@tonic-gate plaintext_tmp = cipher_data;
66250Sstevel@tonic-gate else
66260Sstevel@tonic-gate plaintext_tmp = *taskq_req->dr_cipher_mac_req.mr_data;
66270Sstevel@tonic-gate
66280Sstevel@tonic-gate if ((error = crypto_decrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
66290Sstevel@tonic-gate &cipher_data, taskq_req->dr_cipher_mac_req.mr_data,
66300Sstevel@tonic-gate NULL)) != CRYPTO_SUCCESS)
66310Sstevel@tonic-gate break;
66320Sstevel@tonic-gate
66330Sstevel@tonic-gate /* do an decrypt final */
66340Sstevel@tonic-gate if (taskq_req->dr_cipher_mac_req.mr_data == NULL)
66350Sstevel@tonic-gate /* in-place, everything must have been decrypted */
66360Sstevel@tonic-gate decrypted = cipher_data.cd_length;
66370Sstevel@tonic-gate else
66380Sstevel@tonic-gate decrypted =
66390Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_data->cd_length;
66400Sstevel@tonic-gate plaintext_tmp.cd_offset += decrypted;
66410Sstevel@tonic-gate plaintext_tmp.cd_length -= decrypted;
66420Sstevel@tonic-gate
66430Sstevel@tonic-gate error = crypto_decrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
66440Sstevel@tonic-gate &plaintext_tmp, NULL);
66450Sstevel@tonic-gate if (taskq_req->dr_cipher_mac_req.mr_data != NULL)
66460Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_data->cd_length +=
66470Sstevel@tonic-gate plaintext_tmp.cd_length;
66480Sstevel@tonic-gate
66490Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) {
66500Sstevel@tonic-gate DPROV_CTX_DUAL_MAC(ctx) = NULL;
66510Sstevel@tonic-gate DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
66520Sstevel@tonic-gate (void) dprov_free_context(ctx);
66530Sstevel@tonic-gate }
66540Sstevel@tonic-gate break;
66550Sstevel@tonic-gate }
66560Sstevel@tonic-gate
66570Sstevel@tonic-gate case DPROV_REQ_MAC_DECRYPT_UPDATE:
66580Sstevel@tonic-gate cipher_data = *((crypto_data_t *)dual_data);
66590Sstevel@tonic-gate
66600Sstevel@tonic-gate /* do mac update */
66610Sstevel@tonic-gate if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
66620Sstevel@tonic-gate &cipher_data, NULL)) != CRYPTO_SUCCESS)
66630Sstevel@tonic-gate break;
66640Sstevel@tonic-gate
66650Sstevel@tonic-gate /* do a decrypt update */
66660Sstevel@tonic-gate cipher_data.cd_length = dual_data->dd_len2;
66670Sstevel@tonic-gate cipher_data.cd_offset = dual_data->dd_offset2;
66680Sstevel@tonic-gate error = crypto_decrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
66690Sstevel@tonic-gate &cipher_data, taskq_req->dr_cipher_mac_req.mr_data, NULL);
66700Sstevel@tonic-gate
66710Sstevel@tonic-gate break;
66720Sstevel@tonic-gate
66730Sstevel@tonic-gate case DPROV_REQ_MAC_DECRYPT_FINAL:
66740Sstevel@tonic-gate /* do a mac final */
66750Sstevel@tonic-gate if ((error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
66760Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_mac, NULL)) !=
66770Sstevel@tonic-gate CRYPTO_SUCCESS)
66780Sstevel@tonic-gate break;
66790Sstevel@tonic-gate
66800Sstevel@tonic-gate /* do a decrypt final */
66810Sstevel@tonic-gate error = crypto_decrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
66820Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_data, NULL);
66830Sstevel@tonic-gate
66840Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) {
66850Sstevel@tonic-gate DPROV_CTX_DUAL_MAC(ctx) = NULL;
66860Sstevel@tonic-gate DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
66870Sstevel@tonic-gate (void) dprov_free_context(ctx);
66880Sstevel@tonic-gate }
66890Sstevel@tonic-gate break;
66900Sstevel@tonic-gate
66910Sstevel@tonic-gate case DPROV_REQ_MAC_DECRYPT_ATOMIC:
66920Sstevel@tonic-gate case DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC:
66930Sstevel@tonic-gate cipher_data = *((crypto_data_t *)dual_data);
66940Sstevel@tonic-gate
66950Sstevel@tonic-gate /* structure assignment */
66960Sstevel@tonic-gate cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech;
66970Sstevel@tonic-gate mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech;
66980Sstevel@tonic-gate session_id = taskq_req->dr_cipher_mac_req.mr_session_id;
66990Sstevel@tonic-gate
67000Sstevel@tonic-gate /* get the keys values and providers to use for operations */
67010Sstevel@tonic-gate if ((error = dprov_cipher_mac_key_pd(softc, session_id,
67020Sstevel@tonic-gate taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd,
67030Sstevel@tonic-gate &cipher_mech.cm_type, &mac_mech.cm_type)) != CRYPTO_SUCCESS)
67040Sstevel@tonic-gate break;
67050Sstevel@tonic-gate
67060Sstevel@tonic-gate /* do the atomic mac */
67070Sstevel@tonic-gate if (taskq_req->dr_type == DPROV_REQ_MAC_DECRYPT_ATOMIC)
6708904Smcpowers error = crypto_mac_prov(mac_pd, 0, &mac_mech,
6709904Smcpowers &cipher_data, &mac_key, NULL,
6710904Smcpowers taskq_req->dr_cipher_mac_req.mr_mac, NULL);
67110Sstevel@tonic-gate else
67120Sstevel@tonic-gate /* DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC */
6713904Smcpowers error = crypto_mac_verify_prov(mac_pd, 0, &mac_mech,
6714904Smcpowers &cipher_data, &mac_key, NULL,
6715904Smcpowers taskq_req->dr_cipher_mac_req.mr_mac, NULL);
67160Sstevel@tonic-gate
67170Sstevel@tonic-gate if (error != CRYPTO_SUCCESS)
67180Sstevel@tonic-gate break;
67190Sstevel@tonic-gate
67200Sstevel@tonic-gate /* do the atomic decrypt */
67210Sstevel@tonic-gate cipher_data.cd_length = dual_data->dd_len2;
67220Sstevel@tonic-gate cipher_data.cd_offset = dual_data->dd_offset2;
6723904Smcpowers error = crypto_decrypt_prov(cipher_pd, 0, &cipher_mech,
6724904Smcpowers &cipher_data, &cipher_key, NULL,
6725904Smcpowers taskq_req->dr_cipher_mac_req.mr_data, NULL);
67260Sstevel@tonic-gate
67270Sstevel@tonic-gate break;
67280Sstevel@tonic-gate }
67290Sstevel@tonic-gate
67300Sstevel@tonic-gate dprov_op_done(taskq_req, error);
67310Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_cipher_mac_task: end\n",
67320Sstevel@tonic-gate instance));
67330Sstevel@tonic-gate }
67340Sstevel@tonic-gate
67350Sstevel@tonic-gate /*
67360Sstevel@tonic-gate * taskq dispatcher function for random number generation.
67370Sstevel@tonic-gate */
67380Sstevel@tonic-gate static void
dprov_random_task(dprov_req_t * taskq_req)67390Sstevel@tonic-gate dprov_random_task(dprov_req_t *taskq_req)
67400Sstevel@tonic-gate {
67410Sstevel@tonic-gate dprov_state_t *softc;
67420Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
67430Sstevel@tonic-gate int instance;
67440Sstevel@tonic-gate int error = CRYPTO_SUCCESS;
67450Sstevel@tonic-gate
67460Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
67470Sstevel@tonic-gate DPROV_DEBUG(D_RANDOM, ("(%d) dprov_random_task: started\n", instance));
67480Sstevel@tonic-gate
67490Sstevel@tonic-gate mutex_enter(&softc->ds_lock);
67500Sstevel@tonic-gate
67510Sstevel@tonic-gate switch (taskq_req->dr_type) {
67520Sstevel@tonic-gate
67530Sstevel@tonic-gate DPROV_REQ_RANDOM_SEED:
67540Sstevel@tonic-gate /*
67550Sstevel@tonic-gate * Since we don't really generate random numbers
67560Sstevel@tonic-gate * nothing to do.
67570Sstevel@tonic-gate */
67580Sstevel@tonic-gate break;
67590Sstevel@tonic-gate
67600Sstevel@tonic-gate case DPROV_REQ_RANDOM_GENERATE: {
67610Sstevel@tonic-gate uint_t i;
67620Sstevel@tonic-gate uchar_t c = 0;
67630Sstevel@tonic-gate
67640Sstevel@tonic-gate /*
67650Sstevel@tonic-gate * We don't generate random numbers so that the result
67660Sstevel@tonic-gate * of the operation can be checked during testing.
67670Sstevel@tonic-gate */
67680Sstevel@tonic-gate
67690Sstevel@tonic-gate for (i = 0; i < taskq_req->dr_random_req.rr_len; i++)
67700Sstevel@tonic-gate taskq_req->dr_random_req.rr_buf[i] = c++;
67710Sstevel@tonic-gate
67720Sstevel@tonic-gate break;
67730Sstevel@tonic-gate }
67740Sstevel@tonic-gate }
67750Sstevel@tonic-gate
67760Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
67770Sstevel@tonic-gate dprov_op_done(taskq_req, error);
67780Sstevel@tonic-gate DPROV_DEBUG(D_RANDOM, ("(%d) dprov_random_task: end\n", instance));
67790Sstevel@tonic-gate }
67800Sstevel@tonic-gate
67810Sstevel@tonic-gate
67820Sstevel@tonic-gate /*
67830Sstevel@tonic-gate * taskq dispatcher function for session management operations.
67840Sstevel@tonic-gate */
67850Sstevel@tonic-gate static void
dprov_session_task(dprov_req_t * taskq_req)67860Sstevel@tonic-gate dprov_session_task(dprov_req_t *taskq_req)
67870Sstevel@tonic-gate {
67880Sstevel@tonic-gate dprov_state_t *softc;
67890Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
67900Sstevel@tonic-gate int instance;
67910Sstevel@tonic-gate int error = CRYPTO_NOT_SUPPORTED;
67920Sstevel@tonic-gate crypto_session_id_t session_id =
67930Sstevel@tonic-gate taskq_req->dr_session_req.sr_session_id;
67940Sstevel@tonic-gate dprov_session_t *session;
67950Sstevel@tonic-gate dprov_object_t *object;
67960Sstevel@tonic-gate int i;
67970Sstevel@tonic-gate
67980Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
67990Sstevel@tonic-gate DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_task: started\n",
68000Sstevel@tonic-gate instance));
68010Sstevel@tonic-gate
68020Sstevel@tonic-gate mutex_enter(&softc->ds_lock);
68030Sstevel@tonic-gate
68040Sstevel@tonic-gate if (taskq_req->dr_type != DPROV_REQ_SESSION_OPEN)
68050Sstevel@tonic-gate /* validate session id and get ptr to session */
68060Sstevel@tonic-gate if ((session = softc->ds_sessions[session_id]) == NULL) {
68070Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
68080Sstevel@tonic-gate dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID);
68090Sstevel@tonic-gate return;
68100Sstevel@tonic-gate }
68110Sstevel@tonic-gate
68120Sstevel@tonic-gate switch (taskq_req->dr_type) {
68130Sstevel@tonic-gate
68140Sstevel@tonic-gate case DPROV_REQ_SESSION_OPEN: {
68150Sstevel@tonic-gate dprov_session_t **new_sessions;
68160Sstevel@tonic-gate
68170Sstevel@tonic-gate if (softc->ds_token_initialized == B_FALSE) {
68180Sstevel@tonic-gate error = CRYPTO_OPERATION_NOT_INITIALIZED;
68190Sstevel@tonic-gate break;
68200Sstevel@tonic-gate }
68210Sstevel@tonic-gate
68220Sstevel@tonic-gate /* search for available session slot */
68230Sstevel@tonic-gate for (i = 0; i < softc->ds_sessions_slots; i++)
68240Sstevel@tonic-gate if (softc->ds_sessions[i] == NULL)
68250Sstevel@tonic-gate break;
68260Sstevel@tonic-gate
68270Sstevel@tonic-gate if (i == softc->ds_sessions_slots) {
68280Sstevel@tonic-gate /* ran out of slots, grow sessions array */
68297357SBhargava.Yenduri@Sun.COM new_sessions = kmem_zalloc(
68307357SBhargava.Yenduri@Sun.COM 2 * softc->ds_sessions_slots *
68317357SBhargava.Yenduri@Sun.COM sizeof (dprov_session_t *), KM_NOSLEEP);
68320Sstevel@tonic-gate if (new_sessions == NULL) {
68330Sstevel@tonic-gate error = CRYPTO_SESSION_COUNT;
68340Sstevel@tonic-gate break;
68350Sstevel@tonic-gate }
68360Sstevel@tonic-gate bcopy(softc->ds_sessions, new_sessions,
68377357SBhargava.Yenduri@Sun.COM softc->ds_sessions_slots *
68387357SBhargava.Yenduri@Sun.COM sizeof (dprov_session_t *));
68390Sstevel@tonic-gate kmem_free(softc->ds_sessions, softc->ds_sessions_slots *
68400Sstevel@tonic-gate sizeof (dprov_session_t *));
68410Sstevel@tonic-gate softc->ds_sessions = new_sessions;
68420Sstevel@tonic-gate softc->ds_sessions_slots *= 2;
68430Sstevel@tonic-gate }
68440Sstevel@tonic-gate
68450Sstevel@tonic-gate /* allocate and initialize new session */
68460Sstevel@tonic-gate softc->ds_sessions[i] = kmem_zalloc(
68470Sstevel@tonic-gate sizeof (dprov_session_t), KM_NOSLEEP);
68480Sstevel@tonic-gate if (softc->ds_sessions[i] == NULL) {
68490Sstevel@tonic-gate error = CRYPTO_HOST_MEMORY;
68500Sstevel@tonic-gate break;
68510Sstevel@tonic-gate }
68520Sstevel@tonic-gate softc->ds_sessions_count++;
68530Sstevel@tonic-gate
68540Sstevel@tonic-gate /* initialize session state */
68550Sstevel@tonic-gate softc->ds_sessions[i]->ds_state = DPROV_SESSION_STATE_PUBLIC;
68560Sstevel@tonic-gate
68570Sstevel@tonic-gate /* return new session id to caller */
68580Sstevel@tonic-gate *(taskq_req->dr_session_req.sr_session_id_ptr) = i;
68590Sstevel@tonic-gate
68600Sstevel@tonic-gate error = CRYPTO_SUCCESS;
68610Sstevel@tonic-gate break;
68620Sstevel@tonic-gate }
68630Sstevel@tonic-gate
68640Sstevel@tonic-gate case DPROV_REQ_SESSION_CLOSE:
68650Sstevel@tonic-gate softc->ds_sessions[session_id] = NULL;
68660Sstevel@tonic-gate
68670Sstevel@tonic-gate if (softc->ds_token_initialized == B_FALSE) {
68680Sstevel@tonic-gate error = CRYPTO_OPERATION_NOT_INITIALIZED;
68690Sstevel@tonic-gate break;
68700Sstevel@tonic-gate }
68710Sstevel@tonic-gate
68720Sstevel@tonic-gate dprov_release_session_objects(session);
68730Sstevel@tonic-gate
68740Sstevel@tonic-gate /* free session state and corresponding slot */
68750Sstevel@tonic-gate kmem_free(session, sizeof (dprov_session_t));
68760Sstevel@tonic-gate softc->ds_sessions_count--;
68770Sstevel@tonic-gate
68780Sstevel@tonic-gate error = CRYPTO_SUCCESS;
68790Sstevel@tonic-gate break;
68800Sstevel@tonic-gate
68810Sstevel@tonic-gate case DPROV_REQ_SESSION_LOGIN: {
68820Sstevel@tonic-gate char *pin = taskq_req->dr_session_req.sr_pin;
68830Sstevel@tonic-gate size_t pin_len = taskq_req->dr_session_req.sr_pin_len;
68840Sstevel@tonic-gate crypto_user_type_t user_type =
68850Sstevel@tonic-gate taskq_req->dr_session_req.sr_user_type;
68860Sstevel@tonic-gate
68870Sstevel@tonic-gate /* check user type */
68880Sstevel@tonic-gate if (user_type != CRYPTO_SO && user_type != CRYPTO_USER) {
68890Sstevel@tonic-gate error = CRYPTO_USER_TYPE_INVALID;
68900Sstevel@tonic-gate break;
68910Sstevel@tonic-gate }
68920Sstevel@tonic-gate
68930Sstevel@tonic-gate /* check pin length */
68940Sstevel@tonic-gate if (pin_len > DPROV_MAX_PIN_LEN) {
68950Sstevel@tonic-gate error = CRYPTO_PIN_LEN_RANGE;
68960Sstevel@tonic-gate break;
68970Sstevel@tonic-gate }
68980Sstevel@tonic-gate
68990Sstevel@tonic-gate /* check pin */
69000Sstevel@tonic-gate if (pin == NULL) {
69010Sstevel@tonic-gate error = CRYPTO_PIN_INVALID;
69020Sstevel@tonic-gate break;
69030Sstevel@tonic-gate }
69040Sstevel@tonic-gate
69050Sstevel@tonic-gate /* validate PIN state */
69060Sstevel@tonic-gate if ((user_type == CRYPTO_SO) && !softc->ds_token_initialized ||
69070Sstevel@tonic-gate (user_type == CRYPTO_USER) && !softc->ds_user_pin_set) {
69080Sstevel@tonic-gate error = CRYPTO_USER_PIN_NOT_INITIALIZED;
69090Sstevel@tonic-gate break;
69100Sstevel@tonic-gate }
69110Sstevel@tonic-gate
69120Sstevel@tonic-gate if ((user_type == CRYPTO_SO &&
69130Sstevel@tonic-gate softc->ds_sessions[session_id]->ds_state ==
69140Sstevel@tonic-gate DPROV_SESSION_STATE_SO) ||
69150Sstevel@tonic-gate (user_type == CRYPTO_USER &&
69160Sstevel@tonic-gate softc->ds_sessions[session_id]->ds_state ==
69170Sstevel@tonic-gate DPROV_SESSION_STATE_USER)) {
69180Sstevel@tonic-gate /* SO or user already logged in */
69190Sstevel@tonic-gate error = CRYPTO_USER_ALREADY_LOGGED_IN;
69200Sstevel@tonic-gate break;
69210Sstevel@tonic-gate }
69220Sstevel@tonic-gate
69230Sstevel@tonic-gate if (softc->ds_sessions[session_id]->ds_state !=
69240Sstevel@tonic-gate DPROV_SESSION_STATE_PUBLIC) {
69250Sstevel@tonic-gate /* another user already logged in */
69260Sstevel@tonic-gate error = CRYPTO_USER_ANOTHER_ALREADY_LOGGED_IN;
69270Sstevel@tonic-gate break;
69280Sstevel@tonic-gate }
69290Sstevel@tonic-gate
69300Sstevel@tonic-gate /* everything's fine, update session */
69310Sstevel@tonic-gate softc->ds_sessions[session_id]->ds_state =
69320Sstevel@tonic-gate user_type == CRYPTO_SO ?
69330Sstevel@tonic-gate DPROV_SESSION_STATE_SO : DPROV_SESSION_STATE_USER;
69340Sstevel@tonic-gate
69350Sstevel@tonic-gate error = CRYPTO_SUCCESS;
69360Sstevel@tonic-gate break;
69370Sstevel@tonic-gate }
69380Sstevel@tonic-gate
69390Sstevel@tonic-gate case DPROV_REQ_SESSION_LOGOUT:
69400Sstevel@tonic-gate /* fail if not logged in */
69410Sstevel@tonic-gate if (softc->ds_sessions[session_id]->ds_state ==
69420Sstevel@tonic-gate DPROV_SESSION_STATE_PUBLIC) {
69430Sstevel@tonic-gate error = CRYPTO_USER_NOT_LOGGED_IN;
69440Sstevel@tonic-gate break;
69450Sstevel@tonic-gate }
69460Sstevel@tonic-gate
69470Sstevel@tonic-gate /*
69480Sstevel@tonic-gate * Destroy all private session objects.
69490Sstevel@tonic-gate * Invalidate handles to all private objects.
69500Sstevel@tonic-gate */
69510Sstevel@tonic-gate for (i = 0; i < DPROV_MAX_OBJECTS; i++) {
69520Sstevel@tonic-gate object = softc->ds_sessions[session_id]->ds_objects[i];
69530Sstevel@tonic-gate if (object != NULL && dprov_object_is_private(object)) {
69540Sstevel@tonic-gate if (!dprov_object_is_token(object))
69550Sstevel@tonic-gate /* It's a session object, free it */
69560Sstevel@tonic-gate DPROV_OBJECT_REFRELE(object);
69570Sstevel@tonic-gate softc->ds_sessions[session_id]->ds_objects[i] =
69580Sstevel@tonic-gate NULL;
69590Sstevel@tonic-gate }
69600Sstevel@tonic-gate }
69610Sstevel@tonic-gate
69620Sstevel@tonic-gate /* update session state */
69630Sstevel@tonic-gate softc->ds_sessions[session_id]->ds_state =
69640Sstevel@tonic-gate DPROV_SESSION_STATE_PUBLIC;
69650Sstevel@tonic-gate
69660Sstevel@tonic-gate error = CRYPTO_SUCCESS;
69670Sstevel@tonic-gate break;
69680Sstevel@tonic-gate }
69690Sstevel@tonic-gate
69700Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
69710Sstevel@tonic-gate dprov_op_done(taskq_req, error);
69720Sstevel@tonic-gate DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_task: end\n", instance));
69730Sstevel@tonic-gate }
69740Sstevel@tonic-gate
6975904Smcpowers /* return true if attribute is defined to be a PKCS#11 long */
6976904Smcpowers static boolean_t
fixed_size_attribute(crypto_attr_type_t type)6977904Smcpowers fixed_size_attribute(crypto_attr_type_t type)
6978904Smcpowers {
6979904Smcpowers return (type == DPROV_CKA_CLASS ||
6980904Smcpowers type == DPROV_CKA_CERTIFICATE_TYPE ||
6981904Smcpowers type == DPROV_CKA_KEY_TYPE ||
6982904Smcpowers type == DPROV_HW_FEATURE_TYPE);
6983904Smcpowers }
6984904Smcpowers
6985904Smcpowers /*
6986904Smcpowers * Attributes defined to be a PKCS#11 long causes problems for dprov
6987904Smcpowers * because 32-bit applications set the size to 4 and 64-bit applications
6988904Smcpowers * set the size to 8. dprov always stores these fixed-size attributes
6989904Smcpowers * as uint32_t.
6990904Smcpowers */
6991904Smcpowers static ssize_t
attribute_size(crypto_attr_type_t type,ssize_t len)6992904Smcpowers attribute_size(crypto_attr_type_t type, ssize_t len)
6993904Smcpowers {
6994904Smcpowers if (fixed_size_attribute(type))
6995904Smcpowers return (sizeof (uint32_t));
6996904Smcpowers
6997904Smcpowers return (len);
6998904Smcpowers }
6999904Smcpowers
70000Sstevel@tonic-gate /*
70010Sstevel@tonic-gate * taskq dispatcher function for object management operations.
70020Sstevel@tonic-gate */
70030Sstevel@tonic-gate static void
dprov_object_task(dprov_req_t * taskq_req)70040Sstevel@tonic-gate dprov_object_task(dprov_req_t *taskq_req)
70050Sstevel@tonic-gate {
70060Sstevel@tonic-gate dprov_state_t *softc;
70070Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
70080Sstevel@tonic-gate int instance;
70090Sstevel@tonic-gate int error = CRYPTO_NOT_SUPPORTED;
70100Sstevel@tonic-gate crypto_object_id_t object_id = taskq_req->dr_object_req.or_object_id;
70110Sstevel@tonic-gate crypto_session_id_t session_id = taskq_req->dr_object_req.or_session_id;
70120Sstevel@tonic-gate crypto_object_attribute_t *template =
70130Sstevel@tonic-gate taskq_req->dr_object_req.or_template;
70140Sstevel@tonic-gate uint_t attr_count = taskq_req->dr_object_req.or_attribute_count;
70150Sstevel@tonic-gate dprov_object_t *object;
70160Sstevel@tonic-gate dprov_session_t *session;
70170Sstevel@tonic-gate
70180Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
70190Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_task: started\n", instance));
70200Sstevel@tonic-gate
70210Sstevel@tonic-gate mutex_enter(&softc->ds_lock);
70220Sstevel@tonic-gate
70230Sstevel@tonic-gate /* validate session id and get ptr to session */
70240Sstevel@tonic-gate if ((session = softc->ds_sessions[session_id]) == NULL) {
70250Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
70260Sstevel@tonic-gate dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID);
70270Sstevel@tonic-gate return;
70280Sstevel@tonic-gate }
70290Sstevel@tonic-gate
70300Sstevel@tonic-gate switch (taskq_req->dr_type) {
70310Sstevel@tonic-gate
70320Sstevel@tonic-gate case DPROV_REQ_OBJECT_CREATE:
70330Sstevel@tonic-gate /* create the object from the specified template */
70340Sstevel@tonic-gate if ((error = dprov_create_object_from_template(softc, session,
70350Sstevel@tonic-gate template, attr_count,
70360Sstevel@tonic-gate taskq_req->dr_object_req.or_object_id_ptr, B_TRUE,
70370Sstevel@tonic-gate B_FALSE)) != CRYPTO_SUCCESS)
70380Sstevel@tonic-gate break;
70390Sstevel@tonic-gate
70400Sstevel@tonic-gate break;
70410Sstevel@tonic-gate
70420Sstevel@tonic-gate case DPROV_REQ_OBJECT_COPY:
70430Sstevel@tonic-gate /* check object id */
70440Sstevel@tonic-gate if (object_id >= DPROV_MAX_OBJECTS ||
70450Sstevel@tonic-gate (object = session->ds_objects[object_id]) == NULL) {
70460Sstevel@tonic-gate error = CRYPTO_OBJECT_HANDLE_INVALID;
70470Sstevel@tonic-gate break;
70480Sstevel@tonic-gate }
70490Sstevel@tonic-gate
70500Sstevel@tonic-gate /*
70510Sstevel@tonic-gate * Create a new object from the object passed as
70520Sstevel@tonic-gate * argument.
70530Sstevel@tonic-gate */
70540Sstevel@tonic-gate if ((error = dprov_create_object_from_template(softc, session,
70550Sstevel@tonic-gate object->do_attr, DPROV_MAX_ATTR,
70560Sstevel@tonic-gate taskq_req->dr_object_req.or_object_id_ptr, B_TRUE,
70570Sstevel@tonic-gate B_FALSE)) != CRYPTO_SUCCESS)
70580Sstevel@tonic-gate break;
70590Sstevel@tonic-gate
70600Sstevel@tonic-gate /*
70610Sstevel@tonic-gate * Add the attributes specified by the template to the
70620Sstevel@tonic-gate * newly created object, replacing existing ones if needed.
70630Sstevel@tonic-gate */
70640Sstevel@tonic-gate error = dprov_object_set_attr(session,
70650Sstevel@tonic-gate *taskq_req->dr_object_req.or_object_id_ptr,
70660Sstevel@tonic-gate taskq_req->dr_object_req.or_template,
70670Sstevel@tonic-gate taskq_req->dr_object_req.or_attribute_count, B_TRUE);
70680Sstevel@tonic-gate
70690Sstevel@tonic-gate break;
70700Sstevel@tonic-gate
70710Sstevel@tonic-gate case DPROV_REQ_OBJECT_DESTROY:
70720Sstevel@tonic-gate /* destroy the object */
70730Sstevel@tonic-gate error = dprov_destroy_object(softc, session,
70740Sstevel@tonic-gate taskq_req->dr_object_req.or_object_id);
70750Sstevel@tonic-gate
70760Sstevel@tonic-gate break;
70770Sstevel@tonic-gate
70780Sstevel@tonic-gate case DPROV_REQ_OBJECT_GET_SIZE:
70790Sstevel@tonic-gate /* get ptr to object */
70800Sstevel@tonic-gate if (object_id >= DPROV_MAX_OBJECTS ||
70810Sstevel@tonic-gate session->ds_objects[object_id] == NULL) {
70820Sstevel@tonic-gate error = CRYPTO_OBJECT_HANDLE_INVALID;
70830Sstevel@tonic-gate break;
70840Sstevel@tonic-gate }
70850Sstevel@tonic-gate
70860Sstevel@tonic-gate /*
70870Sstevel@tonic-gate * The PKCS11 specification does not specifies what
70880Sstevel@tonic-gate * the object size really is, here we just return
70890Sstevel@tonic-gate * the number of possible attributes of the object.
70900Sstevel@tonic-gate */
70910Sstevel@tonic-gate *taskq_req->dr_object_req.or_object_size = DPROV_MAX_ATTR;
70920Sstevel@tonic-gate
70930Sstevel@tonic-gate error = CRYPTO_SUCCESS;
70940Sstevel@tonic-gate break;
70950Sstevel@tonic-gate
70960Sstevel@tonic-gate case DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE: {
7097904Smcpowers crypto_attr_type_t type;
7098904Smcpowers size_t olen, tlen;
7099904Smcpowers offset_t offset;
71000Sstevel@tonic-gate int tmpl_idx;
71010Sstevel@tonic-gate int object_idx;
71020Sstevel@tonic-gate ulong_t class = DPROV_CKO_DATA;
71030Sstevel@tonic-gate boolean_t extractable = B_TRUE;
71040Sstevel@tonic-gate
71050Sstevel@tonic-gate error = CRYPTO_SUCCESS;
71060Sstevel@tonic-gate
71070Sstevel@tonic-gate /* get ptr to object */
71080Sstevel@tonic-gate if (object_id >= DPROV_MAX_OBJECTS ||
71090Sstevel@tonic-gate (object = session->ds_objects[object_id]) == NULL) {
71100Sstevel@tonic-gate error = CRYPTO_OBJECT_HANDLE_INVALID;
71110Sstevel@tonic-gate break;
71120Sstevel@tonic-gate }
71130Sstevel@tonic-gate
71140Sstevel@tonic-gate (void) dprov_get_object_attr_boolean(object,
71150Sstevel@tonic-gate DPROV_CKA_EXTRACTABLE, &extractable);
71160Sstevel@tonic-gate
71170Sstevel@tonic-gate (void) dprov_get_object_attr_ulong(object,
71180Sstevel@tonic-gate DPROV_CKA_CLASS, &class);
71190Sstevel@tonic-gate
71200Sstevel@tonic-gate /* return the specified attributes, when possible */
71210Sstevel@tonic-gate for (tmpl_idx = 0; tmpl_idx < attr_count; tmpl_idx++) {
71220Sstevel@tonic-gate /*
71230Sstevel@tonic-gate * Attribute can't be revealed if the CKA_EXTRACTABLE
71240Sstevel@tonic-gate * attribute is set to false.
71250Sstevel@tonic-gate */
7126904Smcpowers type = template[tmpl_idx].oa_type;
71270Sstevel@tonic-gate if (!extractable && class == DPROV_CKO_SECRET_KEY) {
7128904Smcpowers if (type == DPROV_CKA_VALUE) {
71290Sstevel@tonic-gate template[tmpl_idx].oa_value_len = -1;
71300Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_SENSITIVE;
71310Sstevel@tonic-gate continue;
71320Sstevel@tonic-gate }
71330Sstevel@tonic-gate }
71340Sstevel@tonic-gate if (!extractable && class == DPROV_CKO_PRIVATE_KEY) {
7135904Smcpowers if (type == DPROV_CKA_PRIVATE_EXPONENT) {
71360Sstevel@tonic-gate template[tmpl_idx].oa_value_len = -1;
71370Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_SENSITIVE;
71380Sstevel@tonic-gate continue;
71390Sstevel@tonic-gate }
71400Sstevel@tonic-gate }
71410Sstevel@tonic-gate
71420Sstevel@tonic-gate object_idx = dprov_find_attr(object->do_attr,
7143904Smcpowers DPROV_MAX_ATTR, type);
71440Sstevel@tonic-gate if (object_idx == -1) {
71450Sstevel@tonic-gate /* attribute not found in object */
71460Sstevel@tonic-gate template[tmpl_idx].oa_value_len = -1;
71470Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_TYPE_INVALID;
71480Sstevel@tonic-gate continue;
71490Sstevel@tonic-gate }
71500Sstevel@tonic-gate
7151904Smcpowers tlen = template[tmpl_idx].oa_value_len;
7152904Smcpowers olen = object->do_attr[object_idx].oa_value_len;
7153904Smcpowers /* return attribute length */
71540Sstevel@tonic-gate if (template[tmpl_idx].oa_value == NULL) {
7155904Smcpowers /*
7156904Smcpowers * The size of the attribute is set by the
7157904Smcpowers * library according to the data model of the
7158904Smcpowers * application, so don't overwrite it with
7159904Smcpowers * dprov's size.
7160904Smcpowers */
7161904Smcpowers if (!fixed_size_attribute(type))
7162904Smcpowers template[tmpl_idx].oa_value_len = olen;
71630Sstevel@tonic-gate continue;
71640Sstevel@tonic-gate }
7165904Smcpowers
7166904Smcpowers if (tlen < olen) {
71670Sstevel@tonic-gate template[tmpl_idx].oa_value_len = -1;
71680Sstevel@tonic-gate error = CRYPTO_BUFFER_TOO_SMALL;
71690Sstevel@tonic-gate continue;
71700Sstevel@tonic-gate }
7171904Smcpowers
7172904Smcpowers /* copy attribute value */
7173904Smcpowers bzero(template[tmpl_idx].oa_value, tlen);
7174904Smcpowers
7175904Smcpowers offset = 0;
7176904Smcpowers #ifdef _BIG_ENDIAN
7177904Smcpowers if (fixed_size_attribute(type)) {
7178904Smcpowers offset = tlen - olen;
7179904Smcpowers }
7180904Smcpowers #endif
71810Sstevel@tonic-gate bcopy(object->do_attr[object_idx].oa_value,
7182904Smcpowers &template[tmpl_idx].oa_value[offset], olen);
7183904Smcpowers
7184904Smcpowers /* don't update length for fixed-size attributes */
7185904Smcpowers if (!fixed_size_attribute(type))
7186904Smcpowers template[tmpl_idx].oa_value_len = olen;
71870Sstevel@tonic-gate }
71880Sstevel@tonic-gate
71890Sstevel@tonic-gate break;
71900Sstevel@tonic-gate }
71910Sstevel@tonic-gate
71920Sstevel@tonic-gate case DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE:
71930Sstevel@tonic-gate /*
71940Sstevel@tonic-gate * Add the attributes specified by the template to the
71950Sstevel@tonic-gate * newly created object, replacing existing ones if needed.
71960Sstevel@tonic-gate */
71970Sstevel@tonic-gate error = dprov_object_set_attr(session,
71980Sstevel@tonic-gate taskq_req->dr_object_req.or_object_id,
71990Sstevel@tonic-gate taskq_req->dr_object_req.or_template,
72000Sstevel@tonic-gate taskq_req->dr_object_req.or_attribute_count, B_TRUE);
72010Sstevel@tonic-gate
72020Sstevel@tonic-gate break;
72030Sstevel@tonic-gate
72040Sstevel@tonic-gate case DPROV_REQ_OBJECT_FIND_INIT: {
72050Sstevel@tonic-gate dprov_find_ctx_t *find_ctx;
72060Sstevel@tonic-gate int so_idx; /* session object index */
72070Sstevel@tonic-gate int to_idx; /* token object index */
72080Sstevel@tonic-gate
72090Sstevel@tonic-gate error = CRYPTO_SUCCESS;
72100Sstevel@tonic-gate /* allocate find context */
72110Sstevel@tonic-gate find_ctx = kmem_zalloc(sizeof (dprov_find_ctx_t), KM_SLEEP);
72120Sstevel@tonic-gate *taskq_req->dr_object_req.or_find_pp = find_ctx;
72130Sstevel@tonic-gate
72140Sstevel@tonic-gate /* first go through the existing session objects */
72150Sstevel@tonic-gate for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++) {
72160Sstevel@tonic-gate if ((object = session->ds_objects[so_idx]) == NULL)
72170Sstevel@tonic-gate continue;
72180Sstevel@tonic-gate
72190Sstevel@tonic-gate /* setting count to zero means find all objects */
72200Sstevel@tonic-gate if (attr_count > 0) {
72210Sstevel@tonic-gate if (!dprov_attributes_match(object, template,
72220Sstevel@tonic-gate attr_count))
72230Sstevel@tonic-gate continue;
72240Sstevel@tonic-gate }
72250Sstevel@tonic-gate
72260Sstevel@tonic-gate /* session object attributes matches template */
72270Sstevel@tonic-gate find_ctx->fc_ids[find_ctx->fc_nids] = so_idx;
72280Sstevel@tonic-gate find_ctx->fc_nids++;
72290Sstevel@tonic-gate }
72300Sstevel@tonic-gate
72310Sstevel@tonic-gate /*
72320Sstevel@tonic-gate * Go through the token object. For each token object
72330Sstevel@tonic-gate * that can be accessed:
72340Sstevel@tonic-gate * If there was already an session object id assigned
72350Sstevel@tonic-gate * to that token object, skip it, since it was returned
72360Sstevel@tonic-gate * during the check of session objects, else,
72370Sstevel@tonic-gate * assign a new object id for that token object and
72380Sstevel@tonic-gate * add it to the array of matching objects.
72390Sstevel@tonic-gate */
72400Sstevel@tonic-gate for (to_idx = 0; to_idx < DPROV_MAX_OBJECTS &&
72410Sstevel@tonic-gate error == CRYPTO_SUCCESS; to_idx++) {
72420Sstevel@tonic-gate if ((object = softc->ds_objects[to_idx]) == NULL)
72430Sstevel@tonic-gate continue;
72440Sstevel@tonic-gate
72450Sstevel@tonic-gate /* setting count to zero means find all objects */
72460Sstevel@tonic-gate if (attr_count > 0) {
72470Sstevel@tonic-gate if (!dprov_attributes_match(object, template,
72480Sstevel@tonic-gate attr_count))
72490Sstevel@tonic-gate continue;
72500Sstevel@tonic-gate }
72510Sstevel@tonic-gate
72520Sstevel@tonic-gate /* if the the object has been destroyed, skip it */
72530Sstevel@tonic-gate if (object->do_destroyed)
72540Sstevel@tonic-gate continue;
72550Sstevel@tonic-gate
72560Sstevel@tonic-gate /* skip object if it cannot be accessed from session */
72570Sstevel@tonic-gate if (dprov_object_is_private(object) &&
72580Sstevel@tonic-gate session->ds_state != DPROV_SESSION_STATE_USER)
72590Sstevel@tonic-gate continue;
72600Sstevel@tonic-gate
72610Sstevel@tonic-gate /*
72620Sstevel@tonic-gate * Is there already a session object id for this
72630Sstevel@tonic-gate * token object?
72640Sstevel@tonic-gate */
72650Sstevel@tonic-gate for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++)
72660Sstevel@tonic-gate if (session->ds_objects[so_idx] != NULL &&
72670Sstevel@tonic-gate session->ds_objects[so_idx]->do_token_idx ==
72680Sstevel@tonic-gate to_idx)
72690Sstevel@tonic-gate break;
72700Sstevel@tonic-gate if (so_idx < DPROV_MAX_OBJECTS)
72710Sstevel@tonic-gate /* object found in session table, skip it */
72720Sstevel@tonic-gate continue;
72730Sstevel@tonic-gate
72740Sstevel@tonic-gate /* find free session slot for this object */
72750Sstevel@tonic-gate for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++)
72760Sstevel@tonic-gate if (session->ds_objects[so_idx] == NULL)
72770Sstevel@tonic-gate break;
72780Sstevel@tonic-gate if (so_idx == DPROV_MAX_OBJECTS) {
72790Sstevel@tonic-gate /* ran out of session objects slots */
72800Sstevel@tonic-gate kmem_free(find_ctx, sizeof (dprov_find_ctx_t));
72810Sstevel@tonic-gate error = CRYPTO_HOST_MEMORY;
72820Sstevel@tonic-gate break;
72830Sstevel@tonic-gate }
72840Sstevel@tonic-gate
72850Sstevel@tonic-gate /* add object to session objects table */
72860Sstevel@tonic-gate session->ds_objects[so_idx] = object;
72870Sstevel@tonic-gate DPROV_OBJECT_REFHOLD(object);
72880Sstevel@tonic-gate
72890Sstevel@tonic-gate /* add object to list of objects to return */
72900Sstevel@tonic-gate find_ctx->fc_ids[find_ctx->fc_nids] = so_idx;
72910Sstevel@tonic-gate find_ctx->fc_nids++;
72920Sstevel@tonic-gate }
72930Sstevel@tonic-gate
72940Sstevel@tonic-gate break;
72950Sstevel@tonic-gate }
72960Sstevel@tonic-gate
72970Sstevel@tonic-gate case DPROV_REQ_OBJECT_FIND: {
72980Sstevel@tonic-gate crypto_object_id_t *object_ids =
72994424Sizick taskq_req->dr_object_req.or_object_id_ptr;
73000Sstevel@tonic-gate uint_t max_object_count =
73014424Sizick taskq_req->dr_object_req.or_max_object_count;
73020Sstevel@tonic-gate dprov_find_ctx_t *find_ctx =
73034424Sizick taskq_req->dr_object_req.or_find_p;
73040Sstevel@tonic-gate uint_t ret_oid_idx;
73050Sstevel@tonic-gate
73060Sstevel@tonic-gate /* return the desired number of object ids */
73070Sstevel@tonic-gate for (ret_oid_idx = 0; ret_oid_idx < max_object_count &&
73080Sstevel@tonic-gate find_ctx->fc_next < find_ctx->fc_nids; ret_oid_idx++)
73090Sstevel@tonic-gate object_ids[ret_oid_idx] =
73100Sstevel@tonic-gate find_ctx->fc_ids[find_ctx->fc_next++];
73110Sstevel@tonic-gate
73120Sstevel@tonic-gate *taskq_req->dr_object_req.or_object_count_ptr = ret_oid_idx;
73130Sstevel@tonic-gate
73140Sstevel@tonic-gate error = CRYPTO_SUCCESS;
73150Sstevel@tonic-gate break;
73160Sstevel@tonic-gate }
73170Sstevel@tonic-gate
73180Sstevel@tonic-gate case DPROV_REQ_OBJECT_FIND_FINAL:
73190Sstevel@tonic-gate kmem_free(taskq_req->dr_object_req.or_find_p,
73200Sstevel@tonic-gate sizeof (dprov_find_ctx_t));
73210Sstevel@tonic-gate
73220Sstevel@tonic-gate error = CRYPTO_SUCCESS;
73230Sstevel@tonic-gate break;
73240Sstevel@tonic-gate }
73250Sstevel@tonic-gate
73260Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
73270Sstevel@tonic-gate dprov_op_done(taskq_req, error);
73280Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_task: end\n", instance));
73290Sstevel@tonic-gate }
73300Sstevel@tonic-gate
73310Sstevel@tonic-gate /*
73324424Sizick * Copy attribute values into a template. RSA values are precomputed.
73334424Sizick */
73344424Sizick static int
nostore_copy_attribute(crypto_object_attribute_t * template,uint_t count,uint64_t attr_type)73354424Sizick nostore_copy_attribute(crypto_object_attribute_t *template, uint_t count,
73364424Sizick uint64_t attr_type)
73374424Sizick {
73384424Sizick void *value, *dprov_attribute_value;
73394424Sizick size_t dprov_attribute_size;
73404424Sizick size_t value_len = 0;
73414424Sizick int error;
73424424Sizick
73434424Sizick switch (attr_type) {
73444424Sizick case DPROV_CKA_VALUE:
73454424Sizick dprov_attribute_size = sizeof (dh_value);
73464424Sizick dprov_attribute_value = dh_value;
73474424Sizick break;
73484424Sizick
73494424Sizick case DPROV_CKA_MODULUS:
73504424Sizick dprov_attribute_size = sizeof (modulus);
73514424Sizick dprov_attribute_value = modulus;
73524424Sizick break;
73534424Sizick
73544424Sizick case DPROV_CKA_PUBLIC_EXPONENT:
73554424Sizick dprov_attribute_size = sizeof (public_exponent);
73564424Sizick dprov_attribute_value = public_exponent;
73574424Sizick break;
73584424Sizick
73594424Sizick case DPROV_CKA_PRIVATE_EXPONENT:
73604424Sizick dprov_attribute_size = sizeof (private_exponent);
73614424Sizick dprov_attribute_value = private_exponent;
73624424Sizick break;
73634424Sizick
73644424Sizick default:
73654424Sizick return (CRYPTO_ATTRIBUTE_TYPE_INVALID);
73664424Sizick }
73674424Sizick
73684424Sizick error = dprov_get_template_attr_array(template, count, attr_type,
73694424Sizick &value, &value_len);
73704424Sizick if (error != CRYPTO_SUCCESS)
73714424Sizick return (error);
73724424Sizick
73734424Sizick if (value_len < dprov_attribute_size)
73744424Sizick return (CRYPTO_BUFFER_TOO_SMALL);
73754424Sizick
73764424Sizick /*
73774424Sizick * The updated template will be returned to libpkcs11.
73784424Sizick */
73794424Sizick bcopy(dprov_attribute_value, value, dprov_attribute_size);
73804424Sizick
73814424Sizick return (CRYPTO_SUCCESS);
73824424Sizick }
73834424Sizick
73844424Sizick static void
fill_dh(void * value,size_t len)73854424Sizick fill_dh(void *value, size_t len)
73864424Sizick {
73874424Sizick int i = 0;
73884424Sizick char *p = value;
73894424Sizick while (i < len) {
73904424Sizick p[i++] = 'D';
73914424Sizick if (i >= len)
73924424Sizick break;
73934424Sizick p[i++] = 'H';
73944424Sizick }
73954424Sizick }
73964424Sizick
73974424Sizick /*
73980Sstevel@tonic-gate * taskq dispatcher function for key management operations.
73990Sstevel@tonic-gate */
74000Sstevel@tonic-gate static void
dprov_key_task(dprov_req_t * taskq_req)74010Sstevel@tonic-gate dprov_key_task(dprov_req_t *taskq_req)
74020Sstevel@tonic-gate {
74030Sstevel@tonic-gate dprov_state_t *softc;
74040Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
74050Sstevel@tonic-gate int instance;
74060Sstevel@tonic-gate int error = CRYPTO_NOT_SUPPORTED;
74070Sstevel@tonic-gate kcf_provider_desc_t *pd;
74080Sstevel@tonic-gate crypto_session_id_t session_id = taskq_req->dr_key_req.kr_session_id;
74090Sstevel@tonic-gate dprov_session_t *session;
74100Sstevel@tonic-gate
74110Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
74120Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_task: started\n", instance));
74130Sstevel@tonic-gate
74140Sstevel@tonic-gate mutex_enter(&softc->ds_lock);
74150Sstevel@tonic-gate
74160Sstevel@tonic-gate /* validate session id and get ptr to session */
74170Sstevel@tonic-gate if ((session = softc->ds_sessions[session_id]) == NULL) {
74180Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
74190Sstevel@tonic-gate dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID);
74200Sstevel@tonic-gate return;
74210Sstevel@tonic-gate }
74220Sstevel@tonic-gate
74230Sstevel@tonic-gate switch (taskq_req->dr_type) {
74240Sstevel@tonic-gate case DPROV_REQ_KEY_GENERATE: {
74250Sstevel@tonic-gate crypto_mechanism_t *mechp;
74260Sstevel@tonic-gate crypto_object_id_t *object_id_ptr;
74270Sstevel@tonic-gate crypto_object_attribute_t *template;
74280Sstevel@tonic-gate crypto_object_attribute_t attribute;
74290Sstevel@tonic-gate uint_t attribute_count;
74300Sstevel@tonic-gate ulong_t key_type = ~0UL, class = ~0UL;
74310Sstevel@tonic-gate ulong_t value_len;
74320Sstevel@tonic-gate size_t key_len = 0;
74330Sstevel@tonic-gate
74340Sstevel@tonic-gate error = CRYPTO_SUCCESS;
74350Sstevel@tonic-gate
74360Sstevel@tonic-gate template = taskq_req->dr_key_req.kr_template;
74370Sstevel@tonic-gate attribute_count = taskq_req->dr_key_req.kr_attribute_count;
74380Sstevel@tonic-gate object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr;
74390Sstevel@tonic-gate mechp = taskq_req->dr_key_req.kr_mechanism;
74400Sstevel@tonic-gate
74410Sstevel@tonic-gate /* optional */
74420Sstevel@tonic-gate (void) dprov_get_template_attr_ulong(template, attribute_count,
74430Sstevel@tonic-gate DPROV_CKA_CLASS, &class);
74440Sstevel@tonic-gate
74450Sstevel@tonic-gate /* optional */
74460Sstevel@tonic-gate (void) dprov_get_template_attr_ulong(template, attribute_count,
74470Sstevel@tonic-gate DPROV_CKA_KEY_TYPE, &key_type);
74480Sstevel@tonic-gate
74490Sstevel@tonic-gate if (class != ~0UL && class != DPROV_CKO_SECRET_KEY) {
74500Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT;
74510Sstevel@tonic-gate break;
74520Sstevel@tonic-gate }
74530Sstevel@tonic-gate
74540Sstevel@tonic-gate switch (mechp->cm_type) {
74550Sstevel@tonic-gate case DES_KEY_GEN_MECH_INFO_TYPE:
74560Sstevel@tonic-gate if (key_type != ~0UL && key_type != DPROV_CKK_DES) {
74570Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT;
74580Sstevel@tonic-gate break;
74590Sstevel@tonic-gate }
74600Sstevel@tonic-gate key_len = DES_KEY_LEN;
74610Sstevel@tonic-gate key_type = DPROV_CKK_DES;
74620Sstevel@tonic-gate break;
74630Sstevel@tonic-gate
74640Sstevel@tonic-gate case DES3_KEY_GEN_MECH_INFO_TYPE:
74650Sstevel@tonic-gate if (key_type != ~0UL && key_type != DPROV_CKK_DES3) {
74660Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT;
74670Sstevel@tonic-gate break;
74680Sstevel@tonic-gate }
74690Sstevel@tonic-gate key_len = DES3_KEY_LEN;
74700Sstevel@tonic-gate key_type = DPROV_CKK_DES3;
74710Sstevel@tonic-gate break;
74720Sstevel@tonic-gate
74730Sstevel@tonic-gate case AES_KEY_GEN_MECH_INFO_TYPE:
74740Sstevel@tonic-gate if (key_type != ~0UL && key_type != DPROV_CKK_AES) {
74750Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT;
74760Sstevel@tonic-gate break;
74770Sstevel@tonic-gate }
74780Sstevel@tonic-gate if (dprov_get_template_attr_ulong(template,
74790Sstevel@tonic-gate attribute_count, DPROV_CKA_VALUE_LEN,
74800Sstevel@tonic-gate &value_len) != CRYPTO_SUCCESS) {
74810Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCOMPLETE;
74820Sstevel@tonic-gate break;
74830Sstevel@tonic-gate }
74840Sstevel@tonic-gate if (value_len >= AES_MAX_KEY_LEN) {
74850Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
74860Sstevel@tonic-gate break;
74870Sstevel@tonic-gate }
74880Sstevel@tonic-gate key_len = value_len;
74890Sstevel@tonic-gate key_type = DPROV_CKK_AES;
74900Sstevel@tonic-gate break;
74910Sstevel@tonic-gate
7492676Sizick case BLOWFISH_KEY_GEN_MECH_INFO_TYPE:
7493676Sizick if (key_type != ~0UL &&
7494676Sizick key_type != DPROV_CKK_BLOWFISH) {
7495676Sizick error = CRYPTO_TEMPLATE_INCONSISTENT;
7496676Sizick break;
7497676Sizick }
7498676Sizick if (dprov_get_template_attr_ulong(template,
7499676Sizick attribute_count, DPROV_CKA_VALUE_LEN,
7500676Sizick &value_len) != CRYPTO_SUCCESS) {
7501676Sizick error = CRYPTO_TEMPLATE_INCOMPLETE;
7502676Sizick break;
7503676Sizick }
7504676Sizick if (value_len >= BLOWFISH_MAX_KEY_LEN) {
7505676Sizick error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
7506676Sizick break;
7507676Sizick }
7508676Sizick key_len = value_len;
7509676Sizick key_type = DPROV_CKK_BLOWFISH;
7510676Sizick break;
7511676Sizick
75120Sstevel@tonic-gate case RC4_KEY_GEN_MECH_INFO_TYPE:
75130Sstevel@tonic-gate if (key_type != ~0UL && key_type != DPROV_CKK_RC4) {
75140Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT;
75150Sstevel@tonic-gate break;
75160Sstevel@tonic-gate }
75170Sstevel@tonic-gate if (dprov_get_template_attr_ulong(template,
75180Sstevel@tonic-gate attribute_count, DPROV_CKA_VALUE_LEN,
75190Sstevel@tonic-gate &value_len) != CRYPTO_SUCCESS) {
75200Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCOMPLETE;
75210Sstevel@tonic-gate break;
75220Sstevel@tonic-gate }
75230Sstevel@tonic-gate if (value_len >=
75240Sstevel@tonic-gate CRYPTO_BITS2BYTES(ARCFOUR_MAX_KEY_BITS)) {
75250Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
75260Sstevel@tonic-gate break;
75270Sstevel@tonic-gate }
75280Sstevel@tonic-gate key_len = value_len;
75290Sstevel@tonic-gate key_type = DPROV_CKK_RC4;
75300Sstevel@tonic-gate break;
75310Sstevel@tonic-gate
75320Sstevel@tonic-gate default:
75330Sstevel@tonic-gate error = CRYPTO_MECHANISM_INVALID;
75340Sstevel@tonic-gate }
75350Sstevel@tonic-gate
75360Sstevel@tonic-gate if (error != CRYPTO_SUCCESS)
75370Sstevel@tonic-gate break;
75380Sstevel@tonic-gate
75390Sstevel@tonic-gate error = dprov_create_object_from_template(softc, session,
75400Sstevel@tonic-gate template, attribute_count, object_id_ptr, B_FALSE, B_TRUE);
75410Sstevel@tonic-gate
75420Sstevel@tonic-gate if (error != CRYPTO_SUCCESS)
75430Sstevel@tonic-gate break;
75440Sstevel@tonic-gate
75450Sstevel@tonic-gate /* make sure class is set */
75460Sstevel@tonic-gate attribute.oa_type = DPROV_CKA_CLASS;
75470Sstevel@tonic-gate attribute.oa_value = (char *)&class;
75480Sstevel@tonic-gate attribute.oa_value_len = sizeof (ulong_t);
75490Sstevel@tonic-gate error = dprov_object_set_attr(session, *object_id_ptr,
75500Sstevel@tonic-gate &attribute, 1, B_FALSE);
75510Sstevel@tonic-gate
75520Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) {
75530Sstevel@tonic-gate goto destroy_object;
75540Sstevel@tonic-gate }
75550Sstevel@tonic-gate
75560Sstevel@tonic-gate /* make sure key_type is set */
75570Sstevel@tonic-gate attribute.oa_type = DPROV_CKA_KEY_TYPE;
75580Sstevel@tonic-gate attribute.oa_value = (char *)&key_type;
75590Sstevel@tonic-gate attribute.oa_value_len = sizeof (ulong_t);
75600Sstevel@tonic-gate error = dprov_object_set_attr(session, *object_id_ptr,
75610Sstevel@tonic-gate &attribute, 1, B_FALSE);
75620Sstevel@tonic-gate
75630Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) {
75640Sstevel@tonic-gate goto destroy_object;
75650Sstevel@tonic-gate }
75660Sstevel@tonic-gate
75670Sstevel@tonic-gate attribute.oa_type = DPROV_CKA_VALUE;
75680Sstevel@tonic-gate attribute.oa_value = kmem_alloc(key_len, KM_SLEEP);
75690Sstevel@tonic-gate attribute.oa_value_len = key_len;
75700Sstevel@tonic-gate
75710Sstevel@tonic-gate if (random_get_pseudo_bytes((uchar_t *)attribute.oa_value,
75720Sstevel@tonic-gate key_len) != 0) {
75730Sstevel@tonic-gate bzero(attribute.oa_value, key_len);
75740Sstevel@tonic-gate kmem_free(attribute.oa_value, key_len);
75750Sstevel@tonic-gate goto destroy_object;
75760Sstevel@tonic-gate }
75770Sstevel@tonic-gate error = dprov_object_set_attr(session, *object_id_ptr,
75780Sstevel@tonic-gate &attribute, 1, B_FALSE);
75790Sstevel@tonic-gate
75800Sstevel@tonic-gate bzero(attribute.oa_value, key_len);
75810Sstevel@tonic-gate kmem_free(attribute.oa_value, key_len);
75820Sstevel@tonic-gate
75830Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) {
75840Sstevel@tonic-gate goto destroy_object;
75850Sstevel@tonic-gate }
75860Sstevel@tonic-gate break;
75870Sstevel@tonic-gate
75880Sstevel@tonic-gate destroy_object:
75890Sstevel@tonic-gate (void) dprov_destroy_object(softc, session, *object_id_ptr);
75900Sstevel@tonic-gate break;
75910Sstevel@tonic-gate }
75920Sstevel@tonic-gate
75930Sstevel@tonic-gate case DPROV_REQ_KEY_GENERATE_PAIR: {
75940Sstevel@tonic-gate crypto_mechanism_t *mechp;
75950Sstevel@tonic-gate crypto_object_id_t *pub_object_id_ptr;
75960Sstevel@tonic-gate crypto_object_id_t *pri_object_id_ptr;
75970Sstevel@tonic-gate crypto_object_attribute_t *pub_template;
75980Sstevel@tonic-gate crypto_object_attribute_t *pri_template;
75990Sstevel@tonic-gate crypto_object_attribute_t attribute;
76000Sstevel@tonic-gate uint_t pub_attribute_count;
76010Sstevel@tonic-gate uint_t pri_attribute_count;
76020Sstevel@tonic-gate ulong_t pub_key_type = ~0UL, pub_class = ~0UL;
76030Sstevel@tonic-gate ulong_t pri_key_type = ~0UL, pri_class = ~0UL;
76040Sstevel@tonic-gate
76050Sstevel@tonic-gate pub_template = taskq_req->dr_key_req.kr_template;
76060Sstevel@tonic-gate pub_attribute_count = taskq_req->dr_key_req.kr_attribute_count;
76070Sstevel@tonic-gate pub_object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr;
76080Sstevel@tonic-gate pri_template = taskq_req->dr_key_req.kr_private_key_template;
76090Sstevel@tonic-gate pri_attribute_count =
76100Sstevel@tonic-gate taskq_req->dr_key_req.kr_private_key_attribute_count;
76110Sstevel@tonic-gate pri_object_id_ptr =
76120Sstevel@tonic-gate taskq_req->dr_key_req.kr_private_key_object_id_ptr;
76130Sstevel@tonic-gate mechp = taskq_req->dr_key_req.kr_mechanism;
76140Sstevel@tonic-gate
76150Sstevel@tonic-gate error = CRYPTO_SUCCESS;
76160Sstevel@tonic-gate
76170Sstevel@tonic-gate /* optional */
76180Sstevel@tonic-gate (void) dprov_get_template_attr_ulong(pub_template,
76190Sstevel@tonic-gate pub_attribute_count, DPROV_CKA_CLASS, &pub_class);
76200Sstevel@tonic-gate
76210Sstevel@tonic-gate /* optional */
76220Sstevel@tonic-gate (void) dprov_get_template_attr_ulong(pri_template,
76230Sstevel@tonic-gate pri_attribute_count, DPROV_CKA_CLASS, &pri_class);
76240Sstevel@tonic-gate
76250Sstevel@tonic-gate /* optional */
76260Sstevel@tonic-gate (void) dprov_get_template_attr_ulong(pub_template,
76270Sstevel@tonic-gate pub_attribute_count, DPROV_CKA_KEY_TYPE, &pub_key_type);
76280Sstevel@tonic-gate
76290Sstevel@tonic-gate /* optional */
76300Sstevel@tonic-gate (void) dprov_get_template_attr_ulong(pri_template,
76310Sstevel@tonic-gate pri_attribute_count, DPROV_CKA_KEY_TYPE, &pri_key_type);
76320Sstevel@tonic-gate
76330Sstevel@tonic-gate if (pub_class != ~0UL && pub_class != DPROV_CKO_PUBLIC_KEY) {
76340Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT;
76350Sstevel@tonic-gate break;
76360Sstevel@tonic-gate }
76370Sstevel@tonic-gate
76380Sstevel@tonic-gate if (pri_class != ~0UL && pri_class != DPROV_CKO_PRIVATE_KEY) {
76390Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT;
76400Sstevel@tonic-gate break;
76410Sstevel@tonic-gate }
76420Sstevel@tonic-gate
76430Sstevel@tonic-gate switch (mechp->cm_type) {
76440Sstevel@tonic-gate case RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE:
76450Sstevel@tonic-gate if (pub_key_type != ~0UL &&
76460Sstevel@tonic-gate pub_key_type != DPROV_CKK_RSA) {
76470Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT;
76480Sstevel@tonic-gate break;
76490Sstevel@tonic-gate }
76504219Smcpowers pub_key_type = DPROV_CKK_RSA;
76510Sstevel@tonic-gate
76520Sstevel@tonic-gate if (pri_key_type != ~0UL &&
76530Sstevel@tonic-gate pri_key_type != DPROV_CKK_RSA) {
76540Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT;
76550Sstevel@tonic-gate break;
76560Sstevel@tonic-gate }
76570Sstevel@tonic-gate pri_key_type = DPROV_CKK_RSA;
76580Sstevel@tonic-gate
76590Sstevel@tonic-gate if (pub_class != ~0UL &&
76600Sstevel@tonic-gate pub_class != DPROV_CKO_PUBLIC_KEY) {
76610Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT;
76620Sstevel@tonic-gate break;
76630Sstevel@tonic-gate }
76640Sstevel@tonic-gate pub_class = DPROV_CKO_PUBLIC_KEY;
76650Sstevel@tonic-gate
76660Sstevel@tonic-gate if (pri_class != ~0UL &&
76670Sstevel@tonic-gate pri_class != DPROV_CKO_PRIVATE_KEY) {
76680Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT;
76690Sstevel@tonic-gate break;
76700Sstevel@tonic-gate }
76710Sstevel@tonic-gate pri_class = DPROV_CKO_PRIVATE_KEY;
76720Sstevel@tonic-gate break;
76730Sstevel@tonic-gate
76740Sstevel@tonic-gate default:
76750Sstevel@tonic-gate error = CRYPTO_MECHANISM_INVALID;
76760Sstevel@tonic-gate }
76770Sstevel@tonic-gate
76780Sstevel@tonic-gate if (error != CRYPTO_SUCCESS)
76790Sstevel@tonic-gate break;
76800Sstevel@tonic-gate
76810Sstevel@tonic-gate error = dprov_create_object_from_template(softc, session,
76820Sstevel@tonic-gate pub_template, pub_attribute_count, pub_object_id_ptr,
76830Sstevel@tonic-gate B_FALSE, B_TRUE);
76840Sstevel@tonic-gate
76850Sstevel@tonic-gate if (error != CRYPTO_SUCCESS)
76860Sstevel@tonic-gate break;
76870Sstevel@tonic-gate
76880Sstevel@tonic-gate /* make sure class is set */
76890Sstevel@tonic-gate attribute.oa_type = DPROV_CKA_CLASS;
76900Sstevel@tonic-gate attribute.oa_value = (char *)&pub_class;
76910Sstevel@tonic-gate attribute.oa_value_len = sizeof (ulong_t);
76920Sstevel@tonic-gate error = dprov_object_set_attr(session, *pub_object_id_ptr,
76930Sstevel@tonic-gate &attribute, 1, B_FALSE);
76940Sstevel@tonic-gate
76950Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) {
76960Sstevel@tonic-gate goto destroy_public_object;
76970Sstevel@tonic-gate }
76980Sstevel@tonic-gate
76990Sstevel@tonic-gate /* make sure key_type is set */
77000Sstevel@tonic-gate attribute.oa_type = DPROV_CKA_KEY_TYPE;
77010Sstevel@tonic-gate attribute.oa_value = (char *)&pub_key_type;
77020Sstevel@tonic-gate attribute.oa_value_len = sizeof (ulong_t);
77030Sstevel@tonic-gate error = dprov_object_set_attr(session, *pub_object_id_ptr,
77040Sstevel@tonic-gate &attribute, 1, B_FALSE);
77050Sstevel@tonic-gate
77060Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) {
77070Sstevel@tonic-gate goto destroy_public_object;
77080Sstevel@tonic-gate }
77090Sstevel@tonic-gate
77100Sstevel@tonic-gate attribute.oa_type = DPROV_CKA_MODULUS;
77110Sstevel@tonic-gate attribute.oa_value = (char *)modulus;
77120Sstevel@tonic-gate attribute.oa_value_len = sizeof (modulus);
77130Sstevel@tonic-gate error = dprov_object_set_attr(session, *pub_object_id_ptr,
77140Sstevel@tonic-gate &attribute, 1, B_FALSE);
77150Sstevel@tonic-gate
77160Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) {
77170Sstevel@tonic-gate goto destroy_public_object;
77180Sstevel@tonic-gate }
77190Sstevel@tonic-gate
77200Sstevel@tonic-gate attribute.oa_type = DPROV_CKA_PUBLIC_EXPONENT;
77210Sstevel@tonic-gate attribute.oa_value = public_exponent;
77220Sstevel@tonic-gate attribute.oa_value_len = sizeof (public_exponent);
77230Sstevel@tonic-gate error = dprov_object_set_attr(session, *pub_object_id_ptr,
77240Sstevel@tonic-gate &attribute, 1, B_FALSE);
77250Sstevel@tonic-gate
77260Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) {
77270Sstevel@tonic-gate goto destroy_public_object;
77280Sstevel@tonic-gate }
77290Sstevel@tonic-gate
77300Sstevel@tonic-gate error = dprov_create_object_from_template(softc, session,
77310Sstevel@tonic-gate pri_template, pri_attribute_count, pri_object_id_ptr,
77320Sstevel@tonic-gate B_FALSE, B_TRUE);
77330Sstevel@tonic-gate
77340Sstevel@tonic-gate if (error != CRYPTO_SUCCESS)
77350Sstevel@tonic-gate break;
77360Sstevel@tonic-gate
77370Sstevel@tonic-gate /* make sure class is set */
77380Sstevel@tonic-gate attribute.oa_type = DPROV_CKA_CLASS;
77390Sstevel@tonic-gate attribute.oa_value = (char *)&pri_class;
77400Sstevel@tonic-gate attribute.oa_value_len = sizeof (ulong_t);
77410Sstevel@tonic-gate error = dprov_object_set_attr(session, *pri_object_id_ptr,
77420Sstevel@tonic-gate &attribute, 1, B_FALSE);
77430Sstevel@tonic-gate
77440Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) {
77450Sstevel@tonic-gate goto destroy_private_object;
77460Sstevel@tonic-gate }
77470Sstevel@tonic-gate
77480Sstevel@tonic-gate /* make sure key_type is set */
77490Sstevel@tonic-gate attribute.oa_type = DPROV_CKA_KEY_TYPE;
77500Sstevel@tonic-gate attribute.oa_value = (char *)&pri_key_type;
77510Sstevel@tonic-gate attribute.oa_value_len = sizeof (ulong_t);
77520Sstevel@tonic-gate error = dprov_object_set_attr(session, *pri_object_id_ptr,
77530Sstevel@tonic-gate &attribute, 1, B_FALSE);
77540Sstevel@tonic-gate
77550Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) {
77560Sstevel@tonic-gate goto destroy_private_object;
77570Sstevel@tonic-gate }
77580Sstevel@tonic-gate
77590Sstevel@tonic-gate attribute.oa_type = DPROV_CKA_MODULUS;
77600Sstevel@tonic-gate attribute.oa_value = (char *)modulus;
77610Sstevel@tonic-gate attribute.oa_value_len = sizeof (modulus);
77620Sstevel@tonic-gate error = dprov_object_set_attr(session, *pri_object_id_ptr,
77630Sstevel@tonic-gate &attribute, 1, B_FALSE);
77640Sstevel@tonic-gate
77650Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) {
77660Sstevel@tonic-gate goto destroy_private_object;
77670Sstevel@tonic-gate }
77680Sstevel@tonic-gate
77690Sstevel@tonic-gate attribute.oa_type = DPROV_CKA_PRIVATE_EXPONENT;
77700Sstevel@tonic-gate attribute.oa_value = (char *)private_exponent;
77710Sstevel@tonic-gate attribute.oa_value_len = sizeof (private_exponent);
77720Sstevel@tonic-gate error = dprov_object_set_attr(session, *pri_object_id_ptr,
77730Sstevel@tonic-gate &attribute, 1, B_FALSE);
77740Sstevel@tonic-gate
77750Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) {
77760Sstevel@tonic-gate goto destroy_private_object;
77770Sstevel@tonic-gate }
77780Sstevel@tonic-gate break;
77790Sstevel@tonic-gate
77800Sstevel@tonic-gate destroy_private_object:
77810Sstevel@tonic-gate (void) dprov_destroy_object(softc, session,
77820Sstevel@tonic-gate *pri_object_id_ptr);
77830Sstevel@tonic-gate destroy_public_object:
77840Sstevel@tonic-gate (void) dprov_destroy_object(softc, session,
77850Sstevel@tonic-gate *pub_object_id_ptr);
77860Sstevel@tonic-gate
77870Sstevel@tonic-gate break;
77880Sstevel@tonic-gate }
77890Sstevel@tonic-gate
77900Sstevel@tonic-gate case DPROV_REQ_KEY_WRAP: {
77910Sstevel@tonic-gate crypto_mechanism_t mech, *mechp;
77920Sstevel@tonic-gate crypto_key_t key, *keyp;
77930Sstevel@tonic-gate crypto_object_id_t object_id;
77940Sstevel@tonic-gate ulong_t class = DPROV_CKO_DATA;
77950Sstevel@tonic-gate boolean_t extractable = B_TRUE;
77960Sstevel@tonic-gate dprov_object_t *object;
77970Sstevel@tonic-gate int object_idx;
77980Sstevel@tonic-gate char *plaintext_key;
77990Sstevel@tonic-gate size_t plaintext_key_len;
78000Sstevel@tonic-gate crypto_data_t plaintext;
78010Sstevel@tonic-gate crypto_data_t ciphertext;
78020Sstevel@tonic-gate size_t *lenp;
78030Sstevel@tonic-gate
78040Sstevel@tonic-gate mechp = taskq_req->dr_key_req.kr_mechanism;
78050Sstevel@tonic-gate /* structure assignment */
78060Sstevel@tonic-gate mech = *mechp;
78070Sstevel@tonic-gate
78080Sstevel@tonic-gate /* get wrapping key value */
78090Sstevel@tonic-gate if (is_publickey_mech(mech.cm_type)) {
78100Sstevel@tonic-gate if ((error = dprov_key_attr_asymmetric(softc,
78110Sstevel@tonic-gate session_id, taskq_req->dr_type,
78120Sstevel@tonic-gate taskq_req->dr_key_req.kr_key,
78130Sstevel@tonic-gate &key)) != CRYPTO_SUCCESS)
78140Sstevel@tonic-gate break;
78150Sstevel@tonic-gate keyp = &key;
78160Sstevel@tonic-gate } else {
78170Sstevel@tonic-gate if ((error = dprov_key_value_secret(softc,
78180Sstevel@tonic-gate session_id, taskq_req->dr_type,
78190Sstevel@tonic-gate taskq_req->dr_key_req.kr_key,
78200Sstevel@tonic-gate &key)) != CRYPTO_SUCCESS)
78210Sstevel@tonic-gate break;
78220Sstevel@tonic-gate keyp = &key;
78230Sstevel@tonic-gate }
78240Sstevel@tonic-gate
78250Sstevel@tonic-gate /* get the software provider for this mechanism */
78260Sstevel@tonic-gate if ((error = dprov_get_sw_prov(mechp, &pd,
78270Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS)
78280Sstevel@tonic-gate break;
78290Sstevel@tonic-gate
78300Sstevel@tonic-gate object_id = *taskq_req->dr_key_req.kr_object_id_ptr;
78310Sstevel@tonic-gate if (object_id >= DPROV_MAX_OBJECTS) {
78320Sstevel@tonic-gate error = CRYPTO_KEY_HANDLE_INVALID;
78330Sstevel@tonic-gate break;
78340Sstevel@tonic-gate }
78350Sstevel@tonic-gate
78360Sstevel@tonic-gate /* get ptr to object */
78370Sstevel@tonic-gate if ((object = session->ds_objects[object_id]) == NULL) {
78380Sstevel@tonic-gate error = CRYPTO_OBJECT_HANDLE_INVALID;
78390Sstevel@tonic-gate break;
78400Sstevel@tonic-gate }
78410Sstevel@tonic-gate
78420Sstevel@tonic-gate (void) dprov_get_object_attr_boolean(object,
78430Sstevel@tonic-gate DPROV_CKA_EXTRACTABLE, &extractable);
78440Sstevel@tonic-gate
78450Sstevel@tonic-gate if (!extractable) {
78460Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_SENSITIVE;
78470Sstevel@tonic-gate break;
78480Sstevel@tonic-gate }
78490Sstevel@tonic-gate
78500Sstevel@tonic-gate (void) dprov_get_object_attr_ulong(object,
78510Sstevel@tonic-gate DPROV_CKA_CLASS, &class);
78520Sstevel@tonic-gate
78530Sstevel@tonic-gate switch (class) {
78540Sstevel@tonic-gate case DPROV_CKO_SECRET_KEY:
78550Sstevel@tonic-gate object_idx = dprov_find_attr(object->do_attr,
78560Sstevel@tonic-gate DPROV_MAX_ATTR, DPROV_CKA_VALUE);
78570Sstevel@tonic-gate if (object_idx == -1) {
78580Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_TYPE_INVALID;
78590Sstevel@tonic-gate break;
78600Sstevel@tonic-gate }
78610Sstevel@tonic-gate break;
78620Sstevel@tonic-gate
78634424Sizick case DPROV_CKO_PRIVATE_KEY:
78640Sstevel@tonic-gate /*
78650Sstevel@tonic-gate * PKCS#11 says that ASN.1 should be used to encode
78660Sstevel@tonic-gate * specific attributes before encrypting the blob.
78670Sstevel@tonic-gate * We only encrypt the private exponent for the
78680Sstevel@tonic-gate * purpose of testing.
78690Sstevel@tonic-gate */
78700Sstevel@tonic-gate object_idx = dprov_find_attr(object->do_attr,
78710Sstevel@tonic-gate DPROV_MAX_ATTR, DPROV_CKA_PRIVATE_EXPONENT);
78720Sstevel@tonic-gate if (object_idx == -1) {
78730Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_TYPE_INVALID;
78740Sstevel@tonic-gate break;
78750Sstevel@tonic-gate }
78760Sstevel@tonic-gate break;
78770Sstevel@tonic-gate default:
78780Sstevel@tonic-gate error = CRYPTO_KEY_NOT_WRAPPABLE;
78790Sstevel@tonic-gate break;
78800Sstevel@tonic-gate }
78810Sstevel@tonic-gate if (error != CRYPTO_SUCCESS)
78820Sstevel@tonic-gate break;
78830Sstevel@tonic-gate
78840Sstevel@tonic-gate plaintext_key = object->do_attr[object_idx].oa_value;
78850Sstevel@tonic-gate plaintext_key_len = object->do_attr[object_idx].oa_value_len;
78860Sstevel@tonic-gate lenp = taskq_req->dr_key_req.kr_wrapped_key_len_ptr;
78870Sstevel@tonic-gate
78880Sstevel@tonic-gate /* session id is 0 for software provider */
78890Sstevel@tonic-gate plaintext.cd_format = CRYPTO_DATA_RAW;
78900Sstevel@tonic-gate plaintext.cd_offset = 0;
78910Sstevel@tonic-gate plaintext.cd_length = plaintext_key_len;
78920Sstevel@tonic-gate plaintext.cd_raw.iov_base = plaintext_key;
78930Sstevel@tonic-gate plaintext.cd_raw.iov_len = plaintext_key_len;
78940Sstevel@tonic-gate plaintext.cd_miscdata = NULL;
78950Sstevel@tonic-gate
78960Sstevel@tonic-gate ciphertext.cd_format = CRYPTO_DATA_RAW;
78970Sstevel@tonic-gate ciphertext.cd_offset = 0;
78980Sstevel@tonic-gate ciphertext.cd_length = *lenp;
78990Sstevel@tonic-gate ciphertext.cd_raw.iov_base =
79000Sstevel@tonic-gate (char *)taskq_req->dr_key_req.kr_wrapped_key;
79010Sstevel@tonic-gate ciphertext.cd_raw.iov_len = ciphertext.cd_length;
79020Sstevel@tonic-gate ciphertext.cd_miscdata = NULL;
79030Sstevel@tonic-gate
7904904Smcpowers error = crypto_encrypt_prov(pd, 0, &mech, &plaintext, keyp,
7905904Smcpowers NULL, &ciphertext, NULL);
79060Sstevel@tonic-gate
79070Sstevel@tonic-gate KCF_PROV_REFRELE(pd);
79080Sstevel@tonic-gate if (error == CRYPTO_SUCCESS ||
79090Sstevel@tonic-gate error == CRYPTO_BUFFER_TOO_SMALL) {
79100Sstevel@tonic-gate *lenp = ciphertext.cd_length;
79110Sstevel@tonic-gate }
79120Sstevel@tonic-gate break;
79130Sstevel@tonic-gate }
79140Sstevel@tonic-gate
79150Sstevel@tonic-gate case DPROV_REQ_KEY_UNWRAP: {
79160Sstevel@tonic-gate crypto_mechanism_t mech, *mechp;
79170Sstevel@tonic-gate crypto_key_t key, *keyp;
79180Sstevel@tonic-gate crypto_object_id_t *object_id_ptr;
79190Sstevel@tonic-gate ulong_t class = DPROV_CKO_DATA;
79200Sstevel@tonic-gate uchar_t *wrapped_key;
79210Sstevel@tonic-gate char *plaintext_buf;
79220Sstevel@tonic-gate size_t wrapped_key_len;
79230Sstevel@tonic-gate crypto_data_t plaintext;
79240Sstevel@tonic-gate crypto_data_t ciphertext;
79250Sstevel@tonic-gate crypto_object_attribute_t unwrapped_key;
79260Sstevel@tonic-gate crypto_object_attribute_t *template;
79270Sstevel@tonic-gate uint_t attribute_count;
79280Sstevel@tonic-gate
79290Sstevel@tonic-gate template = taskq_req->dr_key_req.kr_template;
79300Sstevel@tonic-gate attribute_count = taskq_req->dr_key_req.kr_attribute_count;
79310Sstevel@tonic-gate object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr;
79320Sstevel@tonic-gate
79330Sstevel@tonic-gate /* all objects must have an object class attribute */
79340Sstevel@tonic-gate if (dprov_get_template_attr_ulong(template, attribute_count,
79350Sstevel@tonic-gate DPROV_CKA_CLASS, &class) != CRYPTO_SUCCESS) {
79360Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCOMPLETE;
79370Sstevel@tonic-gate break;
79380Sstevel@tonic-gate }
79390Sstevel@tonic-gate
79400Sstevel@tonic-gate mechp = taskq_req->dr_key_req.kr_mechanism;
79410Sstevel@tonic-gate /* structure assignment */
79420Sstevel@tonic-gate mech = *mechp;
79430Sstevel@tonic-gate
79440Sstevel@tonic-gate /* get unwrapping key value */
79450Sstevel@tonic-gate if (is_publickey_mech(mech.cm_type)) {
79460Sstevel@tonic-gate if ((error = dprov_key_attr_asymmetric(softc,
79470Sstevel@tonic-gate session_id, taskq_req->dr_type,
79480Sstevel@tonic-gate taskq_req->dr_key_req.kr_key,
79490Sstevel@tonic-gate &key)) != CRYPTO_SUCCESS)
79500Sstevel@tonic-gate break;
79510Sstevel@tonic-gate keyp = &key;
79520Sstevel@tonic-gate } else {
79530Sstevel@tonic-gate if ((error = dprov_key_value_secret(softc,
79540Sstevel@tonic-gate session_id, taskq_req->dr_type,
79550Sstevel@tonic-gate taskq_req->dr_key_req.kr_key,
79560Sstevel@tonic-gate &key)) != CRYPTO_SUCCESS)
79570Sstevel@tonic-gate break;
79580Sstevel@tonic-gate keyp = &key;
79590Sstevel@tonic-gate }
79600Sstevel@tonic-gate
79610Sstevel@tonic-gate /* get the software provider for this mechanism */
79620Sstevel@tonic-gate if ((error = dprov_get_sw_prov(mechp, &pd,
79630Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS)
79640Sstevel@tonic-gate break;
79650Sstevel@tonic-gate
79660Sstevel@tonic-gate wrapped_key = taskq_req->dr_key_req.kr_wrapped_key;
79670Sstevel@tonic-gate wrapped_key_len = *taskq_req->dr_key_req.kr_wrapped_key_len_ptr;
79680Sstevel@tonic-gate ciphertext.cd_format = CRYPTO_DATA_RAW;
79690Sstevel@tonic-gate ciphertext.cd_offset = 0;
79700Sstevel@tonic-gate ciphertext.cd_length = wrapped_key_len;
79710Sstevel@tonic-gate ciphertext.cd_raw.iov_base = (char *)wrapped_key;
79720Sstevel@tonic-gate ciphertext.cd_raw.iov_len = wrapped_key_len;
79730Sstevel@tonic-gate ciphertext.cd_miscdata = NULL;
79740Sstevel@tonic-gate
79750Sstevel@tonic-gate /*
79760Sstevel@tonic-gate * Plaintext length is less than or equal to
79770Sstevel@tonic-gate * the length of the ciphertext.
79780Sstevel@tonic-gate */
79790Sstevel@tonic-gate plaintext_buf = kmem_alloc(wrapped_key_len, KM_SLEEP);
79800Sstevel@tonic-gate plaintext.cd_format = CRYPTO_DATA_RAW;
79810Sstevel@tonic-gate plaintext.cd_offset = 0;
79820Sstevel@tonic-gate plaintext.cd_length = wrapped_key_len;
79830Sstevel@tonic-gate plaintext.cd_raw.iov_base = plaintext_buf;
79840Sstevel@tonic-gate plaintext.cd_raw.iov_len = wrapped_key_len;
79850Sstevel@tonic-gate plaintext.cd_miscdata = NULL;
79860Sstevel@tonic-gate
7987904Smcpowers error = crypto_decrypt_prov(pd, 0, &mech, &ciphertext, keyp,
7988904Smcpowers NULL, &plaintext, NULL);
79890Sstevel@tonic-gate
79900Sstevel@tonic-gate KCF_PROV_REFRELE(pd);
79910Sstevel@tonic-gate
79920Sstevel@tonic-gate if (error != CRYPTO_SUCCESS)
79930Sstevel@tonic-gate goto free_unwrapped_key;
79940Sstevel@tonic-gate
79950Sstevel@tonic-gate error = dprov_create_object_from_template(softc, session,
79960Sstevel@tonic-gate template, attribute_count, object_id_ptr, B_FALSE, B_FALSE);
79970Sstevel@tonic-gate
79980Sstevel@tonic-gate if (error != CRYPTO_SUCCESS)
79990Sstevel@tonic-gate goto free_unwrapped_key;
80000Sstevel@tonic-gate
80010Sstevel@tonic-gate switch (class) {
80020Sstevel@tonic-gate case DPROV_CKO_SECRET_KEY:
80030Sstevel@tonic-gate unwrapped_key.oa_type = DPROV_CKA_VALUE;
80040Sstevel@tonic-gate unwrapped_key.oa_value_len = plaintext.cd_length;
80050Sstevel@tonic-gate unwrapped_key.oa_value = plaintext_buf;
80060Sstevel@tonic-gate break;
80070Sstevel@tonic-gate case DPROV_CKO_PRIVATE_KEY:
80080Sstevel@tonic-gate /*
80090Sstevel@tonic-gate * PKCS#11 says that ASN.1 should be used to encode
80100Sstevel@tonic-gate * specific attributes before encrypting the blob.
80110Sstevel@tonic-gate * We only encrypt the private exponent for the
80120Sstevel@tonic-gate * purpose of testing.
80130Sstevel@tonic-gate */
80140Sstevel@tonic-gate unwrapped_key.oa_type = DPROV_CKA_PRIVATE_EXPONENT;
80150Sstevel@tonic-gate unwrapped_key.oa_value_len = plaintext.cd_length;
80160Sstevel@tonic-gate unwrapped_key.oa_value = plaintext_buf;
80170Sstevel@tonic-gate break;
80180Sstevel@tonic-gate default:
80190Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT;
80200Sstevel@tonic-gate goto free_unwrapped_key;
80210Sstevel@tonic-gate }
80220Sstevel@tonic-gate
80230Sstevel@tonic-gate if ((error = dprov_object_set_attr(session, *object_id_ptr,
80240Sstevel@tonic-gate &unwrapped_key, 1, B_FALSE)) == CRYPTO_SUCCESS)
80250Sstevel@tonic-gate break; /* don't free the unwrapped key */
80260Sstevel@tonic-gate
80270Sstevel@tonic-gate /* failure */
80280Sstevel@tonic-gate (void) dprov_destroy_object(softc, session, *object_id_ptr);
80290Sstevel@tonic-gate break;
80300Sstevel@tonic-gate
80310Sstevel@tonic-gate free_unwrapped_key:
80320Sstevel@tonic-gate bzero(plaintext_buf, wrapped_key_len);
80330Sstevel@tonic-gate kmem_free(plaintext_buf, wrapped_key_len);
80340Sstevel@tonic-gate break;
80350Sstevel@tonic-gate }
80360Sstevel@tonic-gate
80370Sstevel@tonic-gate case DPROV_REQ_KEY_DERIVE: {
80380Sstevel@tonic-gate crypto_mechanism_t digest_mech, *mechp;
80390Sstevel@tonic-gate crypto_key_t key, *base_keyp;
80400Sstevel@tonic-gate crypto_object_id_t *object_id_ptr;
80410Sstevel@tonic-gate crypto_data_t data;
80420Sstevel@tonic-gate crypto_data_t digest;
80430Sstevel@tonic-gate size_t hash_size;
80440Sstevel@tonic-gate char *digest_buf;
80450Sstevel@tonic-gate crypto_object_attribute_t derived_key;
80460Sstevel@tonic-gate crypto_object_attribute_t *template;
80470Sstevel@tonic-gate uint_t attribute_count;
80480Sstevel@tonic-gate ulong_t key_type;
80490Sstevel@tonic-gate void *value;
80500Sstevel@tonic-gate size_t value_len = 0;
80510Sstevel@tonic-gate
80520Sstevel@tonic-gate error = CRYPTO_SUCCESS;
80530Sstevel@tonic-gate
80540Sstevel@tonic-gate template = taskq_req->dr_key_req.kr_template;
80550Sstevel@tonic-gate attribute_count = taskq_req->dr_key_req.kr_attribute_count;
80560Sstevel@tonic-gate object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr;
80570Sstevel@tonic-gate
80580Sstevel@tonic-gate /* required */
80590Sstevel@tonic-gate if (dprov_get_template_attr_ulong(template, attribute_count,
80600Sstevel@tonic-gate DPROV_CKA_KEY_TYPE, &key_type) != CRYPTO_SUCCESS) {
80610Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCOMPLETE;
80620Sstevel@tonic-gate break;
80630Sstevel@tonic-gate }
80640Sstevel@tonic-gate
80650Sstevel@tonic-gate mechp = taskq_req->dr_key_req.kr_mechanism;
80660Sstevel@tonic-gate /* structure assignment */
80670Sstevel@tonic-gate digest_mech = *mechp;
80680Sstevel@tonic-gate
80690Sstevel@tonic-gate switch (digest_mech.cm_type) {
80700Sstevel@tonic-gate case SHA1_KEY_DERIVATION_MECH_INFO_TYPE:
80710Sstevel@tonic-gate hash_size = SHA1_DIGEST_LEN;
80720Sstevel@tonic-gate digest_mech.cm_type = SHA1_MECH_INFO_TYPE;
80730Sstevel@tonic-gate break;
80740Sstevel@tonic-gate
8075676Sizick case SHA256_KEY_DERIVATION_MECH_INFO_TYPE:
8076676Sizick hash_size = SHA256_DIGEST_LENGTH;
8077676Sizick digest_mech.cm_type = SHA256_MECH_INFO_TYPE;
8078676Sizick break;
8079676Sizick
8080676Sizick case SHA384_KEY_DERIVATION_MECH_INFO_TYPE:
8081676Sizick hash_size = SHA384_DIGEST_LENGTH;
8082676Sizick digest_mech.cm_type = SHA384_MECH_INFO_TYPE;
8083676Sizick break;
8084676Sizick
8085676Sizick case SHA512_KEY_DERIVATION_MECH_INFO_TYPE:
8086676Sizick hash_size = SHA512_DIGEST_LENGTH;
8087676Sizick digest_mech.cm_type = SHA512_MECH_INFO_TYPE;
8088676Sizick break;
8089676Sizick
80900Sstevel@tonic-gate case MD5_KEY_DERIVATION_MECH_INFO_TYPE:
80910Sstevel@tonic-gate hash_size = MD5_DIGEST_LEN;
80920Sstevel@tonic-gate digest_mech.cm_type = MD5_MECH_INFO_TYPE;
80930Sstevel@tonic-gate break;
80940Sstevel@tonic-gate
80950Sstevel@tonic-gate default:
80960Sstevel@tonic-gate error = CRYPTO_MECHANISM_INVALID;
80970Sstevel@tonic-gate }
80980Sstevel@tonic-gate
80990Sstevel@tonic-gate if (error != CRYPTO_SUCCESS)
81000Sstevel@tonic-gate break;
81010Sstevel@tonic-gate
81020Sstevel@tonic-gate /* CKA_VALUE is optional */
81030Sstevel@tonic-gate (void) dprov_get_template_attr_array(template, attribute_count,
81040Sstevel@tonic-gate DPROV_CKA_VALUE, &value, &value_len);
81050Sstevel@tonic-gate
81060Sstevel@tonic-gate /* check for inconsistent value length */
81070Sstevel@tonic-gate switch (key_type) {
81080Sstevel@tonic-gate case DPROV_CKK_GENERIC_SECRET:
81090Sstevel@tonic-gate if (value_len > 0) {
81100Sstevel@tonic-gate if (value_len > hash_size)
81110Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
81120Sstevel@tonic-gate } else {
81130Sstevel@tonic-gate value_len = hash_size;
81140Sstevel@tonic-gate }
81150Sstevel@tonic-gate break;
81160Sstevel@tonic-gate
81170Sstevel@tonic-gate case DPROV_CKK_RC4:
81180Sstevel@tonic-gate case DPROV_CKK_AES:
81190Sstevel@tonic-gate if (value_len == 0 ||
81200Sstevel@tonic-gate value_len > hash_size) {
81210Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
81220Sstevel@tonic-gate }
81230Sstevel@tonic-gate break;
81240Sstevel@tonic-gate
81250Sstevel@tonic-gate case DPROV_CKK_DES:
81260Sstevel@tonic-gate if (value_len > 0 &&
81270Sstevel@tonic-gate value_len != DES_KEY_LEN) {
81280Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
81290Sstevel@tonic-gate }
81300Sstevel@tonic-gate value_len = DES_KEY_LEN;
81310Sstevel@tonic-gate break;
81320Sstevel@tonic-gate
81330Sstevel@tonic-gate case DPROV_CKK_DES3:
81340Sstevel@tonic-gate if (value_len > 0 &&
81350Sstevel@tonic-gate value_len != DES3_KEY_LEN) {
81360Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
81370Sstevel@tonic-gate }
81380Sstevel@tonic-gate value_len = DES3_KEY_LEN;
81390Sstevel@tonic-gate break;
81400Sstevel@tonic-gate
81410Sstevel@tonic-gate default:
81420Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
81430Sstevel@tonic-gate break;
81440Sstevel@tonic-gate }
81450Sstevel@tonic-gate
81460Sstevel@tonic-gate if (error != CRYPTO_SUCCESS)
81470Sstevel@tonic-gate break;
81480Sstevel@tonic-gate
81490Sstevel@tonic-gate /* get the software provider for this mechanism */
81500Sstevel@tonic-gate if ((error = dprov_get_sw_prov(&digest_mech, &pd,
81510Sstevel@tonic-gate &digest_mech.cm_type)) != CRYPTO_SUCCESS)
81520Sstevel@tonic-gate break;
81530Sstevel@tonic-gate
81540Sstevel@tonic-gate /* get the base key */
81550Sstevel@tonic-gate error = dprov_key_value_secret(softc, session_id,
81560Sstevel@tonic-gate taskq_req->dr_type, taskq_req->dr_key_req.kr_key, &key);
81570Sstevel@tonic-gate if (error != CRYPTO_SUCCESS)
81580Sstevel@tonic-gate break;
81590Sstevel@tonic-gate
81600Sstevel@tonic-gate base_keyp = &key;
81610Sstevel@tonic-gate
81620Sstevel@tonic-gate data.cd_format = CRYPTO_DATA_RAW;
81630Sstevel@tonic-gate data.cd_offset = 0;
81640Sstevel@tonic-gate data.cd_length = CRYPTO_BITS2BYTES(base_keyp->ck_length);
81650Sstevel@tonic-gate data.cd_raw.iov_base = base_keyp->ck_data;
81660Sstevel@tonic-gate data.cd_raw.iov_len = data.cd_length;
81670Sstevel@tonic-gate
81680Sstevel@tonic-gate digest_buf = kmem_alloc(hash_size, KM_SLEEP);
81690Sstevel@tonic-gate digest.cd_format = CRYPTO_DATA_RAW;
81700Sstevel@tonic-gate digest.cd_offset = 0;
81710Sstevel@tonic-gate digest.cd_length = hash_size;
81720Sstevel@tonic-gate digest.cd_raw.iov_base = digest_buf;
81730Sstevel@tonic-gate digest.cd_raw.iov_len = hash_size;
81740Sstevel@tonic-gate
8175904Smcpowers error = crypto_digest_prov(pd, 0, &digest_mech, &data,
8176904Smcpowers &digest, NULL);
81770Sstevel@tonic-gate
81780Sstevel@tonic-gate KCF_PROV_REFRELE(pd);
81790Sstevel@tonic-gate
81800Sstevel@tonic-gate if (error != CRYPTO_SUCCESS)
81810Sstevel@tonic-gate goto free_derived_key;
81820Sstevel@tonic-gate
81830Sstevel@tonic-gate error = dprov_create_object_from_template(softc, session,
81840Sstevel@tonic-gate template, attribute_count, object_id_ptr, B_FALSE, B_FALSE);
81850Sstevel@tonic-gate
81860Sstevel@tonic-gate if (error != CRYPTO_SUCCESS)
81870Sstevel@tonic-gate goto free_derived_key;
81880Sstevel@tonic-gate
81890Sstevel@tonic-gate derived_key.oa_type = DPROV_CKA_VALUE;
81900Sstevel@tonic-gate derived_key.oa_value = digest_buf;
81910Sstevel@tonic-gate derived_key.oa_value_len = value_len;
81920Sstevel@tonic-gate
81930Sstevel@tonic-gate error = dprov_object_set_attr(session, *object_id_ptr,
81940Sstevel@tonic-gate &derived_key, 1, B_FALSE);
81950Sstevel@tonic-gate
81960Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) {
81970Sstevel@tonic-gate (void) dprov_destroy_object(softc, session,
81980Sstevel@tonic-gate *object_id_ptr);
81990Sstevel@tonic-gate }
82000Sstevel@tonic-gate
82010Sstevel@tonic-gate free_derived_key:
82020Sstevel@tonic-gate bzero(digest_buf, hash_size);
82030Sstevel@tonic-gate kmem_free(digest_buf, hash_size);
82044219Smcpowers break;
82054219Smcpowers }
82064219Smcpowers
82074219Smcpowers case DPROV_REQ_NOSTORE_KEY_GENERATE: {
82084219Smcpowers crypto_object_attribute_t *out_template;
82094219Smcpowers uint_t out_attribute_count;
82104219Smcpowers void *value;
82114219Smcpowers size_t value_len = 0;
82124219Smcpowers
82134219Smcpowers out_template = taskq_req->dr_key_req.kr_out_template1;
82144219Smcpowers out_attribute_count =
82154219Smcpowers taskq_req->dr_key_req.kr_out_attribute_count1;
82164219Smcpowers
82174219Smcpowers error = dprov_get_template_attr_array(out_template,
82184219Smcpowers out_attribute_count, DPROV_CKA_VALUE, &value, &value_len);
82194219Smcpowers if (error != CRYPTO_SUCCESS)
82204219Smcpowers break;
82214219Smcpowers
82224219Smcpowers /* fill the entire array with pattern */
82234219Smcpowers {
82244219Smcpowers int i = 0;
82254219Smcpowers char *p = value;
82264219Smcpowers while (i < value_len) {
82274219Smcpowers p[i++] = 'A';
82284219Smcpowers if (i >= value_len)
82294219Smcpowers break;
82304219Smcpowers p[i++] = 'B';
82314219Smcpowers if (i >= value_len)
82324219Smcpowers break;
82334219Smcpowers p[i++] = 'C';
82344219Smcpowers }
82354219Smcpowers }
82364219Smcpowers
82374219Smcpowers error = CRYPTO_SUCCESS;
82384219Smcpowers break;
82394219Smcpowers }
82404424Sizick
82414424Sizick case DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR: {
82424424Sizick crypto_mechanism_t *mechp;
82434424Sizick crypto_object_attribute_t *pub_template;
82445697Smcpowers crypto_object_attribute_t *pri_template;
82454424Sizick uint_t pub_attribute_count;
82465697Smcpowers uint_t pri_attribute_count;
82474424Sizick crypto_object_attribute_t *out_pub_template;
82484424Sizick crypto_object_attribute_t *out_pri_template;
82494424Sizick uint_t out_pub_attribute_count;
82504424Sizick uint_t out_pri_attribute_count;
82514424Sizick
82524424Sizick mechp = taskq_req->dr_key_req.kr_mechanism;
82534424Sizick pub_template = taskq_req->dr_key_req.kr_template;
82544424Sizick pub_attribute_count = taskq_req->dr_key_req.kr_attribute_count;
82555697Smcpowers pri_template = taskq_req->dr_key_req.kr_private_key_template;
82565697Smcpowers pri_attribute_count =
82575697Smcpowers taskq_req->dr_key_req.kr_private_key_attribute_count;
82584424Sizick out_pub_template = taskq_req->dr_key_req.kr_out_template1;
82594424Sizick out_pub_attribute_count =
82604424Sizick taskq_req->dr_key_req.kr_out_attribute_count1;
82614424Sizick out_pri_template = taskq_req->dr_key_req.kr_out_template2;
82624424Sizick out_pri_attribute_count =
82634424Sizick taskq_req->dr_key_req.kr_out_attribute_count2;
82644424Sizick
82654424Sizick switch (mechp->cm_type) {
82664424Sizick case RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE:
82674424Sizick error = nostore_copy_attribute(out_pub_template,
82684424Sizick out_pub_attribute_count, DPROV_CKA_MODULUS);
82694424Sizick if (error != CRYPTO_SUCCESS)
82704424Sizick break;
82714424Sizick
82724424Sizick error = nostore_copy_attribute(out_pub_template,
82734424Sizick out_pub_attribute_count, DPROV_CKA_PUBLIC_EXPONENT);
82744424Sizick if (error == CRYPTO_ARGUMENTS_BAD) {
82754424Sizick size_t tmp_len = 0;
82764424Sizick void *tmp;
82774424Sizick
82784424Sizick /* public exponent must be here */
82794424Sizick error = dprov_get_template_attr_array(
82804424Sizick pub_template, pub_attribute_count,
82814424Sizick DPROV_CKA_PUBLIC_EXPONENT, &tmp, &tmp_len);
82824424Sizick if (error != CRYPTO_SUCCESS)
82834424Sizick break;
82844424Sizick }
82854424Sizick error = nostore_copy_attribute(out_pri_template,
82864424Sizick out_pri_attribute_count, DPROV_CKA_MODULUS);
82874424Sizick if (error != CRYPTO_SUCCESS)
82884424Sizick break;
82894424Sizick
82904424Sizick error = nostore_copy_attribute(out_pri_template,
82914424Sizick out_pri_attribute_count,
82924424Sizick DPROV_CKA_PRIVATE_EXPONENT);
82934424Sizick break;
82944424Sizick
82954424Sizick case DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE:
82964424Sizick /*
82974424Sizick * There is no software provider for DH mechanism;
82984424Sizick * Just return pre-defined values.
82994424Sizick */
83004424Sizick error = nostore_copy_attribute(out_pub_template,
83014424Sizick out_pub_attribute_count, DPROV_CKA_VALUE);
83024424Sizick error = nostore_copy_attribute(out_pri_template,
83034424Sizick out_pri_attribute_count, DPROV_CKA_VALUE);
83044424Sizick break;
83054424Sizick
83065697Smcpowers case EC_KEY_PAIR_GEN_MECH_INFO_TYPE: {
83075697Smcpowers crypto_mechanism_t mech, *mechp;
83085697Smcpowers kcf_req_params_t params;
83095697Smcpowers crypto_object_attribute_t *pub_template;
83105697Smcpowers uint_t pub_attribute_count;
83115697Smcpowers crypto_object_attribute_t *out_pub_template;
83125697Smcpowers crypto_object_attribute_t *out_pri_template;
83135697Smcpowers uint_t out_pub_attribute_count;
83145697Smcpowers uint_t out_pri_attribute_count;
83155697Smcpowers
83165697Smcpowers mechp = taskq_req->dr_key_req.kr_mechanism;
83175697Smcpowers pub_template = taskq_req->dr_key_req.kr_template;
83185697Smcpowers pub_attribute_count =
83195697Smcpowers taskq_req->dr_key_req.kr_attribute_count;
83205697Smcpowers out_pub_template =
83215697Smcpowers taskq_req->dr_key_req.kr_out_template1;
83225697Smcpowers out_pub_attribute_count =
83235697Smcpowers taskq_req->dr_key_req.kr_out_attribute_count1;
83245697Smcpowers out_pri_template =
83255697Smcpowers taskq_req->dr_key_req.kr_out_template2;
83265697Smcpowers out_pri_attribute_count =
83275697Smcpowers taskq_req->dr_key_req.kr_out_attribute_count2;
83285697Smcpowers
83295697Smcpowers /* get the software provider for this mechanism */
83305697Smcpowers mech = *mechp;
83315697Smcpowers if ((error = dprov_get_sw_prov(mechp, &pd,
83325697Smcpowers &mech.cm_type)) != CRYPTO_SUCCESS)
83335697Smcpowers break;
83345697Smcpowers /*
83355697Smcpowers * Turn 32-bit values into 64-bit values for certain
83365697Smcpowers * attributes like CKA_CLASS.
83375697Smcpowers */
83385697Smcpowers dprov_adjust_attrs(pub_template, pub_attribute_count);
83395697Smcpowers dprov_adjust_attrs(pri_template, pri_attribute_count);
83405697Smcpowers
83415697Smcpowers /* bypass the kernel API for now */
83425697Smcpowers KCF_WRAP_NOSTORE_KEY_OPS_PARAMS(¶ms,
83435697Smcpowers KCF_OP_KEY_GENERATE_PAIR,
83445697Smcpowers 0, /* session 0 for sw provider */
83455697Smcpowers &mech, pub_template, pub_attribute_count,
83465697Smcpowers pri_template, pri_attribute_count, NULL,
83475697Smcpowers out_pub_template, out_pub_attribute_count,
83485697Smcpowers out_pri_template, out_pri_attribute_count);
83495697Smcpowers
83505697Smcpowers error = kcf_submit_request(pd, NULL, NULL, ¶ms,
83515697Smcpowers B_FALSE);
83525697Smcpowers
83535697Smcpowers KCF_PROV_REFRELE(pd);
83545697Smcpowers break;
83555697Smcpowers }
83564424Sizick default:
83574424Sizick error = CRYPTO_MECHANISM_INVALID;
83584424Sizick }
83594424Sizick break;
83604424Sizick }
83614424Sizick
83624424Sizick case DPROV_REQ_NOSTORE_KEY_DERIVE: {
83634424Sizick crypto_mechanism_t *mechp;
83644424Sizick crypto_object_attribute_t *in_template, *out_template;
83654424Sizick crypto_key_t *base_key;
83664424Sizick uint_t in_attribute_count, out_attribute_count;
83674424Sizick ulong_t key_type;
83684424Sizick void *value;
83694424Sizick size_t value_len = 0;
83704424Sizick size_t value_len_value = 0;
83714424Sizick
83724424Sizick in_template = taskq_req->dr_key_req.kr_template;
83734424Sizick out_template = taskq_req->dr_key_req.kr_out_template1;
83744424Sizick in_attribute_count = taskq_req->dr_key_req.kr_attribute_count;
83754424Sizick out_attribute_count =
83764424Sizick taskq_req->dr_key_req.kr_out_attribute_count1;
83774424Sizick mechp = taskq_req->dr_key_req.kr_mechanism;
83784424Sizick base_key = taskq_req->dr_key_req.kr_key;
83794424Sizick
83804424Sizick /*
83814424Sizick * CKA_VALUE must be present so the derived key can
83824424Sizick * be returned by value.
83834424Sizick */
83844424Sizick if (dprov_get_template_attr_array(out_template,
83854424Sizick out_attribute_count, DPROV_CKA_VALUE, &value,
83864424Sizick &value_len) != CRYPTO_SUCCESS) {
83874424Sizick error = CRYPTO_TEMPLATE_INCOMPLETE;
83884424Sizick break;
83894424Sizick }
83904424Sizick
83914424Sizick if (dprov_get_template_attr_ulong(in_template,
83924424Sizick in_attribute_count, DPROV_CKA_KEY_TYPE,
83934424Sizick &key_type) != CRYPTO_SUCCESS) {
83944424Sizick error = CRYPTO_TEMPLATE_INCOMPLETE;
83954424Sizick break;
83964424Sizick }
83974424Sizick switch (mechp->cm_type) {
83984424Sizick case DH_PKCS_DERIVE_MECH_INFO_TYPE: {
83994424Sizick size_t tmp_len = 0;
84004424Sizick void *tmp;
84014424Sizick
84024424Sizick if (base_key->ck_format != CRYPTO_KEY_ATTR_LIST) {
84034424Sizick error = CRYPTO_ARGUMENTS_BAD;
84044424Sizick break;
84054424Sizick }
84064424Sizick
84074424Sizick if ((dprov_get_template_attr_array(base_key->ck_attrs,
84084424Sizick base_key->ck_count, DPROV_CKA_BASE, &tmp,
84094424Sizick &tmp_len) != CRYPTO_SUCCESS) ||
84104424Sizick (dprov_get_template_attr_array(base_key->ck_attrs,
84114424Sizick base_key->ck_count, DPROV_CKA_PRIME, &tmp,
84124424Sizick &tmp_len) != CRYPTO_SUCCESS) ||
84134424Sizick (dprov_get_template_attr_array(base_key->ck_attrs,
84144424Sizick base_key->ck_count, DPROV_CKA_VALUE, &tmp,
84154424Sizick &tmp_len) != CRYPTO_SUCCESS)) {
84164424Sizick error = CRYPTO_TEMPLATE_INCOMPLETE;
84174424Sizick break;
84184424Sizick }
84194424Sizick
84204424Sizick /*
84214424Sizick * CKA_VALUE is added to the derived key template by
84224424Sizick * the library.
84234424Sizick */
84244424Sizick error = CRYPTO_SUCCESS;
84254424Sizick switch (key_type) {
84264424Sizick case DPROV_CKK_AES:
84274424Sizick if (dprov_get_template_attr_ulong(in_template,
84284424Sizick in_attribute_count, DPROV_CKA_VALUE_LEN,
84294424Sizick &value_len_value) != CRYPTO_SUCCESS) {
84304424Sizick error = CRYPTO_TEMPLATE_INCOMPLETE;
84314424Sizick break;
84324424Sizick }
84334424Sizick if (value_len != value_len_value) {
84344424Sizick error = CRYPTO_TEMPLATE_INCONSISTENT;
84354424Sizick break;
84364424Sizick }
84374424Sizick default:
84384424Sizick error = CRYPTO_MECHANISM_INVALID;
84394424Sizick }
84404424Sizick if (error == CRYPTO_SUCCESS)
84414424Sizick fill_dh(value, value_len);
84424424Sizick break;
84434424Sizick }
84445697Smcpowers case ECDH1_DERIVE_MECH_INFO_TYPE: {
84455697Smcpowers crypto_mechanism_t mech;
84465697Smcpowers kcf_req_params_t params;
84475697Smcpowers
84485697Smcpowers /* get the software provider for this mechanism */
84495697Smcpowers mech = *mechp;
84505697Smcpowers if ((error = dprov_get_sw_prov(mechp, &pd,
84515697Smcpowers &mech.cm_type)) != CRYPTO_SUCCESS)
84525697Smcpowers break;
84535697Smcpowers
84545697Smcpowers /*
84555697Smcpowers * Turn 32-bit values into 64-bit values for certain
84565697Smcpowers * attributes like CKA_VALUE_LEN.
84575697Smcpowers */
84585697Smcpowers dprov_adjust_attrs(in_template, in_attribute_count);
84595697Smcpowers
84605697Smcpowers /* bypass the kernel API for now */
84615697Smcpowers KCF_WRAP_NOSTORE_KEY_OPS_PARAMS(¶ms,
84625697Smcpowers KCF_OP_KEY_DERIVE,
84635697Smcpowers 0, /* session 0 for sw provider */
84645697Smcpowers &mech, in_template, in_attribute_count,
84655697Smcpowers NULL, 0, base_key,
84665697Smcpowers out_template, out_attribute_count,
84675697Smcpowers NULL, 0);
84685697Smcpowers
84695697Smcpowers error = kcf_submit_request(pd, NULL, NULL, ¶ms,
84705697Smcpowers B_FALSE);
84715697Smcpowers
84725697Smcpowers KCF_PROV_REFRELE(pd);
84735697Smcpowers break;
84745697Smcpowers }
84755697Smcpowers
84764424Sizick default:
84774424Sizick error = CRYPTO_MECHANISM_INVALID;
84784424Sizick }
84794424Sizick break;
84804424Sizick default:
84814424Sizick error = CRYPTO_MECHANISM_INVALID;
84824424Sizick }
84834219Smcpowers } /* end case */
84840Sstevel@tonic-gate
84850Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
84860Sstevel@tonic-gate dprov_op_done(taskq_req, error);
84870Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_task: end\n", instance));
84880Sstevel@tonic-gate }
84890Sstevel@tonic-gate
84900Sstevel@tonic-gate /*
84910Sstevel@tonic-gate * taskq dispatcher function for provider management operations.
84920Sstevel@tonic-gate */
84930Sstevel@tonic-gate static void
dprov_mgmt_task(dprov_req_t * taskq_req)84940Sstevel@tonic-gate dprov_mgmt_task(dprov_req_t *taskq_req)
84950Sstevel@tonic-gate {
84960Sstevel@tonic-gate dprov_state_t *softc;
84970Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */
84980Sstevel@tonic-gate int instance;
84990Sstevel@tonic-gate int error = CRYPTO_NOT_SUPPORTED;
85000Sstevel@tonic-gate
85010Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
85020Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_mgmt_task: started\n", instance));
85030Sstevel@tonic-gate
85040Sstevel@tonic-gate mutex_enter(&softc->ds_lock);
85050Sstevel@tonic-gate
85060Sstevel@tonic-gate switch (taskq_req->dr_type) {
85070Sstevel@tonic-gate case DPROV_REQ_MGMT_EXTINFO: {
85080Sstevel@tonic-gate crypto_provider_ext_info_t *ext_info =
85090Sstevel@tonic-gate taskq_req->dr_mgmt_req.mr_ext_info;
85100Sstevel@tonic-gate
85110Sstevel@tonic-gate (void) memset(ext_info->ei_label, ' ', CRYPTO_EXT_SIZE_LABEL);
85120Sstevel@tonic-gate if (!softc->ds_token_initialized) {
85130Sstevel@tonic-gate bcopy("(not initialized)", ext_info->ei_label,
85140Sstevel@tonic-gate strlen("(not initialized)"));
85150Sstevel@tonic-gate } else {
85160Sstevel@tonic-gate bcopy(softc->ds_label, ext_info->ei_label,
85170Sstevel@tonic-gate CRYPTO_EXT_SIZE_LABEL);
85180Sstevel@tonic-gate }
85190Sstevel@tonic-gate
85200Sstevel@tonic-gate bcopy(DPROV_MANUFACTURER, ext_info->ei_manufacturerID,
85210Sstevel@tonic-gate CRYPTO_EXT_SIZE_MANUF);
85220Sstevel@tonic-gate bcopy(DPROV_MODEL, ext_info->ei_model, CRYPTO_EXT_SIZE_MODEL);
85230Sstevel@tonic-gate
85240Sstevel@tonic-gate (void) snprintf((char *)ext_info->ei_serial_number, 16, "%d%s",
85250Sstevel@tonic-gate instance, DPROV_ALLSPACES);
85260Sstevel@tonic-gate /* PKCS#11 blank padding */
85270Sstevel@tonic-gate ext_info->ei_serial_number[15] = ' ';
85280Sstevel@tonic-gate ext_info->ei_max_session_count = CRYPTO_EFFECTIVELY_INFINITE;
85290Sstevel@tonic-gate ext_info->ei_max_pin_len = (ulong_t)DPROV_MAX_PIN_LEN;
85300Sstevel@tonic-gate ext_info->ei_min_pin_len = 1;
85310Sstevel@tonic-gate ext_info->ei_total_public_memory = CRYPTO_EFFECTIVELY_INFINITE;
85320Sstevel@tonic-gate ext_info->ei_free_public_memory = CRYPTO_EFFECTIVELY_INFINITE;
85330Sstevel@tonic-gate ext_info->ei_total_private_memory = CRYPTO_EFFECTIVELY_INFINITE;
85340Sstevel@tonic-gate ext_info->ei_free_private_memory = CRYPTO_EFFECTIVELY_INFINITE;
85350Sstevel@tonic-gate ext_info->ei_hardware_version.cv_major = 1;
85360Sstevel@tonic-gate ext_info->ei_hardware_version.cv_minor = 0;
85370Sstevel@tonic-gate ext_info->ei_firmware_version.cv_major = 1;
85380Sstevel@tonic-gate ext_info->ei_firmware_version.cv_minor = 0;
85390Sstevel@tonic-gate
85400Sstevel@tonic-gate ext_info->ei_flags = CRYPTO_EXTF_RNG |
85412800Skrishna CRYPTO_EXTF_LOGIN_REQUIRED |
85420Sstevel@tonic-gate CRYPTO_EXTF_DUAL_CRYPTO_OPERATIONS;
85430Sstevel@tonic-gate if (softc->ds_user_pin_set)
85440Sstevel@tonic-gate ext_info->ei_flags |= CRYPTO_EXTF_USER_PIN_INITIALIZED;
85450Sstevel@tonic-gate if (softc->ds_token_initialized)
85460Sstevel@tonic-gate ext_info->ei_flags |= CRYPTO_EXTF_TOKEN_INITIALIZED;
85470Sstevel@tonic-gate
854811304SJanie.Lu@Sun.COM ext_info->ei_hash_max_input_len = dprov_max_digestsz;
854911304SJanie.Lu@Sun.COM ext_info->ei_hmac_max_input_len = dprov_max_digestsz;
85500Sstevel@tonic-gate error = CRYPTO_SUCCESS;
85510Sstevel@tonic-gate break;
85520Sstevel@tonic-gate }
85530Sstevel@tonic-gate case DPROV_REQ_MGMT_INITTOKEN: {
85540Sstevel@tonic-gate char *pin = taskq_req->dr_mgmt_req.mr_pin;
85550Sstevel@tonic-gate size_t pin_len = taskq_req->dr_mgmt_req.mr_pin_len;
85560Sstevel@tonic-gate char *label = taskq_req->dr_mgmt_req.mr_label;
85570Sstevel@tonic-gate
85580Sstevel@tonic-gate /* cannot initialize token when a session is open */
85590Sstevel@tonic-gate if (softc->ds_sessions_count > 0) {
85600Sstevel@tonic-gate error = CRYPTO_SESSION_EXISTS;
85610Sstevel@tonic-gate break;
85620Sstevel@tonic-gate }
85630Sstevel@tonic-gate
85640Sstevel@tonic-gate /* check PIN length */
85650Sstevel@tonic-gate if (pin_len > DPROV_MAX_PIN_LEN) {
85660Sstevel@tonic-gate error = CRYPTO_PIN_LEN_RANGE;
85670Sstevel@tonic-gate break;
85680Sstevel@tonic-gate }
85690Sstevel@tonic-gate
85700Sstevel@tonic-gate /* check PIN */
85710Sstevel@tonic-gate if (pin == NULL) {
85720Sstevel@tonic-gate error = CRYPTO_PIN_INVALID;
85730Sstevel@tonic-gate break;
85740Sstevel@tonic-gate }
85750Sstevel@tonic-gate
85760Sstevel@tonic-gate /*
85770Sstevel@tonic-gate * If the token has already been initialized, need
85780Sstevel@tonic-gate * to validate supplied PIN.
85790Sstevel@tonic-gate */
85800Sstevel@tonic-gate if (softc->ds_token_initialized &&
85810Sstevel@tonic-gate (softc->ds_so_pin_len != pin_len ||
85820Sstevel@tonic-gate strncmp(softc->ds_so_pin, pin, pin_len) != 0)) {
85830Sstevel@tonic-gate /* invalid SO PIN */
85840Sstevel@tonic-gate error = CRYPTO_PIN_INCORRECT;
85850Sstevel@tonic-gate break;
85860Sstevel@tonic-gate }
85870Sstevel@tonic-gate
85880Sstevel@tonic-gate /* set label */
85890Sstevel@tonic-gate bcopy(label, softc->ds_label, CRYPTO_EXT_SIZE_LABEL);
85900Sstevel@tonic-gate
85910Sstevel@tonic-gate /* set new SO PIN, update state */
85920Sstevel@tonic-gate bcopy(pin, softc->ds_so_pin, pin_len);
85930Sstevel@tonic-gate softc->ds_so_pin_len = pin_len;
85940Sstevel@tonic-gate softc->ds_token_initialized = B_TRUE;
85950Sstevel@tonic-gate softc->ds_user_pin_set = B_FALSE;
85960Sstevel@tonic-gate
85970Sstevel@tonic-gate error = CRYPTO_SUCCESS;
85980Sstevel@tonic-gate break;
85990Sstevel@tonic-gate }
86000Sstevel@tonic-gate case DPROV_REQ_MGMT_INITPIN: {
86010Sstevel@tonic-gate char *pin = taskq_req->dr_mgmt_req.mr_pin;
86020Sstevel@tonic-gate size_t pin_len = taskq_req->dr_mgmt_req.mr_pin_len;
86030Sstevel@tonic-gate crypto_session_id_t session_id =
86040Sstevel@tonic-gate taskq_req->dr_mgmt_req.mr_session_id;
86050Sstevel@tonic-gate
86060Sstevel@tonic-gate /* check session id */
86070Sstevel@tonic-gate if (softc->ds_sessions[session_id] == NULL) {
86080Sstevel@tonic-gate error = CRYPTO_SESSION_HANDLE_INVALID;
86090Sstevel@tonic-gate break;
86100Sstevel@tonic-gate }
86110Sstevel@tonic-gate
86120Sstevel@tonic-gate /* fail if not logged in as SO */
86130Sstevel@tonic-gate if (softc->ds_sessions[session_id]->ds_state !=
86140Sstevel@tonic-gate DPROV_SESSION_STATE_SO) {
86150Sstevel@tonic-gate error = CRYPTO_USER_NOT_LOGGED_IN;
86160Sstevel@tonic-gate break;
86170Sstevel@tonic-gate }
86180Sstevel@tonic-gate
86190Sstevel@tonic-gate /* check PIN length */
86200Sstevel@tonic-gate if (pin_len > DPROV_MAX_PIN_LEN) {
86210Sstevel@tonic-gate error = CRYPTO_PIN_LEN_RANGE;
86220Sstevel@tonic-gate break;
86230Sstevel@tonic-gate }
86240Sstevel@tonic-gate
86250Sstevel@tonic-gate /* check PIN */
86260Sstevel@tonic-gate if (pin == NULL) {
86270Sstevel@tonic-gate error = CRYPTO_PIN_INVALID;
86280Sstevel@tonic-gate break;
86290Sstevel@tonic-gate }
86300Sstevel@tonic-gate
86310Sstevel@tonic-gate /* set new normal user PIN */
86320Sstevel@tonic-gate bcopy(pin, softc->ds_user_pin, pin_len);
86330Sstevel@tonic-gate softc->ds_user_pin_len = pin_len;
86340Sstevel@tonic-gate softc->ds_user_pin_set = B_TRUE;
86350Sstevel@tonic-gate
86360Sstevel@tonic-gate error = CRYPTO_SUCCESS;
86370Sstevel@tonic-gate break;
86380Sstevel@tonic-gate }
86390Sstevel@tonic-gate case DPROV_REQ_MGMT_SETPIN: {
86400Sstevel@tonic-gate char *new_pin = taskq_req->dr_mgmt_req.mr_pin;
86410Sstevel@tonic-gate size_t new_pin_len = taskq_req->dr_mgmt_req.mr_pin_len;
86420Sstevel@tonic-gate char *old_pin = taskq_req->dr_mgmt_req.mr_old_pin;
86430Sstevel@tonic-gate size_t old_pin_len = taskq_req->dr_mgmt_req.mr_old_pin_len;
86440Sstevel@tonic-gate crypto_session_id_t session_id =
86450Sstevel@tonic-gate taskq_req->dr_mgmt_req.mr_session_id;
86460Sstevel@tonic-gate
86470Sstevel@tonic-gate /* check session id */
86480Sstevel@tonic-gate if (softc->ds_sessions[session_id] == NULL) {
86490Sstevel@tonic-gate error = CRYPTO_SESSION_HANDLE_INVALID;
86500Sstevel@tonic-gate break;
86510Sstevel@tonic-gate }
86520Sstevel@tonic-gate
86530Sstevel@tonic-gate /* check PIN length */
86540Sstevel@tonic-gate if (old_pin_len > DPROV_MAX_PIN_LEN ||
86550Sstevel@tonic-gate new_pin_len > DPROV_MAX_PIN_LEN) {
86560Sstevel@tonic-gate error = CRYPTO_PIN_LEN_RANGE;
86570Sstevel@tonic-gate break;
86580Sstevel@tonic-gate }
86590Sstevel@tonic-gate
86600Sstevel@tonic-gate /* check PIN */
86610Sstevel@tonic-gate if (old_pin == NULL || new_pin == NULL) {
86620Sstevel@tonic-gate error = CRYPTO_PIN_INVALID;
86630Sstevel@tonic-gate break;
86640Sstevel@tonic-gate }
86650Sstevel@tonic-gate
86660Sstevel@tonic-gate /* check user PIN state */
86670Sstevel@tonic-gate if (!softc->ds_user_pin_set) {
86680Sstevel@tonic-gate error = CRYPTO_USER_PIN_NOT_INITIALIZED;
86690Sstevel@tonic-gate break;
86700Sstevel@tonic-gate }
86710Sstevel@tonic-gate
86720Sstevel@tonic-gate /*
86730Sstevel@tonic-gate * If the token has already been initialized, need
86740Sstevel@tonic-gate * to validate supplied PIN.
86750Sstevel@tonic-gate */
86760Sstevel@tonic-gate if (softc->ds_user_pin_len != old_pin_len ||
86770Sstevel@tonic-gate strncmp(softc->ds_user_pin, old_pin, old_pin_len) != 0) {
86780Sstevel@tonic-gate /* invalid SO PIN */
86790Sstevel@tonic-gate error = CRYPTO_PIN_INCORRECT;
86800Sstevel@tonic-gate break;
86810Sstevel@tonic-gate }
86820Sstevel@tonic-gate
86830Sstevel@tonic-gate /* set new PIN */
86840Sstevel@tonic-gate bcopy(new_pin, softc->ds_user_pin, new_pin_len);
86850Sstevel@tonic-gate softc->ds_user_pin_len = new_pin_len;
86860Sstevel@tonic-gate
86870Sstevel@tonic-gate error = CRYPTO_SUCCESS;
86880Sstevel@tonic-gate break;
86890Sstevel@tonic-gate }
86900Sstevel@tonic-gate }
86910Sstevel@tonic-gate
86920Sstevel@tonic-gate mutex_exit(&softc->ds_lock);
86930Sstevel@tonic-gate dprov_op_done(taskq_req, error);
86940Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_mgmt_task: end\n", instance));
86950Sstevel@tonic-gate }
86960Sstevel@tonic-gate
86970Sstevel@tonic-gate /*
86980Sstevel@tonic-gate * Returns in the location pointed to by pd a pointer to the descriptor
86990Sstevel@tonic-gate * for the software provider for the specified mechanism.
87000Sstevel@tonic-gate * The provider descriptor is returned held. Returns one of the CRYPTO_
87010Sstevel@tonic-gate * error codes on failure, CRYPTO_SUCCESS on success.
87020Sstevel@tonic-gate */
87030Sstevel@tonic-gate static int
dprov_get_sw_prov(crypto_mechanism_t * mech,kcf_provider_desc_t ** pd,crypto_mech_type_t * provider_mech_type)87040Sstevel@tonic-gate dprov_get_sw_prov(crypto_mechanism_t *mech, kcf_provider_desc_t **pd,
87050Sstevel@tonic-gate crypto_mech_type_t *provider_mech_type)
87060Sstevel@tonic-gate {
87070Sstevel@tonic-gate crypto_mech_type_t kcf_mech_type = CRYPTO_MECH_INVALID;
87080Sstevel@tonic-gate int i, rv;
87090Sstevel@tonic-gate
87100Sstevel@tonic-gate /* lookup the KCF mech type associated with our mech type */
87110Sstevel@tonic-gate for (i = 0; i < sizeof (dprov_mech_info_tab)/
87120Sstevel@tonic-gate sizeof (crypto_mech_info_t); i++) {
87130Sstevel@tonic-gate if (mech->cm_type == dprov_mech_info_tab[i].cm_mech_number) {
87140Sstevel@tonic-gate kcf_mech_type = crypto_mech2id_common(
87154424Sizick dprov_mech_info_tab[i].cm_mech_name, B_TRUE);
87160Sstevel@tonic-gate }
87170Sstevel@tonic-gate }
87180Sstevel@tonic-gate
87193708Skrishna rv = kcf_get_sw_prov(kcf_mech_type, pd, NULL, B_TRUE);
87200Sstevel@tonic-gate if (rv == CRYPTO_SUCCESS)
87210Sstevel@tonic-gate *provider_mech_type = kcf_mech_type;
87220Sstevel@tonic-gate
87230Sstevel@tonic-gate return (rv);
87240Sstevel@tonic-gate }
87250Sstevel@tonic-gate
87260Sstevel@tonic-gate /*
87270Sstevel@tonic-gate * Object management helper functions.
87280Sstevel@tonic-gate */
87290Sstevel@tonic-gate
87300Sstevel@tonic-gate /*
87310Sstevel@tonic-gate * Given a crypto_key_t, return whether the key can be used or not
87320Sstevel@tonic-gate * for the specified request. The attributes used here are defined
87330Sstevel@tonic-gate * in table 42 of the PKCS#11 spec (Common secret key attributes).
87340Sstevel@tonic-gate */
87350Sstevel@tonic-gate static int
dprov_key_can_use(dprov_object_t * object,dprov_req_type_t req_type)87360Sstevel@tonic-gate dprov_key_can_use(dprov_object_t *object, dprov_req_type_t req_type)
87370Sstevel@tonic-gate {
87380Sstevel@tonic-gate boolean_t ret = 0;
87390Sstevel@tonic-gate int rv = CRYPTO_SUCCESS;
87400Sstevel@tonic-gate
87410Sstevel@tonic-gate /* check if object is allowed for specified operation */
87420Sstevel@tonic-gate switch (req_type) {
87430Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_INIT:
87440Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_ATOMIC:
87450Sstevel@tonic-gate rv = dprov_get_object_attr_boolean(object,
87460Sstevel@tonic-gate DPROV_CKA_ENCRYPT, &ret);
87470Sstevel@tonic-gate break;
87480Sstevel@tonic-gate case DPROV_REQ_DECRYPT_INIT:
87490Sstevel@tonic-gate case DPROV_REQ_DECRYPT_ATOMIC:
87500Sstevel@tonic-gate rv = dprov_get_object_attr_boolean(object,
87510Sstevel@tonic-gate DPROV_CKA_DECRYPT, &ret);
87520Sstevel@tonic-gate break;
87530Sstevel@tonic-gate case DPROV_REQ_SIGN_INIT:
87540Sstevel@tonic-gate case DPROV_REQ_SIGN_ATOMIC:
87550Sstevel@tonic-gate case DPROV_REQ_MAC_INIT:
87560Sstevel@tonic-gate case DPROV_REQ_MAC_ATOMIC:
8757904Smcpowers case DPROV_REQ_MAC_VERIFY_ATOMIC:
87580Sstevel@tonic-gate rv = dprov_get_object_attr_boolean(object,
87590Sstevel@tonic-gate DPROV_CKA_SIGN, &ret);
87600Sstevel@tonic-gate break;
87610Sstevel@tonic-gate case DPROV_REQ_SIGN_RECOVER_INIT:
87620Sstevel@tonic-gate case DPROV_REQ_SIGN_RECOVER_ATOMIC:
87630Sstevel@tonic-gate rv = dprov_get_object_attr_boolean(object,
87640Sstevel@tonic-gate DPROV_CKA_SIGN_RECOVER, &ret);
87650Sstevel@tonic-gate break;
87660Sstevel@tonic-gate case DPROV_REQ_VERIFY_INIT:
87670Sstevel@tonic-gate case DPROV_REQ_VERIFY_ATOMIC:
87680Sstevel@tonic-gate rv = dprov_get_object_attr_boolean(object,
87690Sstevel@tonic-gate DPROV_CKA_VERIFY, &ret);
87700Sstevel@tonic-gate break;
87710Sstevel@tonic-gate case DPROV_REQ_VERIFY_RECOVER_INIT:
87720Sstevel@tonic-gate case DPROV_REQ_VERIFY_RECOVER_ATOMIC:
87730Sstevel@tonic-gate rv = dprov_get_object_attr_boolean(object,
87740Sstevel@tonic-gate DPROV_CKA_VERIFY_RECOVER, &ret);
87750Sstevel@tonic-gate break;
87760Sstevel@tonic-gate case DPROV_REQ_KEY_WRAP:
87770Sstevel@tonic-gate rv = dprov_get_object_attr_boolean(object,
87780Sstevel@tonic-gate DPROV_CKA_WRAP, &ret);
87790Sstevel@tonic-gate break;
87800Sstevel@tonic-gate case DPROV_REQ_KEY_UNWRAP:
87810Sstevel@tonic-gate rv = dprov_get_object_attr_boolean(object,
87820Sstevel@tonic-gate DPROV_CKA_UNWRAP, &ret);
87830Sstevel@tonic-gate break;
87840Sstevel@tonic-gate case DPROV_REQ_DIGEST_KEY:
87850Sstevel@tonic-gate /*
87860Sstevel@tonic-gate * There is no attribute to check for; therefore,
87870Sstevel@tonic-gate * any secret key can be used.
87880Sstevel@tonic-gate */
87890Sstevel@tonic-gate ret = B_TRUE;
87900Sstevel@tonic-gate rv = CRYPTO_SUCCESS;
87910Sstevel@tonic-gate break;
87920Sstevel@tonic-gate case DPROV_REQ_KEY_DERIVE:
87930Sstevel@tonic-gate rv = dprov_get_object_attr_boolean(object,
87940Sstevel@tonic-gate DPROV_CKA_DERIVE, &ret);
87950Sstevel@tonic-gate break;
87960Sstevel@tonic-gate }
87970Sstevel@tonic-gate
87980Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS || !ret)
87990Sstevel@tonic-gate return (CRYPTO_KEY_FUNCTION_NOT_PERMITTED);
88000Sstevel@tonic-gate
88010Sstevel@tonic-gate return (CRYPTO_SUCCESS);
88020Sstevel@tonic-gate }
88030Sstevel@tonic-gate
88040Sstevel@tonic-gate /*
88050Sstevel@tonic-gate * Given a crypto_key_t corresponding to a secret key (i.e. for
88060Sstevel@tonic-gate * use with symmetric crypto algorithms) specified in raw format, by
88070Sstevel@tonic-gate * attribute, or by reference, initialize the ck_data and ck_length
88080Sstevel@tonic-gate * fields of the ret_key argument so that they specify the key value
88090Sstevel@tonic-gate * and length.
88100Sstevel@tonic-gate *
88110Sstevel@tonic-gate * For a key by value, this function uess the ck_data and ck_length,
88120Sstevel@tonic-gate * for a key by reference, it looks up the corresponding object and
88130Sstevel@tonic-gate * returns the appropriate attribute. For a key by attribute, it returns
88140Sstevel@tonic-gate * the appropriate attribute. The attributes used are CKA_VALUE to retrieve
88150Sstevel@tonic-gate * the value of the key, and CKA_VALUE_LEN to retrieve its length in bytes.
88160Sstevel@tonic-gate */
88170Sstevel@tonic-gate static int
dprov_key_value_secret(dprov_state_t * softc,crypto_session_id_t session_id,dprov_req_type_t req_type,crypto_key_t * key,crypto_key_t * ret_key)88180Sstevel@tonic-gate dprov_key_value_secret(dprov_state_t *softc, crypto_session_id_t session_id,
88190Sstevel@tonic-gate dprov_req_type_t req_type, crypto_key_t *key, crypto_key_t *ret_key)
88200Sstevel@tonic-gate {
88210Sstevel@tonic-gate ulong_t key_type;
88220Sstevel@tonic-gate int ret = CRYPTO_SUCCESS;
88230Sstevel@tonic-gate
88240Sstevel@tonic-gate ret_key->ck_format = CRYPTO_KEY_RAW;
88250Sstevel@tonic-gate
88260Sstevel@tonic-gate switch (key->ck_format) {
88270Sstevel@tonic-gate
88280Sstevel@tonic-gate case CRYPTO_KEY_RAW:
88290Sstevel@tonic-gate ret_key->ck_data = key->ck_data;
88300Sstevel@tonic-gate ret_key->ck_length = key->ck_length;
88310Sstevel@tonic-gate break;
88320Sstevel@tonic-gate
88330Sstevel@tonic-gate case CRYPTO_KEY_ATTR_LIST: {
88340Sstevel@tonic-gate void *value;
88350Sstevel@tonic-gate size_t len, value_len;
88360Sstevel@tonic-gate
88370Sstevel@tonic-gate if ((ret = dprov_get_key_attr_ulong(key, DPROV_CKA_KEY_TYPE,
88380Sstevel@tonic-gate &key_type)) != CRYPTO_SUCCESS)
88390Sstevel@tonic-gate break;
88400Sstevel@tonic-gate
88410Sstevel@tonic-gate if ((ret = dprov_get_key_attr_array(key, DPROV_CKA_VALUE,
88420Sstevel@tonic-gate &value, &len)) != CRYPTO_SUCCESS)
88430Sstevel@tonic-gate break;
88440Sstevel@tonic-gate
88450Sstevel@tonic-gate /*
88460Sstevel@tonic-gate * The length of the array is expressed in bytes.
88470Sstevel@tonic-gate * Convert to bits now since that's how keys are measured.
88480Sstevel@tonic-gate */
8849*11413Sopensolaris@drydog.com len = CRYPTO_BYTES2BITS(len);
88500Sstevel@tonic-gate
88510Sstevel@tonic-gate /* optional */
88520Sstevel@tonic-gate if ((dprov_get_key_attr_ulong(key, DPROV_CKA_VALUE_LEN,
88530Sstevel@tonic-gate &value_len)) == CRYPTO_SUCCESS) {
88540Sstevel@tonic-gate len = value_len;
88550Sstevel@tonic-gate }
88560Sstevel@tonic-gate
88570Sstevel@tonic-gate ret_key->ck_data = value;
88580Sstevel@tonic-gate ret_key->ck_length = (uint_t)len;
88590Sstevel@tonic-gate
88600Sstevel@tonic-gate break;
88610Sstevel@tonic-gate }
88620Sstevel@tonic-gate
88630Sstevel@tonic-gate case CRYPTO_KEY_REFERENCE: {
88640Sstevel@tonic-gate dprov_object_t *object;
88650Sstevel@tonic-gate void *value;
88660Sstevel@tonic-gate size_t len, value_len;
88670Sstevel@tonic-gate
88680Sstevel@tonic-gate /* check session id */
88690Sstevel@tonic-gate if (softc->ds_sessions[session_id] == NULL) {
88700Sstevel@tonic-gate ret = CRYPTO_SESSION_HANDLE_INVALID;
88710Sstevel@tonic-gate break;
88720Sstevel@tonic-gate }
88730Sstevel@tonic-gate
88740Sstevel@tonic-gate if (key->ck_obj_id >= DPROV_MAX_OBJECTS) {
88750Sstevel@tonic-gate ret = CRYPTO_KEY_HANDLE_INVALID;
88760Sstevel@tonic-gate goto bail;
88770Sstevel@tonic-gate }
88780Sstevel@tonic-gate
88790Sstevel@tonic-gate /* check if object id specified by key is valid */
88800Sstevel@tonic-gate object = softc->ds_sessions[session_id]->
88810Sstevel@tonic-gate ds_objects[key->ck_obj_id];
88820Sstevel@tonic-gate if (object == NULL) {
88830Sstevel@tonic-gate ret = CRYPTO_KEY_HANDLE_INVALID;
88840Sstevel@tonic-gate goto bail;
88850Sstevel@tonic-gate }
88860Sstevel@tonic-gate
88870Sstevel@tonic-gate /* check if object can be used for operation */
88880Sstevel@tonic-gate if ((ret = dprov_key_can_use(object, req_type)) !=
88890Sstevel@tonic-gate CRYPTO_SUCCESS)
88900Sstevel@tonic-gate goto bail;
88910Sstevel@tonic-gate
88920Sstevel@tonic-gate if ((ret = dprov_get_object_attr_ulong(object,
88930Sstevel@tonic-gate DPROV_CKA_KEY_TYPE, &key_type)) != CRYPTO_SUCCESS)
88940Sstevel@tonic-gate goto bail;
88950Sstevel@tonic-gate
88960Sstevel@tonic-gate if ((ret = dprov_get_object_attr_array(object,
88970Sstevel@tonic-gate DPROV_CKA_VALUE, &value, &len)) != CRYPTO_SUCCESS)
88980Sstevel@tonic-gate goto bail;
88990Sstevel@tonic-gate
89000Sstevel@tonic-gate /* optional */
89010Sstevel@tonic-gate if ((dprov_get_object_attr_ulong(object, DPROV_CKA_VALUE_LEN,
89020Sstevel@tonic-gate &value_len)) == CRYPTO_SUCCESS) {
89030Sstevel@tonic-gate len = value_len;
89040Sstevel@tonic-gate }
89050Sstevel@tonic-gate
89060Sstevel@tonic-gate /*
89070Sstevel@tonic-gate * The length of attributes are in bytes.
89080Sstevel@tonic-gate * Convert to bits now since that's how keys are measured.
89090Sstevel@tonic-gate */
8910*11413Sopensolaris@drydog.com len = CRYPTO_BYTES2BITS(len);
89110Sstevel@tonic-gate
89120Sstevel@tonic-gate ret_key->ck_data = value;
89130Sstevel@tonic-gate ret_key->ck_length = (uint_t)len;
89140Sstevel@tonic-gate bail:
89150Sstevel@tonic-gate break;
89160Sstevel@tonic-gate }
89170Sstevel@tonic-gate
89180Sstevel@tonic-gate default:
89190Sstevel@tonic-gate ret = CRYPTO_ARGUMENTS_BAD;
89200Sstevel@tonic-gate break;
89210Sstevel@tonic-gate }
89220Sstevel@tonic-gate
89230Sstevel@tonic-gate return (ret);
89240Sstevel@tonic-gate }
89250Sstevel@tonic-gate
89260Sstevel@tonic-gate /*
89270Sstevel@tonic-gate * Get the attribute list for the specified asymmetric key.
89280Sstevel@tonic-gate */
89290Sstevel@tonic-gate static int
dprov_key_attr_asymmetric(dprov_state_t * softc,crypto_session_id_t session_id,dprov_req_type_t req_type,crypto_key_t * key,crypto_key_t * ret_key)89300Sstevel@tonic-gate dprov_key_attr_asymmetric(dprov_state_t *softc, crypto_session_id_t session_id,
89310Sstevel@tonic-gate dprov_req_type_t req_type, crypto_key_t *key, crypto_key_t *ret_key)
89320Sstevel@tonic-gate {
89330Sstevel@tonic-gate int ret = CRYPTO_SUCCESS;
89340Sstevel@tonic-gate
89350Sstevel@tonic-gate ret_key->ck_format = CRYPTO_KEY_ATTR_LIST;
89360Sstevel@tonic-gate
89370Sstevel@tonic-gate switch (key->ck_format) {
89380Sstevel@tonic-gate
89390Sstevel@tonic-gate case CRYPTO_KEY_ATTR_LIST:
89400Sstevel@tonic-gate ret_key->ck_attrs = key->ck_attrs;
89410Sstevel@tonic-gate ret_key->ck_count = key->ck_count;
89420Sstevel@tonic-gate break;
89430Sstevel@tonic-gate
89440Sstevel@tonic-gate case CRYPTO_KEY_REFERENCE: {
89450Sstevel@tonic-gate dprov_object_t *object;
89460Sstevel@tonic-gate
89470Sstevel@tonic-gate /* check session id */
89480Sstevel@tonic-gate if (softc->ds_sessions[session_id] == NULL) {
89490Sstevel@tonic-gate ret = CRYPTO_SESSION_HANDLE_INVALID;
89500Sstevel@tonic-gate break;
89510Sstevel@tonic-gate }
89520Sstevel@tonic-gate
89530Sstevel@tonic-gate /* check if object id specified by key is valid */
89540Sstevel@tonic-gate object = softc->ds_sessions[session_id]->
89550Sstevel@tonic-gate ds_objects[key->ck_obj_id];
89560Sstevel@tonic-gate if (object == NULL) {
89570Sstevel@tonic-gate ret = CRYPTO_KEY_HANDLE_INVALID;
89580Sstevel@tonic-gate break;
89590Sstevel@tonic-gate }
89600Sstevel@tonic-gate
89610Sstevel@tonic-gate /* check if object can be used for operation */
89620Sstevel@tonic-gate if ((ret = dprov_key_can_use(object, req_type)) !=
89630Sstevel@tonic-gate CRYPTO_SUCCESS)
89640Sstevel@tonic-gate break;
89650Sstevel@tonic-gate
89660Sstevel@tonic-gate ret_key->ck_attrs = object->do_attr;
89670Sstevel@tonic-gate ret_key->ck_count = DPROV_MAX_ATTR;
89680Sstevel@tonic-gate break;
89690Sstevel@tonic-gate }
89700Sstevel@tonic-gate
89710Sstevel@tonic-gate default:
89720Sstevel@tonic-gate ret = CRYPTO_ARGUMENTS_BAD;
89730Sstevel@tonic-gate }
89740Sstevel@tonic-gate
89750Sstevel@tonic-gate return (ret);
89760Sstevel@tonic-gate }
89770Sstevel@tonic-gate
89780Sstevel@tonic-gate /*
89790Sstevel@tonic-gate * Return the index of an attribute of specified type found in
89800Sstevel@tonic-gate * the specified array of attributes. If the attribute cannot
89810Sstevel@tonic-gate * found, return -1.
89820Sstevel@tonic-gate */
89830Sstevel@tonic-gate static int
dprov_find_attr(crypto_object_attribute_t * attr,uint_t nattr,uint64_t attr_type)89840Sstevel@tonic-gate dprov_find_attr(crypto_object_attribute_t *attr, uint_t nattr,
89850Sstevel@tonic-gate uint64_t attr_type)
89860Sstevel@tonic-gate {
89870Sstevel@tonic-gate int i;
89880Sstevel@tonic-gate
89890Sstevel@tonic-gate for (i = 0; i < nattr; i++)
89900Sstevel@tonic-gate if (attr[i].oa_value != NULL &&
89910Sstevel@tonic-gate attr[i].oa_type == attr_type)
89920Sstevel@tonic-gate return (i);
89930Sstevel@tonic-gate
89940Sstevel@tonic-gate return (-1);
89950Sstevel@tonic-gate }
89960Sstevel@tonic-gate
89970Sstevel@tonic-gate /*
89980Sstevel@tonic-gate * Given the given object template and session, return whether
89990Sstevel@tonic-gate * an object can be created from that template according to the
90000Sstevel@tonic-gate * following rules:
90010Sstevel@tonic-gate * - private objects can be created only by a logged-in user
90020Sstevel@tonic-gate */
90030Sstevel@tonic-gate static int
dprov_template_can_create(dprov_session_t * session,crypto_object_attribute_t * template,uint_t nattr,boolean_t check_for_secret)90040Sstevel@tonic-gate dprov_template_can_create(dprov_session_t *session,
90050Sstevel@tonic-gate crypto_object_attribute_t *template, uint_t nattr,
90060Sstevel@tonic-gate boolean_t check_for_secret)
90070Sstevel@tonic-gate {
90080Sstevel@tonic-gate boolean_t is_private = B_FALSE;
90090Sstevel@tonic-gate ulong_t key_type, class;
90100Sstevel@tonic-gate int error;
90110Sstevel@tonic-gate
90120Sstevel@tonic-gate /* check CKA_PRIVATE attribute value */
90130Sstevel@tonic-gate error = dprov_get_template_attr_boolean(template, nattr,
90140Sstevel@tonic-gate DPROV_CKA_PRIVATE, &is_private);
90150Sstevel@tonic-gate if (error == CRYPTO_SUCCESS && is_private) {
90160Sstevel@tonic-gate /* it's a private object */
90170Sstevel@tonic-gate if (session->ds_state != DPROV_SESSION_STATE_USER) {
90180Sstevel@tonic-gate /*
90190Sstevel@tonic-gate * Cannot create private object with SO or public
90200Sstevel@tonic-gate * sessions.
90210Sstevel@tonic-gate */
90220Sstevel@tonic-gate return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
90230Sstevel@tonic-gate }
90240Sstevel@tonic-gate }
90250Sstevel@tonic-gate
90260Sstevel@tonic-gate /* all objects must have an object class attribute */
90270Sstevel@tonic-gate if (dprov_get_template_attr_ulong(template, nattr, DPROV_CKA_CLASS,
90280Sstevel@tonic-gate &class) != CRYPTO_SUCCESS) {
90290Sstevel@tonic-gate return (CRYPTO_TEMPLATE_INCOMPLETE);
90300Sstevel@tonic-gate }
90310Sstevel@tonic-gate
90320Sstevel@tonic-gate /* key objects must have a key type attribute */
90330Sstevel@tonic-gate if (class == DPROV_CKO_SECRET_KEY ||
90340Sstevel@tonic-gate class == DPROV_CKO_PUBLIC_KEY ||
90350Sstevel@tonic-gate class == DPROV_CKO_PRIVATE_KEY) {
90360Sstevel@tonic-gate if (!dprov_template_attr_present(template, nattr,
90370Sstevel@tonic-gate DPROV_CKA_KEY_TYPE)) {
90380Sstevel@tonic-gate return (CRYPTO_TEMPLATE_INCOMPLETE);
90390Sstevel@tonic-gate }
90400Sstevel@tonic-gate }
90410Sstevel@tonic-gate
90420Sstevel@tonic-gate /* check for RSA public key attributes that must be present */
90430Sstevel@tonic-gate if (class == DPROV_CKO_PUBLIC_KEY) {
90440Sstevel@tonic-gate if (dprov_get_template_attr_ulong(template, nattr,
90450Sstevel@tonic-gate DPROV_CKA_KEY_TYPE, &key_type) == CRYPTO_SUCCESS) {
90460Sstevel@tonic-gate if (key_type == DPROV_CKK_RSA) {
90470Sstevel@tonic-gate if (!dprov_template_attr_present(template,
90480Sstevel@tonic-gate nattr, DPROV_CKA_MODULUS) ||
90490Sstevel@tonic-gate !dprov_template_attr_present(template,
90500Sstevel@tonic-gate nattr, DPROV_CKA_PUBLIC_EXPONENT)) {
90510Sstevel@tonic-gate return (CRYPTO_TEMPLATE_INCOMPLETE);
90520Sstevel@tonic-gate }
90530Sstevel@tonic-gate
90540Sstevel@tonic-gate /* these attributes should not be present */
90550Sstevel@tonic-gate if (dprov_template_attr_present(template, nattr,
90560Sstevel@tonic-gate DPROV_CKA_MODULUS_BITS)) {
90570Sstevel@tonic-gate return (CRYPTO_TEMPLATE_INCONSISTENT);
90580Sstevel@tonic-gate }
90590Sstevel@tonic-gate }
90600Sstevel@tonic-gate }
90610Sstevel@tonic-gate }
90620Sstevel@tonic-gate
90630Sstevel@tonic-gate /* check for RSA private key attributes that must be present */
90640Sstevel@tonic-gate if (class == DPROV_CKO_PRIVATE_KEY) {
90650Sstevel@tonic-gate if (dprov_get_template_attr_ulong(template, nattr,
90660Sstevel@tonic-gate DPROV_CKA_KEY_TYPE, &key_type) == CRYPTO_SUCCESS) {
90670Sstevel@tonic-gate if (key_type == DPROV_CKK_RSA) {
90680Sstevel@tonic-gate if (!dprov_template_attr_present(template,
90690Sstevel@tonic-gate nattr, DPROV_CKA_MODULUS))
90700Sstevel@tonic-gate return (CRYPTO_TEMPLATE_INCOMPLETE);
90710Sstevel@tonic-gate
90720Sstevel@tonic-gate if (check_for_secret) {
90730Sstevel@tonic-gate if (!dprov_template_attr_present(
90740Sstevel@tonic-gate template, nattr,
90750Sstevel@tonic-gate DPROV_CKA_PRIVATE_EXPONENT))
90760Sstevel@tonic-gate return (
90770Sstevel@tonic-gate CRYPTO_TEMPLATE_INCOMPLETE);
90780Sstevel@tonic-gate }
90790Sstevel@tonic-gate }
90800Sstevel@tonic-gate }
90810Sstevel@tonic-gate }
90820Sstevel@tonic-gate
90830Sstevel@tonic-gate /* check for secret key attributes that must be present */
90840Sstevel@tonic-gate if (class == DPROV_CKO_SECRET_KEY) {
90850Sstevel@tonic-gate if (check_for_secret) {
90860Sstevel@tonic-gate if (!dprov_template_attr_present(template, nattr,
90870Sstevel@tonic-gate DPROV_CKA_VALUE)) {
90880Sstevel@tonic-gate return (CRYPTO_TEMPLATE_INCOMPLETE);
90890Sstevel@tonic-gate }
90900Sstevel@tonic-gate }
90910Sstevel@tonic-gate
90920Sstevel@tonic-gate /* these attributes should not be present */
90930Sstevel@tonic-gate if (dprov_template_attr_present(template, nattr,
90940Sstevel@tonic-gate DPROV_CKA_VALUE_LEN)) {
90950Sstevel@tonic-gate return (CRYPTO_TEMPLATE_INCONSISTENT);
90960Sstevel@tonic-gate }
90970Sstevel@tonic-gate }
90980Sstevel@tonic-gate
90990Sstevel@tonic-gate return (CRYPTO_SUCCESS);
91000Sstevel@tonic-gate }
91010Sstevel@tonic-gate
91020Sstevel@tonic-gate /*
91030Sstevel@tonic-gate * Create an object from the specified template. Checks whether the
91040Sstevel@tonic-gate * object can be created according to its attributes and the state
91050Sstevel@tonic-gate * of the session. The new session object id is returned. If the
91060Sstevel@tonic-gate * object is a token object, it is added to the per-instance object
91070Sstevel@tonic-gate * table as well.
91080Sstevel@tonic-gate */
91090Sstevel@tonic-gate static int
dprov_create_object_from_template(dprov_state_t * softc,dprov_session_t * session,crypto_object_attribute_t * template,uint_t nattr,crypto_object_id_t * object_id,boolean_t check_for_secret,boolean_t force)91100Sstevel@tonic-gate dprov_create_object_from_template(dprov_state_t *softc,
91110Sstevel@tonic-gate dprov_session_t *session, crypto_object_attribute_t *template,
91120Sstevel@tonic-gate uint_t nattr, crypto_object_id_t *object_id, boolean_t check_for_secret,
91130Sstevel@tonic-gate boolean_t force)
91140Sstevel@tonic-gate {
91150Sstevel@tonic-gate dprov_object_t *object;
91160Sstevel@tonic-gate boolean_t is_token = B_FALSE;
91170Sstevel@tonic-gate boolean_t extractable_attribute_present = B_FALSE;
91184219Smcpowers boolean_t sensitive_attribute_present = B_FALSE;
91190Sstevel@tonic-gate boolean_t private_attribute_present = B_FALSE;
91204219Smcpowers boolean_t token_attribute_present = B_FALSE;
91210Sstevel@tonic-gate uint_t i;
91220Sstevel@tonic-gate int error;
91230Sstevel@tonic-gate uint_t attr;
91240Sstevel@tonic-gate uint_t oattr;
9125904Smcpowers crypto_attr_type_t type;
9126904Smcpowers size_t old_len, new_len;
9127904Smcpowers offset_t offset;
91280Sstevel@tonic-gate
91290Sstevel@tonic-gate if (nattr > DPROV_MAX_ATTR)
91300Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY);
91310Sstevel@tonic-gate
91320Sstevel@tonic-gate if (!force) {
91330Sstevel@tonic-gate /* verify that object can be created */
91340Sstevel@tonic-gate if ((error = dprov_template_can_create(session, template,
91350Sstevel@tonic-gate nattr, check_for_secret)) != CRYPTO_SUCCESS)
91360Sstevel@tonic-gate return (error);
91370Sstevel@tonic-gate }
91380Sstevel@tonic-gate
91390Sstevel@tonic-gate /* allocate new object */
91400Sstevel@tonic-gate object = kmem_zalloc(sizeof (dprov_object_t), KM_SLEEP);
91410Sstevel@tonic-gate if (object == NULL)
91420Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY);
91430Sstevel@tonic-gate
91440Sstevel@tonic-gate /* is it a token object? */
91450Sstevel@tonic-gate /* check CKA_TOKEN attribute value */
91460Sstevel@tonic-gate error = dprov_get_template_attr_boolean(template, nattr,
91470Sstevel@tonic-gate DPROV_CKA_TOKEN, &is_token);
91480Sstevel@tonic-gate if (error == CRYPTO_SUCCESS && is_token) {
91490Sstevel@tonic-gate /* token object, add it to the per-instance object table */
91500Sstevel@tonic-gate for (i = 0; i < DPROV_MAX_OBJECTS; i++)
91510Sstevel@tonic-gate if (softc->ds_objects[i] == NULL)
91520Sstevel@tonic-gate break;
91530Sstevel@tonic-gate if (i == DPROV_MAX_OBJECTS)
91540Sstevel@tonic-gate /* no free slot */
91550Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY);
91560Sstevel@tonic-gate softc->ds_objects[i] = object;
91570Sstevel@tonic-gate object->do_token_idx = i;
91580Sstevel@tonic-gate DPROV_OBJECT_REFHOLD(object);
91590Sstevel@tonic-gate }
91600Sstevel@tonic-gate
91610Sstevel@tonic-gate /* add object to session object table */
91620Sstevel@tonic-gate for (i = 0; i < DPROV_MAX_OBJECTS; i++)
91630Sstevel@tonic-gate if (session->ds_objects[i] == NULL)
91640Sstevel@tonic-gate break;
91650Sstevel@tonic-gate if (i == DPROV_MAX_OBJECTS) {
91660Sstevel@tonic-gate /* no more session object slots */
91670Sstevel@tonic-gate DPROV_OBJECT_REFRELE(object);
91680Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY);
91690Sstevel@tonic-gate }
91700Sstevel@tonic-gate session->ds_objects[i] = object;
91710Sstevel@tonic-gate DPROV_OBJECT_REFHOLD(object);
91720Sstevel@tonic-gate *object_id = i;
91730Sstevel@tonic-gate
91740Sstevel@tonic-gate /* initialize object from template */
91750Sstevel@tonic-gate for (attr = 0, oattr = 0; attr < nattr; attr++) {
91760Sstevel@tonic-gate if (template[attr].oa_value == NULL)
91770Sstevel@tonic-gate continue;
9178904Smcpowers type = template[attr].oa_type;
9179904Smcpowers old_len = template[attr].oa_value_len;
9180904Smcpowers new_len = attribute_size(type, old_len);
9181904Smcpowers
9182904Smcpowers if (type == DPROV_CKA_EXTRACTABLE) {
91830Sstevel@tonic-gate extractable_attribute_present = B_TRUE;
9184904Smcpowers } else if (type == DPROV_CKA_PRIVATE) {
91850Sstevel@tonic-gate private_attribute_present = B_TRUE;
91864219Smcpowers } else if (type == DPROV_CKA_TOKEN) {
91874219Smcpowers token_attribute_present = B_TRUE;
91880Sstevel@tonic-gate }
9189904Smcpowers object->do_attr[oattr].oa_type = type;
9190904Smcpowers object->do_attr[oattr].oa_value_len = new_len;
9191904Smcpowers
9192904Smcpowers object->do_attr[oattr].oa_value = kmem_zalloc(new_len,
9193904Smcpowers KM_SLEEP);
9194904Smcpowers
9195904Smcpowers offset = 0;
9196904Smcpowers #ifdef _BIG_ENDIAN
9197904Smcpowers if (fixed_size_attribute(type)) {
9198904Smcpowers offset = old_len - new_len;
9199904Smcpowers }
9200904Smcpowers #endif
9201904Smcpowers bcopy(&template[attr].oa_value[offset],
9202904Smcpowers object->do_attr[oattr].oa_value, new_len);
92030Sstevel@tonic-gate oattr++;
92040Sstevel@tonic-gate }
92050Sstevel@tonic-gate
92060Sstevel@tonic-gate /* add boolean attributes that must be present */
92070Sstevel@tonic-gate if (extractable_attribute_present == B_FALSE) {
92080Sstevel@tonic-gate object->do_attr[oattr].oa_type = DPROV_CKA_EXTRACTABLE;
92090Sstevel@tonic-gate object->do_attr[oattr].oa_value_len = 1;
92100Sstevel@tonic-gate object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP);
92110Sstevel@tonic-gate object->do_attr[oattr].oa_value[0] = B_TRUE;
92120Sstevel@tonic-gate oattr++;
92130Sstevel@tonic-gate }
92140Sstevel@tonic-gate
92150Sstevel@tonic-gate if (private_attribute_present == B_FALSE) {
92160Sstevel@tonic-gate object->do_attr[oattr].oa_type = DPROV_CKA_PRIVATE;
92170Sstevel@tonic-gate object->do_attr[oattr].oa_value_len = 1;
92180Sstevel@tonic-gate object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP);
92190Sstevel@tonic-gate object->do_attr[oattr].oa_value[0] = B_FALSE;
92200Sstevel@tonic-gate oattr++;
92210Sstevel@tonic-gate }
92220Sstevel@tonic-gate
92234219Smcpowers if (token_attribute_present == B_FALSE) {
92244219Smcpowers object->do_attr[oattr].oa_type = DPROV_CKA_TOKEN;
92254219Smcpowers object->do_attr[oattr].oa_value_len = 1;
92264219Smcpowers object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP);
92274219Smcpowers object->do_attr[oattr].oa_value[0] = B_FALSE;
92284219Smcpowers oattr++;
92294219Smcpowers }
92304219Smcpowers
92314219Smcpowers if (sensitive_attribute_present == B_FALSE) {
92324219Smcpowers object->do_attr[oattr].oa_type = DPROV_CKA_SENSITIVE;
92334219Smcpowers object->do_attr[oattr].oa_value_len = 1;
92344219Smcpowers object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP);
92354219Smcpowers object->do_attr[oattr].oa_value[0] = B_FALSE;
92364219Smcpowers oattr++;
92374219Smcpowers }
92380Sstevel@tonic-gate return (CRYPTO_SUCCESS);
92390Sstevel@tonic-gate }
92400Sstevel@tonic-gate
92410Sstevel@tonic-gate /*
92420Sstevel@tonic-gate * Checks whether or not the object matches the specified attributes.
9243904Smcpowers *
9244904Smcpowers * PKCS#11 attributes which are longs are stored in uint32_t containers
9245904Smcpowers * so they can be matched by both 32 and 64-bit applications.
92460Sstevel@tonic-gate */
92470Sstevel@tonic-gate static boolean_t
dprov_attributes_match(dprov_object_t * object,crypto_object_attribute_t * template,uint_t nattr)92480Sstevel@tonic-gate dprov_attributes_match(dprov_object_t *object,
92490Sstevel@tonic-gate crypto_object_attribute_t *template, uint_t nattr)
92500Sstevel@tonic-gate {
9251904Smcpowers crypto_attr_type_t type;
9252904Smcpowers size_t tlen, olen, diff;
92530Sstevel@tonic-gate int ta_idx; /* template attribute index */
92540Sstevel@tonic-gate int oa_idx; /* object attribute index */
92550Sstevel@tonic-gate
92560Sstevel@tonic-gate for (ta_idx = 0; ta_idx < nattr; ta_idx++) {
92570Sstevel@tonic-gate /* no value for template attribute */
92580Sstevel@tonic-gate if (template[ta_idx].oa_value == NULL)
92590Sstevel@tonic-gate continue;
92600Sstevel@tonic-gate
92610Sstevel@tonic-gate /* find attribute in object */
9262904Smcpowers type = template[ta_idx].oa_type;
9263904Smcpowers oa_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR, type);
92640Sstevel@tonic-gate
92650Sstevel@tonic-gate if (oa_idx == -1)
92660Sstevel@tonic-gate /* attribute not found in object */
92670Sstevel@tonic-gate return (B_FALSE);
92680Sstevel@tonic-gate
9269904Smcpowers tlen = template[ta_idx].oa_value_len;
9270904Smcpowers olen = object->do_attr[oa_idx].oa_value_len;
9271904Smcpowers if (tlen < olen)
92720Sstevel@tonic-gate return (B_FALSE);
92730Sstevel@tonic-gate
9274904Smcpowers diff = 0;
9275904Smcpowers #ifdef _BIG_ENDIAN
9276904Smcpowers /* application may think attribute is 8 bytes */
9277904Smcpowers if (fixed_size_attribute(type))
9278904Smcpowers diff = tlen - olen;
9279904Smcpowers #endif
9280904Smcpowers
9281904Smcpowers if (bcmp(&template[ta_idx].oa_value[diff],
9282904Smcpowers object->do_attr[oa_idx].oa_value, olen) != 0)
92830Sstevel@tonic-gate /* value mismatch */
92840Sstevel@tonic-gate return (B_FALSE);
92850Sstevel@tonic-gate }
92860Sstevel@tonic-gate
92870Sstevel@tonic-gate return (B_TRUE);
92880Sstevel@tonic-gate }
92890Sstevel@tonic-gate
92900Sstevel@tonic-gate /*
92910Sstevel@tonic-gate * Destroy the object specified by its session and object id.
92920Sstevel@tonic-gate */
92930Sstevel@tonic-gate static int
dprov_destroy_object(dprov_state_t * softc,dprov_session_t * session,crypto_object_id_t object_id)92940Sstevel@tonic-gate dprov_destroy_object(dprov_state_t *softc, dprov_session_t *session,
92950Sstevel@tonic-gate crypto_object_id_t object_id)
92960Sstevel@tonic-gate {
92970Sstevel@tonic-gate dprov_object_t *object;
92980Sstevel@tonic-gate
92990Sstevel@tonic-gate if ((object = session->ds_objects[object_id]) == NULL)
93000Sstevel@tonic-gate return (CRYPTO_OBJECT_HANDLE_INVALID);
93010Sstevel@tonic-gate
93020Sstevel@tonic-gate /* remove from session table */
93030Sstevel@tonic-gate session->ds_objects[object_id] = NULL;
93043940Smcpowers
93053940Smcpowers if (dprov_object_is_token(object)) {
93063940Smcpowers if (!object->do_destroyed) {
93073940Smcpowers object->do_destroyed = B_TRUE;
93083940Smcpowers /* remove from per-instance token table */
93093940Smcpowers softc->ds_objects[object->do_token_idx] = NULL;
93103940Smcpowers DPROV_OBJECT_REFRELE(object);
93113940Smcpowers } else {
93123940Smcpowers DPROV_DEBUG(D_OBJECT, ("dprov_destroy_object: "
93133940Smcpowers "object %p already destroyed\n", (void *)object));
93143940Smcpowers }
93153940Smcpowers }
93163940Smcpowers
93170Sstevel@tonic-gate DPROV_OBJECT_REFRELE(object);
93180Sstevel@tonic-gate return (CRYPTO_SUCCESS);
93190Sstevel@tonic-gate }
93200Sstevel@tonic-gate
93210Sstevel@tonic-gate static int
dprov_object_can_modify(dprov_object_t * object,crypto_object_attribute_t * template,uint_t nattr)93220Sstevel@tonic-gate dprov_object_can_modify(dprov_object_t *object,
93230Sstevel@tonic-gate crypto_object_attribute_t *template, uint_t nattr)
93240Sstevel@tonic-gate {
93250Sstevel@tonic-gate ulong_t object_class;
93260Sstevel@tonic-gate
93270Sstevel@tonic-gate /* all objects should have an object class attribute */
93280Sstevel@tonic-gate if (dprov_get_object_attr_ulong(object, DPROV_CKA_CLASS,
93290Sstevel@tonic-gate &object_class) != CRYPTO_SUCCESS) {
93300Sstevel@tonic-gate return (CRYPTO_SUCCESS);
93310Sstevel@tonic-gate }
93320Sstevel@tonic-gate
93330Sstevel@tonic-gate if (object_class == DPROV_CKO_SECRET_KEY ||
93340Sstevel@tonic-gate object_class == DPROV_CKO_PUBLIC_KEY ||
93350Sstevel@tonic-gate object_class == DPROV_CKO_PRIVATE_KEY) {
93360Sstevel@tonic-gate if (dprov_template_attr_present(template, nattr,
93370Sstevel@tonic-gate DPROV_CKA_CLASS) ||
93380Sstevel@tonic-gate dprov_template_attr_present(template, nattr,
93390Sstevel@tonic-gate DPROV_CKA_KEY_TYPE))
93400Sstevel@tonic-gate return (CRYPTO_TEMPLATE_INCONSISTENT);
93410Sstevel@tonic-gate }
93420Sstevel@tonic-gate
93430Sstevel@tonic-gate switch (object_class) {
93440Sstevel@tonic-gate case DPROV_CKO_SECRET_KEY:
93450Sstevel@tonic-gate if (dprov_template_attr_present(template, nattr,
93460Sstevel@tonic-gate DPROV_CKA_VALUE))
93470Sstevel@tonic-gate return (CRYPTO_TEMPLATE_INCONSISTENT);
93480Sstevel@tonic-gate break;
93490Sstevel@tonic-gate
93500Sstevel@tonic-gate case DPROV_CKO_PUBLIC_KEY:
93510Sstevel@tonic-gate if (dprov_template_attr_present(template, nattr,
93520Sstevel@tonic-gate DPROV_CKA_MODULUS) ||
93530Sstevel@tonic-gate dprov_template_attr_present(template, nattr,
93540Sstevel@tonic-gate DPROV_CKA_PUBLIC_EXPONENT))
93550Sstevel@tonic-gate return (CRYPTO_TEMPLATE_INCONSISTENT);
93560Sstevel@tonic-gate break;
93570Sstevel@tonic-gate
93580Sstevel@tonic-gate case DPROV_CKO_PRIVATE_KEY:
93590Sstevel@tonic-gate if (dprov_template_attr_present(template, nattr,
93600Sstevel@tonic-gate DPROV_CKA_MODULUS) ||
93610Sstevel@tonic-gate dprov_template_attr_present(template, nattr,
93620Sstevel@tonic-gate DPROV_CKA_PRIVATE_EXPONENT))
93630Sstevel@tonic-gate return (CRYPTO_TEMPLATE_INCONSISTENT);
93640Sstevel@tonic-gate break;
93650Sstevel@tonic-gate
93660Sstevel@tonic-gate default:
93670Sstevel@tonic-gate return (CRYPTO_SUCCESS);
93680Sstevel@tonic-gate }
93690Sstevel@tonic-gate
93700Sstevel@tonic-gate return (CRYPTO_SUCCESS);
93710Sstevel@tonic-gate }
93720Sstevel@tonic-gate
93730Sstevel@tonic-gate /*
93740Sstevel@tonic-gate * Set the attributes specified by the template in the specified object,
93750Sstevel@tonic-gate * replacing existing ones if needed.
93760Sstevel@tonic-gate */
93770Sstevel@tonic-gate static int
dprov_object_set_attr(dprov_session_t * session,crypto_object_id_t object_id,crypto_object_attribute_t * template,uint_t nattr,boolean_t check_attributes)93780Sstevel@tonic-gate dprov_object_set_attr(dprov_session_t *session, crypto_object_id_t object_id,
93790Sstevel@tonic-gate crypto_object_attribute_t *template, uint_t nattr,
93800Sstevel@tonic-gate boolean_t check_attributes)
93810Sstevel@tonic-gate {
9382904Smcpowers crypto_attr_type_t type;
93830Sstevel@tonic-gate dprov_object_t *object;
9384904Smcpowers size_t old_len, new_len;
93850Sstevel@tonic-gate uint_t i, j;
93860Sstevel@tonic-gate int error;
93870Sstevel@tonic-gate
93880Sstevel@tonic-gate if ((object = session->ds_objects[object_id]) == NULL)
93890Sstevel@tonic-gate return (CRYPTO_OBJECT_HANDLE_INVALID);
93900Sstevel@tonic-gate
93910Sstevel@tonic-gate if (check_attributes) {
93920Sstevel@tonic-gate /* verify that attributes in the template can be modified */
93930Sstevel@tonic-gate if ((error = dprov_object_can_modify(object, template, nattr))
93940Sstevel@tonic-gate != CRYPTO_SUCCESS)
93950Sstevel@tonic-gate return (error);
93960Sstevel@tonic-gate }
93970Sstevel@tonic-gate
93980Sstevel@tonic-gate /* go through the attributes specified in the template */
93990Sstevel@tonic-gate for (i = 0; i < nattr; i++) {
94000Sstevel@tonic-gate if (template[i].oa_value == NULL)
94010Sstevel@tonic-gate continue;
94020Sstevel@tonic-gate
94030Sstevel@tonic-gate /* find attribute in object */
9404904Smcpowers type = template[i].oa_type;
9405904Smcpowers j = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR, type);
94060Sstevel@tonic-gate
94070Sstevel@tonic-gate if (j != -1) {
94080Sstevel@tonic-gate /* attribute already exists, free old value */
94090Sstevel@tonic-gate kmem_free(object->do_attr[j].oa_value,
94100Sstevel@tonic-gate object->do_attr[j].oa_value_len);
94110Sstevel@tonic-gate } else {
94120Sstevel@tonic-gate /* attribute does not exist, create it */
94130Sstevel@tonic-gate for (j = 0; j < DPROV_MAX_ATTR; j++)
94140Sstevel@tonic-gate if (object->do_attr[j].oa_value == NULL)
94150Sstevel@tonic-gate break;
94160Sstevel@tonic-gate if (j == DPROV_MAX_ATTR)
94170Sstevel@tonic-gate /* ran out of attribute slots */
94180Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY);
94190Sstevel@tonic-gate }
94200Sstevel@tonic-gate
9421904Smcpowers old_len = template[i].oa_value_len;
9422904Smcpowers new_len = attribute_size(type, old_len);
9423904Smcpowers
94240Sstevel@tonic-gate /* set object attribute value */
9425904Smcpowers object->do_attr[j].oa_value = kmem_alloc(new_len, KM_SLEEP);
9426904Smcpowers bcopy(&template[i].oa_value[old_len - new_len],
9427904Smcpowers object->do_attr[j].oa_value, new_len);
9428904Smcpowers object->do_attr[j].oa_value_len = new_len;
94290Sstevel@tonic-gate
94300Sstevel@tonic-gate /* and the type */
9431904Smcpowers object->do_attr[j].oa_type = type;
94320Sstevel@tonic-gate }
94330Sstevel@tonic-gate
94340Sstevel@tonic-gate return (CRYPTO_SUCCESS);
94350Sstevel@tonic-gate }
94360Sstevel@tonic-gate
94370Sstevel@tonic-gate
94380Sstevel@tonic-gate /*
94390Sstevel@tonic-gate * Free the specified object.
94400Sstevel@tonic-gate */
94410Sstevel@tonic-gate static void
dprov_free_object(dprov_object_t * object)94420Sstevel@tonic-gate dprov_free_object(dprov_object_t *object)
94430Sstevel@tonic-gate {
94440Sstevel@tonic-gate int i;
94450Sstevel@tonic-gate
94460Sstevel@tonic-gate /* free the object attributes values */
94470Sstevel@tonic-gate for (i = 0; i < DPROV_MAX_ATTR; i++)
94480Sstevel@tonic-gate if (object->do_attr[i].oa_value != NULL)
94490Sstevel@tonic-gate kmem_free(object->do_attr[i].oa_value,
94500Sstevel@tonic-gate object->do_attr[i].oa_value_len);
94510Sstevel@tonic-gate
94520Sstevel@tonic-gate /* free the object */
94530Sstevel@tonic-gate kmem_free(object, sizeof (dprov_object_t));
94540Sstevel@tonic-gate }
94550Sstevel@tonic-gate
94560Sstevel@tonic-gate /*
94570Sstevel@tonic-gate * Checks whether the specified object is a private or public object.
94580Sstevel@tonic-gate */
94590Sstevel@tonic-gate static boolean_t
dprov_object_is_private(dprov_object_t * object)94600Sstevel@tonic-gate dprov_object_is_private(dprov_object_t *object)
94610Sstevel@tonic-gate {
94620Sstevel@tonic-gate boolean_t ret;
94630Sstevel@tonic-gate int err;
94640Sstevel@tonic-gate
94650Sstevel@tonic-gate err = dprov_get_object_attr_boolean(object, DPROV_CKA_PRIVATE, &ret);
94660Sstevel@tonic-gate
94670Sstevel@tonic-gate if (err != CRYPTO_SUCCESS)
94680Sstevel@tonic-gate /* by default, CKA_PRIVATE is false */
94690Sstevel@tonic-gate ret = B_FALSE;
94700Sstevel@tonic-gate
94710Sstevel@tonic-gate return (ret);
94720Sstevel@tonic-gate }
94730Sstevel@tonic-gate
94740Sstevel@tonic-gate /*
94750Sstevel@tonic-gate * Checks whether the specified object is a token or session object.
94760Sstevel@tonic-gate */
94770Sstevel@tonic-gate static boolean_t
dprov_object_is_token(dprov_object_t * object)94780Sstevel@tonic-gate dprov_object_is_token(dprov_object_t *object)
94790Sstevel@tonic-gate {
94800Sstevel@tonic-gate boolean_t ret;
94810Sstevel@tonic-gate int err;
94820Sstevel@tonic-gate
94830Sstevel@tonic-gate err = dprov_get_object_attr_boolean(object, DPROV_CKA_TOKEN, &ret);
94840Sstevel@tonic-gate
94850Sstevel@tonic-gate if (err != CRYPTO_SUCCESS)
94860Sstevel@tonic-gate /* by default, CKA_TOKEN is false */
94870Sstevel@tonic-gate ret = B_FALSE;
94880Sstevel@tonic-gate
94890Sstevel@tonic-gate return (ret);
94900Sstevel@tonic-gate }
94910Sstevel@tonic-gate
94920Sstevel@tonic-gate /*
94930Sstevel@tonic-gate * Common function used by the dprov_get_object_attr_*() family of
94940Sstevel@tonic-gate * functions. Returns the value of the specified attribute of specified
94950Sstevel@tonic-gate * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID
94960Sstevel@tonic-gate * if the length of the attribute does not match the specified length,
94970Sstevel@tonic-gate * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found.
94980Sstevel@tonic-gate */
94990Sstevel@tonic-gate static int
dprov_get_object_attr_scalar_common(dprov_object_t * object,uint64_t attr_type,void * value,size_t value_len)95000Sstevel@tonic-gate dprov_get_object_attr_scalar_common(dprov_object_t *object, uint64_t attr_type,
95010Sstevel@tonic-gate void *value, size_t value_len)
95020Sstevel@tonic-gate {
95030Sstevel@tonic-gate int attr_idx;
95040Sstevel@tonic-gate size_t oa_value_len;
95050Sstevel@tonic-gate size_t offset = 0;
95060Sstevel@tonic-gate
95070Sstevel@tonic-gate if ((attr_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR,
95080Sstevel@tonic-gate attr_type)) == -1)
95090Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
95100Sstevel@tonic-gate
95110Sstevel@tonic-gate oa_value_len = object->do_attr[attr_idx].oa_value_len;
95120Sstevel@tonic-gate if (oa_value_len != value_len) {
95130Sstevel@tonic-gate /*
95140Sstevel@tonic-gate * For some attributes, it's okay to copy the value
95150Sstevel@tonic-gate * into a larger container, e.g. copy an unsigned
95160Sstevel@tonic-gate * 32-bit integer into a 64-bit container.
95170Sstevel@tonic-gate */
95180Sstevel@tonic-gate if (attr_type == DPROV_CKA_VALUE_LEN ||
95190Sstevel@tonic-gate attr_type == DPROV_CKA_KEY_TYPE ||
95200Sstevel@tonic-gate attr_type == DPROV_CKA_CLASS) {
95210Sstevel@tonic-gate if (oa_value_len < value_len) {
95220Sstevel@tonic-gate #ifdef _BIG_ENDIAN
95230Sstevel@tonic-gate offset = value_len - oa_value_len;
95240Sstevel@tonic-gate #endif
95250Sstevel@tonic-gate bzero(value, value_len);
95260Sstevel@tonic-gate goto do_copy;
95270Sstevel@tonic-gate }
95280Sstevel@tonic-gate }
95290Sstevel@tonic-gate /* incorrect attribute value length */
95300Sstevel@tonic-gate return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
95310Sstevel@tonic-gate }
95320Sstevel@tonic-gate
95330Sstevel@tonic-gate do_copy:
95340Sstevel@tonic-gate bcopy(object->do_attr[attr_idx].oa_value, (uchar_t *)value + offset,
95350Sstevel@tonic-gate oa_value_len);
95360Sstevel@tonic-gate
95370Sstevel@tonic-gate return (CRYPTO_SUCCESS);
95380Sstevel@tonic-gate }
95390Sstevel@tonic-gate
95400Sstevel@tonic-gate /*
95410Sstevel@tonic-gate * Get the value of the a boolean attribute from the specified object.
95420Sstevel@tonic-gate */
95430Sstevel@tonic-gate static int
dprov_get_object_attr_boolean(dprov_object_t * object,uint64_t attr_type,boolean_t * attr_value)95440Sstevel@tonic-gate dprov_get_object_attr_boolean(dprov_object_t *object, uint64_t attr_type,
95450Sstevel@tonic-gate boolean_t *attr_value)
95460Sstevel@tonic-gate {
95470Sstevel@tonic-gate uchar_t val;
95480Sstevel@tonic-gate int ret;
95490Sstevel@tonic-gate
95500Sstevel@tonic-gate /* PKCS#11 defines a boolean as one byte */
95510Sstevel@tonic-gate ret = dprov_get_object_attr_scalar_common(object, attr_type, &val, 1);
95520Sstevel@tonic-gate if (ret == CRYPTO_SUCCESS) {
95530Sstevel@tonic-gate *attr_value = (val == '\0') ? B_FALSE : B_TRUE;
95540Sstevel@tonic-gate }
95550Sstevel@tonic-gate return (ret);
95560Sstevel@tonic-gate }
95570Sstevel@tonic-gate
95580Sstevel@tonic-gate /*
95590Sstevel@tonic-gate * Get the value of a ulong_t attribute from the specified object.
95600Sstevel@tonic-gate */
95610Sstevel@tonic-gate static int
dprov_get_object_attr_ulong(dprov_object_t * object,uint64_t attr_type,ulong_t * attr_value)95620Sstevel@tonic-gate dprov_get_object_attr_ulong(dprov_object_t *object, uint64_t attr_type,
95630Sstevel@tonic-gate ulong_t *attr_value)
95640Sstevel@tonic-gate {
95650Sstevel@tonic-gate return (dprov_get_object_attr_scalar_common(object, attr_type,
95660Sstevel@tonic-gate attr_value, sizeof (ulong_t)));
95670Sstevel@tonic-gate }
95680Sstevel@tonic-gate
95690Sstevel@tonic-gate /*
95700Sstevel@tonic-gate * Find the specified byte array attribute of specified type in
95710Sstevel@tonic-gate * the specified object. Returns CRYPTO_SUCCESS
95720Sstevel@tonic-gate * on success or CRYPTO_ARGUMENTS_BAD if the specified
95730Sstevel@tonic-gate * attribute cannot be found.
95740Sstevel@tonic-gate */
95750Sstevel@tonic-gate static int
dprov_get_object_attr_array(dprov_object_t * object,uint64_t attr_type,void ** array,size_t * len)95760Sstevel@tonic-gate dprov_get_object_attr_array(dprov_object_t *object, uint64_t attr_type,
95770Sstevel@tonic-gate void **array, size_t *len)
95780Sstevel@tonic-gate {
95790Sstevel@tonic-gate int attr_idx;
95800Sstevel@tonic-gate
95810Sstevel@tonic-gate if ((attr_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR,
95820Sstevel@tonic-gate attr_type)) == -1)
95830Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
95840Sstevel@tonic-gate
95850Sstevel@tonic-gate *array = object->do_attr[attr_idx].oa_value;
95860Sstevel@tonic-gate *len = object->do_attr[attr_idx].oa_value_len;
95870Sstevel@tonic-gate
95880Sstevel@tonic-gate return (CRYPTO_SUCCESS);
95890Sstevel@tonic-gate }
95900Sstevel@tonic-gate
95910Sstevel@tonic-gate /*
95920Sstevel@tonic-gate * Common function used by the dprov_get_template_attr_*() family of
95930Sstevel@tonic-gate * functions. Returns the value of the specified attribute of specified
95940Sstevel@tonic-gate * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID
95950Sstevel@tonic-gate * if the length of the attribute does not match the specified length,
95960Sstevel@tonic-gate * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found.
95970Sstevel@tonic-gate */
95980Sstevel@tonic-gate static int
dprov_get_template_attr_scalar_common(crypto_object_attribute_t * template,uint_t nattr,uint64_t attr_type,void * value,size_t value_len)95990Sstevel@tonic-gate dprov_get_template_attr_scalar_common(crypto_object_attribute_t *template,
96000Sstevel@tonic-gate uint_t nattr, uint64_t attr_type, void *value, size_t value_len)
96010Sstevel@tonic-gate {
96020Sstevel@tonic-gate size_t oa_value_len;
96030Sstevel@tonic-gate size_t offset = 0;
96040Sstevel@tonic-gate int attr_idx;
96050Sstevel@tonic-gate
96060Sstevel@tonic-gate if ((attr_idx = dprov_find_attr(template, nattr, attr_type)) == -1)
96070Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
96080Sstevel@tonic-gate
96090Sstevel@tonic-gate oa_value_len = template[attr_idx].oa_value_len;
96100Sstevel@tonic-gate if (oa_value_len != value_len) {
96110Sstevel@tonic-gate /*
96120Sstevel@tonic-gate * For some attributes, it's okay to copy the value
96130Sstevel@tonic-gate * into a larger container, e.g. copy an unsigned
96140Sstevel@tonic-gate * 32-bit integer into a 64-bit container.
96150Sstevel@tonic-gate */
96160Sstevel@tonic-gate if (attr_type == DPROV_CKA_VALUE_LEN ||
96170Sstevel@tonic-gate attr_type == DPROV_CKA_KEY_TYPE ||
96180Sstevel@tonic-gate attr_type == DPROV_CKA_CLASS) {
96190Sstevel@tonic-gate if (oa_value_len < value_len) {
96200Sstevel@tonic-gate #ifdef _BIG_ENDIAN
96210Sstevel@tonic-gate offset = value_len - oa_value_len;
96220Sstevel@tonic-gate #endif
96230Sstevel@tonic-gate bzero(value, value_len);
96240Sstevel@tonic-gate goto do_copy;
96250Sstevel@tonic-gate }
96260Sstevel@tonic-gate }
96270Sstevel@tonic-gate /* incorrect attribute value length */
96280Sstevel@tonic-gate return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
96290Sstevel@tonic-gate }
96300Sstevel@tonic-gate
96310Sstevel@tonic-gate do_copy:
96320Sstevel@tonic-gate bcopy(template[attr_idx].oa_value, (uchar_t *)value + offset,
96330Sstevel@tonic-gate oa_value_len);
96340Sstevel@tonic-gate
96350Sstevel@tonic-gate return (CRYPTO_SUCCESS);
96360Sstevel@tonic-gate }
96370Sstevel@tonic-gate
96380Sstevel@tonic-gate /*
96390Sstevel@tonic-gate * Get the value of the a boolean attribute from the specified template
96400Sstevel@tonic-gate */
96410Sstevel@tonic-gate static int
dprov_get_template_attr_boolean(crypto_object_attribute_t * template,uint_t nattr,uint64_t attr_type,boolean_t * attr_value)96420Sstevel@tonic-gate dprov_get_template_attr_boolean(crypto_object_attribute_t *template,
96430Sstevel@tonic-gate uint_t nattr, uint64_t attr_type, boolean_t *attr_value)
96440Sstevel@tonic-gate {
96450Sstevel@tonic-gate uchar_t val;
96460Sstevel@tonic-gate int ret;
96470Sstevel@tonic-gate
96480Sstevel@tonic-gate /* PKCS#11 defines a boolean as one byte */
96490Sstevel@tonic-gate ret = dprov_get_template_attr_scalar_common(template, nattr,
96500Sstevel@tonic-gate attr_type, &val, 1);
96510Sstevel@tonic-gate if (ret == CRYPTO_SUCCESS) {
96520Sstevel@tonic-gate *attr_value = (val == '\0') ? B_FALSE : B_TRUE;
96530Sstevel@tonic-gate }
96540Sstevel@tonic-gate return (ret);
96550Sstevel@tonic-gate }
96560Sstevel@tonic-gate
96570Sstevel@tonic-gate /*
96580Sstevel@tonic-gate * Get the value of a ulong_t attribute from the specified template.
96590Sstevel@tonic-gate */
96600Sstevel@tonic-gate static int
dprov_get_template_attr_ulong(crypto_object_attribute_t * template,uint_t nattr,uint64_t attr_type,ulong_t * attr_value)96610Sstevel@tonic-gate dprov_get_template_attr_ulong(crypto_object_attribute_t *template,
96620Sstevel@tonic-gate uint_t nattr, uint64_t attr_type, ulong_t *attr_value)
96630Sstevel@tonic-gate {
96640Sstevel@tonic-gate return (dprov_get_template_attr_scalar_common(template, nattr,
96650Sstevel@tonic-gate attr_type, attr_value, sizeof (ulong_t)));
96660Sstevel@tonic-gate }
96670Sstevel@tonic-gate
96680Sstevel@tonic-gate static int
dprov_template_attr_present(crypto_object_attribute_t * template,uint_t nattr,uint64_t attr_type)96690Sstevel@tonic-gate dprov_template_attr_present(crypto_object_attribute_t *template,
96700Sstevel@tonic-gate uint_t nattr, uint64_t attr_type)
96710Sstevel@tonic-gate {
96720Sstevel@tonic-gate return (dprov_find_attr(template, nattr,
96730Sstevel@tonic-gate attr_type) == -1 ? B_FALSE : B_TRUE);
96740Sstevel@tonic-gate }
96750Sstevel@tonic-gate
96760Sstevel@tonic-gate /*
96770Sstevel@tonic-gate * Find the specified byte array attribute of specified type in
96780Sstevel@tonic-gate * the specified template. Returns CRYPTO_SUCCESS on success or
96790Sstevel@tonic-gate * CRYPTO_ARGUMENTS_BAD if the specified attribute cannot be found.
96800Sstevel@tonic-gate */
96810Sstevel@tonic-gate static int
dprov_get_template_attr_array(crypto_object_attribute_t * template,uint_t nattr,uint64_t attr_type,void ** array,size_t * len)96820Sstevel@tonic-gate dprov_get_template_attr_array(crypto_object_attribute_t *template,
96830Sstevel@tonic-gate uint_t nattr, uint64_t attr_type, void **array, size_t *len)
96840Sstevel@tonic-gate {
96850Sstevel@tonic-gate int attr_idx;
96860Sstevel@tonic-gate
96870Sstevel@tonic-gate if ((attr_idx = dprov_find_attr(template, nattr, attr_type)) == -1)
96880Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
96890Sstevel@tonic-gate
96900Sstevel@tonic-gate *array = template[attr_idx].oa_value;
96910Sstevel@tonic-gate *len = template[attr_idx].oa_value_len;
96920Sstevel@tonic-gate
96930Sstevel@tonic-gate return (CRYPTO_SUCCESS);
96940Sstevel@tonic-gate }
96950Sstevel@tonic-gate
96960Sstevel@tonic-gate /*
96970Sstevel@tonic-gate * Common function used by the dprov_get_key_attr_*() family of
96980Sstevel@tonic-gate * functions. Returns the value of the specified attribute of specified
96990Sstevel@tonic-gate * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID
97000Sstevel@tonic-gate * if the length of the attribute does not match the specified length,
97010Sstevel@tonic-gate * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found.
97020Sstevel@tonic-gate */
97030Sstevel@tonic-gate static int
dprov_get_key_attr_scalar_common(crypto_key_t * key,uint64_t attr_type,void * value,size_t value_len)97040Sstevel@tonic-gate dprov_get_key_attr_scalar_common(crypto_key_t *key, uint64_t attr_type,
97050Sstevel@tonic-gate void *value, size_t value_len)
97060Sstevel@tonic-gate {
97070Sstevel@tonic-gate int attr_idx;
97080Sstevel@tonic-gate
97090Sstevel@tonic-gate ASSERT(key->ck_format == CRYPTO_KEY_ATTR_LIST);
97100Sstevel@tonic-gate
97110Sstevel@tonic-gate if ((attr_idx = dprov_find_attr(key->ck_attrs, key->ck_count,
97120Sstevel@tonic-gate attr_type)) == -1)
97130Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
97140Sstevel@tonic-gate
97150Sstevel@tonic-gate if (key->ck_attrs[attr_idx].oa_value_len != value_len)
97160Sstevel@tonic-gate /* incorrect attribute value length */
97170Sstevel@tonic-gate return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
97180Sstevel@tonic-gate
97190Sstevel@tonic-gate bcopy(key->ck_attrs[attr_idx].oa_value, value, value_len);
97200Sstevel@tonic-gate
97210Sstevel@tonic-gate return (CRYPTO_SUCCESS);
97220Sstevel@tonic-gate }
97230Sstevel@tonic-gate
97240Sstevel@tonic-gate /*
97250Sstevel@tonic-gate * Get the value of a ulong_t attribute from the specified key.
97260Sstevel@tonic-gate */
97270Sstevel@tonic-gate static int
dprov_get_key_attr_ulong(crypto_key_t * key,uint64_t attr_type,ulong_t * attr_value)97280Sstevel@tonic-gate dprov_get_key_attr_ulong(crypto_key_t *key, uint64_t attr_type,
97290Sstevel@tonic-gate ulong_t *attr_value)
97300Sstevel@tonic-gate {
97310Sstevel@tonic-gate return (dprov_get_key_attr_scalar_common(key, attr_type,
97320Sstevel@tonic-gate attr_value, sizeof (ulong_t)));
97330Sstevel@tonic-gate }
97340Sstevel@tonic-gate
97350Sstevel@tonic-gate /*
97360Sstevel@tonic-gate * Find the specified byte array attribute of specified type in
97370Sstevel@tonic-gate * the specified key by attributes. Returns CRYPTO_SUCCESS
97380Sstevel@tonic-gate * on success or CRYPTO_ARGUMENTS_BAD if the specified
97390Sstevel@tonic-gate * attribute cannot be found.
97400Sstevel@tonic-gate */
97410Sstevel@tonic-gate static int
dprov_get_key_attr_array(crypto_key_t * key,uint64_t attr_type,void ** array,size_t * len)97420Sstevel@tonic-gate dprov_get_key_attr_array(crypto_key_t *key, uint64_t attr_type,
97430Sstevel@tonic-gate void **array, size_t *len)
97440Sstevel@tonic-gate {
97450Sstevel@tonic-gate int attr_idx;
97460Sstevel@tonic-gate
97470Sstevel@tonic-gate ASSERT(key->ck_format == CRYPTO_KEY_ATTR_LIST);
97480Sstevel@tonic-gate
97490Sstevel@tonic-gate if ((attr_idx = dprov_find_attr(key->ck_attrs, key->ck_count,
97500Sstevel@tonic-gate attr_type)) == -1)
97510Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD);
97520Sstevel@tonic-gate
97530Sstevel@tonic-gate *array = key->ck_attrs[attr_idx].oa_value;
97540Sstevel@tonic-gate *len = key->ck_attrs[attr_idx].oa_value_len;
97550Sstevel@tonic-gate
97560Sstevel@tonic-gate return (CRYPTO_SUCCESS);
97570Sstevel@tonic-gate }
97580Sstevel@tonic-gate
97590Sstevel@tonic-gate static void
dprov_release_session_objects(dprov_session_t * session)97600Sstevel@tonic-gate dprov_release_session_objects(dprov_session_t *session)
97610Sstevel@tonic-gate {
97620Sstevel@tonic-gate dprov_object_t *object;
97630Sstevel@tonic-gate int i;
97640Sstevel@tonic-gate
97650Sstevel@tonic-gate for (i = 0; i < DPROV_MAX_OBJECTS; i++) {
97660Sstevel@tonic-gate object = session->ds_objects[i];
97670Sstevel@tonic-gate if (object != NULL) {
97680Sstevel@tonic-gate DPROV_OBJECT_REFRELE(object);
97690Sstevel@tonic-gate }
97700Sstevel@tonic-gate }
97710Sstevel@tonic-gate }
97725697Smcpowers
97735697Smcpowers /*
97745697Smcpowers * Adjust an attribute list by turning 32-bit values into 64-bit values
97755697Smcpowers * for certain attributes like CKA_CLASS. Assumes that at least 8 bytes
97765697Smcpowers * of storage have been allocated for all attributes.
97775697Smcpowers */
97785697Smcpowers static void
dprov_adjust_attrs(crypto_object_attribute_t * in,int in_count)97795697Smcpowers dprov_adjust_attrs(crypto_object_attribute_t *in, int in_count)
97805697Smcpowers {
97815697Smcpowers int i;
97825697Smcpowers size_t offset = 0;
97835697Smcpowers ulong_t tmp = 0;
97845697Smcpowers
97855697Smcpowers for (i = 0; i < in_count; i++) {
97865697Smcpowers /*
97875697Smcpowers * For some attributes, it's okay to copy the value
97885697Smcpowers * into a larger container, e.g. copy an unsigned
97895697Smcpowers * 32-bit integer into a 64-bit container.
97905697Smcpowers */
97915697Smcpowers if (in[i].oa_type == CKA_VALUE_LEN ||
97925697Smcpowers in[i].oa_type == CKA_KEY_TYPE ||
97935697Smcpowers in[i].oa_type == CKA_CLASS) {
97945697Smcpowers if (in[i].oa_value_len < sizeof (ulong_t)) {
97955697Smcpowers #ifdef _BIG_ENDIAN
97965697Smcpowers offset = sizeof (ulong_t) - in[i].oa_value_len;
97975697Smcpowers #endif
97985697Smcpowers bcopy(in[i].oa_value, (uchar_t *)&tmp + offset,
97995697Smcpowers in[i].oa_value_len);
98005697Smcpowers bcopy(&tmp, in[i].oa_value, sizeof (ulong_t));
98015697Smcpowers in[i].oa_value_len = sizeof (ulong_t);
98025697Smcpowers }
98035697Smcpowers }
98045697Smcpowers }
98055697Smcpowers }
9806