17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 58047c9fbSmcpowers * Common Development and Distribution License (the "License"). 68047c9fbSmcpowers * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 2295014fbbSDan OpenSolaris Anderson * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate /* 287c478bd9Sstevel@tonic-gate * Dummy Cryptographic Provider: 297c478bd9Sstevel@tonic-gate * 307c478bd9Sstevel@tonic-gate * This file implements a "dummy" cryptographic provider. It is implemented 317c478bd9Sstevel@tonic-gate * as a pseudo device driver. 327c478bd9Sstevel@tonic-gate * 337c478bd9Sstevel@tonic-gate */ 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate /* 367c478bd9Sstevel@tonic-gate * This driver implements a KEF provider with the following capabilities: 377c478bd9Sstevel@tonic-gate * 387c478bd9Sstevel@tonic-gate * - registration/unregistration with KEF 397c478bd9Sstevel@tonic-gate * - digest entry points 407c478bd9Sstevel@tonic-gate * - mac entry points 417c478bd9Sstevel@tonic-gate * - ctx management 427c478bd9Sstevel@tonic-gate * - support for async requests 437c478bd9Sstevel@tonic-gate * - cipher entry points 447c478bd9Sstevel@tonic-gate * - dual entry points 457c478bd9Sstevel@tonic-gate * - sign entry points 467c478bd9Sstevel@tonic-gate * - verify entry points 477c478bd9Sstevel@tonic-gate * - dual operations entry points 487c478bd9Sstevel@tonic-gate * - dual cipher/mac operation entry points 497c478bd9Sstevel@tonic-gate * - session management 507c478bd9Sstevel@tonic-gate * - object management 517c478bd9Sstevel@tonic-gate * - key management 527c478bd9Sstevel@tonic-gate * - provider management 537c478bd9Sstevel@tonic-gate * 547c478bd9Sstevel@tonic-gate * In order to avoid duplicating the implementation of algorithms 557c478bd9Sstevel@tonic-gate * provided by software providers, this pseudo driver acts as 567c478bd9Sstevel@tonic-gate * a consumer of the framework. When invoking one of the framework's 577c478bd9Sstevel@tonic-gate * entry points, the driver specifies the software provider to 587c478bd9Sstevel@tonic-gate * be used for the operation. 597c478bd9Sstevel@tonic-gate * 607c478bd9Sstevel@tonic-gate * User management: we implement a PKCS#11 style provider which supports: 617c478bd9Sstevel@tonic-gate * - one normal user with a PIN, and 627c478bd9Sstevel@tonic-gate * - one SO user with a PIN. 637c478bd9Sstevel@tonic-gate * These values are kept in the per-instance structure, and are initialized 647c478bd9Sstevel@tonic-gate * with the provider management entry points. 657c478bd9Sstevel@tonic-gate * 667c478bd9Sstevel@tonic-gate */ 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate #include <sys/types.h> 707c478bd9Sstevel@tonic-gate #include <sys/modctl.h> 717c478bd9Sstevel@tonic-gate #include <sys/conf.h> 727c478bd9Sstevel@tonic-gate #include <sys/stat.h> 737c478bd9Sstevel@tonic-gate #include <sys/ddi.h> 747c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 757c478bd9Sstevel@tonic-gate #include <sys/kmem.h> 767c478bd9Sstevel@tonic-gate #include <sys/errno.h> 777c478bd9Sstevel@tonic-gate #include <sys/ksynch.h> 787c478bd9Sstevel@tonic-gate #include <sys/file.h> 797c478bd9Sstevel@tonic-gate #include <sys/open.h> 807c478bd9Sstevel@tonic-gate #include <sys/cred.h> 817c478bd9Sstevel@tonic-gate #include <sys/model.h> 827c478bd9Sstevel@tonic-gate #include <sys/note.h> 837c478bd9Sstevel@tonic-gate #include <sys/random.h> 847c478bd9Sstevel@tonic-gate #include <sys/byteorder.h> 857c478bd9Sstevel@tonic-gate #include <sys/crypto/common.h> 867c478bd9Sstevel@tonic-gate #include <sys/crypto/spi.h> 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate #include <sys/taskq.h> 897c478bd9Sstevel@tonic-gate #include <sys/disp.h> 907c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 917c478bd9Sstevel@tonic-gate #include <sys/crypto/impl.h> 927c478bd9Sstevel@tonic-gate #include <sys/crypto/sched_impl.h> 93894b2776Smcpowers 94f66d273dSizick #include <sys/sha2.h> 9523c57df7Smcpowers #include <modes/modes.h> 9623c57df7Smcpowers #include <aes/aes_impl.h> 97894b2776Smcpowers #include <des/des_impl.h> 98f9fbec18Smcpowers #include <ecc/ecc_impl.h> 99894b2776Smcpowers #include <blowfish/blowfish_impl.h> 100894b2776Smcpowers 1017c478bd9Sstevel@tonic-gate /* 1027c478bd9Sstevel@tonic-gate * Debugging macros. 1037c478bd9Sstevel@tonic-gate */ 1047c478bd9Sstevel@tonic-gate #ifdef DEBUG 1057c478bd9Sstevel@tonic-gate #define D_INIT 0x00000001 /* _init/_fini/_info */ 1067c478bd9Sstevel@tonic-gate #define D_ATTACH 0x00000002 /* attach/detach */ 1077c478bd9Sstevel@tonic-gate #define D_DIGEST 0x00000010 /* digest entry points */ 1087c478bd9Sstevel@tonic-gate #define D_MAC 0x00000020 /* mac entry points */ 1097c478bd9Sstevel@tonic-gate #define D_CONTEXT 0x00000040 /* context entry points */ 1107c478bd9Sstevel@tonic-gate #define D_CIPHER 0x00000080 /* cipher entry points */ 1117c478bd9Sstevel@tonic-gate #define D_SIGN 0x00000100 /* sign entry points */ 1127c478bd9Sstevel@tonic-gate #define D_VERIFY 0x00000200 /* verify entry points */ 1137c478bd9Sstevel@tonic-gate #define D_SESSION 0x00000400 /* session management entry points */ 1147c478bd9Sstevel@tonic-gate #define D_MGMT 0x00000800 /* provider management entry points */ 1157c478bd9Sstevel@tonic-gate #define D_DUAL 0x00001000 /* dual ops */ 1167c478bd9Sstevel@tonic-gate #define D_CIPHER_MAC 0x00002000 /* cipher/mac dual ops */ 1177c478bd9Sstevel@tonic-gate #define D_OBJECT 0x00004000 /* object management */ 1187c478bd9Sstevel@tonic-gate #define D_RANDOM 0x00008000 /* random number generation */ 1197c478bd9Sstevel@tonic-gate #define D_KEY 0x00010000 /* key management */ 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate static uint32_t dprov_debug = 0; 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate #define DPROV_DEBUG(f, x) if (dprov_debug & (f)) { (void) printf x; } 1247c478bd9Sstevel@tonic-gate #define DPROV_CALL(f, r, x) if (dprov_debug & (f)) { (void) r x; } 1257c478bd9Sstevel@tonic-gate #else /* DEBUG */ 1267c478bd9Sstevel@tonic-gate #define DPROV_DEBUG(f, x) 1277c478bd9Sstevel@tonic-gate #define DPROV_CALL(f, r, x) 1287c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 1297c478bd9Sstevel@tonic-gate 130034448feSmcpowers static int nostore_key_gen; 131ba5f469cSkrishna static boolean_t dprov_no_multipart = B_FALSE; 132ba5f469cSkrishna static int dprov_max_digestsz = INT_MAX; 133ba5f469cSkrishna 1347c478bd9Sstevel@tonic-gate /* 1357c478bd9Sstevel@tonic-gate * DDI entry points. 1367c478bd9Sstevel@tonic-gate */ 1377c478bd9Sstevel@tonic-gate static int dprov_attach(dev_info_t *, ddi_attach_cmd_t); 1387c478bd9Sstevel@tonic-gate static int dprov_detach(dev_info_t *, ddi_detach_cmd_t); 1397c478bd9Sstevel@tonic-gate static int dprov_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate /* 1427c478bd9Sstevel@tonic-gate * Module linkage. 1437c478bd9Sstevel@tonic-gate */ 1447c478bd9Sstevel@tonic-gate static struct cb_ops cbops = { 1457c478bd9Sstevel@tonic-gate nodev, /* cb_open */ 1467c478bd9Sstevel@tonic-gate nodev, /* cb_close */ 1477c478bd9Sstevel@tonic-gate nodev, /* cb_strategy */ 1487c478bd9Sstevel@tonic-gate nodev, /* cb_print */ 1497c478bd9Sstevel@tonic-gate nodev, /* cb_dump */ 1507c478bd9Sstevel@tonic-gate nodev, /* cb_read */ 1517c478bd9Sstevel@tonic-gate nodev, /* cb_write */ 1527c478bd9Sstevel@tonic-gate nodev, /* cb_ioctl */ 1537c478bd9Sstevel@tonic-gate nodev, /* cb_devmap */ 1547c478bd9Sstevel@tonic-gate nodev, /* cb_mmap */ 1557c478bd9Sstevel@tonic-gate nodev, /* cb_segmap */ 1567c478bd9Sstevel@tonic-gate nochpoll, /* cb_chpoll */ 1577c478bd9Sstevel@tonic-gate ddi_prop_op, /* cb_prop_op */ 1587c478bd9Sstevel@tonic-gate NULL, /* cb_streamtab */ 1597c478bd9Sstevel@tonic-gate D_MP, /* cb_flag */ 1607c478bd9Sstevel@tonic-gate CB_REV, /* cb_rev */ 1617c478bd9Sstevel@tonic-gate nodev, /* cb_aread */ 1627c478bd9Sstevel@tonic-gate nodev, /* cb_awrite */ 1637c478bd9Sstevel@tonic-gate }; 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate static struct dev_ops devops = { 1667c478bd9Sstevel@tonic-gate DEVO_REV, /* devo_rev */ 1677c478bd9Sstevel@tonic-gate 0, /* devo_refcnt */ 1687c478bd9Sstevel@tonic-gate dprov_getinfo, /* devo_getinfo */ 1697c478bd9Sstevel@tonic-gate nulldev, /* devo_identify */ 1707c478bd9Sstevel@tonic-gate nulldev, /* devo_probe */ 1717c478bd9Sstevel@tonic-gate dprov_attach, /* devo_attach */ 1727c478bd9Sstevel@tonic-gate dprov_detach, /* devo_detach */ 1737c478bd9Sstevel@tonic-gate nodev, /* devo_reset */ 1747c478bd9Sstevel@tonic-gate &cbops, /* devo_cb_ops */ 1757c478bd9Sstevel@tonic-gate NULL, /* devo_bus_ops */ 1767c478bd9Sstevel@tonic-gate NULL, /* devo_power */ 17719397407SSherry Moore ddi_quiesce_not_needed, /* devo_quiesce */ 1787c478bd9Sstevel@tonic-gate }; 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate static struct modldrv modldrv = { 1817c478bd9Sstevel@tonic-gate &mod_driverops, 182d2b32306Smcpowers "Pseudo KCF Prov (drv)", 1837c478bd9Sstevel@tonic-gate &devops 1847c478bd9Sstevel@tonic-gate }; 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate static struct modlcrypto modlcrypto = { 1877c478bd9Sstevel@tonic-gate &mod_cryptoops, 188d2b32306Smcpowers "Pseudo KCF Prov (crypto)" 1897c478bd9Sstevel@tonic-gate }; 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate static struct modlinkage modlinkage = { 1927c478bd9Sstevel@tonic-gate MODREV_1, 1937c478bd9Sstevel@tonic-gate &modldrv, 1947c478bd9Sstevel@tonic-gate &modlcrypto, 1957c478bd9Sstevel@tonic-gate NULL 1967c478bd9Sstevel@tonic-gate }; 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate /* 1997c478bd9Sstevel@tonic-gate * CSPI information (entry points, provider info, etc.) 2007c478bd9Sstevel@tonic-gate */ 2017c478bd9Sstevel@tonic-gate 2027c478bd9Sstevel@tonic-gate typedef enum dprov_mech_type { 2035151fb12Sdarrenm MD4_MECH_INFO_TYPE, /* SUN_CKM_MD4 */ 2045151fb12Sdarrenm 2057c478bd9Sstevel@tonic-gate MD5_MECH_INFO_TYPE, /* SUN_CKM_MD5 */ 2067c478bd9Sstevel@tonic-gate MD5_HMAC_MECH_INFO_TYPE, /* SUN_CKM_MD5_HMAC */ 2077c478bd9Sstevel@tonic-gate MD5_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_MD5_HMAC_GENERAL */ 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate SHA1_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA1_HMAC */ 2107c478bd9Sstevel@tonic-gate SHA1_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA1_HMAC_GENERAL */ 2117c478bd9Sstevel@tonic-gate SHA1_MECH_INFO_TYPE, /* SUN_CKM_SHA1 */ 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate SHA256_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA256_HMAC */ 2147c478bd9Sstevel@tonic-gate SHA256_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA256_HMAC_GENERAL */ 2157c478bd9Sstevel@tonic-gate SHA256_MECH_INFO_TYPE, /* SUN_CKM_SHA256 */ 2167c478bd9Sstevel@tonic-gate SHA384_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA384_HMAC */ 2177c478bd9Sstevel@tonic-gate SHA384_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA384_HMAC_GENERAL */ 2187c478bd9Sstevel@tonic-gate SHA384_MECH_INFO_TYPE, /* SUN_CKM_SHA384 */ 2197c478bd9Sstevel@tonic-gate SHA512_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA512_HMAC */ 2207c478bd9Sstevel@tonic-gate SHA512_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA512_HMAC_GENERAL */ 2217c478bd9Sstevel@tonic-gate SHA512_MECH_INFO_TYPE, /* SUN_CKM_SHA512 */ 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate DES_CBC_MECH_INFO_TYPE, /* SUN_CKM_DES_CBC */ 2247c478bd9Sstevel@tonic-gate DES3_CBC_MECH_INFO_TYPE, /* SUN_CKM_DES3_CBC */ 2257c478bd9Sstevel@tonic-gate DES_ECB_MECH_INFO_TYPE, /* SUN_CKM_DES_ECB */ 2267c478bd9Sstevel@tonic-gate DES3_ECB_MECH_INFO_TYPE, /* SUN_CKM_DES3_ECB */ 2277c478bd9Sstevel@tonic-gate 228f66d273dSizick BLOWFISH_CBC_MECH_INFO_TYPE, /* SUN_CKM_BLOWFISH_CBC */ 229f66d273dSizick BLOWFISH_ECB_MECH_INFO_TYPE, /* SUN_CKM_BLOWFISH_ECB */ 2307c478bd9Sstevel@tonic-gate AES_CBC_MECH_INFO_TYPE, /* SUN_CKM_AES_CBC */ 2317c478bd9Sstevel@tonic-gate AES_ECB_MECH_INFO_TYPE, /* SUN_CKM_AES_ECB */ 232894b2776Smcpowers AES_CTR_MECH_INFO_TYPE, /* SUN_CKM_AES_CTR */ 2332d864512Sdinak AES_CCM_MECH_INFO_TYPE, /* SUN_CKM_AES_CCM */ 234983a1033SMark Powers AES_GCM_MECH_INFO_TYPE, /* SUN_CKM_AES_GCM */ 235983a1033SMark Powers AES_GMAC_MECH_INFO_TYPE, /* SUN_CKM_AES_GMAC */ 2367c478bd9Sstevel@tonic-gate RC4_MECH_INFO_TYPE, /* SUN_CKM_RC4 */ 2377c478bd9Sstevel@tonic-gate RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_RSA_PKCS */ 2387c478bd9Sstevel@tonic-gate RSA_X_509_MECH_INFO_TYPE, /* SUN_CKM_RSA_X_509 */ 2397c478bd9Sstevel@tonic-gate MD5_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_MD5_RSA_PKCS */ 2407c478bd9Sstevel@tonic-gate SHA1_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_SHA1_RSA_PKCS */ 241f66d273dSizick SHA256_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_SHA256_RSA_PKCS */ 242f66d273dSizick SHA384_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_SHA384_RSA_PKCS */ 243f66d273dSizick SHA512_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_SHA512_RSA_PKCS */ 2447c478bd9Sstevel@tonic-gate MD5_KEY_DERIVATION_MECH_INFO_TYPE, /* SUN_CKM_MD5_KEY_DERIVATION */ 2457c478bd9Sstevel@tonic-gate SHA1_KEY_DERIVATION_MECH_INFO_TYPE, /* SUN_CKM_SHA1_KEY_DERIVATION */ 246f66d273dSizick /* SUN_CKM_SHA256_KEY_DERIVATION */ 247f66d273dSizick SHA256_KEY_DERIVATION_MECH_INFO_TYPE, 248f66d273dSizick /* SUN_CKM_SHA384_KEY_DERIVATION */ 249f66d273dSizick SHA384_KEY_DERIVATION_MECH_INFO_TYPE, 250f66d273dSizick /* SUN_CKM_SHA512_KEY_DERIVATION */ 251f66d273dSizick SHA512_KEY_DERIVATION_MECH_INFO_TYPE, 2527c478bd9Sstevel@tonic-gate DES_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_DES_KEY_GEN */ 2537c478bd9Sstevel@tonic-gate DES3_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_DES3_KEY_GEN */ 2547c478bd9Sstevel@tonic-gate AES_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_AES_KEY_GEN */ 255f66d273dSizick BLOWFISH_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_BLOWFISH_KEY_GEN */ 2567c478bd9Sstevel@tonic-gate RC4_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_RC4_KEY_GEN */ 257f9fbec18Smcpowers EC_KEY_PAIR_GEN_MECH_INFO_TYPE, /* SUN_CKM_EC_KEY_PAIR_GEN */ 258f9fbec18Smcpowers ECDSA_MECH_INFO_TYPE, /* SUN_CKM_ECDSA */ 259f9fbec18Smcpowers ECDSA_SHA1_MECH_INFO_TYPE, /* SUN_CKM_ECDSA_SHA1 */ 260f9fbec18Smcpowers ECDH1_DERIVE_MECH_INFO_TYPE, /* SUN_CKM_ECDH1_DERIVE */ 2615b0c7657Sizick DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE, /* SUN_CKM_DH_PKCS_KEY_PAIR_GEN */ 2625b0c7657Sizick DH_PKCS_DERIVE_MECH_INFO_TYPE, /* SUN_CKM_DH_PKCS_DERIVE */ 2637c478bd9Sstevel@tonic-gate RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE /* SUN_CKM_RSA_PKCS_KEY_PAIR_GEN */ 2647c478bd9Sstevel@tonic-gate } dprov_mech_type_t; 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate /* 2677c478bd9Sstevel@tonic-gate * Mechanism info structure passed to KCF during registration. 2687c478bd9Sstevel@tonic-gate */ 2697c478bd9Sstevel@tonic-gate #define MD5_DIGEST_LEN 16 /* MD5 digest size */ 2707c478bd9Sstevel@tonic-gate #define MD5_HMAC_BLOCK_SIZE 64 /* MD5-HMAC block size */ 2715b675b31SVladimir Kotal #define MD5_HMAC_MIN_KEY_LEN 1 /* MD5-HMAC min key length in bytes */ 2725b675b31SVladimir Kotal #define MD5_HMAC_MAX_KEY_LEN INT_MAX /* MD5-HMAC max key length in bytes */ 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate #define SHA1_DIGEST_LEN 20 /* SHA1 digest size */ 2757c478bd9Sstevel@tonic-gate #define SHA1_HMAC_BLOCK_SIZE 64 /* SHA1-HMAC block size */ 2765b675b31SVladimir Kotal #define SHA1_HMAC_MIN_KEY_LEN 1 /* SHA1-HMAC min key length in bytes */ 2775b675b31SVladimir Kotal #define SHA1_HMAC_MAX_KEY_LEN INT_MAX /* SHA1-HMAC max key length in bytes */ 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate #define DES_KEY_LEN 8 /* DES key length in bytes */ 2807c478bd9Sstevel@tonic-gate #define DES3_KEY_LEN 24 /* DES3 key length in bytes */ 2817c478bd9Sstevel@tonic-gate 282f66d273dSizick #define BLOWFISH_MIN_KEY_LEN 32 /* Blowfish min key length in bits */ 283f66d273dSizick #define BLOWFISH_MAX_KEY_LEN 448 /* Blowfish max key length in bits */ 2847c478bd9Sstevel@tonic-gate 2857c478bd9Sstevel@tonic-gate #define AES_MIN_KEY_LEN 16 /* AES min key length in bytes */ 2867c478bd9Sstevel@tonic-gate #define AES_MAX_KEY_LEN 32 /* AES max key length in bytes */ 2877c478bd9Sstevel@tonic-gate 2887c478bd9Sstevel@tonic-gate #define ARCFOUR_MIN_KEY_BITS 40 /* RC4 min supported key size */ 2897c478bd9Sstevel@tonic-gate #define ARCFOUR_MAX_KEY_BITS 2048 /* RC4 max supported key size */ 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate #define RSA_MIN_KEY_LEN 256 /* RSA min key length in bits */ 2927c478bd9Sstevel@tonic-gate #define RSA_MAX_KEY_LEN 4096 /* RSA max key length in bits */ 2937c478bd9Sstevel@tonic-gate 2945b0c7657Sizick #define DH_MIN_KEY_LEN 64 /* DH min key length in bits */ 2955b0c7657Sizick #define DH_MAX_KEY_LEN 4096 /* DH max key length in bits */ 2965b0c7657Sizick 2977c478bd9Sstevel@tonic-gate #define DPROV_CKM_MD5_KEY_DERIVATION "CKM_MD5_KEY_DERIVATION" 2987c478bd9Sstevel@tonic-gate #define DPROV_CKM_SHA1_KEY_DERIVATION "CKM_SHA1_KEY_DERIVATION" 299f66d273dSizick #define DPROV_CKM_SHA256_KEY_DERIVATION "CKM_SHA256_KEY_DERIVATION" 300f66d273dSizick #define DPROV_CKM_SHA384_KEY_DERIVATION "CKM_SHA384_KEY_DERIVATION" 301f66d273dSizick #define DPROV_CKM_SHA512_KEY_DERIVATION "CKM_SHA512_KEY_DERIVATION" 3027c478bd9Sstevel@tonic-gate #define DPROV_CKM_DES_KEY_GEN "CKM_DES_KEY_GEN" 3037c478bd9Sstevel@tonic-gate #define DPROV_CKM_DES3_KEY_GEN "CKM_DES3_KEY_GEN" 3047c478bd9Sstevel@tonic-gate #define DPROV_CKM_AES_KEY_GEN "CKM_AES_KEY_GEN" 305f66d273dSizick #define DPROV_CKM_BLOWFISH_KEY_GEN "CKM_BLOWFISH_KEY_GEN" 3067c478bd9Sstevel@tonic-gate #define DPROV_CKM_RC4_KEY_GEN "CKM_RC4_KEY_GEN" 3077c478bd9Sstevel@tonic-gate #define DPROV_CKM_RSA_PKCS_KEY_PAIR_GEN "CKM_RSA_PKCS_KEY_PAIR_GEN" 308f9fbec18Smcpowers #define DPROV_CKM_EC_KEY_PAIR_GEN "CKM_EC_KEY_PAIR_GEN" 309f9fbec18Smcpowers #define DPROV_CKM_ECDSA "CKM_ECDSA" 310f9fbec18Smcpowers #define DPROV_CKM_ECDSA_SHA1 "CKM_ECDSA_SHA1" 311f9fbec18Smcpowers #define DPROV_CKM_ECDH1_DERIVE "CKM_ECDH1_DERIVE" 3125b0c7657Sizick #define DPROV_CKM_DH_PKCS_KEY_PAIR_GEN "CKM_DH_PKCS_KEY_PAIR_GEN" 3135b0c7657Sizick #define DPROV_CKM_DH_PKCS_DERIVE "CKM_DH_PKCS_DERIVE" 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate static crypto_mech_info_t dprov_mech_info_tab[] = { 3165151fb12Sdarrenm /* MD4 */ 3175151fb12Sdarrenm {SUN_CKM_MD4, MD4_MECH_INFO_TYPE, 3185151fb12Sdarrenm CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0, 3195151fb12Sdarrenm CRYPTO_KEYSIZE_UNIT_IN_BITS}, 3207c478bd9Sstevel@tonic-gate /* MD5 */ 3217c478bd9Sstevel@tonic-gate {SUN_CKM_MD5, MD5_MECH_INFO_TYPE, 3227c478bd9Sstevel@tonic-gate CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0, 3237c478bd9Sstevel@tonic-gate CRYPTO_KEYSIZE_UNIT_IN_BITS}, 3247c478bd9Sstevel@tonic-gate /* MD5-HMAC */ 3257c478bd9Sstevel@tonic-gate {SUN_CKM_MD5_HMAC, MD5_HMAC_MECH_INFO_TYPE, 3267c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | 3277c478bd9Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 3287c478bd9Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 3297c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT | 3307c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, 3317c478bd9Sstevel@tonic-gate MD5_HMAC_MIN_KEY_LEN, MD5_HMAC_MAX_KEY_LEN, 3325b675b31SVladimir Kotal CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 3337c478bd9Sstevel@tonic-gate /* MD5-HMAC GENERAL */ 3347c478bd9Sstevel@tonic-gate {SUN_CKM_MD5_HMAC_GENERAL, MD5_HMAC_GEN_MECH_INFO_TYPE, 3357c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | 3367c478bd9Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 3377c478bd9Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 3387c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT | 3397c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, 3407c478bd9Sstevel@tonic-gate MD5_HMAC_MIN_KEY_LEN, MD5_HMAC_MAX_KEY_LEN, 3415b675b31SVladimir Kotal CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 3427c478bd9Sstevel@tonic-gate /* SHA1 */ 3437c478bd9Sstevel@tonic-gate {SUN_CKM_SHA1, SHA1_MECH_INFO_TYPE, 3447c478bd9Sstevel@tonic-gate CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0, 3457c478bd9Sstevel@tonic-gate CRYPTO_KEYSIZE_UNIT_IN_BITS}, 3467c478bd9Sstevel@tonic-gate /* SHA1-HMAC */ 3477c478bd9Sstevel@tonic-gate {SUN_CKM_SHA1_HMAC, SHA1_HMAC_MECH_INFO_TYPE, 3487c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | 3497c478bd9Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 3507c478bd9Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 3517c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT | 3527c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, 3537c478bd9Sstevel@tonic-gate SHA1_HMAC_MIN_KEY_LEN, SHA1_HMAC_MAX_KEY_LEN, 3545b675b31SVladimir Kotal CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 3557c478bd9Sstevel@tonic-gate /* SHA1-HMAC GENERAL */ 3567c478bd9Sstevel@tonic-gate {SUN_CKM_SHA1_HMAC_GENERAL, SHA1_HMAC_GEN_MECH_INFO_TYPE, 3577c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | 3587c478bd9Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 3597c478bd9Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 3607c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT | 3617c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, 3627c478bd9Sstevel@tonic-gate SHA1_HMAC_MIN_KEY_LEN, SHA1_HMAC_MAX_KEY_LEN, 3635b675b31SVladimir Kotal CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 3647c478bd9Sstevel@tonic-gate /* SHA256 */ 3657c478bd9Sstevel@tonic-gate {SUN_CKM_SHA256, SHA256_MECH_INFO_TYPE, 3667c478bd9Sstevel@tonic-gate CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0, 3677c478bd9Sstevel@tonic-gate CRYPTO_KEYSIZE_UNIT_IN_BITS}, 3687c478bd9Sstevel@tonic-gate /* SHA256-HMAC */ 3697c478bd9Sstevel@tonic-gate {SUN_CKM_SHA256_HMAC, SHA256_HMAC_MECH_INFO_TYPE, 3707c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | 3717c478bd9Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 3727c478bd9Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 3737c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT | 3747c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, 3757c478bd9Sstevel@tonic-gate SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN, 3765b675b31SVladimir Kotal CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 3777c478bd9Sstevel@tonic-gate /* SHA256-HMAC GENERAL */ 3787c478bd9Sstevel@tonic-gate {SUN_CKM_SHA256_HMAC_GENERAL, SHA256_HMAC_GEN_MECH_INFO_TYPE, 3797c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | 3807c478bd9Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 3817c478bd9Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 3827c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT | 3837c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, 3847c478bd9Sstevel@tonic-gate SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN, 3855b675b31SVladimir Kotal CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 3867c478bd9Sstevel@tonic-gate /* SHA384 */ 3877c478bd9Sstevel@tonic-gate {SUN_CKM_SHA384, SHA384_MECH_INFO_TYPE, 3887c478bd9Sstevel@tonic-gate CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0, 3897c478bd9Sstevel@tonic-gate CRYPTO_KEYSIZE_UNIT_IN_BITS}, 3907c478bd9Sstevel@tonic-gate /* SHA384-HMAC */ 3917c478bd9Sstevel@tonic-gate {SUN_CKM_SHA384_HMAC, SHA384_HMAC_MECH_INFO_TYPE, 3927c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | 3937c478bd9Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 3947c478bd9Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 3957c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT | 3967c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, 3977c478bd9Sstevel@tonic-gate SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN, 3985b675b31SVladimir Kotal CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 3997c478bd9Sstevel@tonic-gate /* SHA384-HMAC GENERAL */ 4007c478bd9Sstevel@tonic-gate {SUN_CKM_SHA384_HMAC_GENERAL, SHA384_HMAC_GEN_MECH_INFO_TYPE, 4017c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | 4027c478bd9Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 4037c478bd9Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 4047c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT | 4057c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, 4067c478bd9Sstevel@tonic-gate SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN, 4075b675b31SVladimir Kotal CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 4087c478bd9Sstevel@tonic-gate /* SHA512 */ 4097c478bd9Sstevel@tonic-gate {SUN_CKM_SHA512, SHA512_MECH_INFO_TYPE, 4107c478bd9Sstevel@tonic-gate CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0, 4117c478bd9Sstevel@tonic-gate CRYPTO_KEYSIZE_UNIT_IN_BITS}, 4127c478bd9Sstevel@tonic-gate /* SHA512-HMAC */ 4137c478bd9Sstevel@tonic-gate {SUN_CKM_SHA512_HMAC, SHA512_HMAC_MECH_INFO_TYPE, 4147c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | 4157c478bd9Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 4167c478bd9Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 4177c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT | 4187c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, 4197c478bd9Sstevel@tonic-gate SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN, 4205b675b31SVladimir Kotal CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 4217c478bd9Sstevel@tonic-gate /* SHA512-HMAC GENERAL */ 4227c478bd9Sstevel@tonic-gate {SUN_CKM_SHA512_HMAC_GENERAL, SHA512_HMAC_GEN_MECH_INFO_TYPE, 4237c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | 4247c478bd9Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 4257c478bd9Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 4267c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT | 4277c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, 4287c478bd9Sstevel@tonic-gate SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN, 4295b675b31SVladimir Kotal CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 4307c478bd9Sstevel@tonic-gate /* DES-CBC */ 4317c478bd9Sstevel@tonic-gate {SUN_CKM_DES_CBC, DES_CBC_MECH_INFO_TYPE, 4327c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 4337c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 4347c478bd9Sstevel@tonic-gate CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 4357c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT_ATOMIC, 4367c478bd9Sstevel@tonic-gate DES_KEY_LEN, DES_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 4377c478bd9Sstevel@tonic-gate /* DES3-CBC */ 4387c478bd9Sstevel@tonic-gate {SUN_CKM_DES3_CBC, DES3_CBC_MECH_INFO_TYPE, 4397c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 4407c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 4417c478bd9Sstevel@tonic-gate CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 4427c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT_ATOMIC, 4437c478bd9Sstevel@tonic-gate DES3_KEY_LEN, DES3_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 4447c478bd9Sstevel@tonic-gate /* DES-ECB */ 4457c478bd9Sstevel@tonic-gate {SUN_CKM_DES_ECB, DES_ECB_MECH_INFO_TYPE, 4467c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 4477c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 4487c478bd9Sstevel@tonic-gate CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 4497c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT_ATOMIC, 4507c478bd9Sstevel@tonic-gate DES_KEY_LEN, DES_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 4517c478bd9Sstevel@tonic-gate /* DES3-ECB */ 4527c478bd9Sstevel@tonic-gate {SUN_CKM_DES3_ECB, DES3_ECB_MECH_INFO_TYPE, 4537c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 4547c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 4557c478bd9Sstevel@tonic-gate CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 4567c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT_ATOMIC, 4577c478bd9Sstevel@tonic-gate DES3_KEY_LEN, DES3_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 458f66d273dSizick /* BLOWFISH-CBC */ 459f66d273dSizick {SUN_CKM_BLOWFISH_CBC, BLOWFISH_CBC_MECH_INFO_TYPE, 4607c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 4617c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 4627c478bd9Sstevel@tonic-gate CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 463f66d273dSizick CRYPTO_FG_MAC_DECRYPT_ATOMIC, BLOWFISH_MIN_KEY_LEN, 464f66d273dSizick BLOWFISH_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 465f66d273dSizick /* BLOWFISH-ECB */ 466f66d273dSizick {SUN_CKM_BLOWFISH_ECB, BLOWFISH_ECB_MECH_INFO_TYPE, 4677c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 4687c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 4697c478bd9Sstevel@tonic-gate CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 470f66d273dSizick CRYPTO_FG_MAC_DECRYPT_ATOMIC, BLOWFISH_MIN_KEY_LEN, 471f66d273dSizick BLOWFISH_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 4727c478bd9Sstevel@tonic-gate /* AES-CBC */ 4737c478bd9Sstevel@tonic-gate {SUN_CKM_AES_CBC, AES_CBC_MECH_INFO_TYPE, 4747c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 4757c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 4767c478bd9Sstevel@tonic-gate CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 4777c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT_ATOMIC, 4787c478bd9Sstevel@tonic-gate AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 4797c478bd9Sstevel@tonic-gate /* AES-ECB */ 4807c478bd9Sstevel@tonic-gate {SUN_CKM_AES_ECB, AES_ECB_MECH_INFO_TYPE, 4817c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 4827c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 4837c478bd9Sstevel@tonic-gate CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 4847c478bd9Sstevel@tonic-gate CRYPTO_FG_MAC_DECRYPT_ATOMIC, 4857c478bd9Sstevel@tonic-gate AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 486894b2776Smcpowers /* AES-CTR */ 487894b2776Smcpowers {SUN_CKM_AES_CTR, AES_CTR_MECH_INFO_TYPE, 488894b2776Smcpowers CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 489894b2776Smcpowers CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 490894b2776Smcpowers CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 491894b2776Smcpowers CRYPTO_FG_MAC_DECRYPT_ATOMIC, 492894b2776Smcpowers AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 4932d864512Sdinak /* AES-CCM */ 4942d864512Sdinak {SUN_CKM_AES_CCM, AES_CCM_MECH_INFO_TYPE, 4952d864512Sdinak CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 4962d864512Sdinak CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 4972d864512Sdinak CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 4982d864512Sdinak CRYPTO_FG_MAC_DECRYPT_ATOMIC, 4992d864512Sdinak AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 5004d703b5cSMark Powers /* AES-GCM */ 5014d703b5cSMark Powers {SUN_CKM_AES_GCM, AES_GCM_MECH_INFO_TYPE, 5024d703b5cSMark Powers CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 5034d703b5cSMark Powers CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 5044d703b5cSMark Powers CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 5054d703b5cSMark Powers CRYPTO_FG_MAC_DECRYPT_ATOMIC, 5064d703b5cSMark Powers AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 507983a1033SMark Powers /* AES-GMAC */ 508983a1033SMark Powers {SUN_CKM_AES_GMAC, AES_GMAC_MECH_INFO_TYPE, 509983a1033SMark Powers CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 510983a1033SMark Powers CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 511983a1033SMark Powers CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 512983a1033SMark Powers CRYPTO_FG_MAC_DECRYPT_ATOMIC | 513983a1033SMark Powers CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 514983a1033SMark Powers CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 515983a1033SMark Powers AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 5167c478bd9Sstevel@tonic-gate /* RC4 */ 5177c478bd9Sstevel@tonic-gate {SUN_CKM_RC4, RC4_MECH_INFO_TYPE, 5187c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 5197c478bd9Sstevel@tonic-gate CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC, 5207c478bd9Sstevel@tonic-gate ARCFOUR_MIN_KEY_BITS, ARCFOUR_MAX_KEY_BITS, 5216a1073f8Skrishna CRYPTO_KEYSIZE_UNIT_IN_BITS | CRYPTO_CAN_SHARE_OPSTATE}, 5227c478bd9Sstevel@tonic-gate /* RSA_PKCS */ 5237c478bd9Sstevel@tonic-gate {SUN_CKM_RSA_PKCS, RSA_PKCS_MECH_INFO_TYPE, 5247c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 5257c478bd9Sstevel@tonic-gate CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC | 5267c478bd9Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 5277c478bd9Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 5287c478bd9Sstevel@tonic-gate CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC | 5297c478bd9Sstevel@tonic-gate CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC, 5307c478bd9Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 5317c478bd9Sstevel@tonic-gate /* RSA_X_509 */ 5327c478bd9Sstevel@tonic-gate {SUN_CKM_RSA_X_509, RSA_X_509_MECH_INFO_TYPE, 5337c478bd9Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 5347c478bd9Sstevel@tonic-gate CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC | 5357c478bd9Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 5367c478bd9Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 5377c478bd9Sstevel@tonic-gate CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC | 5387c478bd9Sstevel@tonic-gate CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC, 5397c478bd9Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 5407c478bd9Sstevel@tonic-gate /* MD5_RSA_PKCS */ 5417c478bd9Sstevel@tonic-gate {SUN_CKM_MD5_RSA_PKCS, MD5_RSA_PKCS_MECH_INFO_TYPE, 5427c478bd9Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 5437c478bd9Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 5447c478bd9Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 5457c478bd9Sstevel@tonic-gate /* SHA1_RSA_PKCS */ 5467c478bd9Sstevel@tonic-gate {SUN_CKM_SHA1_RSA_PKCS, SHA1_RSA_PKCS_MECH_INFO_TYPE, 5477c478bd9Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 5487c478bd9Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 5497c478bd9Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 550f66d273dSizick /* SHA256_RSA_PKCS */ 551f66d273dSizick {SUN_CKM_SHA256_RSA_PKCS, SHA256_RSA_PKCS_MECH_INFO_TYPE, 552f66d273dSizick CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 553f66d273dSizick CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 554f66d273dSizick RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 555f66d273dSizick /* SHA384_RSA_PKCS */ 556f66d273dSizick {SUN_CKM_SHA384_RSA_PKCS, SHA384_RSA_PKCS_MECH_INFO_TYPE, 557f66d273dSizick CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 558f66d273dSizick CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 559f66d273dSizick RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 560f66d273dSizick /* SHA512_RSA_PKCS */ 561f66d273dSizick {SUN_CKM_SHA512_RSA_PKCS, SHA512_RSA_PKCS_MECH_INFO_TYPE, 562f66d273dSizick CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 563f66d273dSizick CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 564f66d273dSizick RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 5657c478bd9Sstevel@tonic-gate /* MD5_KEY_DERIVATION */ 5667c478bd9Sstevel@tonic-gate {DPROV_CKM_MD5_KEY_DERIVATION, MD5_KEY_DERIVATION_MECH_INFO_TYPE, 5677c478bd9Sstevel@tonic-gate CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 5687c478bd9Sstevel@tonic-gate /* SHA1_KEY_DERIVATION */ 5697c478bd9Sstevel@tonic-gate {DPROV_CKM_SHA1_KEY_DERIVATION, SHA1_KEY_DERIVATION_MECH_INFO_TYPE, 5707c478bd9Sstevel@tonic-gate CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 571f66d273dSizick /* SHA256_KEY_DERIVATION */ 572f66d273dSizick {DPROV_CKM_SHA256_KEY_DERIVATION, SHA256_KEY_DERIVATION_MECH_INFO_TYPE, 573f66d273dSizick CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 574f66d273dSizick /* SHA384_KEY_DERIVATION */ 575f66d273dSizick {DPROV_CKM_SHA384_KEY_DERIVATION, SHA384_KEY_DERIVATION_MECH_INFO_TYPE, 576f66d273dSizick CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 577f66d273dSizick /* SHA512_KEY_DERIVATION */ 578f66d273dSizick {DPROV_CKM_SHA512_KEY_DERIVATION, SHA512_KEY_DERIVATION_MECH_INFO_TYPE, 579f66d273dSizick CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 5807c478bd9Sstevel@tonic-gate /* DES_KEY_GENERATION */ 5817c478bd9Sstevel@tonic-gate {DPROV_CKM_DES_KEY_GEN, DES_KEY_GEN_MECH_INFO_TYPE, 5827c478bd9Sstevel@tonic-gate CRYPTO_FG_GENERATE, DES_KEY_LEN, DES_KEY_LEN, 5837c478bd9Sstevel@tonic-gate CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 5847c478bd9Sstevel@tonic-gate /* DES3_KEY_GENERATION */ 5857c478bd9Sstevel@tonic-gate {DPROV_CKM_DES3_KEY_GEN, DES3_KEY_GEN_MECH_INFO_TYPE, 5867c478bd9Sstevel@tonic-gate CRYPTO_FG_GENERATE, DES3_KEY_LEN, DES3_KEY_LEN, 5877c478bd9Sstevel@tonic-gate CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 5887c478bd9Sstevel@tonic-gate /* AES_KEY_GENERATION */ 5897c478bd9Sstevel@tonic-gate {DPROV_CKM_AES_KEY_GEN, AES_KEY_GEN_MECH_INFO_TYPE, 5907c478bd9Sstevel@tonic-gate CRYPTO_FG_GENERATE, AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, 5917c478bd9Sstevel@tonic-gate CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 592f66d273dSizick /* BLOWFISH_KEY_GENERATION */ 593f66d273dSizick {DPROV_CKM_BLOWFISH_KEY_GEN, BLOWFISH_KEY_GEN_MECH_INFO_TYPE, 594f66d273dSizick CRYPTO_FG_GENERATE, BLOWFISH_MIN_KEY_LEN, BLOWFISH_MAX_KEY_LEN, 595f66d273dSizick CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 5967c478bd9Sstevel@tonic-gate /* RC4_KEY_GENERATION */ 5977c478bd9Sstevel@tonic-gate {DPROV_CKM_RC4_KEY_GEN, RC4_KEY_GEN_MECH_INFO_TYPE, 5987c478bd9Sstevel@tonic-gate CRYPTO_FG_GENERATE, ARCFOUR_MIN_KEY_BITS, ARCFOUR_MAX_KEY_BITS, 5997c478bd9Sstevel@tonic-gate CRYPTO_KEYSIZE_UNIT_IN_BITS}, 6005b0c7657Sizick /* DH_PKCS_KEY_PAIR_GEN */ 6015b0c7657Sizick {DPROV_CKM_DH_PKCS_KEY_PAIR_GEN, DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE, 6025b0c7657Sizick CRYPTO_FG_GENERATE_KEY_PAIR, DH_MIN_KEY_LEN, DH_MAX_KEY_LEN, 6035b0c7657Sizick CRYPTO_KEYSIZE_UNIT_IN_BITS}, 6045b0c7657Sizick /* DH_PKCS_DERIVE */ 6055b0c7657Sizick {DPROV_CKM_DH_PKCS_DERIVE, DH_PKCS_DERIVE_MECH_INFO_TYPE, 6065b0c7657Sizick CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 6077c478bd9Sstevel@tonic-gate /* RSA_PKCS_KEY_PAIR_GEN */ 6087c478bd9Sstevel@tonic-gate {DPROV_CKM_RSA_PKCS_KEY_PAIR_GEN, RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE, 6097c478bd9Sstevel@tonic-gate CRYPTO_FG_GENERATE_KEY_PAIR, RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, 610f9fbec18Smcpowers CRYPTO_KEYSIZE_UNIT_IN_BITS}, 611f9fbec18Smcpowers /* EC_KEY_PAIR_GEN */ 612f9fbec18Smcpowers {DPROV_CKM_EC_KEY_PAIR_GEN, EC_KEY_PAIR_GEN_MECH_INFO_TYPE, 613f9fbec18Smcpowers CRYPTO_FG_GENERATE_KEY_PAIR, EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, 614f9fbec18Smcpowers CRYPTO_KEYSIZE_UNIT_IN_BITS}, 615f9fbec18Smcpowers /* ECDSA */ 616f9fbec18Smcpowers {DPROV_CKM_ECDSA, ECDSA_MECH_INFO_TYPE, 617f9fbec18Smcpowers CRYPTO_FG_SIGN | CRYPTO_FG_VERIFY | 618f9fbec18Smcpowers CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC | 619f9fbec18Smcpowers EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 620f9fbec18Smcpowers /* ECDSA_SHA1 */ 621f9fbec18Smcpowers {DPROV_CKM_ECDSA_SHA1, ECDSA_SHA1_MECH_INFO_TYPE, 622f9fbec18Smcpowers CRYPTO_FG_SIGN | CRYPTO_FG_VERIFY | 623f9fbec18Smcpowers CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC | 624f9fbec18Smcpowers EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 625f9fbec18Smcpowers /* ECDH1_DERIVE */ 626f9fbec18Smcpowers {DPROV_CKM_ECDH1_DERIVE, ECDH1_DERIVE_MECH_INFO_TYPE, 627f9fbec18Smcpowers CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS} 6287c478bd9Sstevel@tonic-gate }; 6297c478bd9Sstevel@tonic-gate 6305b0c7657Sizick /* 6315b0c7657Sizick * Crypto Values 6325b0c7657Sizick * 6335b0c7657Sizick * These values are the used in the STC ef test suite. If they are changed 6345b0c7657Sizick * the test suite needs to be changed. 6355b0c7657Sizick */ 6365b0c7657Sizick static uchar_t dh_value[8] = { 'd', 'h', 'd', 'h', 'd', 'h', 'd', '\0' }; 6375b0c7657Sizick char public_exponent[3] = { 0x01, 0x00, 0x01 }; 6385b0c7657Sizick static uchar_t private_exponent[128] = { 6395b0c7657Sizick 0x8e, 0xc9, 0x70, 0x57, 0x6b, 0xcd, 0xfb, 0xa9, 6405b0c7657Sizick 0x19, 0xad, 0xcd, 0x91, 0x69, 0xd5, 0x52, 0xec, 6415b0c7657Sizick 0x72, 0x1e, 0x45, 0x15, 0x06, 0xdc, 0x65, 0x2d, 6425b0c7657Sizick 0x98, 0xc4, 0xce, 0x33, 0x54, 0x15, 0x70, 0x8d, 6435b0c7657Sizick 0xfa, 0x65, 0xea, 0x53, 0x44, 0xf3, 0x3e, 0x3f, 6445b0c7657Sizick 0xb4, 0x4c, 0x60, 0xd5, 0x01, 0x2d, 0xa4, 0x12, 6455b0c7657Sizick 0x99, 0xbf, 0x3f, 0x0b, 0xcd, 0xbb, 0x24, 0x10, 6465b0c7657Sizick 0x60, 0x30, 0x5e, 0x58, 0xf8, 0x59, 0xaa, 0xd1, 6475b0c7657Sizick 0x63, 0x3b, 0xbc, 0xcb, 0x94, 0x58, 0x38, 0x24, 6485b0c7657Sizick 0xfc, 0x65, 0x25, 0xc5, 0xa6, 0x51, 0xa2, 0x2e, 6495b0c7657Sizick 0xf1, 0x5e, 0xf5, 0xc1, 0xf5, 0x46, 0xf7, 0xbd, 6505b0c7657Sizick 0xc7, 0x62, 0xa8, 0xe2, 0x27, 0xd6, 0x94, 0x5b, 6515b0c7657Sizick 0xd3, 0xa2, 0xb5, 0x76, 0x42, 0x67, 0x6b, 0x86, 6525b0c7657Sizick 0x91, 0x97, 0x4d, 0x07, 0x92, 0x00, 0x4a, 0xdf, 6535b0c7657Sizick 0x0b, 0x65, 0x64, 0x05, 0x03, 0x48, 0x27, 0xeb, 6545b0c7657Sizick 0xce, 0x9a, 0x49, 0x7f, 0x3e, 0x10, 0xe0, 0x01 6555b0c7657Sizick }; 6565b0c7657Sizick 6575b0c7657Sizick static uchar_t modulus[128] = { 6585b0c7657Sizick 0x94, 0x32, 0xb9, 0x12, 0x1d, 0x68, 0x2c, 0xda, 6595b0c7657Sizick 0x2b, 0xe0, 0xe4, 0x97, 0x1b, 0x4d, 0xdc, 0x43, 6605b0c7657Sizick 0xdf, 0x38, 0x6e, 0x7b, 0x9f, 0x07, 0x58, 0xae, 6615b0c7657Sizick 0x9d, 0x82, 0x1e, 0xc7, 0xbc, 0x92, 0xbf, 0xd3, 6625b0c7657Sizick 0xce, 0x00, 0xbb, 0x91, 0xc9, 0x79, 0x06, 0x03, 6635b0c7657Sizick 0x1f, 0xbc, 0x9f, 0x94, 0x75, 0x29, 0x5f, 0xd7, 6645b0c7657Sizick 0xc5, 0xf3, 0x73, 0x8a, 0xa4, 0x35, 0x43, 0x7a, 6655b0c7657Sizick 0x00, 0x32, 0x97, 0x3e, 0x86, 0xef, 0x70, 0x6f, 6665b0c7657Sizick 0x18, 0x56, 0x15, 0xaa, 0x6a, 0x87, 0xe7, 0x8d, 6675b0c7657Sizick 0x7d, 0xdd, 0x1f, 0xa4, 0xe4, 0x31, 0xd4, 0x7a, 6685b0c7657Sizick 0x8c, 0x0e, 0x20, 0xd2, 0x23, 0xf5, 0x57, 0x3c, 6695b0c7657Sizick 0x1b, 0xa8, 0x44, 0xa4, 0x57, 0x8f, 0x33, 0x52, 6705b0c7657Sizick 0xad, 0x83, 0xae, 0x4a, 0x97, 0xa6, 0x1e, 0xa6, 6715b0c7657Sizick 0x2b, 0xfa, 0xea, 0xeb, 0x6e, 0x71, 0xb8, 0xb6, 6725b0c7657Sizick 0x0a, 0x36, 0xed, 0x83, 0xce, 0xb0, 0xdf, 0xc1, 6735b0c7657Sizick 0xd4, 0x3a, 0xe9, 0x99, 0x6f, 0xf3, 0x96, 0xb7 6745b0c7657Sizick }; 6755b0c7657Sizick 6765b0c7657Sizick 6777c478bd9Sstevel@tonic-gate static void dprov_provider_status(crypto_provider_handle_t, uint_t *); 6787c478bd9Sstevel@tonic-gate 6797c478bd9Sstevel@tonic-gate static crypto_control_ops_t dprov_control_ops = { 6807c478bd9Sstevel@tonic-gate dprov_provider_status 6817c478bd9Sstevel@tonic-gate }; 6827c478bd9Sstevel@tonic-gate 6837c478bd9Sstevel@tonic-gate #define DPROV_MANUFACTURER "SUNW " 6847c478bd9Sstevel@tonic-gate #define DPROV_MODEL "dprov " 6857c478bd9Sstevel@tonic-gate #define DPROV_ALLSPACES " " 6867c478bd9Sstevel@tonic-gate 6877c478bd9Sstevel@tonic-gate static int dprov_digest_init(crypto_ctx_t *, crypto_mechanism_t *, 6887c478bd9Sstevel@tonic-gate crypto_req_handle_t); 6897c478bd9Sstevel@tonic-gate static int dprov_digest(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 6907c478bd9Sstevel@tonic-gate crypto_req_handle_t); 6917c478bd9Sstevel@tonic-gate static int dprov_digest_update(crypto_ctx_t *, crypto_data_t *, 6927c478bd9Sstevel@tonic-gate crypto_req_handle_t); 6937c478bd9Sstevel@tonic-gate static int dprov_digest_key(crypto_ctx_t *, crypto_key_t *, 6947c478bd9Sstevel@tonic-gate crypto_req_handle_t); 6957c478bd9Sstevel@tonic-gate static int dprov_digest_final(crypto_ctx_t *, crypto_data_t *, 6967c478bd9Sstevel@tonic-gate crypto_req_handle_t); 6977c478bd9Sstevel@tonic-gate static int dprov_digest_atomic(crypto_provider_handle_t, crypto_session_id_t, 6987c478bd9Sstevel@tonic-gate crypto_mechanism_t *, crypto_data_t *, crypto_data_t *, 6997c478bd9Sstevel@tonic-gate crypto_req_handle_t); 7007c478bd9Sstevel@tonic-gate 7017c478bd9Sstevel@tonic-gate static crypto_digest_ops_t dprov_digest_ops = { 7027c478bd9Sstevel@tonic-gate dprov_digest_init, 7037c478bd9Sstevel@tonic-gate dprov_digest, 7047c478bd9Sstevel@tonic-gate dprov_digest_update, 7057c478bd9Sstevel@tonic-gate dprov_digest_key, 7067c478bd9Sstevel@tonic-gate dprov_digest_final, 7077c478bd9Sstevel@tonic-gate dprov_digest_atomic 7087c478bd9Sstevel@tonic-gate }; 7097c478bd9Sstevel@tonic-gate 7107c478bd9Sstevel@tonic-gate static int dprov_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *, 7117c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t, crypto_req_handle_t); 7127c478bd9Sstevel@tonic-gate static int dprov_mac(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 7137c478bd9Sstevel@tonic-gate crypto_req_handle_t); 7147c478bd9Sstevel@tonic-gate static int dprov_mac_update(crypto_ctx_t *, crypto_data_t *, 7157c478bd9Sstevel@tonic-gate crypto_req_handle_t); 7167c478bd9Sstevel@tonic-gate static int dprov_mac_final(crypto_ctx_t *, crypto_data_t *, 7177c478bd9Sstevel@tonic-gate crypto_req_handle_t); 7187c478bd9Sstevel@tonic-gate static int dprov_mac_atomic(crypto_provider_handle_t, crypto_session_id_t, 7197c478bd9Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 7207c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 7217c478bd9Sstevel@tonic-gate static int dprov_mac_verify_atomic(crypto_provider_handle_t, 7227c478bd9Sstevel@tonic-gate crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 7237c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 7247c478bd9Sstevel@tonic-gate 7257c478bd9Sstevel@tonic-gate static crypto_mac_ops_t dprov_mac_ops = { 7267c478bd9Sstevel@tonic-gate dprov_mac_init, 7277c478bd9Sstevel@tonic-gate dprov_mac, 7287c478bd9Sstevel@tonic-gate dprov_mac_update, 7297c478bd9Sstevel@tonic-gate dprov_mac_final, 7307c478bd9Sstevel@tonic-gate dprov_mac_atomic, 7317c478bd9Sstevel@tonic-gate dprov_mac_verify_atomic 7327c478bd9Sstevel@tonic-gate }; 7337c478bd9Sstevel@tonic-gate 7347c478bd9Sstevel@tonic-gate static int dprov_encrypt_init(crypto_ctx_t *, crypto_mechanism_t *, 7357c478bd9Sstevel@tonic-gate crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 7367c478bd9Sstevel@tonic-gate static int dprov_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 7377c478bd9Sstevel@tonic-gate crypto_req_handle_t); 7387c478bd9Sstevel@tonic-gate static int dprov_encrypt_update(crypto_ctx_t *, crypto_data_t *, 7397c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_req_handle_t); 7407c478bd9Sstevel@tonic-gate static int dprov_encrypt_final(crypto_ctx_t *, crypto_data_t *, 7417c478bd9Sstevel@tonic-gate crypto_req_handle_t); 7427c478bd9Sstevel@tonic-gate static int dprov_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t, 7437c478bd9Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 7447c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 7457c478bd9Sstevel@tonic-gate 7467c478bd9Sstevel@tonic-gate static int dprov_decrypt_init(crypto_ctx_t *, crypto_mechanism_t *, 7477c478bd9Sstevel@tonic-gate crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 7487c478bd9Sstevel@tonic-gate static int dprov_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 7497c478bd9Sstevel@tonic-gate crypto_req_handle_t); 7507c478bd9Sstevel@tonic-gate static int dprov_decrypt_update(crypto_ctx_t *, crypto_data_t *, 7517c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_req_handle_t); 7527c478bd9Sstevel@tonic-gate static int dprov_decrypt_final(crypto_ctx_t *, crypto_data_t *, 7537c478bd9Sstevel@tonic-gate crypto_req_handle_t); 7547c478bd9Sstevel@tonic-gate static int dprov_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t, 7557c478bd9Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 7567c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 7577c478bd9Sstevel@tonic-gate 7587c478bd9Sstevel@tonic-gate static crypto_cipher_ops_t dprov_cipher_ops = { 7597c478bd9Sstevel@tonic-gate dprov_encrypt_init, 7607c478bd9Sstevel@tonic-gate dprov_encrypt, 7617c478bd9Sstevel@tonic-gate dprov_encrypt_update, 7627c478bd9Sstevel@tonic-gate dprov_encrypt_final, 7637c478bd9Sstevel@tonic-gate dprov_encrypt_atomic, 7647c478bd9Sstevel@tonic-gate dprov_decrypt_init, 7657c478bd9Sstevel@tonic-gate dprov_decrypt, 7667c478bd9Sstevel@tonic-gate dprov_decrypt_update, 7677c478bd9Sstevel@tonic-gate dprov_decrypt_final, 7687c478bd9Sstevel@tonic-gate dprov_decrypt_atomic 7697c478bd9Sstevel@tonic-gate }; 7707c478bd9Sstevel@tonic-gate 7717c478bd9Sstevel@tonic-gate static int dprov_sign_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *, 7727c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t, crypto_req_handle_t); 7737c478bd9Sstevel@tonic-gate static int dprov_sign(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 7747c478bd9Sstevel@tonic-gate crypto_req_handle_t); 7757c478bd9Sstevel@tonic-gate static int dprov_sign_update(crypto_ctx_t *, crypto_data_t *, 7767c478bd9Sstevel@tonic-gate crypto_req_handle_t); 7777c478bd9Sstevel@tonic-gate static int dprov_sign_final(crypto_ctx_t *, crypto_data_t *, 7787c478bd9Sstevel@tonic-gate crypto_req_handle_t); 7797c478bd9Sstevel@tonic-gate static int dprov_sign_atomic(crypto_provider_handle_t, crypto_session_id_t, 7807c478bd9Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *, 7817c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t, crypto_req_handle_t); 7827c478bd9Sstevel@tonic-gate static int dprov_sign_recover_init(crypto_ctx_t *, crypto_mechanism_t *, 7837c478bd9Sstevel@tonic-gate crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 7847c478bd9Sstevel@tonic-gate static int dprov_sign_recover(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 7857c478bd9Sstevel@tonic-gate crypto_req_handle_t); 7867c478bd9Sstevel@tonic-gate static int dprov_sign_recover_atomic(crypto_provider_handle_t, 7877c478bd9Sstevel@tonic-gate crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, 7887c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t, 7897c478bd9Sstevel@tonic-gate crypto_req_handle_t); 7907c478bd9Sstevel@tonic-gate 7917c478bd9Sstevel@tonic-gate static crypto_sign_ops_t dprov_sign_ops = { 7927c478bd9Sstevel@tonic-gate dprov_sign_init, 7937c478bd9Sstevel@tonic-gate dprov_sign, 7947c478bd9Sstevel@tonic-gate dprov_sign_update, 7957c478bd9Sstevel@tonic-gate dprov_sign_final, 7967c478bd9Sstevel@tonic-gate dprov_sign_atomic, 7977c478bd9Sstevel@tonic-gate dprov_sign_recover_init, 7987c478bd9Sstevel@tonic-gate dprov_sign_recover, 7997c478bd9Sstevel@tonic-gate dprov_sign_recover_atomic 8007c478bd9Sstevel@tonic-gate }; 8017c478bd9Sstevel@tonic-gate 8027c478bd9Sstevel@tonic-gate static int dprov_verify_init(crypto_ctx_t *, crypto_mechanism_t *, 8037c478bd9Sstevel@tonic-gate crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 8047c478bd9Sstevel@tonic-gate static int dprov_verify(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 8057c478bd9Sstevel@tonic-gate crypto_req_handle_t); 8067c478bd9Sstevel@tonic-gate static int dprov_verify_update(crypto_ctx_t *, crypto_data_t *, 8077c478bd9Sstevel@tonic-gate crypto_req_handle_t); 8087c478bd9Sstevel@tonic-gate static int dprov_verify_final(crypto_ctx_t *, crypto_data_t *, 8097c478bd9Sstevel@tonic-gate crypto_req_handle_t); 8107c478bd9Sstevel@tonic-gate static int dprov_verify_atomic(crypto_provider_handle_t, crypto_session_id_t, 8117c478bd9Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 8127c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 8137c478bd9Sstevel@tonic-gate static int dprov_verify_recover_init(crypto_ctx_t *, crypto_mechanism_t *, 8147c478bd9Sstevel@tonic-gate crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 8157c478bd9Sstevel@tonic-gate static int dprov_verify_recover(crypto_ctx_t *, crypto_data_t *, 8167c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_req_handle_t); 8177c478bd9Sstevel@tonic-gate static int dprov_verify_recover_atomic(crypto_provider_handle_t, 8187c478bd9Sstevel@tonic-gate crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, 8197c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t, 8207c478bd9Sstevel@tonic-gate crypto_req_handle_t); 8217c478bd9Sstevel@tonic-gate 8227c478bd9Sstevel@tonic-gate static crypto_verify_ops_t dprov_verify_ops = { 8237c478bd9Sstevel@tonic-gate dprov_verify_init, 8247c478bd9Sstevel@tonic-gate dprov_verify, 8257c478bd9Sstevel@tonic-gate dprov_verify_update, 8267c478bd9Sstevel@tonic-gate dprov_verify_final, 8277c478bd9Sstevel@tonic-gate dprov_verify_atomic, 8287c478bd9Sstevel@tonic-gate dprov_verify_recover_init, 8297c478bd9Sstevel@tonic-gate dprov_verify_recover, 8307c478bd9Sstevel@tonic-gate dprov_verify_recover_atomic 8317c478bd9Sstevel@tonic-gate }; 8327c478bd9Sstevel@tonic-gate 8337c478bd9Sstevel@tonic-gate static int dprov_digest_encrypt_update(crypto_ctx_t *, crypto_ctx_t *, 8347c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_req_handle_t); 8357c478bd9Sstevel@tonic-gate static int dprov_decrypt_digest_update(crypto_ctx_t *, crypto_ctx_t *, 8367c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_req_handle_t); 8377c478bd9Sstevel@tonic-gate static int dprov_sign_encrypt_update(crypto_ctx_t *, crypto_ctx_t *, 8387c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_req_handle_t); 8397c478bd9Sstevel@tonic-gate static int dprov_decrypt_verify_update(crypto_ctx_t *, crypto_ctx_t *, 8407c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_req_handle_t); 8417c478bd9Sstevel@tonic-gate 8427c478bd9Sstevel@tonic-gate static crypto_dual_ops_t dprov_dual_ops = { 8437c478bd9Sstevel@tonic-gate dprov_digest_encrypt_update, 8447c478bd9Sstevel@tonic-gate dprov_decrypt_digest_update, 8457c478bd9Sstevel@tonic-gate dprov_sign_encrypt_update, 8467c478bd9Sstevel@tonic-gate dprov_decrypt_verify_update 8477c478bd9Sstevel@tonic-gate }; 8487c478bd9Sstevel@tonic-gate 8497c478bd9Sstevel@tonic-gate static int dprov_encrypt_mac_init(crypto_ctx_t *, 8507c478bd9Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *, 8517c478bd9Sstevel@tonic-gate crypto_key_t *, crypto_spi_ctx_template_t, 8527c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t, crypto_req_handle_t); 8537c478bd9Sstevel@tonic-gate static int dprov_encrypt_mac(crypto_ctx_t *, 8547c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_dual_data_t *, crypto_data_t *, 8557c478bd9Sstevel@tonic-gate crypto_req_handle_t); 8567c478bd9Sstevel@tonic-gate static int dprov_encrypt_mac_update(crypto_ctx_t *, 8577c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_dual_data_t *, crypto_req_handle_t); 8587c478bd9Sstevel@tonic-gate static int dprov_encrypt_mac_final(crypto_ctx_t *, 8597c478bd9Sstevel@tonic-gate crypto_dual_data_t *, crypto_data_t *, crypto_req_handle_t); 8607c478bd9Sstevel@tonic-gate static int dprov_encrypt_mac_atomic(crypto_provider_handle_t, 8617c478bd9Sstevel@tonic-gate crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, 8627c478bd9Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 8637c478bd9Sstevel@tonic-gate crypto_dual_data_t *, crypto_data_t *, crypto_spi_ctx_template_t, 8647c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t, crypto_req_handle_t); 8657c478bd9Sstevel@tonic-gate 8667c478bd9Sstevel@tonic-gate static int dprov_mac_decrypt_init(crypto_ctx_t *, 8677c478bd9Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *, 8687c478bd9Sstevel@tonic-gate crypto_key_t *, crypto_spi_ctx_template_t, 8697c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t, crypto_req_handle_t); 8707c478bd9Sstevel@tonic-gate static int dprov_mac_decrypt(crypto_ctx_t *, 8717c478bd9Sstevel@tonic-gate crypto_dual_data_t *, crypto_data_t *, crypto_data_t *, 8727c478bd9Sstevel@tonic-gate crypto_req_handle_t); 8737c478bd9Sstevel@tonic-gate static int dprov_mac_decrypt_update(crypto_ctx_t *, 8747c478bd9Sstevel@tonic-gate crypto_dual_data_t *, crypto_data_t *, crypto_req_handle_t); 8757c478bd9Sstevel@tonic-gate static int dprov_mac_decrypt_final(crypto_ctx_t *, 8767c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_req_handle_t); 8777c478bd9Sstevel@tonic-gate static int dprov_mac_decrypt_atomic(crypto_provider_handle_t, 8787c478bd9Sstevel@tonic-gate crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, 8797c478bd9Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_dual_data_t *, 8807c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t, 8817c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t, crypto_req_handle_t); 8827c478bd9Sstevel@tonic-gate static int dprov_mac_verify_decrypt_atomic(crypto_provider_handle_t, 8837c478bd9Sstevel@tonic-gate crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, 8847c478bd9Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_dual_data_t *, 8857c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t, 8867c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t, crypto_req_handle_t); 8877c478bd9Sstevel@tonic-gate 8887c478bd9Sstevel@tonic-gate static crypto_dual_cipher_mac_ops_t dprov_cipher_mac_ops = { 8897c478bd9Sstevel@tonic-gate dprov_encrypt_mac_init, 8907c478bd9Sstevel@tonic-gate dprov_encrypt_mac, 8917c478bd9Sstevel@tonic-gate dprov_encrypt_mac_update, 8927c478bd9Sstevel@tonic-gate dprov_encrypt_mac_final, 8937c478bd9Sstevel@tonic-gate dprov_encrypt_mac_atomic, 8947c478bd9Sstevel@tonic-gate dprov_mac_decrypt_init, 8957c478bd9Sstevel@tonic-gate dprov_mac_decrypt, 8967c478bd9Sstevel@tonic-gate dprov_mac_decrypt_update, 8977c478bd9Sstevel@tonic-gate dprov_mac_decrypt_final, 8987c478bd9Sstevel@tonic-gate dprov_mac_decrypt_atomic, 8997c478bd9Sstevel@tonic-gate dprov_mac_verify_decrypt_atomic 9007c478bd9Sstevel@tonic-gate }; 9017c478bd9Sstevel@tonic-gate 9027c478bd9Sstevel@tonic-gate static int dprov_seed_random(crypto_provider_handle_t, crypto_session_id_t, 9038047c9fbSmcpowers uchar_t *, size_t, uint_t, uint32_t, crypto_req_handle_t); 9047c478bd9Sstevel@tonic-gate static int dprov_generate_random(crypto_provider_handle_t, crypto_session_id_t, 9057c478bd9Sstevel@tonic-gate uchar_t *, size_t, crypto_req_handle_t); 9067c478bd9Sstevel@tonic-gate 9077c478bd9Sstevel@tonic-gate static crypto_random_number_ops_t dprov_random_number_ops = { 9087c478bd9Sstevel@tonic-gate dprov_seed_random, 9097c478bd9Sstevel@tonic-gate dprov_generate_random 9107c478bd9Sstevel@tonic-gate }; 9117c478bd9Sstevel@tonic-gate 9127c478bd9Sstevel@tonic-gate static int dprov_session_open(crypto_provider_handle_t, crypto_session_id_t *, 9137c478bd9Sstevel@tonic-gate crypto_req_handle_t); 9147c478bd9Sstevel@tonic-gate static int dprov_session_close(crypto_provider_handle_t, crypto_session_id_t, 9157c478bd9Sstevel@tonic-gate crypto_req_handle_t); 9167c478bd9Sstevel@tonic-gate static int dprov_session_login(crypto_provider_handle_t, crypto_session_id_t, 9177c478bd9Sstevel@tonic-gate crypto_user_type_t, char *, size_t, crypto_req_handle_t); 9187c478bd9Sstevel@tonic-gate static int dprov_session_logout(crypto_provider_handle_t, crypto_session_id_t, 9197c478bd9Sstevel@tonic-gate crypto_req_handle_t); 9207c478bd9Sstevel@tonic-gate 9217c478bd9Sstevel@tonic-gate static crypto_session_ops_t dprov_session_ops = { 9227c478bd9Sstevel@tonic-gate dprov_session_open, 9237c478bd9Sstevel@tonic-gate dprov_session_close, 9247c478bd9Sstevel@tonic-gate dprov_session_login, 9257c478bd9Sstevel@tonic-gate dprov_session_logout 9267c478bd9Sstevel@tonic-gate }; 9277c478bd9Sstevel@tonic-gate 9287c478bd9Sstevel@tonic-gate static int dprov_object_create(crypto_provider_handle_t, crypto_session_id_t, 9297c478bd9Sstevel@tonic-gate crypto_object_attribute_t *, uint_t, crypto_object_id_t *, 9307c478bd9Sstevel@tonic-gate crypto_req_handle_t); 9317c478bd9Sstevel@tonic-gate static int dprov_object_copy(crypto_provider_handle_t, crypto_session_id_t, 9327c478bd9Sstevel@tonic-gate crypto_object_id_t, crypto_object_attribute_t *, uint_t, 9337c478bd9Sstevel@tonic-gate crypto_object_id_t *, crypto_req_handle_t); 9347c478bd9Sstevel@tonic-gate static int dprov_object_destroy(crypto_provider_handle_t, crypto_session_id_t, 9357c478bd9Sstevel@tonic-gate crypto_object_id_t, crypto_req_handle_t); 9367c478bd9Sstevel@tonic-gate static int dprov_object_get_size(crypto_provider_handle_t, crypto_session_id_t, 9377c478bd9Sstevel@tonic-gate crypto_object_id_t, size_t *, crypto_req_handle_t); 9387c478bd9Sstevel@tonic-gate static int dprov_object_get_attribute_value(crypto_provider_handle_t, 9397c478bd9Sstevel@tonic-gate crypto_session_id_t, crypto_object_id_t, 9407c478bd9Sstevel@tonic-gate crypto_object_attribute_t *, uint_t, crypto_req_handle_t); 9417c478bd9Sstevel@tonic-gate static int dprov_object_set_attribute_value(crypto_provider_handle_t, 9427c478bd9Sstevel@tonic-gate crypto_session_id_t, crypto_object_id_t, 9437c478bd9Sstevel@tonic-gate crypto_object_attribute_t *, uint_t, crypto_req_handle_t); 9447c478bd9Sstevel@tonic-gate static int dprov_object_find_init(crypto_provider_handle_t, crypto_session_id_t, 9457c478bd9Sstevel@tonic-gate crypto_object_attribute_t *, uint_t, void **, 9467c478bd9Sstevel@tonic-gate crypto_req_handle_t); 9477c478bd9Sstevel@tonic-gate static int dprov_object_find(crypto_provider_handle_t, void *, 9487c478bd9Sstevel@tonic-gate crypto_object_id_t *, uint_t, uint_t *, crypto_req_handle_t); 9497c478bd9Sstevel@tonic-gate static int dprov_object_find_final(crypto_provider_handle_t, void *, 9507c478bd9Sstevel@tonic-gate crypto_req_handle_t); 9517c478bd9Sstevel@tonic-gate 9527c478bd9Sstevel@tonic-gate static crypto_object_ops_t dprov_object_ops = { 9537c478bd9Sstevel@tonic-gate dprov_object_create, 9547c478bd9Sstevel@tonic-gate dprov_object_copy, 9557c478bd9Sstevel@tonic-gate dprov_object_destroy, 9567c478bd9Sstevel@tonic-gate dprov_object_get_size, 9577c478bd9Sstevel@tonic-gate dprov_object_get_attribute_value, 9587c478bd9Sstevel@tonic-gate dprov_object_set_attribute_value, 9597c478bd9Sstevel@tonic-gate dprov_object_find_init, 9607c478bd9Sstevel@tonic-gate dprov_object_find, 9617c478bd9Sstevel@tonic-gate dprov_object_find_final 9627c478bd9Sstevel@tonic-gate }; 9637c478bd9Sstevel@tonic-gate 9647c478bd9Sstevel@tonic-gate static int dprov_key_generate(crypto_provider_handle_t, crypto_session_id_t, 9657c478bd9Sstevel@tonic-gate crypto_mechanism_t *, crypto_object_attribute_t *, uint_t, 9667c478bd9Sstevel@tonic-gate crypto_object_id_t *, crypto_req_handle_t); 9677c478bd9Sstevel@tonic-gate static int dprov_key_generate_pair(crypto_provider_handle_t, 9687c478bd9Sstevel@tonic-gate crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *, 9697c478bd9Sstevel@tonic-gate uint_t, crypto_object_attribute_t *, uint_t, crypto_object_id_t *, 9707c478bd9Sstevel@tonic-gate crypto_object_id_t *, crypto_req_handle_t); 9717c478bd9Sstevel@tonic-gate static int dprov_key_wrap(crypto_provider_handle_t, crypto_session_id_t, 9727c478bd9Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_object_id_t *, 9737c478bd9Sstevel@tonic-gate uchar_t *, size_t *, crypto_req_handle_t); 9747c478bd9Sstevel@tonic-gate static int dprov_key_unwrap(crypto_provider_handle_t, crypto_session_id_t, 9757c478bd9Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, uchar_t *, size_t *, 9767c478bd9Sstevel@tonic-gate crypto_object_attribute_t *, uint_t, 9777c478bd9Sstevel@tonic-gate crypto_object_id_t *, crypto_req_handle_t); 9787c478bd9Sstevel@tonic-gate static int dprov_key_derive(crypto_provider_handle_t, crypto_session_id_t, 9797c478bd9Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_object_attribute_t *, 9807c478bd9Sstevel@tonic-gate uint_t, crypto_object_id_t *, crypto_req_handle_t); 9817c478bd9Sstevel@tonic-gate 9827c478bd9Sstevel@tonic-gate static crypto_key_ops_t dprov_key_ops = { 9837c478bd9Sstevel@tonic-gate dprov_key_generate, 9847c478bd9Sstevel@tonic-gate dprov_key_generate_pair, 9857c478bd9Sstevel@tonic-gate dprov_key_wrap, 9867c478bd9Sstevel@tonic-gate dprov_key_unwrap, 9877c478bd9Sstevel@tonic-gate dprov_key_derive 9887c478bd9Sstevel@tonic-gate }; 9897c478bd9Sstevel@tonic-gate 9907c478bd9Sstevel@tonic-gate static int dprov_ext_info(crypto_provider_handle_t, 9917c478bd9Sstevel@tonic-gate crypto_provider_ext_info_t *, crypto_req_handle_t); 9927c478bd9Sstevel@tonic-gate static int dprov_init_token(crypto_provider_handle_t, char *, size_t, 9937c478bd9Sstevel@tonic-gate char *, crypto_req_handle_t); 9947c478bd9Sstevel@tonic-gate static int dprov_init_pin(crypto_provider_handle_t, crypto_session_id_t, 9957c478bd9Sstevel@tonic-gate char *, size_t, crypto_req_handle_t); 9967c478bd9Sstevel@tonic-gate static int dprov_set_pin(crypto_provider_handle_t, crypto_session_id_t, 9977c478bd9Sstevel@tonic-gate char *, size_t, char *, size_t, crypto_req_handle_t); 9987c478bd9Sstevel@tonic-gate 9997c478bd9Sstevel@tonic-gate static crypto_provider_management_ops_t dprov_management_ops = { 10007c478bd9Sstevel@tonic-gate dprov_ext_info, 10017c478bd9Sstevel@tonic-gate dprov_init_token, 10027c478bd9Sstevel@tonic-gate dprov_init_pin, 10037c478bd9Sstevel@tonic-gate dprov_set_pin 10047c478bd9Sstevel@tonic-gate }; 10057c478bd9Sstevel@tonic-gate 10067c478bd9Sstevel@tonic-gate static int dprov_free_context(crypto_ctx_t *); 1007894b2776Smcpowers static int dprov_copyin_mechanism(crypto_provider_handle_t, 1008894b2776Smcpowers crypto_mechanism_t *, crypto_mechanism_t *, int *error, int); 1009894b2776Smcpowers static int dprov_copyout_mechanism(crypto_provider_handle_t, 1010894b2776Smcpowers crypto_mechanism_t *, crypto_mechanism_t *, int *error, int); 1011894b2776Smcpowers static int dprov_free_mechanism(crypto_provider_handle_t, 1012894b2776Smcpowers crypto_mechanism_t *); 10137c478bd9Sstevel@tonic-gate 10147c478bd9Sstevel@tonic-gate static crypto_ctx_ops_t dprov_ctx_ops = { 10157c478bd9Sstevel@tonic-gate NULL, 10167c478bd9Sstevel@tonic-gate dprov_free_context 10177c478bd9Sstevel@tonic-gate }; 10187c478bd9Sstevel@tonic-gate 1019894b2776Smcpowers static crypto_mech_ops_t dprov_mech_ops = { 1020894b2776Smcpowers dprov_copyin_mechanism, 1021894b2776Smcpowers dprov_copyout_mechanism, 1022894b2776Smcpowers dprov_free_mechanism 1023894b2776Smcpowers }; 1024894b2776Smcpowers 1025034448feSmcpowers static int dprov_nostore_key_generate(crypto_provider_handle_t, 1026034448feSmcpowers crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *, 1027034448feSmcpowers uint_t, crypto_object_attribute_t *, uint_t, crypto_req_handle_t); 10285b0c7657Sizick static int dprov_nostore_key_generate_pair(crypto_provider_handle_t, 10295b0c7657Sizick crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *, 10305b0c7657Sizick uint_t, crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *, 10315b0c7657Sizick uint_t, crypto_object_attribute_t *, uint_t, crypto_req_handle_t); 10325b0c7657Sizick static int dprov_nostore_key_derive(crypto_provider_handle_t, 10335b0c7657Sizick crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, 10345b0c7657Sizick crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *, 10355b0c7657Sizick uint_t, crypto_req_handle_t); 1036034448feSmcpowers 1037034448feSmcpowers static crypto_nostore_key_ops_t dprov_nostore_key_ops = { 1038034448feSmcpowers dprov_nostore_key_generate, 10395b0c7657Sizick dprov_nostore_key_generate_pair, 10405b0c7657Sizick dprov_nostore_key_derive 1041034448feSmcpowers }; 1042034448feSmcpowers 10437c478bd9Sstevel@tonic-gate static crypto_ops_t dprov_crypto_ops = { 10447c478bd9Sstevel@tonic-gate &dprov_control_ops, 10457c478bd9Sstevel@tonic-gate &dprov_digest_ops, 10467c478bd9Sstevel@tonic-gate &dprov_cipher_ops, 10477c478bd9Sstevel@tonic-gate &dprov_mac_ops, 10487c478bd9Sstevel@tonic-gate &dprov_sign_ops, 10497c478bd9Sstevel@tonic-gate &dprov_verify_ops, 10507c478bd9Sstevel@tonic-gate &dprov_dual_ops, 10517c478bd9Sstevel@tonic-gate &dprov_cipher_mac_ops, 10527c478bd9Sstevel@tonic-gate &dprov_random_number_ops, 10537c478bd9Sstevel@tonic-gate &dprov_session_ops, 10547c478bd9Sstevel@tonic-gate &dprov_object_ops, 10557c478bd9Sstevel@tonic-gate &dprov_key_ops, 10567c478bd9Sstevel@tonic-gate &dprov_management_ops, 1057894b2776Smcpowers &dprov_ctx_ops, 1058894b2776Smcpowers &dprov_mech_ops 10597c478bd9Sstevel@tonic-gate }; 10607c478bd9Sstevel@tonic-gate 10617c478bd9Sstevel@tonic-gate 10627c478bd9Sstevel@tonic-gate /* maximum SO and user PIN lengths */ 10637c478bd9Sstevel@tonic-gate #define DPROV_MAX_PIN_LEN 128 10647c478bd9Sstevel@tonic-gate 10657c478bd9Sstevel@tonic-gate /* 10667c478bd9Sstevel@tonic-gate * Objects: each session is associated with an array of objects. 10677c478bd9Sstevel@tonic-gate * Unlike PKCS#11, the objects cannot be shared between sessions. 10687c478bd9Sstevel@tonic-gate * The ioctl driver multiplexes PKCS#11 sessions to providers 10697c478bd9Sstevel@tonic-gate * sessions in order to support this semantic. This simplifies 10707c478bd9Sstevel@tonic-gate * the CSPI greatly since the provider does not have to associate 10717c478bd9Sstevel@tonic-gate * sessions with a user space process. 10727c478bd9Sstevel@tonic-gate * There is also a per-instance array of objects, which correspond 10737c478bd9Sstevel@tonic-gate * to PKCS#11 token objects. These objects can be shared by multiple 10747c478bd9Sstevel@tonic-gate * sesions. 10757c478bd9Sstevel@tonic-gate * 10767c478bd9Sstevel@tonic-gate * Token objects are identified by having a CKA_TOKEN attribute B_TRUE. 10777c478bd9Sstevel@tonic-gate * Private objects are identified by having a CKA_PRIVATE attribute 10787c478bd9Sstevel@tonic-gate * set to B_TRUE. 10797c478bd9Sstevel@tonic-gate */ 10807c478bd9Sstevel@tonic-gate 10817c478bd9Sstevel@tonic-gate #define DPROV_MAX_OBJECTS 128 /* max # of objects */ 10827c478bd9Sstevel@tonic-gate #define DPROV_MAX_ATTR 64 /* max # of attributes per object */ 10837c478bd9Sstevel@tonic-gate 10847c478bd9Sstevel@tonic-gate /* object description */ 10857c478bd9Sstevel@tonic-gate typedef struct dprov_object { 10867c478bd9Sstevel@tonic-gate crypto_object_attribute_t do_attr[DPROV_MAX_ATTR]; /* attributes */ 10877c478bd9Sstevel@tonic-gate uint_t do_token_idx; /* index in per-instance table */ 10887c478bd9Sstevel@tonic-gate /* for token objects. */ 10897c478bd9Sstevel@tonic-gate boolean_t do_destroyed; /* object has been destroyed. */ 10907c478bd9Sstevel@tonic-gate /* keep object around until all */ 10917c478bd9Sstevel@tonic-gate /* sessions that refer to it */ 10927c478bd9Sstevel@tonic-gate /* are closed, but mark it */ 10937c478bd9Sstevel@tonic-gate /* destroyed so that references */ 10947c478bd9Sstevel@tonic-gate /* to the object fail. */ 10957c478bd9Sstevel@tonic-gate /* used for token objects only */ 10967c478bd9Sstevel@tonic-gate uint_t do_refcnt; 10977c478bd9Sstevel@tonic-gate } dprov_object_t; 10987c478bd9Sstevel@tonic-gate 10997c478bd9Sstevel@tonic-gate /* 11007c478bd9Sstevel@tonic-gate * If a session has a reference to a dprov_object_t, 11017c478bd9Sstevel@tonic-gate * it REFHOLD()s. 11027c478bd9Sstevel@tonic-gate */ 11037c478bd9Sstevel@tonic-gate #define DPROV_OBJECT_REFHOLD(object) { \ 1104*1a5e258fSJosef 'Jeff' Sipek atomic_inc_32(&(object)->do_refcnt); \ 11057c478bd9Sstevel@tonic-gate ASSERT((object)->do_refcnt != 0); \ 11067c478bd9Sstevel@tonic-gate } 11077c478bd9Sstevel@tonic-gate 11087c478bd9Sstevel@tonic-gate /* 11097c478bd9Sstevel@tonic-gate * Releases a reference to an object. When the last 11107c478bd9Sstevel@tonic-gate * reference is released, the object is freed. 11117c478bd9Sstevel@tonic-gate */ 11127c478bd9Sstevel@tonic-gate #define DPROV_OBJECT_REFRELE(object) { \ 11137c478bd9Sstevel@tonic-gate ASSERT((object)->do_refcnt != 0); \ 11147c478bd9Sstevel@tonic-gate membar_exit(); \ 1115*1a5e258fSJosef 'Jeff' Sipek if (atomic_dec_32_nv(&(object)->do_refcnt) == 0) \ 11167c478bd9Sstevel@tonic-gate dprov_free_object(object); \ 11177c478bd9Sstevel@tonic-gate } 11187c478bd9Sstevel@tonic-gate 11197c478bd9Sstevel@tonic-gate /* 11207c478bd9Sstevel@tonic-gate * Object attributes are passed to the provider using crypto_object_attribute 11217c478bd9Sstevel@tonic-gate * structures, which contain the type of the attribute, a pointer to 11227c478bd9Sstevel@tonic-gate * it's value, and the length of its value. The attribute types values 11237c478bd9Sstevel@tonic-gate * are defined by the PKCS#11 specification. This provider only cares 11247c478bd9Sstevel@tonic-gate * about a subset of these attributes. In order to avoid having to 11257c478bd9Sstevel@tonic-gate * include the PKCS#11 header files, we define here the attributes values 11267c478bd9Sstevel@tonic-gate * which are used by the provider. 11277c478bd9Sstevel@tonic-gate */ 11287c478bd9Sstevel@tonic-gate 11297c478bd9Sstevel@tonic-gate #define DPROV_CKA_CLASS 0x00000000 11307c478bd9Sstevel@tonic-gate #define DPROV_CKA_TOKEN 0x00000001 11317c478bd9Sstevel@tonic-gate #define DPROV_CKA_PRIVATE 0x00000002 11327c478bd9Sstevel@tonic-gate #define DPROV_CKA_VALUE 0x00000011 1133894b2776Smcpowers #define DPROV_CKA_CERTIFICATE_TYPE 0x00000080 11347c478bd9Sstevel@tonic-gate #define DPROV_CKA_KEY_TYPE 0x00000100 1135034448feSmcpowers #define DPROV_CKA_SENSITIVE 0x00000103 11367c478bd9Sstevel@tonic-gate #define DPROV_CKA_ENCRYPT 0x00000104 11377c478bd9Sstevel@tonic-gate #define DPROV_CKA_DECRYPT 0x00000105 11387c478bd9Sstevel@tonic-gate #define DPROV_CKA_WRAP 0x00000106 11397c478bd9Sstevel@tonic-gate #define DPROV_CKA_UNWRAP 0x00000107 11407c478bd9Sstevel@tonic-gate #define DPROV_CKA_SIGN 0x00000108 11417c478bd9Sstevel@tonic-gate #define DPROV_CKA_SIGN_RECOVER 0x00000109 11427c478bd9Sstevel@tonic-gate #define DPROV_CKA_VERIFY 0x0000010A 11437c478bd9Sstevel@tonic-gate #define DPROV_CKA_VERIFY_RECOVER 0x0000010B 11447c478bd9Sstevel@tonic-gate #define DPROV_CKA_DERIVE 0x0000010C 11457c478bd9Sstevel@tonic-gate #define DPROV_CKA_MODULUS 0x00000120 11467c478bd9Sstevel@tonic-gate #define DPROV_CKA_MODULUS_BITS 0x00000121 11477c478bd9Sstevel@tonic-gate #define DPROV_CKA_PUBLIC_EXPONENT 0x00000122 11487c478bd9Sstevel@tonic-gate #define DPROV_CKA_PRIVATE_EXPONENT 0x00000123 11495b0c7657Sizick #define DPROV_CKA_PRIME 0x00000130 11505b0c7657Sizick #define DPROV_CKA_BASE 0x00000132 11517c478bd9Sstevel@tonic-gate #define DPROV_CKA_VALUE_BITS 0x00000160 11527c478bd9Sstevel@tonic-gate #define DPROV_CKA_VALUE_LEN 0x00000161 11537c478bd9Sstevel@tonic-gate #define DPROV_CKA_EXTRACTABLE 0x00000162 1154f9fbec18Smcpowers #define DPROV_CKA_EC_PARAMS 0x00000180 1155f9fbec18Smcpowers #define DPROV_CKA_EC_POINT 0x00000181 1156894b2776Smcpowers #define DPROV_HW_FEATURE_TYPE 0x00000300 11577c478bd9Sstevel@tonic-gate 11587c478bd9Sstevel@tonic-gate /* 11597c478bd9Sstevel@tonic-gate * Object classes from PKCS#11 11607c478bd9Sstevel@tonic-gate */ 11617c478bd9Sstevel@tonic-gate #define DPROV_CKO_DATA 0x00000000 11627c478bd9Sstevel@tonic-gate #define DPROV_CKO_CERTIFICATE 0x00000001 11637c478bd9Sstevel@tonic-gate #define DPROV_CKO_PUBLIC_KEY 0x00000002 11647c478bd9Sstevel@tonic-gate #define DPROV_CKO_PRIVATE_KEY 0x00000003 11657c478bd9Sstevel@tonic-gate #define DPROV_CKO_SECRET_KEY 0x00000004 11667c478bd9Sstevel@tonic-gate #define DPROV_CKO_HW_FEATURE 0x00000005 11677c478bd9Sstevel@tonic-gate #define DPROV_CKO_DOMAIN_PARAMETERS 0x00000006 11687c478bd9Sstevel@tonic-gate #define DPROV_CKO_VENDOR_DEFINED 0x80000000 11697c478bd9Sstevel@tonic-gate 11707c478bd9Sstevel@tonic-gate /* 11717c478bd9Sstevel@tonic-gate * A few key types from PKCS#11 11727c478bd9Sstevel@tonic-gate */ 11737c478bd9Sstevel@tonic-gate #define DPROV_CKK_RSA 0x00000000 11747c478bd9Sstevel@tonic-gate #define DPROV_CKK_GENERIC_SECRET 0x00000010 11757c478bd9Sstevel@tonic-gate #define DPROV_CKK_RC4 0x00000012 11767c478bd9Sstevel@tonic-gate #define DPROV_CKK_DES 0x00000013 11777c478bd9Sstevel@tonic-gate #define DPROV_CKK_DES3 0x00000015 11787c478bd9Sstevel@tonic-gate #define DPROV_CKK_AES 0x0000001F 1179f66d273dSizick #define DPROV_CKK_BLOWFISH 0x00000020 11807c478bd9Sstevel@tonic-gate 11817c478bd9Sstevel@tonic-gate /* 11827c478bd9Sstevel@tonic-gate * Find object context. Allows the find object init/find/final 11837c478bd9Sstevel@tonic-gate * to store data persistent across calls. 11847c478bd9Sstevel@tonic-gate */ 11857c478bd9Sstevel@tonic-gate typedef struct dprov_find_ctx { 11867c478bd9Sstevel@tonic-gate crypto_object_id_t fc_ids[DPROV_MAX_OBJECTS]; /* object ids */ 11877c478bd9Sstevel@tonic-gate uint_t fc_nids; /* number of ids in fc_ids */ 11887c478bd9Sstevel@tonic-gate uint_t fc_next; /* next id to return */ 11897c478bd9Sstevel@tonic-gate } dprov_find_ctx_t; 11907c478bd9Sstevel@tonic-gate 11917c478bd9Sstevel@tonic-gate /* 11927c478bd9Sstevel@tonic-gate * Session management: each instance is associated with an array 11937c478bd9Sstevel@tonic-gate * of sessions. KEF providers sessions are always R/W the library and 11947c478bd9Sstevel@tonic-gate * the ioctl maintain the PKCS#11 R/W attributes for the session. 11957c478bd9Sstevel@tonic-gate */ 11967c478bd9Sstevel@tonic-gate 11977c478bd9Sstevel@tonic-gate #define DPROV_MIN_SESSIONS 32 /* # of sessions to start with */ 11987c478bd9Sstevel@tonic-gate 11997c478bd9Sstevel@tonic-gate typedef enum dprov_session_state { 12007c478bd9Sstevel@tonic-gate DPROV_SESSION_STATE_PUBLIC, /* public (default) */ 12017c478bd9Sstevel@tonic-gate DPROV_SESSION_STATE_SO, /* SO logged in */ 12027c478bd9Sstevel@tonic-gate DPROV_SESSION_STATE_USER /* user logged in */ 12037c478bd9Sstevel@tonic-gate } dprov_session_state_t; 12047c478bd9Sstevel@tonic-gate 12057c478bd9Sstevel@tonic-gate /* session description */ 12067c478bd9Sstevel@tonic-gate typedef struct dprov_session { 12077c478bd9Sstevel@tonic-gate dprov_session_state_t ds_state; /* session state */ 12087c478bd9Sstevel@tonic-gate dprov_object_t *ds_objects[DPROV_MAX_OBJECTS]; /* session objects */ 12097c478bd9Sstevel@tonic-gate } dprov_session_t; 12107c478bd9Sstevel@tonic-gate 12117c478bd9Sstevel@tonic-gate 12127c478bd9Sstevel@tonic-gate static crypto_provider_info_t dprov_prov_info = { 1213894b2776Smcpowers CRYPTO_SPI_VERSION_2, 12147c478bd9Sstevel@tonic-gate "Dummy Pseudo HW Provider", 12157c478bd9Sstevel@tonic-gate CRYPTO_HW_PROVIDER, 12167c478bd9Sstevel@tonic-gate NULL, /* pi_provider_dev */ 12177c478bd9Sstevel@tonic-gate NULL, /* pi_provider_handle */ 12187c478bd9Sstevel@tonic-gate &dprov_crypto_ops, 12197c478bd9Sstevel@tonic-gate sizeof (dprov_mech_info_tab)/sizeof (crypto_mech_info_t), 12207c478bd9Sstevel@tonic-gate dprov_mech_info_tab, 12217c478bd9Sstevel@tonic-gate 0, /* pi_logical_provider_count */ 1222ba5f469cSkrishna NULL, /* pi_logical_providers */ 1223ba5f469cSkrishna 0 /* pi_flags */ 12247c478bd9Sstevel@tonic-gate }; 12257c478bd9Sstevel@tonic-gate 12267c478bd9Sstevel@tonic-gate /* 12277c478bd9Sstevel@tonic-gate * Per-instance info. 12287c478bd9Sstevel@tonic-gate */ 12297c478bd9Sstevel@tonic-gate typedef struct dprov_state { 12307c478bd9Sstevel@tonic-gate kmutex_t ds_lock; /* per-instance lock */ 12317c478bd9Sstevel@tonic-gate dev_info_t *ds_dip; /* device info */ 12327c478bd9Sstevel@tonic-gate crypto_kcf_provider_handle_t ds_prov_handle; /* framework handle */ 12337c478bd9Sstevel@tonic-gate taskq_t *ds_taskq; /* taskq for async behavior */ 12347c478bd9Sstevel@tonic-gate char ds_user_pin[DPROV_MAX_PIN_LEN]; /* normal user PIN */ 12357c478bd9Sstevel@tonic-gate uint_t ds_user_pin_len; 12367c478bd9Sstevel@tonic-gate char ds_so_pin[DPROV_MAX_PIN_LEN]; /* SO PIN */ 12377c478bd9Sstevel@tonic-gate uint_t ds_so_pin_len; 12387c478bd9Sstevel@tonic-gate dprov_session_t **ds_sessions; /* sessions for this instance */ 12397c478bd9Sstevel@tonic-gate uint_t ds_sessions_slots; /* number of session slots */ 12407c478bd9Sstevel@tonic-gate uint_t ds_sessions_count; /* number of open sessions */ 12417c478bd9Sstevel@tonic-gate boolean_t ds_token_initialized; /* provider initialized? */ 12427c478bd9Sstevel@tonic-gate boolean_t ds_user_pin_set; /* user pin set? */ 12437c478bd9Sstevel@tonic-gate char ds_label[CRYPTO_EXT_SIZE_LABEL]; /* "token" label */ 12447c478bd9Sstevel@tonic-gate dprov_object_t *ds_objects[DPROV_MAX_OBJECTS]; /* "token" objects */ 12457c478bd9Sstevel@tonic-gate } dprov_state_t; 12467c478bd9Sstevel@tonic-gate 12477c478bd9Sstevel@tonic-gate 12487c478bd9Sstevel@tonic-gate /* 12497c478bd9Sstevel@tonic-gate * A taskq is associated with each instance of the pseudo driver in order 12507c478bd9Sstevel@tonic-gate * to simulate the asynchronous execution of requests. 12517c478bd9Sstevel@tonic-gate * The following defines the taskq request structures. 12527c478bd9Sstevel@tonic-gate */ 12537c478bd9Sstevel@tonic-gate 12547c478bd9Sstevel@tonic-gate /* request types */ 12557c478bd9Sstevel@tonic-gate typedef enum dprov_req_type { 12567c478bd9Sstevel@tonic-gate /* digest requests */ 12577c478bd9Sstevel@tonic-gate DPROV_REQ_DIGEST_INIT = 1, 12587c478bd9Sstevel@tonic-gate DPROV_REQ_DIGEST, 12597c478bd9Sstevel@tonic-gate DPROV_REQ_DIGEST_UPDATE, 12607c478bd9Sstevel@tonic-gate DPROV_REQ_DIGEST_KEY, 12617c478bd9Sstevel@tonic-gate DPROV_REQ_DIGEST_FINAL, 12627c478bd9Sstevel@tonic-gate DPROV_REQ_DIGEST_ATOMIC, 12637c478bd9Sstevel@tonic-gate /* cipher requests */ 12647c478bd9Sstevel@tonic-gate DPROV_REQ_ENCRYPT_INIT, 12657c478bd9Sstevel@tonic-gate DPROV_REQ_ENCRYPT, 12667c478bd9Sstevel@tonic-gate DPROV_REQ_ENCRYPT_UPDATE, 12677c478bd9Sstevel@tonic-gate DPROV_REQ_ENCRYPT_FINAL, 12687c478bd9Sstevel@tonic-gate DPROV_REQ_ENCRYPT_ATOMIC, 12697c478bd9Sstevel@tonic-gate DPROV_REQ_DECRYPT_INIT, 12707c478bd9Sstevel@tonic-gate DPROV_REQ_DECRYPT, 12717c478bd9Sstevel@tonic-gate DPROV_REQ_DECRYPT_UPDATE, 12727c478bd9Sstevel@tonic-gate DPROV_REQ_DECRYPT_FINAL, 12737c478bd9Sstevel@tonic-gate DPROV_REQ_DECRYPT_ATOMIC, 12747c478bd9Sstevel@tonic-gate /* mac requests */ 12757c478bd9Sstevel@tonic-gate DPROV_REQ_MAC_INIT, 12767c478bd9Sstevel@tonic-gate DPROV_REQ_MAC, 12777c478bd9Sstevel@tonic-gate DPROV_REQ_MAC_UPDATE, 12787c478bd9Sstevel@tonic-gate DPROV_REQ_MAC_FINAL, 12797c478bd9Sstevel@tonic-gate DPROV_REQ_MAC_ATOMIC, 12807c478bd9Sstevel@tonic-gate DPROV_REQ_MAC_VERIFY_ATOMIC, 12817c478bd9Sstevel@tonic-gate /* sign requests */ 12827c478bd9Sstevel@tonic-gate DPROV_REQ_SIGN_INIT, 12837c478bd9Sstevel@tonic-gate DPROV_REQ_SIGN, 12847c478bd9Sstevel@tonic-gate DPROV_REQ_SIGN_UPDATE, 12857c478bd9Sstevel@tonic-gate DPROV_REQ_SIGN_FINAL, 12867c478bd9Sstevel@tonic-gate DPROV_REQ_SIGN_ATOMIC, 12877c478bd9Sstevel@tonic-gate DPROV_REQ_SIGN_RECOVER_INIT, 12887c478bd9Sstevel@tonic-gate DPROV_REQ_SIGN_RECOVER, 12897c478bd9Sstevel@tonic-gate DPROV_REQ_SIGN_RECOVER_ATOMIC, 12907c478bd9Sstevel@tonic-gate /* verify requests */ 12917c478bd9Sstevel@tonic-gate DPROV_REQ_VERIFY_INIT, 12927c478bd9Sstevel@tonic-gate DPROV_REQ_VERIFY, 12937c478bd9Sstevel@tonic-gate DPROV_REQ_VERIFY_UPDATE, 12947c478bd9Sstevel@tonic-gate DPROV_REQ_VERIFY_FINAL, 12957c478bd9Sstevel@tonic-gate DPROV_REQ_VERIFY_ATOMIC, 12967c478bd9Sstevel@tonic-gate DPROV_REQ_VERIFY_RECOVER_INIT, 12977c478bd9Sstevel@tonic-gate DPROV_REQ_VERIFY_RECOVER, 12987c478bd9Sstevel@tonic-gate DPROV_REQ_VERIFY_RECOVER_ATOMIC, 12997c478bd9Sstevel@tonic-gate /* dual ops requests */ 13007c478bd9Sstevel@tonic-gate DPROV_REQ_DIGEST_ENCRYPT_UPDATE, 13017c478bd9Sstevel@tonic-gate DPROV_REQ_DECRYPT_DIGEST_UPDATE, 13027c478bd9Sstevel@tonic-gate DPROV_REQ_SIGN_ENCRYPT_UPDATE, 13037c478bd9Sstevel@tonic-gate DPROV_REQ_DECRYPT_VERIFY_UPDATE, 13047c478bd9Sstevel@tonic-gate /* dual cipher/mac requests */ 13057c478bd9Sstevel@tonic-gate DPROV_REQ_ENCRYPT_MAC_INIT, 13067c478bd9Sstevel@tonic-gate DPROV_REQ_ENCRYPT_MAC, 13077c478bd9Sstevel@tonic-gate DPROV_REQ_ENCRYPT_MAC_UPDATE, 13087c478bd9Sstevel@tonic-gate DPROV_REQ_ENCRYPT_MAC_FINAL, 13097c478bd9Sstevel@tonic-gate DPROV_REQ_ENCRYPT_MAC_ATOMIC, 13107c478bd9Sstevel@tonic-gate DPROV_REQ_MAC_DECRYPT_INIT, 13117c478bd9Sstevel@tonic-gate DPROV_REQ_MAC_DECRYPT, 13127c478bd9Sstevel@tonic-gate DPROV_REQ_MAC_DECRYPT_UPDATE, 13137c478bd9Sstevel@tonic-gate DPROV_REQ_MAC_DECRYPT_FINAL, 13147c478bd9Sstevel@tonic-gate DPROV_REQ_MAC_DECRYPT_ATOMIC, 13157c478bd9Sstevel@tonic-gate DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC, 13167c478bd9Sstevel@tonic-gate /* random number ops */ 13177c478bd9Sstevel@tonic-gate DPROV_REQ_RANDOM_SEED, 13187c478bd9Sstevel@tonic-gate DPROV_REQ_RANDOM_GENERATE, 13197c478bd9Sstevel@tonic-gate /* session management requests */ 13207c478bd9Sstevel@tonic-gate DPROV_REQ_SESSION_OPEN, 13217c478bd9Sstevel@tonic-gate DPROV_REQ_SESSION_CLOSE, 13227c478bd9Sstevel@tonic-gate DPROV_REQ_SESSION_LOGIN, 13237c478bd9Sstevel@tonic-gate DPROV_REQ_SESSION_LOGOUT, 13247c478bd9Sstevel@tonic-gate /* object management requests */ 13257c478bd9Sstevel@tonic-gate DPROV_REQ_OBJECT_CREATE, 13267c478bd9Sstevel@tonic-gate DPROV_REQ_OBJECT_COPY, 13277c478bd9Sstevel@tonic-gate DPROV_REQ_OBJECT_DESTROY, 13287c478bd9Sstevel@tonic-gate DPROV_REQ_OBJECT_GET_SIZE, 13297c478bd9Sstevel@tonic-gate DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE, 13307c478bd9Sstevel@tonic-gate DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE, 13317c478bd9Sstevel@tonic-gate DPROV_REQ_OBJECT_FIND_INIT, 13327c478bd9Sstevel@tonic-gate DPROV_REQ_OBJECT_FIND, 13337c478bd9Sstevel@tonic-gate DPROV_REQ_OBJECT_FIND_FINAL, 13347c478bd9Sstevel@tonic-gate /* key management requests */ 13357c478bd9Sstevel@tonic-gate DPROV_REQ_KEY_GENERATE, 13367c478bd9Sstevel@tonic-gate DPROV_REQ_KEY_GENERATE_PAIR, 13377c478bd9Sstevel@tonic-gate DPROV_REQ_KEY_WRAP, 13387c478bd9Sstevel@tonic-gate DPROV_REQ_KEY_UNWRAP, 13397c478bd9Sstevel@tonic-gate DPROV_REQ_KEY_DERIVE, 13407c478bd9Sstevel@tonic-gate /* provider management requests */ 13417c478bd9Sstevel@tonic-gate DPROV_REQ_MGMT_EXTINFO, 13427c478bd9Sstevel@tonic-gate DPROV_REQ_MGMT_INITTOKEN, 13437c478bd9Sstevel@tonic-gate DPROV_REQ_MGMT_INITPIN, 1344034448feSmcpowers DPROV_REQ_MGMT_SETPIN, 1345034448feSmcpowers /* no (key)store key management requests */ 13465b0c7657Sizick DPROV_REQ_NOSTORE_KEY_GENERATE, 13475b0c7657Sizick DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR, 13485b0c7657Sizick DPROV_REQ_NOSTORE_KEY_DERIVE 13497c478bd9Sstevel@tonic-gate } dprov_req_type_t; 13507c478bd9Sstevel@tonic-gate 13517c478bd9Sstevel@tonic-gate /* for DPROV_REQ_DIGEST requests */ 13527c478bd9Sstevel@tonic-gate typedef struct dprov_digest_req { 13537c478bd9Sstevel@tonic-gate crypto_mechanism_t *dr_mechanism; 13547c478bd9Sstevel@tonic-gate crypto_ctx_t *dr_ctx; 13557c478bd9Sstevel@tonic-gate crypto_data_t *dr_data; 13567c478bd9Sstevel@tonic-gate crypto_key_t *dr_key; 13577c478bd9Sstevel@tonic-gate crypto_data_t *dr_digest; 13587c478bd9Sstevel@tonic-gate } dprov_digest_req_t; 13597c478bd9Sstevel@tonic-gate 13607c478bd9Sstevel@tonic-gate /* for DPROV_REQ_MAC requests */ 13617c478bd9Sstevel@tonic-gate typedef struct dprov_mac_req { 13627c478bd9Sstevel@tonic-gate crypto_mechanism_t *dr_mechanism; 13637c478bd9Sstevel@tonic-gate crypto_ctx_t *dr_ctx; 13647c478bd9Sstevel@tonic-gate crypto_key_t *dr_key; 1365ba5f469cSkrishna crypto_data_t *dr_data; 13667c478bd9Sstevel@tonic-gate crypto_data_t *dr_mac; 13677c478bd9Sstevel@tonic-gate crypto_session_id_t dr_session_id; 13687c478bd9Sstevel@tonic-gate } dprov_mac_req_t; 13697c478bd9Sstevel@tonic-gate 13707c478bd9Sstevel@tonic-gate /* for DPROV_REQ_ENCRYPT and DPROV_REQ_DECRYPT requests */ 13717c478bd9Sstevel@tonic-gate typedef struct dprov_cipher_req { 13727c478bd9Sstevel@tonic-gate crypto_mechanism_t *dr_mechanism; 13737c478bd9Sstevel@tonic-gate crypto_ctx_t *dr_ctx; 13747c478bd9Sstevel@tonic-gate crypto_key_t *dr_key; 13757c478bd9Sstevel@tonic-gate crypto_data_t *dr_plaintext; 13767c478bd9Sstevel@tonic-gate crypto_data_t *dr_ciphertext; 13777c478bd9Sstevel@tonic-gate crypto_session_id_t dr_session_id; 13787c478bd9Sstevel@tonic-gate } dprov_cipher_req_t; 13797c478bd9Sstevel@tonic-gate 13807c478bd9Sstevel@tonic-gate /* for DPROV_REQ_SIGN requests */ 13817c478bd9Sstevel@tonic-gate typedef struct dprov_sign_req { 13827c478bd9Sstevel@tonic-gate crypto_mechanism_t *sr_mechanism; 13837c478bd9Sstevel@tonic-gate crypto_ctx_t *sr_ctx; 13847c478bd9Sstevel@tonic-gate crypto_key_t *sr_key; 13857c478bd9Sstevel@tonic-gate crypto_data_t *sr_data; 13867c478bd9Sstevel@tonic-gate crypto_data_t *sr_signature; 13877c478bd9Sstevel@tonic-gate crypto_session_id_t sr_session_id; 13887c478bd9Sstevel@tonic-gate } dprov_sign_req_t; 13897c478bd9Sstevel@tonic-gate 13907c478bd9Sstevel@tonic-gate /* for DPROV_REQ_VERIFY requests */ 13917c478bd9Sstevel@tonic-gate typedef struct dprov_verify_req { 13927c478bd9Sstevel@tonic-gate crypto_mechanism_t *vr_mechanism; 13937c478bd9Sstevel@tonic-gate crypto_ctx_t *vr_ctx; 13947c478bd9Sstevel@tonic-gate crypto_key_t *vr_key; 13957c478bd9Sstevel@tonic-gate crypto_data_t *vr_data; 13967c478bd9Sstevel@tonic-gate crypto_data_t *vr_signature; 13977c478bd9Sstevel@tonic-gate crypto_session_id_t vr_session_id; 13987c478bd9Sstevel@tonic-gate } dprov_verify_req_t; 13997c478bd9Sstevel@tonic-gate 14007c478bd9Sstevel@tonic-gate /* for dual ops requests */ 14017c478bd9Sstevel@tonic-gate typedef struct dprov_dual_req { 14027c478bd9Sstevel@tonic-gate crypto_ctx_t *dr_signverify_ctx; 14037c478bd9Sstevel@tonic-gate crypto_ctx_t *dr_cipher_ctx; 14047c478bd9Sstevel@tonic-gate crypto_data_t *dr_plaintext; 14057c478bd9Sstevel@tonic-gate crypto_data_t *dr_ciphertext; 14067c478bd9Sstevel@tonic-gate } dprov_dual_req_t; 14077c478bd9Sstevel@tonic-gate 14087c478bd9Sstevel@tonic-gate /* for cipher/mac dual ops requests */ 14097c478bd9Sstevel@tonic-gate typedef struct dprov_cipher_mac_req { 14107c478bd9Sstevel@tonic-gate crypto_session_id_t mr_session_id; 14117c478bd9Sstevel@tonic-gate crypto_ctx_t *mr_ctx; 14127c478bd9Sstevel@tonic-gate crypto_mechanism_t *mr_cipher_mech; 14137c478bd9Sstevel@tonic-gate crypto_key_t *mr_cipher_key; 14147c478bd9Sstevel@tonic-gate crypto_mechanism_t *mr_mac_mech; 14157c478bd9Sstevel@tonic-gate crypto_key_t *mr_mac_key; 14167c478bd9Sstevel@tonic-gate crypto_dual_data_t *mr_dual_data; 14177c478bd9Sstevel@tonic-gate crypto_data_t *mr_data; 14187c478bd9Sstevel@tonic-gate crypto_data_t *mr_mac; 14197c478bd9Sstevel@tonic-gate } dprov_cipher_mac_req_t; 14207c478bd9Sstevel@tonic-gate 14217c478bd9Sstevel@tonic-gate /* for DPROV_REQ_RANDOM requests */ 14227c478bd9Sstevel@tonic-gate typedef struct dprov_random_req { 14237c478bd9Sstevel@tonic-gate uchar_t *rr_buf; 14247c478bd9Sstevel@tonic-gate size_t rr_len; 14257c478bd9Sstevel@tonic-gate crypto_session_id_t rr_session_id; 14268047c9fbSmcpowers uint_t rr_entropy_est; 14278047c9fbSmcpowers uint32_t rr_flags; 14287c478bd9Sstevel@tonic-gate } dprov_random_req_t; 14297c478bd9Sstevel@tonic-gate 14307c478bd9Sstevel@tonic-gate /* for DPROV_REQ_SESSION requests */ 14317c478bd9Sstevel@tonic-gate typedef struct dprov_session_req { 14327c478bd9Sstevel@tonic-gate crypto_session_id_t *sr_session_id_ptr; 14337c478bd9Sstevel@tonic-gate crypto_session_id_t sr_session_id; 14347c478bd9Sstevel@tonic-gate crypto_user_type_t sr_user_type; 14357c478bd9Sstevel@tonic-gate char *sr_pin; 14367c478bd9Sstevel@tonic-gate size_t sr_pin_len; 14377c478bd9Sstevel@tonic-gate } dprov_session_req_t; 14387c478bd9Sstevel@tonic-gate 14397c478bd9Sstevel@tonic-gate /* for DPROV_REQ_OBJECT requests */ 14407c478bd9Sstevel@tonic-gate typedef struct dprov_object_req { 14417c478bd9Sstevel@tonic-gate crypto_session_id_t or_session_id; 14427c478bd9Sstevel@tonic-gate crypto_object_id_t or_object_id; 14437c478bd9Sstevel@tonic-gate crypto_object_attribute_t *or_template; 14447c478bd9Sstevel@tonic-gate uint_t or_attribute_count; 14457c478bd9Sstevel@tonic-gate crypto_object_id_t *or_object_id_ptr; 14467c478bd9Sstevel@tonic-gate size_t *or_object_size; 14477c478bd9Sstevel@tonic-gate void **or_find_pp; 14487c478bd9Sstevel@tonic-gate void *or_find_p; 14497c478bd9Sstevel@tonic-gate uint_t or_max_object_count; 14507c478bd9Sstevel@tonic-gate uint_t *or_object_count_ptr; 14517c478bd9Sstevel@tonic-gate } dprov_object_req_t; 14527c478bd9Sstevel@tonic-gate 14537c478bd9Sstevel@tonic-gate /* for DPROV_REQ_KEY requests */ 14547c478bd9Sstevel@tonic-gate typedef struct dprov_key_req { 14557c478bd9Sstevel@tonic-gate crypto_session_id_t kr_session_id; 14567c478bd9Sstevel@tonic-gate crypto_mechanism_t *kr_mechanism; 14577c478bd9Sstevel@tonic-gate crypto_object_attribute_t *kr_template; 14587c478bd9Sstevel@tonic-gate uint_t kr_attribute_count; 14597c478bd9Sstevel@tonic-gate crypto_object_id_t *kr_object_id_ptr; 14607c478bd9Sstevel@tonic-gate crypto_object_attribute_t *kr_private_key_template; 14617c478bd9Sstevel@tonic-gate uint_t kr_private_key_attribute_count; 14627c478bd9Sstevel@tonic-gate crypto_object_id_t *kr_private_key_object_id_ptr; 14637c478bd9Sstevel@tonic-gate crypto_key_t *kr_key; 14647c478bd9Sstevel@tonic-gate uchar_t *kr_wrapped_key; 14657c478bd9Sstevel@tonic-gate size_t *kr_wrapped_key_len_ptr; 1466034448feSmcpowers crypto_object_attribute_t *kr_out_template1; 1467034448feSmcpowers crypto_object_attribute_t *kr_out_template2; 1468034448feSmcpowers uint_t kr_out_attribute_count1; 1469034448feSmcpowers uint_t kr_out_attribute_count2; 14707c478bd9Sstevel@tonic-gate } dprov_key_req_t; 14717c478bd9Sstevel@tonic-gate 14727c478bd9Sstevel@tonic-gate /* for DPROV_REQ_MGMT requests */ 14737c478bd9Sstevel@tonic-gate typedef struct dprov_mgmt_req { 14747c478bd9Sstevel@tonic-gate crypto_session_id_t mr_session_id; 14757c478bd9Sstevel@tonic-gate char *mr_pin; 14767c478bd9Sstevel@tonic-gate size_t mr_pin_len; 14777c478bd9Sstevel@tonic-gate char *mr_old_pin; 14787c478bd9Sstevel@tonic-gate size_t mr_old_pin_len; 14797c478bd9Sstevel@tonic-gate char *mr_label; 14807c478bd9Sstevel@tonic-gate crypto_provider_ext_info_t *mr_ext_info; 14817c478bd9Sstevel@tonic-gate } dprov_mgmt_req_t; 14827c478bd9Sstevel@tonic-gate 14837c478bd9Sstevel@tonic-gate /* request, as queued on taskq */ 14847c478bd9Sstevel@tonic-gate typedef struct dprov_req { 14857c478bd9Sstevel@tonic-gate dprov_req_type_t dr_type; 14867c478bd9Sstevel@tonic-gate dprov_state_t *dr_softc; 14877c478bd9Sstevel@tonic-gate crypto_req_handle_t dr_kcf_req; 14887c478bd9Sstevel@tonic-gate union { 14897c478bd9Sstevel@tonic-gate dprov_digest_req_t dru_digest_req; 14907c478bd9Sstevel@tonic-gate dprov_mac_req_t dru_mac_req; 14917c478bd9Sstevel@tonic-gate dprov_cipher_req_t dru_cipher_req; 14927c478bd9Sstevel@tonic-gate dprov_sign_req_t dru_sign_req; 14937c478bd9Sstevel@tonic-gate dprov_verify_req_t dru_verify_req; 14947c478bd9Sstevel@tonic-gate dprov_dual_req_t dru_dual_req; 14957c478bd9Sstevel@tonic-gate dprov_cipher_mac_req_t dru_cipher_mac_req; 14967c478bd9Sstevel@tonic-gate dprov_random_req_t dru_random_req; 14977c478bd9Sstevel@tonic-gate dprov_session_req_t dru_session_req; 14987c478bd9Sstevel@tonic-gate dprov_object_req_t dru_object_req; 14997c478bd9Sstevel@tonic-gate dprov_key_req_t dru_key_req; 15007c478bd9Sstevel@tonic-gate dprov_mgmt_req_t dru_mgmt_req; 15017c478bd9Sstevel@tonic-gate } dr_req; 15027c478bd9Sstevel@tonic-gate } dprov_req_t; 15037c478bd9Sstevel@tonic-gate 15047c478bd9Sstevel@tonic-gate /* shortcuts for union fields */ 15057c478bd9Sstevel@tonic-gate #define dr_digest_req dr_req.dru_digest_req 15067c478bd9Sstevel@tonic-gate #define dr_mac_req dr_req.dru_mac_req 15077c478bd9Sstevel@tonic-gate #define dr_cipher_req dr_req.dru_cipher_req 15087c478bd9Sstevel@tonic-gate #define dr_sign_req dr_req.dru_sign_req 15097c478bd9Sstevel@tonic-gate #define dr_verify_req dr_req.dru_verify_req 15107c478bd9Sstevel@tonic-gate #define dr_dual_req dr_req.dru_dual_req 15117c478bd9Sstevel@tonic-gate #define dr_cipher_mac_req dr_req.dru_cipher_mac_req 15127c478bd9Sstevel@tonic-gate #define dr_random_req dr_req.dru_random_req 15137c478bd9Sstevel@tonic-gate #define dr_session_req dr_req.dru_session_req 15147c478bd9Sstevel@tonic-gate #define dr_object_req dr_req.dru_object_req 15157c478bd9Sstevel@tonic-gate #define dr_key_req dr_req.dru_key_req 15167c478bd9Sstevel@tonic-gate #define dr_mgmt_req dr_req.dru_mgmt_req 15177c478bd9Sstevel@tonic-gate 15187c478bd9Sstevel@tonic-gate /* prototypes for the tasq dispatcher functions */ 15197c478bd9Sstevel@tonic-gate static void dprov_digest_task(dprov_req_t *); 15207c478bd9Sstevel@tonic-gate static void dprov_mac_task(dprov_req_t *); 15217c478bd9Sstevel@tonic-gate static void dprov_sign_task(dprov_req_t *); 15227c478bd9Sstevel@tonic-gate static void dprov_verify_task(dprov_req_t *); 15237c478bd9Sstevel@tonic-gate static void dprov_dual_task(dprov_req_t *); 15247c478bd9Sstevel@tonic-gate static void dprov_cipher_task(dprov_req_t *); 15257c478bd9Sstevel@tonic-gate static void dprov_cipher_mac_task(dprov_req_t *); 15267c478bd9Sstevel@tonic-gate static void dprov_random_task(dprov_req_t *); 15277c478bd9Sstevel@tonic-gate static void dprov_session_task(dprov_req_t *); 15287c478bd9Sstevel@tonic-gate static void dprov_object_task(dprov_req_t *); 15297c478bd9Sstevel@tonic-gate static void dprov_key_task(dprov_req_t *); 15307c478bd9Sstevel@tonic-gate static void dprov_mgmt_task(dprov_req_t *); 15317c478bd9Sstevel@tonic-gate 15327c478bd9Sstevel@tonic-gate /* helper functions */ 15337c478bd9Sstevel@tonic-gate static int dprov_digest_submit_req(dprov_req_type_t, dprov_state_t *, 15347c478bd9Sstevel@tonic-gate crypto_req_handle_t, crypto_mechanism_t *, crypto_data_t *, crypto_key_t *, 15357c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_ctx_t *, int); 15367c478bd9Sstevel@tonic-gate static int dprov_cipher_submit_req(dprov_req_type_t, dprov_state_t *, 15377c478bd9Sstevel@tonic-gate crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 15387c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int); 15397c478bd9Sstevel@tonic-gate static int dprov_mac_submit_req(dprov_req_type_t, dprov_state_t *, 15407c478bd9Sstevel@tonic-gate crypto_req_handle_t, crypto_mechanism_t *, crypto_data_t *, 15417c478bd9Sstevel@tonic-gate crypto_key_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int); 15427c478bd9Sstevel@tonic-gate static int dprov_sign_submit_req(dprov_req_type_t, dprov_state_t *, 15437c478bd9Sstevel@tonic-gate crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *, 15447c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int); 15457c478bd9Sstevel@tonic-gate static int dprov_verify_submit_req(dprov_req_type_t, dprov_state_t *, 15467c478bd9Sstevel@tonic-gate crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *, 15477c478bd9Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int); 15487c478bd9Sstevel@tonic-gate static int dprov_dual_submit_req(dprov_req_type_t, dprov_state_t *, 15497c478bd9Sstevel@tonic-gate crypto_req_handle_t, crypto_ctx_t *, crypto_ctx_t *, crypto_data_t *, 15507c478bd9Sstevel@tonic-gate crypto_data_t *); 15517c478bd9Sstevel@tonic-gate static int dprov_cipher_mac_submit_req(dprov_req_type_t, dprov_state_t *, 15527c478bd9Sstevel@tonic-gate crypto_req_handle_t, crypto_ctx_t *, crypto_session_id_t, 15537c478bd9Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *, crypto_key_t *, 15547c478bd9Sstevel@tonic-gate crypto_dual_data_t *, crypto_data_t *, crypto_data_t *, int); 15557c478bd9Sstevel@tonic-gate static int dprov_random_submit_req(dprov_req_type_t, dprov_state_t *, 15568047c9fbSmcpowers crypto_req_handle_t, uchar_t *, size_t, crypto_session_id_t, uint_t, 15578047c9fbSmcpowers uint32_t); 15587c478bd9Sstevel@tonic-gate static int dprov_session_submit_req(dprov_req_type_t, dprov_state_t *, 15597c478bd9Sstevel@tonic-gate crypto_req_handle_t, crypto_session_id_t *, crypto_session_id_t, 15607c478bd9Sstevel@tonic-gate crypto_user_type_t, char *, size_t); 15617c478bd9Sstevel@tonic-gate static int dprov_object_submit_req(dprov_req_type_t, dprov_state_t *, 15627c478bd9Sstevel@tonic-gate crypto_req_handle_t, crypto_session_id_t, crypto_object_id_t, 15637c478bd9Sstevel@tonic-gate crypto_object_attribute_t *, uint_t, crypto_object_id_t *, size_t *, 15647c478bd9Sstevel@tonic-gate void **, void *, uint_t, uint_t *, int); 15657c478bd9Sstevel@tonic-gate static int dprov_key_submit_req(dprov_req_type_t, dprov_state_t *, 15667c478bd9Sstevel@tonic-gate crypto_req_handle_t, crypto_session_id_t, crypto_mechanism_t *, 15677c478bd9Sstevel@tonic-gate crypto_object_attribute_t *, uint_t, crypto_object_id_t *, 15687c478bd9Sstevel@tonic-gate crypto_object_attribute_t *, uint_t, crypto_object_id_t *, 1569034448feSmcpowers crypto_key_t *, uchar_t *, size_t *, crypto_object_attribute_t *, 1570034448feSmcpowers uint_t, crypto_object_attribute_t *, uint_t); 15717c478bd9Sstevel@tonic-gate static int dprov_mgmt_submit_req(dprov_req_type_t, dprov_state_t *, 15727c478bd9Sstevel@tonic-gate crypto_req_handle_t, crypto_session_id_t, char *, size_t, char *, size_t, 15737c478bd9Sstevel@tonic-gate char *, crypto_provider_ext_info_t *); 15747c478bd9Sstevel@tonic-gate static int dprov_get_sw_prov(crypto_mechanism_t *, kcf_provider_desc_t **, 15757c478bd9Sstevel@tonic-gate crypto_mech_type_t *); 15767c478bd9Sstevel@tonic-gate 15777c478bd9Sstevel@tonic-gate /* object management helper functions */ 15787c478bd9Sstevel@tonic-gate static void dprov_free_object(dprov_object_t *); 15797c478bd9Sstevel@tonic-gate static void dprov_release_session_objects(dprov_session_t *); 1580f9fbec18Smcpowers static void dprov_adjust_attrs(crypto_object_attribute_t *, int); 15817c478bd9Sstevel@tonic-gate static boolean_t dprov_object_is_private(dprov_object_t *); 15827c478bd9Sstevel@tonic-gate static boolean_t dprov_object_is_token(dprov_object_t *); 15837c478bd9Sstevel@tonic-gate static int dprov_key_value_secret(dprov_state_t *, crypto_session_id_t, 15847c478bd9Sstevel@tonic-gate dprov_req_type_t, crypto_key_t *, crypto_key_t *); 15857c478bd9Sstevel@tonic-gate static int dprov_key_attr_asymmetric(dprov_state_t *, crypto_session_id_t, 15867c478bd9Sstevel@tonic-gate dprov_req_type_t, crypto_key_t *, crypto_key_t *); 15877c478bd9Sstevel@tonic-gate static int dprov_get_object_attr_boolean(dprov_object_t *, uint64_t, 15887c478bd9Sstevel@tonic-gate boolean_t *); 15897c478bd9Sstevel@tonic-gate static int dprov_get_object_attr_ulong(dprov_object_t *, uint64_t, ulong_t *); 15907c478bd9Sstevel@tonic-gate static int dprov_get_object_attr_array(dprov_object_t *, uint64_t, void **, 15917c478bd9Sstevel@tonic-gate size_t *); 15927c478bd9Sstevel@tonic-gate static int dprov_get_key_attr_ulong(crypto_key_t *, uint64_t, ulong_t *); 15937c478bd9Sstevel@tonic-gate static int dprov_get_key_attr_array(crypto_key_t *, uint64_t, void **, 15947c478bd9Sstevel@tonic-gate size_t *); 15957c478bd9Sstevel@tonic-gate static int dprov_create_object_from_template(dprov_state_t *, dprov_session_t *, 15967c478bd9Sstevel@tonic-gate crypto_object_attribute_t *, uint_t, crypto_object_id_t *, boolean_t, 15977c478bd9Sstevel@tonic-gate boolean_t); 15987c478bd9Sstevel@tonic-gate static int dprov_get_template_attr_scalar_common(crypto_object_attribute_t *, 15997c478bd9Sstevel@tonic-gate uint_t, uint64_t, void *, size_t); 16007c478bd9Sstevel@tonic-gate static int dprov_get_template_attr_boolean(crypto_object_attribute_t *, 16017c478bd9Sstevel@tonic-gate uint_t, uint64_t, boolean_t *); 16027c478bd9Sstevel@tonic-gate static int dprov_get_template_attr_ulong(crypto_object_attribute_t *, uint_t, 16037c478bd9Sstevel@tonic-gate uint64_t, ulong_t *); 16047c478bd9Sstevel@tonic-gate static int dprov_template_attr_present(crypto_object_attribute_t *, uint_t, 16057c478bd9Sstevel@tonic-gate uint64_t); 16067c478bd9Sstevel@tonic-gate static int dprov_get_template_attr_array(crypto_object_attribute_t *, uint_t, 16077c478bd9Sstevel@tonic-gate uint64_t, void **, size_t *); 16087c478bd9Sstevel@tonic-gate static int dprov_destroy_object(dprov_state_t *, dprov_session_t *, 16097c478bd9Sstevel@tonic-gate crypto_object_id_t); 16107c478bd9Sstevel@tonic-gate static int dprov_object_set_attr(dprov_session_t *, crypto_object_id_t, 16117c478bd9Sstevel@tonic-gate crypto_object_attribute_t *, uint_t, boolean_t); 16127c478bd9Sstevel@tonic-gate static int dprov_find_attr(crypto_object_attribute_t *, uint_t, uint64_t); 16137c478bd9Sstevel@tonic-gate static boolean_t dprov_attributes_match(dprov_object_t *, 16147c478bd9Sstevel@tonic-gate crypto_object_attribute_t *, uint_t); 16157c478bd9Sstevel@tonic-gate 16167c478bd9Sstevel@tonic-gate /* retrieve the softc and instance number from a SPI crypto context */ 16177c478bd9Sstevel@tonic-gate #define DPROV_SOFTC_FROM_CTX(ctx, softc, instance) { \ 16187c478bd9Sstevel@tonic-gate (softc) = (dprov_state_t *)(ctx)->cc_provider; \ 16197c478bd9Sstevel@tonic-gate (instance) = ddi_get_instance((softc)->ds_dip); \ 16207c478bd9Sstevel@tonic-gate } 16217c478bd9Sstevel@tonic-gate 16227c478bd9Sstevel@tonic-gate /* retrieve the softc and instance number from a taskq request */ 16237c478bd9Sstevel@tonic-gate #define DPROV_SOFTC_FROM_REQ(req, softc, instance) { \ 16247c478bd9Sstevel@tonic-gate (softc) = (req)->dr_softc; \ 16257c478bd9Sstevel@tonic-gate (instance) = ddi_get_instance((softc)->ds_dip); \ 16267c478bd9Sstevel@tonic-gate } 16277c478bd9Sstevel@tonic-gate 16287c478bd9Sstevel@tonic-gate /* 16297c478bd9Sstevel@tonic-gate * The dprov private context most of the time contains a pointer to the 16307c478bd9Sstevel@tonic-gate * crypto_context_t that was allocated when calling a KCF function. 16317c478bd9Sstevel@tonic-gate * Dual cipher/mac operations however require the dprov driver 16327c478bd9Sstevel@tonic-gate * to maintain the contexts associated with the separate cipher 16337c478bd9Sstevel@tonic-gate * and mac operations. These two types of dprov contexts are 16347c478bd9Sstevel@tonic-gate * defined below. 16357c478bd9Sstevel@tonic-gate */ 16367c478bd9Sstevel@tonic-gate typedef enum dprov_ctx_type { 16377c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE, 16387c478bd9Sstevel@tonic-gate DPROV_CTX_DUAL 16397c478bd9Sstevel@tonic-gate } dprov_ctx_type_t; 16407c478bd9Sstevel@tonic-gate 16417c478bd9Sstevel@tonic-gate /* 16427c478bd9Sstevel@tonic-gate * When the context refers to a single KCF context, the 16437c478bd9Sstevel@tonic-gate * cc_provider field of a crypto_ctx_t points to a structure of 16447c478bd9Sstevel@tonic-gate * type dprov_ctx_single. 16457c478bd9Sstevel@tonic-gate */ 16467c478bd9Sstevel@tonic-gate typedef struct dprov_ctx_single { 16477c478bd9Sstevel@tonic-gate dprov_ctx_type_t dc_type; 16487c478bd9Sstevel@tonic-gate crypto_context_t dc_ctx; 1649ba5f469cSkrishna boolean_t dc_svrfy_to_mac; 16507c478bd9Sstevel@tonic-gate } dprov_ctx_single_t; 16517c478bd9Sstevel@tonic-gate 16527c478bd9Sstevel@tonic-gate /* 16537c478bd9Sstevel@tonic-gate * When the context is used for cipher/mac operations, it contains 16547c478bd9Sstevel@tonic-gate * pointers to to KCF contexts, one for the cipher operation, the 16557c478bd9Sstevel@tonic-gate * other for the mac operation. 16567c478bd9Sstevel@tonic-gate */ 16577c478bd9Sstevel@tonic-gate typedef struct dprov_ctx_dual { 16587c478bd9Sstevel@tonic-gate dprov_ctx_type_t cd_type; 16597c478bd9Sstevel@tonic-gate crypto_context_t cd_cipher_ctx; 16607c478bd9Sstevel@tonic-gate crypto_context_t cd_mac_ctx; 16617c478bd9Sstevel@tonic-gate } dprov_ctx_dual_t; 16627c478bd9Sstevel@tonic-gate 16637c478bd9Sstevel@tonic-gate /* 16647c478bd9Sstevel@tonic-gate * Helper macros for context accessors. These macros return the 16657c478bd9Sstevel@tonic-gate * k-API context corresponding to the given SPI context for 16667c478bd9Sstevel@tonic-gate * single and dual cipher/mac operations. 16677c478bd9Sstevel@tonic-gate */ 16687c478bd9Sstevel@tonic-gate 1669ba5f469cSkrishna #define DPROV_CTX_P(_ctx) \ 1670ba5f469cSkrishna ((dprov_ctx_single_t *)(_ctx)->cc_provider_private) 1671ba5f469cSkrishna 1672ba5f469cSkrishna #define DPROV_CTX_SINGLE(_ctx) ((DPROV_CTX_P(_ctx))->dc_ctx) 16737c478bd9Sstevel@tonic-gate 16747c478bd9Sstevel@tonic-gate #define DPROV_CTX_DUAL_CIPHER(_ctx) \ 16757c478bd9Sstevel@tonic-gate (((dprov_ctx_dual_t *)(_ctx)->cc_provider_private)->cd_cipher_ctx) 16767c478bd9Sstevel@tonic-gate 16777c478bd9Sstevel@tonic-gate #define DPROV_CTX_DUAL_MAC(_ctx) \ 16787c478bd9Sstevel@tonic-gate (((dprov_ctx_dual_t *)(_ctx)->cc_provider_private)->cd_mac_ctx) 16797c478bd9Sstevel@tonic-gate 16807c478bd9Sstevel@tonic-gate static int dprov_alloc_context(dprov_req_type_t, crypto_ctx_t *); 16817c478bd9Sstevel@tonic-gate 16827c478bd9Sstevel@tonic-gate 16837c478bd9Sstevel@tonic-gate 16847c478bd9Sstevel@tonic-gate static void *statep; /* state pointer */ 16857c478bd9Sstevel@tonic-gate 16867c478bd9Sstevel@tonic-gate /* 16877c478bd9Sstevel@tonic-gate * DDI entry points. 16887c478bd9Sstevel@tonic-gate */ 16897c478bd9Sstevel@tonic-gate int 16907c478bd9Sstevel@tonic-gate _init(void) 16917c478bd9Sstevel@tonic-gate { 16927c478bd9Sstevel@tonic-gate int error; 16937c478bd9Sstevel@tonic-gate 16947c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_INIT, ("dprov: in _init\n")); 16957c478bd9Sstevel@tonic-gate 16967c478bd9Sstevel@tonic-gate if ((error = ddi_soft_state_init(&statep, sizeof (dprov_state_t), 16977c478bd9Sstevel@tonic-gate 0)) != 0) 16987c478bd9Sstevel@tonic-gate return (error); 16997c478bd9Sstevel@tonic-gate 17007c478bd9Sstevel@tonic-gate return (mod_install(&modlinkage)); 17017c478bd9Sstevel@tonic-gate } 17027c478bd9Sstevel@tonic-gate 17037c478bd9Sstevel@tonic-gate int 17047c478bd9Sstevel@tonic-gate _fini(void) 17057c478bd9Sstevel@tonic-gate { 17067c478bd9Sstevel@tonic-gate int error; 17077c478bd9Sstevel@tonic-gate 17087c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_INIT, ("dprov: in _fini\n")); 17097c478bd9Sstevel@tonic-gate 17107c478bd9Sstevel@tonic-gate if ((error = mod_remove(&modlinkage)) != 0) 17117c478bd9Sstevel@tonic-gate return (error); 17127c478bd9Sstevel@tonic-gate 17137c478bd9Sstevel@tonic-gate ddi_soft_state_fini(&statep); 17147c478bd9Sstevel@tonic-gate 17157c478bd9Sstevel@tonic-gate return (0); 17167c478bd9Sstevel@tonic-gate } 17177c478bd9Sstevel@tonic-gate 17187c478bd9Sstevel@tonic-gate int 17197c478bd9Sstevel@tonic-gate _info(struct modinfo *modinfop) 17207c478bd9Sstevel@tonic-gate { 17217c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_INIT, ("dprov: in _info\n")); 17227c478bd9Sstevel@tonic-gate 17237c478bd9Sstevel@tonic-gate return (mod_info(&modlinkage, modinfop)); 17247c478bd9Sstevel@tonic-gate } 17257c478bd9Sstevel@tonic-gate 17267c478bd9Sstevel@tonic-gate /* ARGSUSED */ 17277c478bd9Sstevel@tonic-gate static int 17287c478bd9Sstevel@tonic-gate dprov_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result) 17297c478bd9Sstevel@tonic-gate { 17307c478bd9Sstevel@tonic-gate int instance = getminor((dev_t)arg); 17317c478bd9Sstevel@tonic-gate dprov_state_t *softc; 17327c478bd9Sstevel@tonic-gate 17337c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_getinfo() for %d\n", 17347c478bd9Sstevel@tonic-gate instance)); 17357c478bd9Sstevel@tonic-gate 17367c478bd9Sstevel@tonic-gate switch (cmd) { 17377c478bd9Sstevel@tonic-gate case DDI_INFO_DEVT2DEVINFO: 17387c478bd9Sstevel@tonic-gate softc = ddi_get_soft_state(statep, instance); 17397c478bd9Sstevel@tonic-gate *result = softc->ds_dip; 17407c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 17417c478bd9Sstevel@tonic-gate 17427c478bd9Sstevel@tonic-gate case DDI_INFO_DEVT2INSTANCE: 17437c478bd9Sstevel@tonic-gate *result = (void *)(uintptr_t)instance; 17447c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 17457c478bd9Sstevel@tonic-gate } 17467c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 17477c478bd9Sstevel@tonic-gate } 17487c478bd9Sstevel@tonic-gate 17497c478bd9Sstevel@tonic-gate static int 17507c478bd9Sstevel@tonic-gate dprov_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 17517c478bd9Sstevel@tonic-gate { 17527c478bd9Sstevel@tonic-gate int instance = ddi_get_instance(dip); 17537c478bd9Sstevel@tonic-gate dprov_state_t *softc; 17547c478bd9Sstevel@tonic-gate char devname[256]; 17557c478bd9Sstevel@tonic-gate int ret; 17567c478bd9Sstevel@tonic-gate 17577c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_attach() for %d\n", 17587c478bd9Sstevel@tonic-gate instance)); 17597c478bd9Sstevel@tonic-gate 17607c478bd9Sstevel@tonic-gate if (cmd != DDI_ATTACH) { 17617c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 17627c478bd9Sstevel@tonic-gate } 17637c478bd9Sstevel@tonic-gate 17647c478bd9Sstevel@tonic-gate /* get new softc and initialize it */ 17657c478bd9Sstevel@tonic-gate if (ddi_soft_state_zalloc(statep, instance) != DDI_SUCCESS) 17667c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 17677c478bd9Sstevel@tonic-gate 17687c478bd9Sstevel@tonic-gate softc = ddi_get_soft_state(statep, instance); 17697c478bd9Sstevel@tonic-gate mutex_init(&softc->ds_lock, NULL, MUTEX_DRIVER, NULL); 17707c478bd9Sstevel@tonic-gate softc->ds_dip = dip; 17717c478bd9Sstevel@tonic-gate softc->ds_prov_handle = NULL; 17727c478bd9Sstevel@tonic-gate 17737c478bd9Sstevel@tonic-gate /* create minor node */ 1774973f6396Sizick (void) sprintf(devname, "dprov%d", instance); 17757c478bd9Sstevel@tonic-gate if (ddi_create_minor_node(dip, devname, S_IFCHR, instance, 17767c478bd9Sstevel@tonic-gate DDI_PSEUDO, 0) != DDI_SUCCESS) { 17777c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "attach: failed creating minor node"); 17787c478bd9Sstevel@tonic-gate mutex_destroy(&softc->ds_lock); 17797c478bd9Sstevel@tonic-gate ddi_soft_state_free(statep, instance); 17807c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 17817c478bd9Sstevel@tonic-gate } 17827c478bd9Sstevel@tonic-gate 1783034448feSmcpowers nostore_key_gen = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1784034448feSmcpowers DDI_PROP_DONTPASS, "nostore_key_gen", 0); 1785034448feSmcpowers if (nostore_key_gen != 0) { 1786034448feSmcpowers dprov_prov_info.pi_interface_version = CRYPTO_SPI_VERSION_3; 1787034448feSmcpowers dprov_crypto_ops.co_object_ops = NULL; 1788034448feSmcpowers dprov_crypto_ops.co_nostore_key_ops = &dprov_nostore_key_ops; 1789034448feSmcpowers } 1790034448feSmcpowers 1791ba5f469cSkrishna dprov_max_digestsz = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1792ba5f469cSkrishna DDI_PROP_DONTPASS, "max_digest_sz", INT_MAX); 1793ba5f469cSkrishna if (dprov_max_digestsz != INT_MAX && dprov_max_digestsz != 0 && 1794ba5f469cSkrishna dprov_max_digestsz != DDI_PROP_NOT_FOUND) { 1795ba5f469cSkrishna dprov_no_multipart = B_TRUE; 17964df55fdeSJanie Lu dprov_prov_info.pi_flags |= 17974df55fdeSJanie Lu (CRYPTO_HASH_NO_UPDATE | CRYPTO_HMAC_NO_UPDATE); 1798ba5f469cSkrishna } 1799ba5f469cSkrishna 18007c478bd9Sstevel@tonic-gate /* create taskq */ 18017c478bd9Sstevel@tonic-gate softc->ds_taskq = taskq_create(devname, 1, minclsyspri, 18027c478bd9Sstevel@tonic-gate crypto_taskq_minalloc, crypto_taskq_maxalloc, TASKQ_PREPOPULATE); 18037c478bd9Sstevel@tonic-gate 18047c478bd9Sstevel@tonic-gate /* initialize table of sessions */ 18057c478bd9Sstevel@tonic-gate softc->ds_sessions = kmem_zalloc(DPROV_MIN_SESSIONS * 18067c478bd9Sstevel@tonic-gate sizeof (dprov_session_t *), KM_SLEEP); 18077c478bd9Sstevel@tonic-gate softc->ds_sessions_slots = DPROV_MIN_SESSIONS; 18087c478bd9Sstevel@tonic-gate softc->ds_sessions_count = 0; 18097c478bd9Sstevel@tonic-gate 18107c478bd9Sstevel@tonic-gate /* initialized done by init_token entry point */ 18117c478bd9Sstevel@tonic-gate softc->ds_token_initialized = B_TRUE; 18127c478bd9Sstevel@tonic-gate 1813894b2776Smcpowers (void) memset(softc->ds_label, ' ', CRYPTO_EXT_SIZE_LABEL); 1814894b2776Smcpowers bcopy("Dummy Pseudo HW Provider", softc->ds_label, 24); 1815894b2776Smcpowers 18167c478bd9Sstevel@tonic-gate bcopy("changeme", softc->ds_user_pin, 8); 18177c478bd9Sstevel@tonic-gate softc->ds_user_pin_len = 8; 18187c478bd9Sstevel@tonic-gate softc->ds_user_pin_set = B_TRUE; 18197c478bd9Sstevel@tonic-gate 18207c478bd9Sstevel@tonic-gate /* register with the crypto framework */ 18217c478bd9Sstevel@tonic-gate dprov_prov_info.pi_provider_dev.pd_hw = dip; 18227c478bd9Sstevel@tonic-gate dprov_prov_info.pi_provider_handle = softc; 1823ba5f469cSkrishna 1824ba5f469cSkrishna if (dprov_no_multipart) { /* Export only single part */ 1825ba5f469cSkrishna dprov_digest_ops.digest_update = NULL; 1826ba5f469cSkrishna dprov_digest_ops.digest_key = NULL; 1827ba5f469cSkrishna dprov_digest_ops.digest_final = NULL; 1828ba5f469cSkrishna dprov_object_ops.object_create = NULL; 1829ba5f469cSkrishna } 1830ba5f469cSkrishna 18317c478bd9Sstevel@tonic-gate if ((ret = crypto_register_provider(&dprov_prov_info, 18327c478bd9Sstevel@tonic-gate &softc->ds_prov_handle)) != CRYPTO_SUCCESS) { 18337c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, 18347c478bd9Sstevel@tonic-gate "dprov crypto_register_provider() failed (0x%x)", ret); 18357c478bd9Sstevel@tonic-gate taskq_destroy(softc->ds_taskq); 18367c478bd9Sstevel@tonic-gate kmem_free(softc->ds_sessions, softc->ds_sessions_slots * 18377c478bd9Sstevel@tonic-gate sizeof (dprov_session_t *)); 18387c478bd9Sstevel@tonic-gate mutex_destroy(&softc->ds_lock); 18397c478bd9Sstevel@tonic-gate ddi_soft_state_free(statep, instance); 18407c478bd9Sstevel@tonic-gate ddi_remove_minor_node(dip, NULL); 18417c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 18427c478bd9Sstevel@tonic-gate } 18437c478bd9Sstevel@tonic-gate 18447c478bd9Sstevel@tonic-gate /* 18457c478bd9Sstevel@tonic-gate * This call is for testing only; it is not required by the SPI. 18467c478bd9Sstevel@tonic-gate */ 18477c478bd9Sstevel@tonic-gate crypto_provider_notification(softc->ds_prov_handle, 18487c478bd9Sstevel@tonic-gate CRYPTO_PROVIDER_READY); 18497c478bd9Sstevel@tonic-gate 18507c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 18517c478bd9Sstevel@tonic-gate } 18527c478bd9Sstevel@tonic-gate 18537c478bd9Sstevel@tonic-gate static int 18547c478bd9Sstevel@tonic-gate dprov_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 18557c478bd9Sstevel@tonic-gate { 18567c478bd9Sstevel@tonic-gate int instance = ddi_get_instance(dip); 18577c478bd9Sstevel@tonic-gate dprov_state_t *softc = ddi_get_soft_state(statep, instance); 18587c478bd9Sstevel@tonic-gate dprov_session_t *session; 18597c478bd9Sstevel@tonic-gate int i, ret; 18607c478bd9Sstevel@tonic-gate 18617c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_detach() for %d\n", 18627c478bd9Sstevel@tonic-gate instance)); 18637c478bd9Sstevel@tonic-gate 18647c478bd9Sstevel@tonic-gate if (cmd != DDI_DETACH) 18657c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 18667c478bd9Sstevel@tonic-gate 18677c478bd9Sstevel@tonic-gate /* unregister from the crypto framework */ 18687c478bd9Sstevel@tonic-gate if (softc->ds_prov_handle != NULL) 18697c478bd9Sstevel@tonic-gate if ((ret = crypto_unregister_provider( 18707c478bd9Sstevel@tonic-gate softc->ds_prov_handle)) != CRYPTO_SUCCESS) { 18717c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_detach: " 18727c478bd9Sstevel@tonic-gate "crypto_unregister_provider() " 18737c478bd9Sstevel@tonic-gate "failed (0x%x)", ret); 18747c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 18757c478bd9Sstevel@tonic-gate } 18767c478bd9Sstevel@tonic-gate 18777c478bd9Sstevel@tonic-gate 18787c478bd9Sstevel@tonic-gate taskq_destroy(softc->ds_taskq); 18797c478bd9Sstevel@tonic-gate 18807c478bd9Sstevel@tonic-gate for (i = 0; i < softc->ds_sessions_slots; i++) { 18817c478bd9Sstevel@tonic-gate if ((session = softc->ds_sessions[i]) == NULL) 18827c478bd9Sstevel@tonic-gate continue; 18837c478bd9Sstevel@tonic-gate 18847c478bd9Sstevel@tonic-gate dprov_release_session_objects(session); 18857c478bd9Sstevel@tonic-gate 18867c478bd9Sstevel@tonic-gate kmem_free(session, sizeof (dprov_session_t)); 18877c478bd9Sstevel@tonic-gate softc->ds_sessions_count--; 18887c478bd9Sstevel@tonic-gate 18897c478bd9Sstevel@tonic-gate } 18907c478bd9Sstevel@tonic-gate 18917c478bd9Sstevel@tonic-gate kmem_free(softc->ds_sessions, softc->ds_sessions_slots * 18927c478bd9Sstevel@tonic-gate sizeof (dprov_session_t *)); 18937c478bd9Sstevel@tonic-gate /* free token objects */ 18947c478bd9Sstevel@tonic-gate for (i = 0; i < DPROV_MAX_OBJECTS; i++) 18957c478bd9Sstevel@tonic-gate if (softc->ds_objects[i] != NULL) 18967c478bd9Sstevel@tonic-gate dprov_free_object(softc->ds_objects[i]); 18977c478bd9Sstevel@tonic-gate 18987c478bd9Sstevel@tonic-gate mutex_destroy(&softc->ds_lock); 18997c478bd9Sstevel@tonic-gate ddi_soft_state_free(statep, instance); 19007c478bd9Sstevel@tonic-gate 19017c478bd9Sstevel@tonic-gate ddi_remove_minor_node(dip, NULL); 19027c478bd9Sstevel@tonic-gate 19037c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 19047c478bd9Sstevel@tonic-gate } 19057c478bd9Sstevel@tonic-gate 19067c478bd9Sstevel@tonic-gate /* 19077c478bd9Sstevel@tonic-gate * Control entry points. 19087c478bd9Sstevel@tonic-gate */ 19097c478bd9Sstevel@tonic-gate static void 19107c478bd9Sstevel@tonic-gate dprov_provider_status(crypto_provider_handle_t provider, uint_t *status) 19117c478bd9Sstevel@tonic-gate { 19127c478bd9Sstevel@tonic-gate _NOTE(ARGUNUSED(provider)) 19137c478bd9Sstevel@tonic-gate 19147c478bd9Sstevel@tonic-gate *status = CRYPTO_PROVIDER_READY; 19157c478bd9Sstevel@tonic-gate } 19167c478bd9Sstevel@tonic-gate 19177c478bd9Sstevel@tonic-gate /* 19187c478bd9Sstevel@tonic-gate * Digest entry points. 19197c478bd9Sstevel@tonic-gate */ 19207c478bd9Sstevel@tonic-gate 19217c478bd9Sstevel@tonic-gate static int 19227c478bd9Sstevel@tonic-gate dprov_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 19237c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 19247c478bd9Sstevel@tonic-gate { 19257c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 19267c478bd9Sstevel@tonic-gate dprov_state_t *softc; 19277c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 19287c478bd9Sstevel@tonic-gate int instance; 19297c478bd9Sstevel@tonic-gate 19307c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 19317c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 19327c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_init: started\n", instance)); 19337c478bd9Sstevel@tonic-gate 19347c478bd9Sstevel@tonic-gate /* check mechanism */ 19355151fb12Sdarrenm if (mechanism->cm_type != MD4_MECH_INFO_TYPE && 19365151fb12Sdarrenm mechanism->cm_type != MD5_MECH_INFO_TYPE && 19377c478bd9Sstevel@tonic-gate mechanism->cm_type != SHA1_MECH_INFO_TYPE && 19387c478bd9Sstevel@tonic-gate mechanism->cm_type != SHA256_MECH_INFO_TYPE && 19397c478bd9Sstevel@tonic-gate mechanism->cm_type != SHA384_MECH_INFO_TYPE && 19407c478bd9Sstevel@tonic-gate mechanism->cm_type != SHA512_MECH_INFO_TYPE) { 19417c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_digest_init: unexpected mech type " 19427c478bd9Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type); 19437c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 19447c478bd9Sstevel@tonic-gate } 19457c478bd9Sstevel@tonic-gate 19467c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 19477c478bd9Sstevel@tonic-gate error = dprov_digest_submit_req(DPROV_REQ_DIGEST_INIT, softc, req, 19487c478bd9Sstevel@tonic-gate mechanism, NULL, NULL, NULL, ctx, KM_SLEEP); 19497c478bd9Sstevel@tonic-gate 19507c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_init: done err = 0x%x\n", 19517c478bd9Sstevel@tonic-gate instance, error)); 19527c478bd9Sstevel@tonic-gate 19537c478bd9Sstevel@tonic-gate return (error); 19547c478bd9Sstevel@tonic-gate } 19557c478bd9Sstevel@tonic-gate 19567c478bd9Sstevel@tonic-gate static int 19577c478bd9Sstevel@tonic-gate dprov_digest(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *digest, 19587c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 19597c478bd9Sstevel@tonic-gate { 19607c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 19617c478bd9Sstevel@tonic-gate dprov_state_t *softc; 19627c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 19637c478bd9Sstevel@tonic-gate int instance; 19647c478bd9Sstevel@tonic-gate 1965ba5f469cSkrishna if (dprov_no_multipart && data->cd_length > dprov_max_digestsz) 1966ba5f469cSkrishna return (CRYPTO_BUFFER_TOO_BIG); 1967ba5f469cSkrishna 19687c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 19697c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 19707c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest: started\n", instance)); 19717c478bd9Sstevel@tonic-gate 19727c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 19737c478bd9Sstevel@tonic-gate error = dprov_digest_submit_req(DPROV_REQ_DIGEST, softc, req, 19747c478bd9Sstevel@tonic-gate NULL, data, NULL, digest, ctx, KM_NOSLEEP); 19757c478bd9Sstevel@tonic-gate 19767c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest: done, err = 0x%x\n", 19777c478bd9Sstevel@tonic-gate instance, error)); 19787c478bd9Sstevel@tonic-gate 19797c478bd9Sstevel@tonic-gate return (error); 19807c478bd9Sstevel@tonic-gate } 19817c478bd9Sstevel@tonic-gate 19827c478bd9Sstevel@tonic-gate static int 19837c478bd9Sstevel@tonic-gate dprov_digest_update(crypto_ctx_t *ctx, crypto_data_t *data, 19847c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 19857c478bd9Sstevel@tonic-gate { 19867c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 19877c478bd9Sstevel@tonic-gate dprov_state_t *softc; 19887c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 19897c478bd9Sstevel@tonic-gate int instance; 19907c478bd9Sstevel@tonic-gate 19917c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 19927c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 19937c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_update: started\n", 19947c478bd9Sstevel@tonic-gate instance)); 19957c478bd9Sstevel@tonic-gate 19967c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 19977c478bd9Sstevel@tonic-gate error = dprov_digest_submit_req(DPROV_REQ_DIGEST_UPDATE, softc, 19987c478bd9Sstevel@tonic-gate req, NULL, data, NULL, NULL, ctx, KM_NOSLEEP); 19997c478bd9Sstevel@tonic-gate 20007c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_update: done err = 0x0%x\n", 20017c478bd9Sstevel@tonic-gate instance, error)); 20027c478bd9Sstevel@tonic-gate 20037c478bd9Sstevel@tonic-gate return (error); 20047c478bd9Sstevel@tonic-gate } 20057c478bd9Sstevel@tonic-gate 20067c478bd9Sstevel@tonic-gate static int 20077c478bd9Sstevel@tonic-gate dprov_digest_key(crypto_ctx_t *ctx, crypto_key_t *key, crypto_req_handle_t req) 20087c478bd9Sstevel@tonic-gate { 20097c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 20107c478bd9Sstevel@tonic-gate dprov_state_t *softc; 20117c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 20127c478bd9Sstevel@tonic-gate int instance; 20137c478bd9Sstevel@tonic-gate 20147c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 20157c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 20167c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_key: started\n", instance)); 20177c478bd9Sstevel@tonic-gate 20187c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 20197c478bd9Sstevel@tonic-gate error = dprov_digest_submit_req(DPROV_REQ_DIGEST_KEY, softc, req, NULL, 20207c478bd9Sstevel@tonic-gate NULL, key, NULL, ctx, KM_NOSLEEP); 20217c478bd9Sstevel@tonic-gate 20227c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_key: done err = 0x0%x\n", 20237c478bd9Sstevel@tonic-gate instance, error)); 20247c478bd9Sstevel@tonic-gate 20257c478bd9Sstevel@tonic-gate return (error); 20267c478bd9Sstevel@tonic-gate } 20277c478bd9Sstevel@tonic-gate 20287c478bd9Sstevel@tonic-gate static int 20297c478bd9Sstevel@tonic-gate dprov_digest_final(crypto_ctx_t *ctx, crypto_data_t *digest, 20307c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 20317c478bd9Sstevel@tonic-gate { 20327c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 20337c478bd9Sstevel@tonic-gate dprov_state_t *softc; 20347c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 20357c478bd9Sstevel@tonic-gate int instance; 20367c478bd9Sstevel@tonic-gate 20377c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 20387c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 20397c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_final: started\n", instance)); 20407c478bd9Sstevel@tonic-gate 20417c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 20427c478bd9Sstevel@tonic-gate error = dprov_digest_submit_req(DPROV_REQ_DIGEST_FINAL, softc, req, 20437c478bd9Sstevel@tonic-gate NULL, NULL, NULL, digest, ctx, KM_NOSLEEP); 20447c478bd9Sstevel@tonic-gate 20457c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_final: done err = 0x0%x\n", 20467c478bd9Sstevel@tonic-gate instance, error)); 20477c478bd9Sstevel@tonic-gate 20487c478bd9Sstevel@tonic-gate return (error); 20497c478bd9Sstevel@tonic-gate } 20507c478bd9Sstevel@tonic-gate 20517c478bd9Sstevel@tonic-gate /* ARGSUSED */ 20527c478bd9Sstevel@tonic-gate static int 20537c478bd9Sstevel@tonic-gate dprov_digest_atomic(crypto_provider_handle_t provider, 20547c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 20557c478bd9Sstevel@tonic-gate crypto_data_t *data, crypto_data_t *digest, 20567c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 20577c478bd9Sstevel@tonic-gate { 20587c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 20597c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 20607c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 20617c478bd9Sstevel@tonic-gate int instance; 20627c478bd9Sstevel@tonic-gate 2063ba5f469cSkrishna if (dprov_no_multipart && data->cd_length > dprov_max_digestsz) 2064ba5f469cSkrishna return (CRYPTO_BUFFER_TOO_BIG); 2065ba5f469cSkrishna 20667c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 20677c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_atomic: started\n", 20687c478bd9Sstevel@tonic-gate instance)); 20697c478bd9Sstevel@tonic-gate 20707c478bd9Sstevel@tonic-gate /* check mechanism */ 20715151fb12Sdarrenm if (mechanism->cm_type != MD4_MECH_INFO_TYPE && 20725151fb12Sdarrenm mechanism->cm_type != MD5_MECH_INFO_TYPE && 20737c478bd9Sstevel@tonic-gate mechanism->cm_type != SHA1_MECH_INFO_TYPE && 20747c478bd9Sstevel@tonic-gate mechanism->cm_type != SHA256_MECH_INFO_TYPE && 20757c478bd9Sstevel@tonic-gate mechanism->cm_type != SHA384_MECH_INFO_TYPE && 20767c478bd9Sstevel@tonic-gate mechanism->cm_type != SHA512_MECH_INFO_TYPE) { 20777c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_digest_atomic: unexpected mech type " 20787c478bd9Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type); 20797c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 20807c478bd9Sstevel@tonic-gate } 20817c478bd9Sstevel@tonic-gate 20827c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 20837c478bd9Sstevel@tonic-gate error = dprov_digest_submit_req(DPROV_REQ_DIGEST_ATOMIC, softc, req, 20847c478bd9Sstevel@tonic-gate mechanism, data, NULL, digest, NULL, KM_SLEEP); 20857c478bd9Sstevel@tonic-gate 20867c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_atomic: done err = 0x0%x\n", 20877c478bd9Sstevel@tonic-gate instance, error)); 20887c478bd9Sstevel@tonic-gate 20897c478bd9Sstevel@tonic-gate return (error); 20907c478bd9Sstevel@tonic-gate } 20917c478bd9Sstevel@tonic-gate 20927c478bd9Sstevel@tonic-gate /* 20937c478bd9Sstevel@tonic-gate * MAC entry points. 20947c478bd9Sstevel@tonic-gate */ 20957c478bd9Sstevel@tonic-gate 20967c478bd9Sstevel@tonic-gate /* 20977c478bd9Sstevel@tonic-gate * Checks whether the specified mech_type is supported by mac 20987c478bd9Sstevel@tonic-gate * entry points. 20997c478bd9Sstevel@tonic-gate */ 21007c478bd9Sstevel@tonic-gate static boolean_t 21017c478bd9Sstevel@tonic-gate dprov_valid_mac_mech(crypto_mech_type_t mech_type) 21027c478bd9Sstevel@tonic-gate { 21037c478bd9Sstevel@tonic-gate return (mech_type == MD5_HMAC_MECH_INFO_TYPE || 21047c478bd9Sstevel@tonic-gate mech_type == MD5_HMAC_GEN_MECH_INFO_TYPE || 21057c478bd9Sstevel@tonic-gate mech_type == SHA1_HMAC_MECH_INFO_TYPE || 21067c478bd9Sstevel@tonic-gate mech_type == SHA1_HMAC_GEN_MECH_INFO_TYPE || 21077c478bd9Sstevel@tonic-gate mech_type == SHA256_HMAC_MECH_INFO_TYPE || 21087c478bd9Sstevel@tonic-gate mech_type == SHA256_HMAC_GEN_MECH_INFO_TYPE || 21097c478bd9Sstevel@tonic-gate mech_type == SHA384_HMAC_MECH_INFO_TYPE || 21107c478bd9Sstevel@tonic-gate mech_type == SHA384_HMAC_GEN_MECH_INFO_TYPE || 21117c478bd9Sstevel@tonic-gate mech_type == SHA512_HMAC_MECH_INFO_TYPE || 2112983a1033SMark Powers mech_type == SHA512_HMAC_GEN_MECH_INFO_TYPE || 2113983a1033SMark Powers mech_type == AES_GMAC_MECH_INFO_TYPE); 21147c478bd9Sstevel@tonic-gate } 21157c478bd9Sstevel@tonic-gate 21167c478bd9Sstevel@tonic-gate static int 21177c478bd9Sstevel@tonic-gate dprov_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 21187c478bd9Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 21197c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 21207c478bd9Sstevel@tonic-gate { 21217c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 21227c478bd9Sstevel@tonic-gate dprov_state_t *softc; 21237c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 21247c478bd9Sstevel@tonic-gate int instance; 21257c478bd9Sstevel@tonic-gate 21267c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 21277c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 21287c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_init: started\n", instance)); 21297c478bd9Sstevel@tonic-gate 21307c478bd9Sstevel@tonic-gate /* check mechanism */ 21317c478bd9Sstevel@tonic-gate if (!dprov_valid_mac_mech(mechanism->cm_type)) { 21327c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_mac_init: unexpected mech type " 21337c478bd9Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type); 21347c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 21357c478bd9Sstevel@tonic-gate } 21367c478bd9Sstevel@tonic-gate 21377c478bd9Sstevel@tonic-gate if (ctx_template != NULL) 21387c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 21397c478bd9Sstevel@tonic-gate 21407c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 21417c478bd9Sstevel@tonic-gate error = dprov_mac_submit_req(DPROV_REQ_MAC_INIT, softc, req, 21427c478bd9Sstevel@tonic-gate mechanism, NULL, key, NULL, ctx, 0, KM_SLEEP); 21437c478bd9Sstevel@tonic-gate 21447c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_init: done err = 0x%x\n", 21457c478bd9Sstevel@tonic-gate instance, error)); 21467c478bd9Sstevel@tonic-gate 21477c478bd9Sstevel@tonic-gate return (error); 21487c478bd9Sstevel@tonic-gate } 21497c478bd9Sstevel@tonic-gate 21507c478bd9Sstevel@tonic-gate static int 21517c478bd9Sstevel@tonic-gate dprov_mac(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *mac, 21527c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 21537c478bd9Sstevel@tonic-gate { 21547c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 21557c478bd9Sstevel@tonic-gate dprov_state_t *softc; 21567c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 21577c478bd9Sstevel@tonic-gate int instance; 21587c478bd9Sstevel@tonic-gate 21597c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 21607c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 21617c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac: started\n", instance)); 21627c478bd9Sstevel@tonic-gate 21637c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 21647c478bd9Sstevel@tonic-gate error = dprov_mac_submit_req(DPROV_REQ_MAC, softc, req, 21657c478bd9Sstevel@tonic-gate NULL, data, NULL, mac, ctx, 0, KM_NOSLEEP); 21667c478bd9Sstevel@tonic-gate 21677c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac: done, err = 0x%x\n", instance, 21687c478bd9Sstevel@tonic-gate error)); 21697c478bd9Sstevel@tonic-gate 21707c478bd9Sstevel@tonic-gate return (error); 21717c478bd9Sstevel@tonic-gate } 21727c478bd9Sstevel@tonic-gate 21737c478bd9Sstevel@tonic-gate static int 21747c478bd9Sstevel@tonic-gate dprov_mac_update(crypto_ctx_t *ctx, crypto_data_t *data, 21757c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 21767c478bd9Sstevel@tonic-gate { 21777c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 21787c478bd9Sstevel@tonic-gate dprov_state_t *softc; 21797c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 21807c478bd9Sstevel@tonic-gate int instance; 21817c478bd9Sstevel@tonic-gate 21827c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 21837c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 21847c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_update: started\n", instance)); 21857c478bd9Sstevel@tonic-gate 21867c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 21877c478bd9Sstevel@tonic-gate error = dprov_mac_submit_req(DPROV_REQ_MAC_UPDATE, softc, 21887c478bd9Sstevel@tonic-gate req, NULL, data, NULL, NULL, ctx, 0, KM_NOSLEEP); 21897c478bd9Sstevel@tonic-gate 21907c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_update: done err = 0x0%x\n", 21917c478bd9Sstevel@tonic-gate instance, error)); 21927c478bd9Sstevel@tonic-gate 21937c478bd9Sstevel@tonic-gate return (error); 21947c478bd9Sstevel@tonic-gate } 21957c478bd9Sstevel@tonic-gate 21967c478bd9Sstevel@tonic-gate static int 21977c478bd9Sstevel@tonic-gate dprov_mac_final(crypto_ctx_t *ctx, crypto_data_t *mac, crypto_req_handle_t req) 21987c478bd9Sstevel@tonic-gate { 21997c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 22007c478bd9Sstevel@tonic-gate dprov_state_t *softc; 22017c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 22027c478bd9Sstevel@tonic-gate int instance; 22037c478bd9Sstevel@tonic-gate 22047c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 22057c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 22067c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_final: started\n", instance)); 22077c478bd9Sstevel@tonic-gate 22087c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 22097c478bd9Sstevel@tonic-gate error = dprov_mac_submit_req(DPROV_REQ_MAC_FINAL, softc, req, 22107c478bd9Sstevel@tonic-gate NULL, NULL, NULL, mac, ctx, 0, KM_NOSLEEP); 22117c478bd9Sstevel@tonic-gate 22127c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_final: done err = 0x0%x\n", 22137c478bd9Sstevel@tonic-gate instance, error)); 22147c478bd9Sstevel@tonic-gate 22157c478bd9Sstevel@tonic-gate return (error); 22167c478bd9Sstevel@tonic-gate } 22177c478bd9Sstevel@tonic-gate 22187c478bd9Sstevel@tonic-gate static int 22197c478bd9Sstevel@tonic-gate dprov_mac_atomic(crypto_provider_handle_t provider, 22207c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 22217c478bd9Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac, 22227c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 22237c478bd9Sstevel@tonic-gate { 22247c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 22257c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 22267c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 22277c478bd9Sstevel@tonic-gate int instance; 22287c478bd9Sstevel@tonic-gate 22297c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 22307c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_atomic: started\n", instance)); 22317c478bd9Sstevel@tonic-gate 22327c478bd9Sstevel@tonic-gate if (ctx_template != NULL) 22337c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 22347c478bd9Sstevel@tonic-gate 22357c478bd9Sstevel@tonic-gate /* check mechanism */ 22367c478bd9Sstevel@tonic-gate if (!dprov_valid_mac_mech(mechanism->cm_type)) { 22377c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_mac_atomic: unexpected mech type " 22387c478bd9Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type); 22397c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 22407c478bd9Sstevel@tonic-gate } 22417c478bd9Sstevel@tonic-gate 22427c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 22437c478bd9Sstevel@tonic-gate error = dprov_mac_submit_req(DPROV_REQ_MAC_ATOMIC, softc, req, 22447c478bd9Sstevel@tonic-gate mechanism, data, key, mac, NULL, session_id, KM_SLEEP); 22457c478bd9Sstevel@tonic-gate 22467c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_atomic: done err = 0x0%x\n", 22477c478bd9Sstevel@tonic-gate instance, error)); 22487c478bd9Sstevel@tonic-gate 22497c478bd9Sstevel@tonic-gate return (error); 22507c478bd9Sstevel@tonic-gate } 22517c478bd9Sstevel@tonic-gate 22527c478bd9Sstevel@tonic-gate static int 22537c478bd9Sstevel@tonic-gate dprov_mac_verify_atomic(crypto_provider_handle_t provider, 22547c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 22557c478bd9Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac, 22567c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 22577c478bd9Sstevel@tonic-gate { 22587c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 22597c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 22607c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 22617c478bd9Sstevel@tonic-gate int instance; 22627c478bd9Sstevel@tonic-gate 22637c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 22647c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_verify_atomic: started\n", 22657c478bd9Sstevel@tonic-gate instance)); 22667c478bd9Sstevel@tonic-gate 22677c478bd9Sstevel@tonic-gate if (ctx_template != NULL) 22687c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 22697c478bd9Sstevel@tonic-gate 22707c478bd9Sstevel@tonic-gate /* check mechanism */ 22717c478bd9Sstevel@tonic-gate if (!dprov_valid_mac_mech(mechanism->cm_type)) { 22727c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_mac_verify_atomic: unexpected mech " 22737c478bd9Sstevel@tonic-gate "type 0x%llx\n", (unsigned long long)mechanism->cm_type); 22747c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 22757c478bd9Sstevel@tonic-gate } 22767c478bd9Sstevel@tonic-gate 22777c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 22787c478bd9Sstevel@tonic-gate error = dprov_mac_submit_req(DPROV_REQ_MAC_VERIFY_ATOMIC, softc, req, 22797c478bd9Sstevel@tonic-gate mechanism, data, key, mac, NULL, session_id, KM_SLEEP); 22807c478bd9Sstevel@tonic-gate 22817c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_verify_atomic: done err = 0x0%x\n", 22827c478bd9Sstevel@tonic-gate instance, error)); 22837c478bd9Sstevel@tonic-gate 22847c478bd9Sstevel@tonic-gate return (error); 22857c478bd9Sstevel@tonic-gate } 22867c478bd9Sstevel@tonic-gate 22877c478bd9Sstevel@tonic-gate /* 22887c478bd9Sstevel@tonic-gate * Cipher (encrypt/decrypt) entry points. 22897c478bd9Sstevel@tonic-gate */ 22907c478bd9Sstevel@tonic-gate 22917c478bd9Sstevel@tonic-gate /* 22927c478bd9Sstevel@tonic-gate * Checks whether the specified mech_type is supported by cipher entry 22937c478bd9Sstevel@tonic-gate * points. 22947c478bd9Sstevel@tonic-gate */ 22957c478bd9Sstevel@tonic-gate static boolean_t 22967c478bd9Sstevel@tonic-gate dprov_valid_cipher_mech(crypto_mech_type_t mech_type) 22977c478bd9Sstevel@tonic-gate { 22987c478bd9Sstevel@tonic-gate return (mech_type == DES_CBC_MECH_INFO_TYPE || 22997c478bd9Sstevel@tonic-gate mech_type == DES3_CBC_MECH_INFO_TYPE || 23007c478bd9Sstevel@tonic-gate mech_type == DES_ECB_MECH_INFO_TYPE || 23017c478bd9Sstevel@tonic-gate mech_type == DES3_ECB_MECH_INFO_TYPE || 2302f66d273dSizick mech_type == BLOWFISH_CBC_MECH_INFO_TYPE || 2303f66d273dSizick mech_type == BLOWFISH_ECB_MECH_INFO_TYPE || 23047c478bd9Sstevel@tonic-gate mech_type == AES_CBC_MECH_INFO_TYPE || 23057c478bd9Sstevel@tonic-gate mech_type == AES_ECB_MECH_INFO_TYPE || 2306894b2776Smcpowers mech_type == AES_CTR_MECH_INFO_TYPE || 23072d864512Sdinak mech_type == AES_CCM_MECH_INFO_TYPE || 23084d703b5cSMark Powers mech_type == AES_GCM_MECH_INFO_TYPE || 2309983a1033SMark Powers mech_type == AES_GMAC_MECH_INFO_TYPE || 23107c478bd9Sstevel@tonic-gate mech_type == RC4_MECH_INFO_TYPE || 23117c478bd9Sstevel@tonic-gate mech_type == RSA_PKCS_MECH_INFO_TYPE || 23127c478bd9Sstevel@tonic-gate mech_type == RSA_X_509_MECH_INFO_TYPE || 23137c478bd9Sstevel@tonic-gate mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE || 2314f66d273dSizick mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE || 2315f66d273dSizick mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE || 2316f66d273dSizick mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE || 2317f66d273dSizick mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE); 23187c478bd9Sstevel@tonic-gate } 23197c478bd9Sstevel@tonic-gate 23207c478bd9Sstevel@tonic-gate static boolean_t 23217c478bd9Sstevel@tonic-gate is_publickey_mech(crypto_mech_type_t mech_type) 23227c478bd9Sstevel@tonic-gate { 23237c478bd9Sstevel@tonic-gate return (mech_type == RSA_PKCS_MECH_INFO_TYPE || 23247c478bd9Sstevel@tonic-gate mech_type == RSA_X_509_MECH_INFO_TYPE || 23257c478bd9Sstevel@tonic-gate mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE || 2326f66d273dSizick mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE || 2327f66d273dSizick mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE || 2328f66d273dSizick mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE || 2329f9fbec18Smcpowers mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE || 2330f9fbec18Smcpowers mech_type == ECDSA_SHA1_MECH_INFO_TYPE || 2331f9fbec18Smcpowers mech_type == ECDSA_MECH_INFO_TYPE); 23327c478bd9Sstevel@tonic-gate } 23337c478bd9Sstevel@tonic-gate 23347c478bd9Sstevel@tonic-gate 23357c478bd9Sstevel@tonic-gate /* ARGSUSED */ 23367c478bd9Sstevel@tonic-gate static int 23377c478bd9Sstevel@tonic-gate dprov_encrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 23387c478bd9Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 23397c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 23407c478bd9Sstevel@tonic-gate { 23417c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 23427c478bd9Sstevel@tonic-gate dprov_state_t *softc; 23437c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 23447c478bd9Sstevel@tonic-gate int instance; 23457c478bd9Sstevel@tonic-gate 23467c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 23477c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 23487c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_init: started\n", 23497c478bd9Sstevel@tonic-gate instance)); 23507c478bd9Sstevel@tonic-gate 23517c478bd9Sstevel@tonic-gate /* check mechanism */ 23527c478bd9Sstevel@tonic-gate if (!dprov_valid_cipher_mech(mechanism->cm_type)) { 23537c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_encrypt_init: unexpected mech type " 23547c478bd9Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type); 23557c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 23567c478bd9Sstevel@tonic-gate } 23577c478bd9Sstevel@tonic-gate 23587c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 23597c478bd9Sstevel@tonic-gate error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_INIT, softc, 23607c478bd9Sstevel@tonic-gate req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP); 23617c478bd9Sstevel@tonic-gate 23627c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_init: done err = 0x0%x\n", 23637c478bd9Sstevel@tonic-gate instance, error)); 23647c478bd9Sstevel@tonic-gate 23657c478bd9Sstevel@tonic-gate return (error); 23667c478bd9Sstevel@tonic-gate } 23677c478bd9Sstevel@tonic-gate 23687c478bd9Sstevel@tonic-gate /* ARGSUSED */ 23697c478bd9Sstevel@tonic-gate static int 23707c478bd9Sstevel@tonic-gate dprov_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext, 23717c478bd9Sstevel@tonic-gate crypto_data_t *ciphertext, crypto_req_handle_t req) 23727c478bd9Sstevel@tonic-gate { 23737c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 23747c478bd9Sstevel@tonic-gate dprov_state_t *softc; 23757c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 23767c478bd9Sstevel@tonic-gate int instance; 23777c478bd9Sstevel@tonic-gate 23787c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 23797c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 23807c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt: started\n", instance)); 23817c478bd9Sstevel@tonic-gate 23827c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 23837c478bd9Sstevel@tonic-gate error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT, softc, 23847c478bd9Sstevel@tonic-gate req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP); 23857c478bd9Sstevel@tonic-gate 23867c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt: done err = 0x0%x\n", 23877c478bd9Sstevel@tonic-gate instance, error)); 23887c478bd9Sstevel@tonic-gate 23897c478bd9Sstevel@tonic-gate return (error); 23907c478bd9Sstevel@tonic-gate } 23917c478bd9Sstevel@tonic-gate 23927c478bd9Sstevel@tonic-gate /* ARGSUSED */ 23937c478bd9Sstevel@tonic-gate static int 23947c478bd9Sstevel@tonic-gate dprov_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext, 23957c478bd9Sstevel@tonic-gate crypto_data_t *ciphertext, crypto_req_handle_t req) 23967c478bd9Sstevel@tonic-gate { 23977c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 23987c478bd9Sstevel@tonic-gate dprov_state_t *softc; 23997c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 24007c478bd9Sstevel@tonic-gate int instance; 24017c478bd9Sstevel@tonic-gate 24027c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 24037c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 24047c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_update: started\n", 24057c478bd9Sstevel@tonic-gate instance)); 24067c478bd9Sstevel@tonic-gate 24077c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 24087c478bd9Sstevel@tonic-gate error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_UPDATE, softc, 24097c478bd9Sstevel@tonic-gate req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP); 24107c478bd9Sstevel@tonic-gate 24117c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_update: done err = 0x0%x\n", 24127c478bd9Sstevel@tonic-gate instance, error)); 24137c478bd9Sstevel@tonic-gate 24147c478bd9Sstevel@tonic-gate return (error); 24157c478bd9Sstevel@tonic-gate } 24167c478bd9Sstevel@tonic-gate 24177c478bd9Sstevel@tonic-gate /* ARGSUSED */ 24187c478bd9Sstevel@tonic-gate static int 24197c478bd9Sstevel@tonic-gate dprov_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *ciphertext, 24207c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 24217c478bd9Sstevel@tonic-gate { 24227c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 24237c478bd9Sstevel@tonic-gate dprov_state_t *softc; 24247c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 24257c478bd9Sstevel@tonic-gate int instance; 24267c478bd9Sstevel@tonic-gate 24277c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 24287c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 24297c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_final: started\n", 24307c478bd9Sstevel@tonic-gate instance)); 24317c478bd9Sstevel@tonic-gate 24327c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 24337c478bd9Sstevel@tonic-gate error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_FINAL, softc, 24347c478bd9Sstevel@tonic-gate req, NULL, NULL, NULL, ciphertext, ctx, 0, KM_NOSLEEP); 24357c478bd9Sstevel@tonic-gate 24367c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_final: done err = 0x0%x\n", 24377c478bd9Sstevel@tonic-gate instance, error)); 24387c478bd9Sstevel@tonic-gate 24397c478bd9Sstevel@tonic-gate return (error); 24407c478bd9Sstevel@tonic-gate } 24417c478bd9Sstevel@tonic-gate 24427c478bd9Sstevel@tonic-gate static int 24437c478bd9Sstevel@tonic-gate dprov_encrypt_atomic(crypto_provider_handle_t provider, 24447c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 24457c478bd9Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext, 24467c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 24477c478bd9Sstevel@tonic-gate { 24487c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 24497c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 24507c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 24517c478bd9Sstevel@tonic-gate int instance; 24527c478bd9Sstevel@tonic-gate 24537c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 24547c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_encrypt_atomic: started\n", instance)); 24557c478bd9Sstevel@tonic-gate 24567c478bd9Sstevel@tonic-gate if (ctx_template != NULL) 24577c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 24587c478bd9Sstevel@tonic-gate 24597c478bd9Sstevel@tonic-gate /* check mechanism */ 24607c478bd9Sstevel@tonic-gate if (!dprov_valid_cipher_mech(mechanism->cm_type)) { 24617c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_encrypt_atomic: unexpected mech type " 24627c478bd9Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type); 24637c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 24647c478bd9Sstevel@tonic-gate } 24657c478bd9Sstevel@tonic-gate 24667c478bd9Sstevel@tonic-gate error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_ATOMIC, softc, 24677c478bd9Sstevel@tonic-gate req, mechanism, key, plaintext, ciphertext, NULL, session_id, 24687c478bd9Sstevel@tonic-gate KM_SLEEP); 24697c478bd9Sstevel@tonic-gate 24707c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_encrypt_atomic: done err = 0x0%x\n", 24717c478bd9Sstevel@tonic-gate instance, error)); 24727c478bd9Sstevel@tonic-gate 24737c478bd9Sstevel@tonic-gate return (error); 24747c478bd9Sstevel@tonic-gate } 24757c478bd9Sstevel@tonic-gate 24767c478bd9Sstevel@tonic-gate /* ARGSUSED */ 24777c478bd9Sstevel@tonic-gate static int 24787c478bd9Sstevel@tonic-gate dprov_decrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 24797c478bd9Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 24807c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 24817c478bd9Sstevel@tonic-gate { 24827c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 24837c478bd9Sstevel@tonic-gate dprov_state_t *softc; 24847c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 24857c478bd9Sstevel@tonic-gate int instance; 24867c478bd9Sstevel@tonic-gate 24877c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 24887c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 24897c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_init: started\n", 24907c478bd9Sstevel@tonic-gate instance)); 24917c478bd9Sstevel@tonic-gate 24927c478bd9Sstevel@tonic-gate /* check mechanism */ 24937c478bd9Sstevel@tonic-gate if (!dprov_valid_cipher_mech(mechanism->cm_type)) { 24947c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_decrypt_init: unexpected mech type " 24957c478bd9Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type); 24967c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 24977c478bd9Sstevel@tonic-gate } 24987c478bd9Sstevel@tonic-gate 24997c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 25007c478bd9Sstevel@tonic-gate error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_INIT, softc, 25017c478bd9Sstevel@tonic-gate req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP); 25027c478bd9Sstevel@tonic-gate 25037c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_init: done err = 0x0%x\n", 25047c478bd9Sstevel@tonic-gate instance, error)); 25057c478bd9Sstevel@tonic-gate 25067c478bd9Sstevel@tonic-gate return (error); 25077c478bd9Sstevel@tonic-gate } 25087c478bd9Sstevel@tonic-gate 25097c478bd9Sstevel@tonic-gate /* ARGSUSED */ 25107c478bd9Sstevel@tonic-gate static int 25117c478bd9Sstevel@tonic-gate dprov_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext, 25127c478bd9Sstevel@tonic-gate crypto_data_t *plaintext, crypto_req_handle_t req) 25137c478bd9Sstevel@tonic-gate { 25147c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 25157c478bd9Sstevel@tonic-gate 25167c478bd9Sstevel@tonic-gate dprov_state_t *softc; 25177c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 25187c478bd9Sstevel@tonic-gate int instance; 25197c478bd9Sstevel@tonic-gate 25207c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 25217c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 25227c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt: started\n", instance)); 25237c478bd9Sstevel@tonic-gate 25247c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 25257c478bd9Sstevel@tonic-gate error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT, softc, 25267c478bd9Sstevel@tonic-gate req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP); 25277c478bd9Sstevel@tonic-gate 25287c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt: done err = 0x0%x\n", 25297c478bd9Sstevel@tonic-gate instance, error)); 25307c478bd9Sstevel@tonic-gate 25317c478bd9Sstevel@tonic-gate return (error); 25327c478bd9Sstevel@tonic-gate } 25337c478bd9Sstevel@tonic-gate 25347c478bd9Sstevel@tonic-gate /* ARGSUSED */ 25357c478bd9Sstevel@tonic-gate static int 25367c478bd9Sstevel@tonic-gate dprov_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext, 25377c478bd9Sstevel@tonic-gate crypto_data_t *plaintext, crypto_req_handle_t req) 25387c478bd9Sstevel@tonic-gate { 25397c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 25407c478bd9Sstevel@tonic-gate dprov_state_t *softc; 25417c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 25427c478bd9Sstevel@tonic-gate int instance; 25437c478bd9Sstevel@tonic-gate 25447c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 25457c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 25467c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_update: started\n", 25477c478bd9Sstevel@tonic-gate instance)); 25487c478bd9Sstevel@tonic-gate 25497c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 25507c478bd9Sstevel@tonic-gate error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_UPDATE, softc, 25517c478bd9Sstevel@tonic-gate req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP); 25527c478bd9Sstevel@tonic-gate 25537c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_update: done err = 0x0%x\n", 25547c478bd9Sstevel@tonic-gate instance, error)); 25557c478bd9Sstevel@tonic-gate 25567c478bd9Sstevel@tonic-gate return (error); 25577c478bd9Sstevel@tonic-gate } 25587c478bd9Sstevel@tonic-gate 25597c478bd9Sstevel@tonic-gate /* ARGSUSED */ 25607c478bd9Sstevel@tonic-gate static int 25617c478bd9Sstevel@tonic-gate dprov_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *plaintext, 25627c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 25637c478bd9Sstevel@tonic-gate { 25647c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 25657c478bd9Sstevel@tonic-gate dprov_state_t *softc; 25667c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 25677c478bd9Sstevel@tonic-gate int instance; 25687c478bd9Sstevel@tonic-gate 25697c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 25707c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 25717c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_final: started\n", 25727c478bd9Sstevel@tonic-gate instance)); 25737c478bd9Sstevel@tonic-gate 25747c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 25757c478bd9Sstevel@tonic-gate error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_FINAL, softc, 25767c478bd9Sstevel@tonic-gate req, NULL, NULL, plaintext, NULL, ctx, 0, KM_NOSLEEP); 25777c478bd9Sstevel@tonic-gate 25787c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_final: done err = 0x0%x\n", 25797c478bd9Sstevel@tonic-gate instance, error)); 25807c478bd9Sstevel@tonic-gate 25817c478bd9Sstevel@tonic-gate return (error); 25827c478bd9Sstevel@tonic-gate } 25837c478bd9Sstevel@tonic-gate 25847c478bd9Sstevel@tonic-gate static int 25857c478bd9Sstevel@tonic-gate dprov_decrypt_atomic(crypto_provider_handle_t provider, 25867c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 25877c478bd9Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext, 25887c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 25897c478bd9Sstevel@tonic-gate { 25907c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 25917c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 25927c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 25937c478bd9Sstevel@tonic-gate int instance; 25947c478bd9Sstevel@tonic-gate 25957c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 25967c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_decrypt_atomic: started\n", instance)); 25977c478bd9Sstevel@tonic-gate 25987c478bd9Sstevel@tonic-gate if (ctx_template != NULL) 25997c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 26007c478bd9Sstevel@tonic-gate 26017c478bd9Sstevel@tonic-gate /* check mechanism */ 26027c478bd9Sstevel@tonic-gate if (!dprov_valid_cipher_mech(mechanism->cm_type)) { 26037c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_atomic_init: unexpected mech type " 26047c478bd9Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type); 26057c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 26067c478bd9Sstevel@tonic-gate } 26077c478bd9Sstevel@tonic-gate 26087c478bd9Sstevel@tonic-gate error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_ATOMIC, softc, 26097c478bd9Sstevel@tonic-gate req, mechanism, key, plaintext, ciphertext, NULL, session_id, 26107c478bd9Sstevel@tonic-gate KM_SLEEP); 26117c478bd9Sstevel@tonic-gate 26127c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_decrypt_atomic: done err = 0x0%x\n", 26137c478bd9Sstevel@tonic-gate instance, error)); 26147c478bd9Sstevel@tonic-gate 26157c478bd9Sstevel@tonic-gate return (error); 26167c478bd9Sstevel@tonic-gate } 26177c478bd9Sstevel@tonic-gate 26187c478bd9Sstevel@tonic-gate /* 26197c478bd9Sstevel@tonic-gate * Sign entry points. 26207c478bd9Sstevel@tonic-gate */ 26217c478bd9Sstevel@tonic-gate 26227c478bd9Sstevel@tonic-gate /* 26237c478bd9Sstevel@tonic-gate * Checks whether the specified mech_type is supported by sign/verify 26247c478bd9Sstevel@tonic-gate * entry points. 26257c478bd9Sstevel@tonic-gate */ 26267c478bd9Sstevel@tonic-gate static boolean_t 26277c478bd9Sstevel@tonic-gate dprov_valid_sign_verif_mech(crypto_mech_type_t mech_type) 26287c478bd9Sstevel@tonic-gate { 26297c478bd9Sstevel@tonic-gate return (mech_type == MD5_HMAC_MECH_INFO_TYPE || 26307c478bd9Sstevel@tonic-gate mech_type == MD5_HMAC_GEN_MECH_INFO_TYPE || 2631ba5f469cSkrishna mech_type == SHA1_HMAC_MECH_INFO_TYPE || 2632ba5f469cSkrishna mech_type == SHA1_HMAC_GEN_MECH_INFO_TYPE || 2633ba5f469cSkrishna mech_type == SHA256_HMAC_MECH_INFO_TYPE || 2634ba5f469cSkrishna mech_type == SHA256_HMAC_GEN_MECH_INFO_TYPE || 2635ba5f469cSkrishna mech_type == SHA384_HMAC_MECH_INFO_TYPE || 2636ba5f469cSkrishna mech_type == SHA384_HMAC_GEN_MECH_INFO_TYPE || 2637ba5f469cSkrishna mech_type == SHA512_HMAC_MECH_INFO_TYPE || 2638ba5f469cSkrishna mech_type == SHA512_HMAC_GEN_MECH_INFO_TYPE || 26397c478bd9Sstevel@tonic-gate mech_type == RSA_PKCS_MECH_INFO_TYPE || 26407c478bd9Sstevel@tonic-gate mech_type == RSA_X_509_MECH_INFO_TYPE || 26417c478bd9Sstevel@tonic-gate mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE || 2642f66d273dSizick mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE || 2643f66d273dSizick mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE || 2644f66d273dSizick mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE || 2645f9fbec18Smcpowers mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE || 2646f9fbec18Smcpowers mech_type == ECDSA_SHA1_MECH_INFO_TYPE || 2647f9fbec18Smcpowers mech_type == ECDSA_MECH_INFO_TYPE); 26487c478bd9Sstevel@tonic-gate } 26497c478bd9Sstevel@tonic-gate 26507c478bd9Sstevel@tonic-gate static int 26517c478bd9Sstevel@tonic-gate dprov_sign_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 26527c478bd9Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 26537c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 26547c478bd9Sstevel@tonic-gate { 26557c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 26567c478bd9Sstevel@tonic-gate dprov_state_t *softc; 26577c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 26587c478bd9Sstevel@tonic-gate int instance; 26597c478bd9Sstevel@tonic-gate 26607c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 26617c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 26627c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_init: started\n", instance)); 26637c478bd9Sstevel@tonic-gate 26647c478bd9Sstevel@tonic-gate /* check mechanism */ 26657c478bd9Sstevel@tonic-gate if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) { 26667c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_sign_init: unexpected mech type " 26677c478bd9Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type); 26687c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 26697c478bd9Sstevel@tonic-gate } 26707c478bd9Sstevel@tonic-gate 26717c478bd9Sstevel@tonic-gate if (ctx_template != NULL) 26727c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 26737c478bd9Sstevel@tonic-gate 26747c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 26757c478bd9Sstevel@tonic-gate error = dprov_sign_submit_req(DPROV_REQ_SIGN_INIT, softc, req, 26767c478bd9Sstevel@tonic-gate mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP); 26777c478bd9Sstevel@tonic-gate 26787c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_init: done err = 0x%x\n", 26797c478bd9Sstevel@tonic-gate instance, error)); 26807c478bd9Sstevel@tonic-gate 26817c478bd9Sstevel@tonic-gate return (error); 26827c478bd9Sstevel@tonic-gate } 26837c478bd9Sstevel@tonic-gate 26847c478bd9Sstevel@tonic-gate static int 26857c478bd9Sstevel@tonic-gate dprov_sign(crypto_ctx_t *ctx, crypto_data_t *data, 26867c478bd9Sstevel@tonic-gate crypto_data_t *signature, crypto_req_handle_t req) 26877c478bd9Sstevel@tonic-gate { 26887c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 26897c478bd9Sstevel@tonic-gate dprov_state_t *softc; 26907c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 26917c478bd9Sstevel@tonic-gate int instance; 26927c478bd9Sstevel@tonic-gate 26937c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 26947c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 26957c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign: started\n", instance)); 26967c478bd9Sstevel@tonic-gate 26977c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 26987c478bd9Sstevel@tonic-gate error = dprov_sign_submit_req(DPROV_REQ_SIGN, softc, req, 26997c478bd9Sstevel@tonic-gate NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP); 27007c478bd9Sstevel@tonic-gate 27017c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign: done err = 0x%x\n", 27027c478bd9Sstevel@tonic-gate instance, error)); 27037c478bd9Sstevel@tonic-gate 27047c478bd9Sstevel@tonic-gate return (error); 27057c478bd9Sstevel@tonic-gate } 27067c478bd9Sstevel@tonic-gate 27077c478bd9Sstevel@tonic-gate static int 27087c478bd9Sstevel@tonic-gate dprov_sign_update(crypto_ctx_t *ctx, crypto_data_t *data, 27097c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 27107c478bd9Sstevel@tonic-gate { 27117c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 27127c478bd9Sstevel@tonic-gate dprov_state_t *softc; 27137c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 27147c478bd9Sstevel@tonic-gate int instance; 27157c478bd9Sstevel@tonic-gate 27167c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 27177c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 27187c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_update: started\n", instance)); 27197c478bd9Sstevel@tonic-gate 27207c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 27217c478bd9Sstevel@tonic-gate error = dprov_sign_submit_req(DPROV_REQ_SIGN_UPDATE, softc, req, 27227c478bd9Sstevel@tonic-gate NULL, NULL, data, NULL, ctx, 0, KM_NOSLEEP); 27237c478bd9Sstevel@tonic-gate 27247c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_update: done err = 0x%x\n", 27257c478bd9Sstevel@tonic-gate instance, error)); 27267c478bd9Sstevel@tonic-gate 27277c478bd9Sstevel@tonic-gate return (error); 27287c478bd9Sstevel@tonic-gate } 27297c478bd9Sstevel@tonic-gate 27307c478bd9Sstevel@tonic-gate static int 27317c478bd9Sstevel@tonic-gate dprov_sign_final(crypto_ctx_t *ctx, crypto_data_t *signature, 27327c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 27337c478bd9Sstevel@tonic-gate { 27347c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 27357c478bd9Sstevel@tonic-gate dprov_state_t *softc; 27367c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 27377c478bd9Sstevel@tonic-gate int instance; 27387c478bd9Sstevel@tonic-gate 27397c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 27407c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 27417c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_final: started\n", instance)); 27427c478bd9Sstevel@tonic-gate 27437c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 27447c478bd9Sstevel@tonic-gate error = dprov_sign_submit_req(DPROV_REQ_SIGN_FINAL, softc, req, 27457c478bd9Sstevel@tonic-gate NULL, NULL, NULL, signature, ctx, 0, KM_NOSLEEP); 27467c478bd9Sstevel@tonic-gate 27477c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_final: done err = 0x%x\n", 27487c478bd9Sstevel@tonic-gate instance, error)); 27497c478bd9Sstevel@tonic-gate 27507c478bd9Sstevel@tonic-gate return (error); 27517c478bd9Sstevel@tonic-gate } 27527c478bd9Sstevel@tonic-gate 27537c478bd9Sstevel@tonic-gate static int 27547c478bd9Sstevel@tonic-gate dprov_sign_atomic(crypto_provider_handle_t provider, 27557c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 27567c478bd9Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature, 27577c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 27587c478bd9Sstevel@tonic-gate { 27597c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 27607c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 27617c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 27627c478bd9Sstevel@tonic-gate int instance; 27637c478bd9Sstevel@tonic-gate 27647c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 27657c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_atomic: started\n", instance)); 27667c478bd9Sstevel@tonic-gate 27677c478bd9Sstevel@tonic-gate /* check mechanism */ 27687c478bd9Sstevel@tonic-gate if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) { 27697c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_sign_atomic: unexpected mech type " 27707c478bd9Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type); 27717c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 27727c478bd9Sstevel@tonic-gate } 27737c478bd9Sstevel@tonic-gate 27747c478bd9Sstevel@tonic-gate if (ctx_template != NULL) 27757c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 27767c478bd9Sstevel@tonic-gate 27777c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 27787c478bd9Sstevel@tonic-gate error = dprov_sign_submit_req(DPROV_REQ_SIGN_ATOMIC, softc, req, 27797c478bd9Sstevel@tonic-gate mechanism, key, data, signature, NULL, session_id, KM_SLEEP); 27807c478bd9Sstevel@tonic-gate 27817c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_atomic: done err = 0x%x\n", 27827c478bd9Sstevel@tonic-gate instance, error)); 27837c478bd9Sstevel@tonic-gate 27847c478bd9Sstevel@tonic-gate return (error); 27857c478bd9Sstevel@tonic-gate } 27867c478bd9Sstevel@tonic-gate 27877c478bd9Sstevel@tonic-gate static int 27887c478bd9Sstevel@tonic-gate dprov_sign_recover_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 27897c478bd9Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 27907c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 27917c478bd9Sstevel@tonic-gate { 27927c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 27937c478bd9Sstevel@tonic-gate dprov_state_t *softc; 27947c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 27957c478bd9Sstevel@tonic-gate int instance; 27967c478bd9Sstevel@tonic-gate 27977c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 27987c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 27997c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_init: started\n", 28007c478bd9Sstevel@tonic-gate instance)); 28017c478bd9Sstevel@tonic-gate 28027c478bd9Sstevel@tonic-gate if (ctx_template != NULL) 28037c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 28047c478bd9Sstevel@tonic-gate 28057c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 28067c478bd9Sstevel@tonic-gate error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER_INIT, softc, req, 28077c478bd9Sstevel@tonic-gate mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP); 28087c478bd9Sstevel@tonic-gate 28097c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_init: done err = 0x%x\n", 28107c478bd9Sstevel@tonic-gate instance, error)); 28117c478bd9Sstevel@tonic-gate 28127c478bd9Sstevel@tonic-gate return (error); 28137c478bd9Sstevel@tonic-gate } 28147c478bd9Sstevel@tonic-gate 28157c478bd9Sstevel@tonic-gate static int 28167c478bd9Sstevel@tonic-gate dprov_sign_recover(crypto_ctx_t *ctx, crypto_data_t *data, 28177c478bd9Sstevel@tonic-gate crypto_data_t *signature, crypto_req_handle_t req) 28187c478bd9Sstevel@tonic-gate { 28197c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 28207c478bd9Sstevel@tonic-gate dprov_state_t *softc; 28217c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 28227c478bd9Sstevel@tonic-gate int instance; 28237c478bd9Sstevel@tonic-gate 28247c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 28257c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 28267c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover: started\n", instance)); 28277c478bd9Sstevel@tonic-gate 28287c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 28297c478bd9Sstevel@tonic-gate error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER, softc, req, 28307c478bd9Sstevel@tonic-gate NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP); 28317c478bd9Sstevel@tonic-gate 28327c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover: done err = 0x%x\n", 28337c478bd9Sstevel@tonic-gate instance, error)); 28347c478bd9Sstevel@tonic-gate 28357c478bd9Sstevel@tonic-gate return (error); 28367c478bd9Sstevel@tonic-gate } 28377c478bd9Sstevel@tonic-gate 28387c478bd9Sstevel@tonic-gate static int 28397c478bd9Sstevel@tonic-gate dprov_sign_recover_atomic(crypto_provider_handle_t provider, 28407c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 28417c478bd9Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature, 28427c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 28437c478bd9Sstevel@tonic-gate { 28447c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 28457c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 28467c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 28477c478bd9Sstevel@tonic-gate int instance; 28487c478bd9Sstevel@tonic-gate 28497c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 28507c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_atomic: started\n", 28517c478bd9Sstevel@tonic-gate instance)); 28527c478bd9Sstevel@tonic-gate 28537c478bd9Sstevel@tonic-gate if (ctx_template != NULL) 28547c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 28557c478bd9Sstevel@tonic-gate 28567c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 28577c478bd9Sstevel@tonic-gate error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER_ATOMIC, softc, req, 28587c478bd9Sstevel@tonic-gate mechanism, key, data, signature, NULL, session_id, KM_SLEEP); 28597c478bd9Sstevel@tonic-gate 28607c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_atomic: done " 28617c478bd9Sstevel@tonic-gate "err = 0x%x\n", instance, error)); 28627c478bd9Sstevel@tonic-gate 28637c478bd9Sstevel@tonic-gate return (error); 28647c478bd9Sstevel@tonic-gate } 28657c478bd9Sstevel@tonic-gate 28667c478bd9Sstevel@tonic-gate /* 28677c478bd9Sstevel@tonic-gate * Verify entry points. 28687c478bd9Sstevel@tonic-gate */ 28697c478bd9Sstevel@tonic-gate 28707c478bd9Sstevel@tonic-gate static int 28717c478bd9Sstevel@tonic-gate dprov_verify_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 28727c478bd9Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 28737c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 28747c478bd9Sstevel@tonic-gate { 28757c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 28767c478bd9Sstevel@tonic-gate dprov_state_t *softc; 28777c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 28787c478bd9Sstevel@tonic-gate int instance; 28797c478bd9Sstevel@tonic-gate 28807c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 28817c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 28827c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_init: started\n", instance)); 28837c478bd9Sstevel@tonic-gate 28847c478bd9Sstevel@tonic-gate /* check mechanism */ 28857c478bd9Sstevel@tonic-gate if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) { 28867c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_verify_init: unexpected mech type " 28877c478bd9Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type); 28887c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 28897c478bd9Sstevel@tonic-gate } 28907c478bd9Sstevel@tonic-gate 28917c478bd9Sstevel@tonic-gate if (ctx_template != NULL) 28927c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 28937c478bd9Sstevel@tonic-gate 28947c478bd9Sstevel@tonic-gate error = dprov_verify_submit_req(DPROV_REQ_VERIFY_INIT, softc, req, 28957c478bd9Sstevel@tonic-gate mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP); 28967c478bd9Sstevel@tonic-gate 28977c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_init: done err = 0x%x\n", 28987c478bd9Sstevel@tonic-gate instance, error)); 28997c478bd9Sstevel@tonic-gate 29007c478bd9Sstevel@tonic-gate return (error); 29017c478bd9Sstevel@tonic-gate } 29027c478bd9Sstevel@tonic-gate 29037c478bd9Sstevel@tonic-gate static int 29047c478bd9Sstevel@tonic-gate dprov_verify(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 29057c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 29067c478bd9Sstevel@tonic-gate { 29077c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 29087c478bd9Sstevel@tonic-gate dprov_state_t *softc; 29097c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 29107c478bd9Sstevel@tonic-gate int instance; 29117c478bd9Sstevel@tonic-gate 29127c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 29137c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 29147c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify: started\n", instance)); 29157c478bd9Sstevel@tonic-gate 29167c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 29177c478bd9Sstevel@tonic-gate error = dprov_verify_submit_req(DPROV_REQ_VERIFY, softc, req, 29187c478bd9Sstevel@tonic-gate NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP); 29197c478bd9Sstevel@tonic-gate 29207c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify: done err = 0x%x\n", 29217c478bd9Sstevel@tonic-gate instance, error)); 29227c478bd9Sstevel@tonic-gate 29237c478bd9Sstevel@tonic-gate return (error); 29247c478bd9Sstevel@tonic-gate } 29257c478bd9Sstevel@tonic-gate 29267c478bd9Sstevel@tonic-gate static int 29277c478bd9Sstevel@tonic-gate dprov_verify_update(crypto_ctx_t *ctx, crypto_data_t *data, 29287c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 29297c478bd9Sstevel@tonic-gate { 29307c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 29317c478bd9Sstevel@tonic-gate dprov_state_t *softc; 29327c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 29337c478bd9Sstevel@tonic-gate int instance; 29347c478bd9Sstevel@tonic-gate 29357c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 29367c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 29377c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_update: started\n", 29387c478bd9Sstevel@tonic-gate instance)); 29397c478bd9Sstevel@tonic-gate 29407c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 29417c478bd9Sstevel@tonic-gate error = dprov_verify_submit_req(DPROV_REQ_VERIFY_UPDATE, softc, req, 29427c478bd9Sstevel@tonic-gate NULL, NULL, data, NULL, ctx, 0, KM_NOSLEEP); 29437c478bd9Sstevel@tonic-gate 29447c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_update: done err = 0x%x\n", 29457c478bd9Sstevel@tonic-gate instance, error)); 29467c478bd9Sstevel@tonic-gate 29477c478bd9Sstevel@tonic-gate return (error); 29487c478bd9Sstevel@tonic-gate } 29497c478bd9Sstevel@tonic-gate 29507c478bd9Sstevel@tonic-gate static int 29517c478bd9Sstevel@tonic-gate dprov_verify_final(crypto_ctx_t *ctx, crypto_data_t *signature, 29527c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 29537c478bd9Sstevel@tonic-gate { 29547c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 29557c478bd9Sstevel@tonic-gate dprov_state_t *softc; 29567c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 29577c478bd9Sstevel@tonic-gate int instance; 29587c478bd9Sstevel@tonic-gate 29597c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 29607c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 29617c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_final: started\n", instance)); 29627c478bd9Sstevel@tonic-gate 29637c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 29647c478bd9Sstevel@tonic-gate error = dprov_verify_submit_req(DPROV_REQ_VERIFY_FINAL, softc, req, 29657c478bd9Sstevel@tonic-gate NULL, NULL, NULL, signature, ctx, 0, KM_NOSLEEP); 29667c478bd9Sstevel@tonic-gate 29677c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_final: done err = 0x%x\n", 29687c478bd9Sstevel@tonic-gate instance, error)); 29697c478bd9Sstevel@tonic-gate 29707c478bd9Sstevel@tonic-gate return (error); 29717c478bd9Sstevel@tonic-gate } 29727c478bd9Sstevel@tonic-gate 29737c478bd9Sstevel@tonic-gate static int 29747c478bd9Sstevel@tonic-gate dprov_verify_atomic(crypto_provider_handle_t provider, 29757c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 29767c478bd9Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature, 29777c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 29787c478bd9Sstevel@tonic-gate { 29797c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 29807c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 29817c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 29827c478bd9Sstevel@tonic-gate int instance; 29837c478bd9Sstevel@tonic-gate 29847c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 29857c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_atomic: started\n", 29867c478bd9Sstevel@tonic-gate instance)); 29877c478bd9Sstevel@tonic-gate 29887c478bd9Sstevel@tonic-gate /* check mechanism */ 29897c478bd9Sstevel@tonic-gate if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) { 29907c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_verify_atomic: unexpected mech type " 29917c478bd9Sstevel@tonic-gate "0x%llx\n", (unsigned long long)mechanism->cm_type); 29927c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 29937c478bd9Sstevel@tonic-gate } 29947c478bd9Sstevel@tonic-gate 29957c478bd9Sstevel@tonic-gate if (ctx_template != NULL) 29967c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 29977c478bd9Sstevel@tonic-gate 29987c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 29997c478bd9Sstevel@tonic-gate error = dprov_verify_submit_req(DPROV_REQ_VERIFY_ATOMIC, softc, req, 30007c478bd9Sstevel@tonic-gate mechanism, key, data, signature, NULL, session_id, KM_SLEEP); 30017c478bd9Sstevel@tonic-gate 30027c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_atomic: done err = 0x%x\n", 30037c478bd9Sstevel@tonic-gate instance, error)); 30047c478bd9Sstevel@tonic-gate 30057c478bd9Sstevel@tonic-gate return (error); 30067c478bd9Sstevel@tonic-gate } 30077c478bd9Sstevel@tonic-gate 30087c478bd9Sstevel@tonic-gate static int 30097c478bd9Sstevel@tonic-gate dprov_verify_recover_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 30107c478bd9Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 30117c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 30127c478bd9Sstevel@tonic-gate { 30137c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 30147c478bd9Sstevel@tonic-gate dprov_state_t *softc; 30157c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 30167c478bd9Sstevel@tonic-gate int instance; 30177c478bd9Sstevel@tonic-gate 30187c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 30197c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 30207c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_init: started\n", 30217c478bd9Sstevel@tonic-gate instance)); 30227c478bd9Sstevel@tonic-gate 30237c478bd9Sstevel@tonic-gate if (ctx_template != NULL) 30247c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 30257c478bd9Sstevel@tonic-gate 30267c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 30277c478bd9Sstevel@tonic-gate error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER_INIT, softc, 30287c478bd9Sstevel@tonic-gate req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP); 30297c478bd9Sstevel@tonic-gate 30307c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_init: done " 30317c478bd9Sstevel@tonic-gate "err = 0x%x\n", instance, error)); 30327c478bd9Sstevel@tonic-gate 30337c478bd9Sstevel@tonic-gate return (error); 30347c478bd9Sstevel@tonic-gate } 30357c478bd9Sstevel@tonic-gate 30367c478bd9Sstevel@tonic-gate static int 30377c478bd9Sstevel@tonic-gate dprov_verify_recover(crypto_ctx_t *ctx, crypto_data_t *signature, 30387c478bd9Sstevel@tonic-gate crypto_data_t *data, crypto_req_handle_t req) 30397c478bd9Sstevel@tonic-gate { 30407c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 30417c478bd9Sstevel@tonic-gate dprov_state_t *softc; 30427c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 30437c478bd9Sstevel@tonic-gate int instance; 30447c478bd9Sstevel@tonic-gate 30457c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 30467c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 30477c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover: started\n", 30487c478bd9Sstevel@tonic-gate instance)); 30497c478bd9Sstevel@tonic-gate 30507c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 30517c478bd9Sstevel@tonic-gate error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER, softc, req, 30527c478bd9Sstevel@tonic-gate NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP); 30537c478bd9Sstevel@tonic-gate 30547c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover: done err = 0x%x\n", 30557c478bd9Sstevel@tonic-gate instance, error)); 30567c478bd9Sstevel@tonic-gate 30577c478bd9Sstevel@tonic-gate return (error); 30587c478bd9Sstevel@tonic-gate } 30597c478bd9Sstevel@tonic-gate 30607c478bd9Sstevel@tonic-gate static int 30617c478bd9Sstevel@tonic-gate dprov_verify_recover_atomic(crypto_provider_handle_t provider, 30627c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 30637c478bd9Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *signature, crypto_data_t *data, 30647c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 30657c478bd9Sstevel@tonic-gate { 30667c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 30677c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 30687c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 30697c478bd9Sstevel@tonic-gate int instance; 30707c478bd9Sstevel@tonic-gate 30717c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 30727c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_atomic: started\n", 30737c478bd9Sstevel@tonic-gate instance)); 30747c478bd9Sstevel@tonic-gate 30757c478bd9Sstevel@tonic-gate if (ctx_template != NULL) 30767c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 30777c478bd9Sstevel@tonic-gate 30787c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 30797c478bd9Sstevel@tonic-gate error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER_ATOMIC, softc, 30807c478bd9Sstevel@tonic-gate req, mechanism, key, data, signature, NULL, session_id, KM_SLEEP); 30817c478bd9Sstevel@tonic-gate 30827c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_atomic: done " 30837c478bd9Sstevel@tonic-gate "err = 0x%x\n", instance, error)); 30847c478bd9Sstevel@tonic-gate 30857c478bd9Sstevel@tonic-gate return (error); 30867c478bd9Sstevel@tonic-gate } 30877c478bd9Sstevel@tonic-gate 30887c478bd9Sstevel@tonic-gate /* 30897c478bd9Sstevel@tonic-gate * Dual operations entry points. 30907c478bd9Sstevel@tonic-gate */ 30917c478bd9Sstevel@tonic-gate 30927c478bd9Sstevel@tonic-gate static int 30937c478bd9Sstevel@tonic-gate dprov_digest_encrypt_update(crypto_ctx_t *digest_ctx, 30947c478bd9Sstevel@tonic-gate crypto_ctx_t *encrypt_ctx, crypto_data_t *plaintext, 30957c478bd9Sstevel@tonic-gate crypto_data_t *ciphertext, crypto_req_handle_t req) 30967c478bd9Sstevel@tonic-gate { 30977c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 30987c478bd9Sstevel@tonic-gate dprov_state_t *softc; 30997c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 31007c478bd9Sstevel@tonic-gate int instance; 31017c478bd9Sstevel@tonic-gate 31027c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 31037c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(digest_ctx, softc, instance); 31047c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DUAL, ("(%d) dprov_digest_encrypt_update: started\n", 31057c478bd9Sstevel@tonic-gate instance)); 31067c478bd9Sstevel@tonic-gate 31077c478bd9Sstevel@tonic-gate if (digest_ctx->cc_provider != encrypt_ctx->cc_provider) 31087c478bd9Sstevel@tonic-gate return (CRYPTO_INVALID_CONTEXT); 31097c478bd9Sstevel@tonic-gate 31107c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 31117c478bd9Sstevel@tonic-gate error = dprov_dual_submit_req(DPROV_REQ_DIGEST_ENCRYPT_UPDATE, 31127c478bd9Sstevel@tonic-gate softc, req, digest_ctx, encrypt_ctx, plaintext, ciphertext); 31137c478bd9Sstevel@tonic-gate 31147c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DUAL, ("(%d) dprov_digest_encrypt_update: done " 31157c478bd9Sstevel@tonic-gate "err = 0x%x\n", instance, error)); 31167c478bd9Sstevel@tonic-gate 31177c478bd9Sstevel@tonic-gate return (error); 31187c478bd9Sstevel@tonic-gate } 31197c478bd9Sstevel@tonic-gate 31207c478bd9Sstevel@tonic-gate static int 31217c478bd9Sstevel@tonic-gate dprov_decrypt_digest_update(crypto_ctx_t *decrypt_ctx, crypto_ctx_t *digest_ctx, 31227c478bd9Sstevel@tonic-gate crypto_data_t *ciphertext, crypto_data_t *plaintext, 31237c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 31247c478bd9Sstevel@tonic-gate { 31257c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 31267c478bd9Sstevel@tonic-gate dprov_state_t *softc; 31277c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 31287c478bd9Sstevel@tonic-gate int instance; 31297c478bd9Sstevel@tonic-gate 31307c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 31317c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(decrypt_ctx, softc, instance); 31327c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_digest_update: started\n", 31337c478bd9Sstevel@tonic-gate instance)); 31347c478bd9Sstevel@tonic-gate 31357c478bd9Sstevel@tonic-gate if (decrypt_ctx->cc_provider != digest_ctx->cc_provider) 31367c478bd9Sstevel@tonic-gate return (CRYPTO_INVALID_CONTEXT); 31377c478bd9Sstevel@tonic-gate 31387c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 31397c478bd9Sstevel@tonic-gate error = dprov_dual_submit_req(DPROV_REQ_DECRYPT_DIGEST_UPDATE, 31407c478bd9Sstevel@tonic-gate softc, req, digest_ctx, decrypt_ctx, plaintext, ciphertext); 31417c478bd9Sstevel@tonic-gate 31427c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_digest_update: done " 31437c478bd9Sstevel@tonic-gate "err = 0x%x\n", instance, error)); 31447c478bd9Sstevel@tonic-gate 31457c478bd9Sstevel@tonic-gate return (error); 31467c478bd9Sstevel@tonic-gate } 31477c478bd9Sstevel@tonic-gate 31487c478bd9Sstevel@tonic-gate static int 31497c478bd9Sstevel@tonic-gate dprov_sign_encrypt_update(crypto_ctx_t *sign_ctx, crypto_ctx_t *encrypt_ctx, 31507c478bd9Sstevel@tonic-gate crypto_data_t *plaintext, crypto_data_t *ciphertext, 31517c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 31527c478bd9Sstevel@tonic-gate { 31537c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 31547c478bd9Sstevel@tonic-gate dprov_state_t *softc; 31557c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 31567c478bd9Sstevel@tonic-gate int instance; 31577c478bd9Sstevel@tonic-gate 31587c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 31597c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(sign_ctx, softc, instance); 31607c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DUAL, ("(%d) dprov_sign_encrypt_update: started\n", 31617c478bd9Sstevel@tonic-gate instance)); 31627c478bd9Sstevel@tonic-gate 31637c478bd9Sstevel@tonic-gate if (sign_ctx->cc_provider != encrypt_ctx->cc_provider) 31647c478bd9Sstevel@tonic-gate return (CRYPTO_INVALID_CONTEXT); 31657c478bd9Sstevel@tonic-gate 31667c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 31677c478bd9Sstevel@tonic-gate error = dprov_dual_submit_req(DPROV_REQ_SIGN_ENCRYPT_UPDATE, 31687c478bd9Sstevel@tonic-gate softc, req, sign_ctx, encrypt_ctx, plaintext, ciphertext); 31697c478bd9Sstevel@tonic-gate 31707c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DUAL, ("(%d) dprov_sign_encrypt_update: done " 31717c478bd9Sstevel@tonic-gate "err = 0x%x\n", instance, error)); 31727c478bd9Sstevel@tonic-gate 31737c478bd9Sstevel@tonic-gate return (error); 31747c478bd9Sstevel@tonic-gate } 31757c478bd9Sstevel@tonic-gate 31767c478bd9Sstevel@tonic-gate static int 31777c478bd9Sstevel@tonic-gate dprov_decrypt_verify_update(crypto_ctx_t *decrypt_ctx, crypto_ctx_t *verify_ctx, 31787c478bd9Sstevel@tonic-gate crypto_data_t *ciphertext, crypto_data_t *plaintext, 31797c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 31807c478bd9Sstevel@tonic-gate { 31817c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 31827c478bd9Sstevel@tonic-gate dprov_state_t *softc; 31837c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 31847c478bd9Sstevel@tonic-gate int instance; 31857c478bd9Sstevel@tonic-gate 31867c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 31877c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(decrypt_ctx, softc, instance); 31887c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_verify_update: started\n", 31897c478bd9Sstevel@tonic-gate instance)); 31907c478bd9Sstevel@tonic-gate 31917c478bd9Sstevel@tonic-gate if (decrypt_ctx->cc_provider != verify_ctx->cc_provider) 31927c478bd9Sstevel@tonic-gate return (CRYPTO_INVALID_CONTEXT); 31937c478bd9Sstevel@tonic-gate 31947c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 31957c478bd9Sstevel@tonic-gate error = dprov_dual_submit_req(DPROV_REQ_DECRYPT_VERIFY_UPDATE, 31967c478bd9Sstevel@tonic-gate softc, req, verify_ctx, decrypt_ctx, plaintext, ciphertext); 31977c478bd9Sstevel@tonic-gate 31987c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_verify_update: done " 31997c478bd9Sstevel@tonic-gate "err = 0x%x\n", instance, error)); 32007c478bd9Sstevel@tonic-gate 32017c478bd9Sstevel@tonic-gate return (error); 32027c478bd9Sstevel@tonic-gate } 32037c478bd9Sstevel@tonic-gate 32047c478bd9Sstevel@tonic-gate /* 32057c478bd9Sstevel@tonic-gate * Dual cipher-mac entry points. 32067c478bd9Sstevel@tonic-gate */ 32077c478bd9Sstevel@tonic-gate 32087c478bd9Sstevel@tonic-gate static int 32097c478bd9Sstevel@tonic-gate dprov_encrypt_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *encrypt_mech, 32107c478bd9Sstevel@tonic-gate crypto_key_t *encrypt_key, crypto_mechanism_t *mac_mech, 32117c478bd9Sstevel@tonic-gate crypto_key_t *mac_key, crypto_spi_ctx_template_t encr_ctx_template, 32127c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t mac_ctx_template, 32137c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 32147c478bd9Sstevel@tonic-gate { 32157c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 32167c478bd9Sstevel@tonic-gate dprov_state_t *softc; 32177c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 32187c478bd9Sstevel@tonic-gate int instance; 32197c478bd9Sstevel@tonic-gate 32207c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 32217c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 32227c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_init: started\n", 32237c478bd9Sstevel@tonic-gate instance)); 32247c478bd9Sstevel@tonic-gate 32257c478bd9Sstevel@tonic-gate /* check mechanisms */ 32267c478bd9Sstevel@tonic-gate if (!dprov_valid_cipher_mech(encrypt_mech->cm_type)) { 32277c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_encrypt_mac_init: unexpected encrypt " 32287c478bd9Sstevel@tonic-gate "mech type 0x%llx\n", 32297c478bd9Sstevel@tonic-gate (unsigned long long)encrypt_mech->cm_type); 32307c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 32317c478bd9Sstevel@tonic-gate } 32327c478bd9Sstevel@tonic-gate if (!dprov_valid_mac_mech(mac_mech->cm_type)) { 32337c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_encrypt_mac_init: unexpected mac " 32347c478bd9Sstevel@tonic-gate "mech type 0x%llx\n", 32357c478bd9Sstevel@tonic-gate (unsigned long long)mac_mech->cm_type); 32367c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 32377c478bd9Sstevel@tonic-gate } 32387c478bd9Sstevel@tonic-gate 32397c478bd9Sstevel@tonic-gate if (encr_ctx_template != NULL || mac_ctx_template != NULL) 32407c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 32417c478bd9Sstevel@tonic-gate 32427c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 32437c478bd9Sstevel@tonic-gate error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_INIT, 32447c478bd9Sstevel@tonic-gate softc, req, ctx, 0, encrypt_mech, encrypt_key, mac_mech, mac_key, 32457c478bd9Sstevel@tonic-gate NULL, NULL, NULL, KM_SLEEP); 32467c478bd9Sstevel@tonic-gate 32477c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_init: done " 32487c478bd9Sstevel@tonic-gate "err = 0x%x\n", instance, error)); 32497c478bd9Sstevel@tonic-gate 32507c478bd9Sstevel@tonic-gate return (error); 32517c478bd9Sstevel@tonic-gate } 32527c478bd9Sstevel@tonic-gate 32537c478bd9Sstevel@tonic-gate static int 32547c478bd9Sstevel@tonic-gate dprov_encrypt_mac(crypto_ctx_t *ctx, crypto_data_t *plaintext, 32557c478bd9Sstevel@tonic-gate crypto_dual_data_t *ciphertext, crypto_data_t *mac, crypto_req_handle_t req) 32567c478bd9Sstevel@tonic-gate { 32577c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 32587c478bd9Sstevel@tonic-gate dprov_state_t *softc; 32597c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 32607c478bd9Sstevel@tonic-gate int instance; 32617c478bd9Sstevel@tonic-gate 32627c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 32637c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 32647c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac: started\n", 32657c478bd9Sstevel@tonic-gate instance)); 32667c478bd9Sstevel@tonic-gate 32677c478bd9Sstevel@tonic-gate /* 32687c478bd9Sstevel@tonic-gate * submit request to the taskq 32697c478bd9Sstevel@tonic-gate * Careful! cihertext/plaintext order inversion 32707c478bd9Sstevel@tonic-gate */ 32717c478bd9Sstevel@tonic-gate error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC, 32727c478bd9Sstevel@tonic-gate softc, req, ctx, 0, NULL, NULL, NULL, NULL, 32737c478bd9Sstevel@tonic-gate ciphertext, plaintext, mac, KM_NOSLEEP); 32747c478bd9Sstevel@tonic-gate 32757c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac: done " 32767c478bd9Sstevel@tonic-gate "err = 0x%x\n", instance, error)); 32777c478bd9Sstevel@tonic-gate 32787c478bd9Sstevel@tonic-gate return (error); 32797c478bd9Sstevel@tonic-gate } 32807c478bd9Sstevel@tonic-gate 32817c478bd9Sstevel@tonic-gate static int 32827c478bd9Sstevel@tonic-gate dprov_encrypt_mac_update(crypto_ctx_t *ctx, crypto_data_t *plaintext, 32837c478bd9Sstevel@tonic-gate crypto_dual_data_t *ciphertext, crypto_req_handle_t req) 32847c478bd9Sstevel@tonic-gate { 32857c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 32867c478bd9Sstevel@tonic-gate dprov_state_t *softc; 32877c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 32887c478bd9Sstevel@tonic-gate int instance; 32897c478bd9Sstevel@tonic-gate 32907c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 32917c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 32927c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_update: started\n", 32937c478bd9Sstevel@tonic-gate instance)); 32947c478bd9Sstevel@tonic-gate 32957c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 32967c478bd9Sstevel@tonic-gate error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_UPDATE, 32977c478bd9Sstevel@tonic-gate softc, req, ctx, 0, NULL, NULL, NULL, NULL, 32987c478bd9Sstevel@tonic-gate ciphertext, plaintext, NULL, KM_NOSLEEP); 32997c478bd9Sstevel@tonic-gate 33007c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_update: done " 33017c478bd9Sstevel@tonic-gate "err = 0x%x\n", instance, error)); 33027c478bd9Sstevel@tonic-gate 33037c478bd9Sstevel@tonic-gate return (error); 33047c478bd9Sstevel@tonic-gate } 33057c478bd9Sstevel@tonic-gate 33067c478bd9Sstevel@tonic-gate static int 33077c478bd9Sstevel@tonic-gate dprov_encrypt_mac_final(crypto_ctx_t *ctx, 33087c478bd9Sstevel@tonic-gate crypto_dual_data_t *ciphertext, crypto_data_t *mac, 33097c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 33107c478bd9Sstevel@tonic-gate { 33117c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 33127c478bd9Sstevel@tonic-gate dprov_state_t *softc; 33137c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 33147c478bd9Sstevel@tonic-gate int instance; 33157c478bd9Sstevel@tonic-gate 33167c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 33177c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 33187c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_final: started\n", 33197c478bd9Sstevel@tonic-gate instance)); 33207c478bd9Sstevel@tonic-gate 33217c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 33227c478bd9Sstevel@tonic-gate error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_FINAL, 33237c478bd9Sstevel@tonic-gate softc, req, ctx, 0, NULL, NULL, NULL, NULL, 33247c478bd9Sstevel@tonic-gate ciphertext, NULL, mac, KM_NOSLEEP); 33257c478bd9Sstevel@tonic-gate 33267c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_final: done " 33277c478bd9Sstevel@tonic-gate "err = 0x%x\n", instance, error)); 33287c478bd9Sstevel@tonic-gate 33297c478bd9Sstevel@tonic-gate return (error); 33307c478bd9Sstevel@tonic-gate } 33317c478bd9Sstevel@tonic-gate 33327c478bd9Sstevel@tonic-gate static int 33337c478bd9Sstevel@tonic-gate dprov_encrypt_mac_atomic(crypto_provider_handle_t provider, 33347c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *encrypt_mech, 33357c478bd9Sstevel@tonic-gate crypto_key_t *encrypt_key, crypto_mechanism_t *mac_mech, 33367c478bd9Sstevel@tonic-gate crypto_key_t *mac_key, crypto_data_t *plaintext, 33377c478bd9Sstevel@tonic-gate crypto_dual_data_t *ciphertext, crypto_data_t *mac, 33387c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t encr_ctx_template, 33397c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t mac_ctx_template, 33407c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 33417c478bd9Sstevel@tonic-gate { 33427c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 33437c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 33447c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 33457c478bd9Sstevel@tonic-gate int instance; 33467c478bd9Sstevel@tonic-gate 33477c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 33487c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_atomic: started\n", 33497c478bd9Sstevel@tonic-gate instance)); 33507c478bd9Sstevel@tonic-gate 33517c478bd9Sstevel@tonic-gate /* check mechanisms */ 33527c478bd9Sstevel@tonic-gate if (!dprov_valid_cipher_mech(encrypt_mech->cm_type)) { 33537c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_encrypt_mac_atomic: unexpected encrypt " 33547c478bd9Sstevel@tonic-gate "mech type 0x%llx\n", 33557c478bd9Sstevel@tonic-gate (unsigned long long)encrypt_mech->cm_type); 33567c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 33577c478bd9Sstevel@tonic-gate } 33587c478bd9Sstevel@tonic-gate if (!dprov_valid_mac_mech(mac_mech->cm_type)) { 33597c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_encrypt_mac_atomic: unexpected mac " 33607c478bd9Sstevel@tonic-gate "mech type 0x%llx\n", 33617c478bd9Sstevel@tonic-gate (unsigned long long)mac_mech->cm_type); 33627c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 33637c478bd9Sstevel@tonic-gate } 33647c478bd9Sstevel@tonic-gate 33657c478bd9Sstevel@tonic-gate if (encr_ctx_template != NULL || mac_ctx_template != NULL) 33667c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 33677c478bd9Sstevel@tonic-gate 33687c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 33697c478bd9Sstevel@tonic-gate error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_ATOMIC, 33707c478bd9Sstevel@tonic-gate softc, req, NULL, session_id, encrypt_mech, encrypt_key, mac_mech, 33717c478bd9Sstevel@tonic-gate mac_key, ciphertext, plaintext, mac, KM_SLEEP); 33727c478bd9Sstevel@tonic-gate 33737c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_atomic: done " 33747c478bd9Sstevel@tonic-gate "err = 0x%x\n", instance, error)); 33757c478bd9Sstevel@tonic-gate 33767c478bd9Sstevel@tonic-gate return (error); 33777c478bd9Sstevel@tonic-gate } 33787c478bd9Sstevel@tonic-gate 33797c478bd9Sstevel@tonic-gate static int 33807c478bd9Sstevel@tonic-gate dprov_mac_decrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mac_mech, 33817c478bd9Sstevel@tonic-gate crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech, 33827c478bd9Sstevel@tonic-gate crypto_key_t *decrypt_key, crypto_spi_ctx_template_t mac_ctx_template, 33837c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t decr_ctx_template, 33847c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 33857c478bd9Sstevel@tonic-gate { 33867c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 33877c478bd9Sstevel@tonic-gate dprov_state_t *softc; 33887c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 33897c478bd9Sstevel@tonic-gate int instance; 33907c478bd9Sstevel@tonic-gate 33917c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 33927c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 33937c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_init: started\n", 33947c478bd9Sstevel@tonic-gate instance)); 33957c478bd9Sstevel@tonic-gate 33967c478bd9Sstevel@tonic-gate /* check mechanisms */ 33977c478bd9Sstevel@tonic-gate if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) { 33987c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_mac_decrypt_init: unexpected decrypt " 33997c478bd9Sstevel@tonic-gate "mech type 0x%llx\n", 34007c478bd9Sstevel@tonic-gate (unsigned long long)decrypt_mech->cm_type); 34017c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 34027c478bd9Sstevel@tonic-gate } 34037c478bd9Sstevel@tonic-gate if (!dprov_valid_mac_mech(mac_mech->cm_type)) { 34047c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_mac_decrypt_init: unexpected mac " 34057c478bd9Sstevel@tonic-gate "mech type 0x%llx\n", 34067c478bd9Sstevel@tonic-gate (unsigned long long)mac_mech->cm_type); 34077c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 34087c478bd9Sstevel@tonic-gate } 34097c478bd9Sstevel@tonic-gate 34107c478bd9Sstevel@tonic-gate if (decr_ctx_template != NULL || mac_ctx_template != NULL) 34117c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 34127c478bd9Sstevel@tonic-gate 34137c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 34147c478bd9Sstevel@tonic-gate error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_INIT, 34157c478bd9Sstevel@tonic-gate softc, req, ctx, 0, decrypt_mech, decrypt_key, mac_mech, mac_key, 34167c478bd9Sstevel@tonic-gate NULL, NULL, NULL, KM_SLEEP); 34177c478bd9Sstevel@tonic-gate 34187c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_init: done " 34197c478bd9Sstevel@tonic-gate "err = 0x%x\n", instance, error)); 34207c478bd9Sstevel@tonic-gate 34217c478bd9Sstevel@tonic-gate return (error); 34227c478bd9Sstevel@tonic-gate } 34237c478bd9Sstevel@tonic-gate 34247c478bd9Sstevel@tonic-gate static int 34257c478bd9Sstevel@tonic-gate dprov_mac_decrypt(crypto_ctx_t *ctx, crypto_dual_data_t *ciphertext, 34267c478bd9Sstevel@tonic-gate crypto_data_t *mac, crypto_data_t *plaintext, crypto_req_handle_t req) 34277c478bd9Sstevel@tonic-gate { 34287c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 34297c478bd9Sstevel@tonic-gate dprov_state_t *softc; 34307c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 34317c478bd9Sstevel@tonic-gate int instance; 34327c478bd9Sstevel@tonic-gate 34337c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 34347c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 34357c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt: started\n", 34367c478bd9Sstevel@tonic-gate instance)); 34377c478bd9Sstevel@tonic-gate 34387c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 34397c478bd9Sstevel@tonic-gate error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT, 34407c478bd9Sstevel@tonic-gate softc, req, ctx, 0, NULL, NULL, NULL, NULL, 34417c478bd9Sstevel@tonic-gate ciphertext, plaintext, mac, KM_NOSLEEP); 34427c478bd9Sstevel@tonic-gate 34437c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt: done " 34447c478bd9Sstevel@tonic-gate "err = 0x%x\n", instance, error)); 34457c478bd9Sstevel@tonic-gate 34467c478bd9Sstevel@tonic-gate return (error); 34477c478bd9Sstevel@tonic-gate } 34487c478bd9Sstevel@tonic-gate 34497c478bd9Sstevel@tonic-gate static int 34507c478bd9Sstevel@tonic-gate dprov_mac_decrypt_update(crypto_ctx_t *ctx, crypto_dual_data_t *ciphertext, 34517c478bd9Sstevel@tonic-gate crypto_data_t *plaintext, crypto_req_handle_t req) 34527c478bd9Sstevel@tonic-gate { 34537c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 34547c478bd9Sstevel@tonic-gate dprov_state_t *softc; 34557c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 34567c478bd9Sstevel@tonic-gate int instance; 34577c478bd9Sstevel@tonic-gate 34587c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 34597c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 34607c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_update: started\n", 34617c478bd9Sstevel@tonic-gate instance)); 34627c478bd9Sstevel@tonic-gate 34637c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 34647c478bd9Sstevel@tonic-gate error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_UPDATE, 34657c478bd9Sstevel@tonic-gate softc, req, ctx, 0, NULL, NULL, NULL, NULL, 34667c478bd9Sstevel@tonic-gate ciphertext, plaintext, NULL, KM_NOSLEEP); 34677c478bd9Sstevel@tonic-gate 34687c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_update: done " 34697c478bd9Sstevel@tonic-gate "err = 0x%x\n", instance, error)); 34707c478bd9Sstevel@tonic-gate 34717c478bd9Sstevel@tonic-gate return (error); 34727c478bd9Sstevel@tonic-gate } 34737c478bd9Sstevel@tonic-gate 34747c478bd9Sstevel@tonic-gate static int 34757c478bd9Sstevel@tonic-gate dprov_mac_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *mac, 34767c478bd9Sstevel@tonic-gate crypto_data_t *plaintext, crypto_req_handle_t req) 34777c478bd9Sstevel@tonic-gate { 34787c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 34797c478bd9Sstevel@tonic-gate dprov_state_t *softc; 34807c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 34817c478bd9Sstevel@tonic-gate int instance; 34827c478bd9Sstevel@tonic-gate 34837c478bd9Sstevel@tonic-gate /* extract softc and instance number from context */ 34847c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 34857c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_final: started\n", 34867c478bd9Sstevel@tonic-gate instance)); 34877c478bd9Sstevel@tonic-gate 34887c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 34897c478bd9Sstevel@tonic-gate error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_FINAL, 34907c478bd9Sstevel@tonic-gate softc, req, ctx, 0, NULL, NULL, NULL, NULL, 34917c478bd9Sstevel@tonic-gate NULL, plaintext, mac, KM_NOSLEEP); 34927c478bd9Sstevel@tonic-gate 34937c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_final: done " 34947c478bd9Sstevel@tonic-gate "err = 0x%x\n", instance, error)); 34957c478bd9Sstevel@tonic-gate 34967c478bd9Sstevel@tonic-gate return (error); 34977c478bd9Sstevel@tonic-gate } 34987c478bd9Sstevel@tonic-gate 34997c478bd9Sstevel@tonic-gate static int 35007c478bd9Sstevel@tonic-gate dprov_mac_decrypt_atomic(crypto_provider_handle_t provider, 35017c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mac_mech, 35027c478bd9Sstevel@tonic-gate crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech, 35037c478bd9Sstevel@tonic-gate crypto_key_t *decrypt_key, crypto_dual_data_t *ciphertext, 35047c478bd9Sstevel@tonic-gate crypto_data_t *mac, crypto_data_t *plaintext, 35057c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t mac_ctx_template, 35067c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t decr_ctx_template, 35077c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 35087c478bd9Sstevel@tonic-gate { 35097c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 35107c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 35117c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 35127c478bd9Sstevel@tonic-gate int instance; 35137c478bd9Sstevel@tonic-gate 35147c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 35157c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_atomic: started\n", 35167c478bd9Sstevel@tonic-gate instance)); 35177c478bd9Sstevel@tonic-gate 35187c478bd9Sstevel@tonic-gate /* check mechanisms */ 35197c478bd9Sstevel@tonic-gate if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) { 35207c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_mac_decrypt_atomic: unexpected encrypt " 35217c478bd9Sstevel@tonic-gate "mech type 0x%llx\n", 35227c478bd9Sstevel@tonic-gate (unsigned long long)decrypt_mech->cm_type); 35237c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 35247c478bd9Sstevel@tonic-gate } 35257c478bd9Sstevel@tonic-gate if (!dprov_valid_mac_mech(mac_mech->cm_type)) { 35267c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_mac_decrypt_atomic: unexpected mac " 35277c478bd9Sstevel@tonic-gate "mech type 0x%llx\n", 35287c478bd9Sstevel@tonic-gate (unsigned long long)mac_mech->cm_type); 35297c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 35307c478bd9Sstevel@tonic-gate } 35317c478bd9Sstevel@tonic-gate 35327c478bd9Sstevel@tonic-gate if (decr_ctx_template != NULL || mac_ctx_template != NULL) 35337c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 35347c478bd9Sstevel@tonic-gate 35357c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 35367c478bd9Sstevel@tonic-gate error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_ATOMIC, 35377c478bd9Sstevel@tonic-gate softc, req, NULL, session_id, decrypt_mech, decrypt_key, mac_mech, 35387c478bd9Sstevel@tonic-gate mac_key, ciphertext, plaintext, mac, KM_SLEEP); 35397c478bd9Sstevel@tonic-gate 35407c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_atomic: done " 35417c478bd9Sstevel@tonic-gate "err = 0x%x\n", instance, error)); 35427c478bd9Sstevel@tonic-gate 35437c478bd9Sstevel@tonic-gate return (error); 35447c478bd9Sstevel@tonic-gate } 35457c478bd9Sstevel@tonic-gate 35467c478bd9Sstevel@tonic-gate static int 35477c478bd9Sstevel@tonic-gate dprov_mac_verify_decrypt_atomic(crypto_provider_handle_t provider, 35487c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mac_mech, 35497c478bd9Sstevel@tonic-gate crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech, 35507c478bd9Sstevel@tonic-gate crypto_key_t *decrypt_key, crypto_dual_data_t *ciphertext, 35517c478bd9Sstevel@tonic-gate crypto_data_t *mac, crypto_data_t *plaintext, 35527c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t mac_ctx_template, 35537c478bd9Sstevel@tonic-gate crypto_spi_ctx_template_t decr_ctx_template, 35547c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 35557c478bd9Sstevel@tonic-gate { 35567c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 35577c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 35587c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 35597c478bd9Sstevel@tonic-gate int instance; 35607c478bd9Sstevel@tonic-gate 35617c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 35627c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_verify_decrypt_atomic:" 35637c478bd9Sstevel@tonic-gate "started\n", instance)); 35647c478bd9Sstevel@tonic-gate 35657c478bd9Sstevel@tonic-gate /* check mechanisms */ 35667c478bd9Sstevel@tonic-gate if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) { 35677c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_mac_verify_decrypt_atomic: " 35687c478bd9Sstevel@tonic-gate "unexpected encrypt mech type 0x%llx\n", 35697c478bd9Sstevel@tonic-gate (unsigned long long)decrypt_mech->cm_type); 35707c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 35717c478bd9Sstevel@tonic-gate } 35727c478bd9Sstevel@tonic-gate if (!dprov_valid_mac_mech(mac_mech->cm_type)) { 35737c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "dprov_mac_verify_decrypt_atomic: " 35747c478bd9Sstevel@tonic-gate "unexpected mac mech type 0x%llx\n", 35757c478bd9Sstevel@tonic-gate (unsigned long long)mac_mech->cm_type); 35767c478bd9Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 35777c478bd9Sstevel@tonic-gate } 35787c478bd9Sstevel@tonic-gate 35797c478bd9Sstevel@tonic-gate if (decr_ctx_template != NULL || mac_ctx_template != NULL) 35807c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 35817c478bd9Sstevel@tonic-gate 35827c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 35837c478bd9Sstevel@tonic-gate error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC, 35847c478bd9Sstevel@tonic-gate softc, req, NULL, session_id, decrypt_mech, decrypt_key, mac_mech, 35857c478bd9Sstevel@tonic-gate mac_key, ciphertext, plaintext, mac, KM_SLEEP); 35867c478bd9Sstevel@tonic-gate 35877c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_verify_decrypt_atomic: done " 35887c478bd9Sstevel@tonic-gate "err = 0x%x\n", instance, error)); 35897c478bd9Sstevel@tonic-gate 35907c478bd9Sstevel@tonic-gate return (error); 35917c478bd9Sstevel@tonic-gate } 35927c478bd9Sstevel@tonic-gate 35937c478bd9Sstevel@tonic-gate /* 35947c478bd9Sstevel@tonic-gate * Random number entry points. 35957c478bd9Sstevel@tonic-gate */ 35967c478bd9Sstevel@tonic-gate 35977c478bd9Sstevel@tonic-gate static int 35987c478bd9Sstevel@tonic-gate dprov_seed_random(crypto_provider_handle_t provider, crypto_session_id_t sid, 35998047c9fbSmcpowers uchar_t *buf, size_t len, uint_t entropy_est, uint32_t flags, 36008047c9fbSmcpowers crypto_req_handle_t req) 36017c478bd9Sstevel@tonic-gate { 36027c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 36037c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 36047c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 36057c478bd9Sstevel@tonic-gate int instance; 36067c478bd9Sstevel@tonic-gate 36077c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 36087c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_RANDOM, ("(%d) dprov_seed_random: started\n", 36097c478bd9Sstevel@tonic-gate instance)); 36107c478bd9Sstevel@tonic-gate 36117c478bd9Sstevel@tonic-gate error = dprov_random_submit_req(DPROV_REQ_RANDOM_SEED, softc, 36128047c9fbSmcpowers req, buf, len, sid, entropy_est, flags); 36137c478bd9Sstevel@tonic-gate 36147c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_RANDOM, ("(%d) dprov_seed_random: done err = 0x0%x\n", 36157c478bd9Sstevel@tonic-gate instance, error)); 36167c478bd9Sstevel@tonic-gate 36177c478bd9Sstevel@tonic-gate return (error); 36187c478bd9Sstevel@tonic-gate } 36197c478bd9Sstevel@tonic-gate 36207c478bd9Sstevel@tonic-gate static int 36217c478bd9Sstevel@tonic-gate dprov_generate_random(crypto_provider_handle_t provider, 36227c478bd9Sstevel@tonic-gate crypto_session_id_t sid, uchar_t *buf, size_t len, crypto_req_handle_t req) 36237c478bd9Sstevel@tonic-gate { 36247c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 36257c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 36267c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 36277c478bd9Sstevel@tonic-gate int instance; 36287c478bd9Sstevel@tonic-gate 36297c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 36307c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_RANDOM, ("(%d) dprov_generate_random: started\n", 36317c478bd9Sstevel@tonic-gate instance)); 36327c478bd9Sstevel@tonic-gate 36337c478bd9Sstevel@tonic-gate error = dprov_random_submit_req(DPROV_REQ_RANDOM_GENERATE, softc, 36348047c9fbSmcpowers req, buf, len, sid, 0, 0); 36357c478bd9Sstevel@tonic-gate 36367c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_RANDOM, ("(%d) dprov_generate_random: done " 36377c478bd9Sstevel@tonic-gate "err = 0x0%x\n", instance, error)); 36387c478bd9Sstevel@tonic-gate 36397c478bd9Sstevel@tonic-gate return (error); 36407c478bd9Sstevel@tonic-gate } 36417c478bd9Sstevel@tonic-gate 36427c478bd9Sstevel@tonic-gate /* 36437c478bd9Sstevel@tonic-gate * Session Management entry points. 36447c478bd9Sstevel@tonic-gate */ 36457c478bd9Sstevel@tonic-gate 36467c478bd9Sstevel@tonic-gate static int 36477c478bd9Sstevel@tonic-gate dprov_session_open(crypto_provider_handle_t provider, 36487c478bd9Sstevel@tonic-gate crypto_session_id_t *session_id, crypto_req_handle_t req) 36497c478bd9Sstevel@tonic-gate { 36507c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 36517c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 36527c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 36537c478bd9Sstevel@tonic-gate int instance; 36547c478bd9Sstevel@tonic-gate 36557c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 36567c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_open: started\n", 36577c478bd9Sstevel@tonic-gate instance)); 36587c478bd9Sstevel@tonic-gate 36597c478bd9Sstevel@tonic-gate error = dprov_session_submit_req(DPROV_REQ_SESSION_OPEN, softc, 36607c478bd9Sstevel@tonic-gate req, session_id, 0, 0, NULL, 0); 36617c478bd9Sstevel@tonic-gate 36627c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_open: done err = 0x0%x\n", 36637c478bd9Sstevel@tonic-gate instance, error)); 36647c478bd9Sstevel@tonic-gate 36657c478bd9Sstevel@tonic-gate return (error); 36667c478bd9Sstevel@tonic-gate } 36677c478bd9Sstevel@tonic-gate 36687c478bd9Sstevel@tonic-gate static int 36697c478bd9Sstevel@tonic-gate dprov_session_close(crypto_provider_handle_t provider, 36707c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_req_handle_t req) 36717c478bd9Sstevel@tonic-gate { 36727c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 36737c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 36747c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 36757c478bd9Sstevel@tonic-gate int instance; 36767c478bd9Sstevel@tonic-gate 36777c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 36787c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_close: started\n", 36797c478bd9Sstevel@tonic-gate instance)); 36807c478bd9Sstevel@tonic-gate 36817c478bd9Sstevel@tonic-gate error = dprov_session_submit_req(DPROV_REQ_SESSION_CLOSE, softc, 36827c478bd9Sstevel@tonic-gate req, 0, session_id, 0, NULL, 0); 36837c478bd9Sstevel@tonic-gate 36847c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_close: done err = 0x0%x\n", 36857c478bd9Sstevel@tonic-gate instance, error)); 36867c478bd9Sstevel@tonic-gate 36877c478bd9Sstevel@tonic-gate return (error); 36887c478bd9Sstevel@tonic-gate } 36897c478bd9Sstevel@tonic-gate 36907c478bd9Sstevel@tonic-gate static int 36917c478bd9Sstevel@tonic-gate dprov_session_login(crypto_provider_handle_t provider, 36927c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_user_type_t user_type, 36937c478bd9Sstevel@tonic-gate char *pin, size_t pin_len, crypto_req_handle_t req) 36947c478bd9Sstevel@tonic-gate { 36957c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 36967c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 36977c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 36987c478bd9Sstevel@tonic-gate int instance; 36997c478bd9Sstevel@tonic-gate 37007c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 37017c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_login: started\n", 37027c478bd9Sstevel@tonic-gate instance)); 37037c478bd9Sstevel@tonic-gate 37047c478bd9Sstevel@tonic-gate error = dprov_session_submit_req(DPROV_REQ_SESSION_LOGIN, softc, 37057c478bd9Sstevel@tonic-gate req, 0, session_id, user_type, pin, pin_len); 37067c478bd9Sstevel@tonic-gate 37077c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_login: done err = 0x0%x\n", 37087c478bd9Sstevel@tonic-gate instance, error)); 37097c478bd9Sstevel@tonic-gate 37107c478bd9Sstevel@tonic-gate return (error); 37117c478bd9Sstevel@tonic-gate } 37127c478bd9Sstevel@tonic-gate 37137c478bd9Sstevel@tonic-gate static int 37147c478bd9Sstevel@tonic-gate dprov_session_logout(crypto_provider_handle_t provider, 37157c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_req_handle_t req) 37167c478bd9Sstevel@tonic-gate { 37177c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 37187c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 37197c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 37207c478bd9Sstevel@tonic-gate int instance; 37217c478bd9Sstevel@tonic-gate 37227c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 37237c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_logout: started\n", 37247c478bd9Sstevel@tonic-gate instance)); 37257c478bd9Sstevel@tonic-gate 37267c478bd9Sstevel@tonic-gate error = dprov_session_submit_req(DPROV_REQ_SESSION_LOGOUT, softc, 37277c478bd9Sstevel@tonic-gate req, 0, session_id, 0, NULL, 0); 37287c478bd9Sstevel@tonic-gate 37297c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_logout: done err = 0x0%x\n", 37307c478bd9Sstevel@tonic-gate instance, error)); 37317c478bd9Sstevel@tonic-gate 37327c478bd9Sstevel@tonic-gate return (error); 37337c478bd9Sstevel@tonic-gate } 37347c478bd9Sstevel@tonic-gate 37357c478bd9Sstevel@tonic-gate /* 37367c478bd9Sstevel@tonic-gate * Object management entry points. 37377c478bd9Sstevel@tonic-gate */ 37387c478bd9Sstevel@tonic-gate 37397c478bd9Sstevel@tonic-gate static int 37407c478bd9Sstevel@tonic-gate dprov_object_create(crypto_provider_handle_t provider, 37417c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_object_attribute_t *template, 37427c478bd9Sstevel@tonic-gate uint_t attribute_count, crypto_object_id_t *object, 37437c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 37447c478bd9Sstevel@tonic-gate { 37457c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 37467c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 37477c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 37487c478bd9Sstevel@tonic-gate int instance; 37497c478bd9Sstevel@tonic-gate 37507c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 37517c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_create: started\n", 37527c478bd9Sstevel@tonic-gate instance)); 37537c478bd9Sstevel@tonic-gate 37547c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 37557c478bd9Sstevel@tonic-gate error = dprov_object_submit_req(DPROV_REQ_OBJECT_CREATE, softc, req, 37567c478bd9Sstevel@tonic-gate session_id, 0, template, attribute_count, object, NULL, NULL, 37577c478bd9Sstevel@tonic-gate NULL, 0, NULL, KM_NOSLEEP); 37587c478bd9Sstevel@tonic-gate 37597c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_create: done err = 0x0%x\n", 37607c478bd9Sstevel@tonic-gate instance, error)); 37617c478bd9Sstevel@tonic-gate 37627c478bd9Sstevel@tonic-gate return (error); 37637c478bd9Sstevel@tonic-gate } 37647c478bd9Sstevel@tonic-gate 37657c478bd9Sstevel@tonic-gate static int 37667c478bd9Sstevel@tonic-gate dprov_object_copy(crypto_provider_handle_t provider, 37677c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_object_id_t object, 37687c478bd9Sstevel@tonic-gate crypto_object_attribute_t *template, uint_t attribute_count, 37697c478bd9Sstevel@tonic-gate crypto_object_id_t *new_object, crypto_req_handle_t req) 37707c478bd9Sstevel@tonic-gate { 37717c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 37727c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 37737c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 37747c478bd9Sstevel@tonic-gate int instance; 37757c478bd9Sstevel@tonic-gate 37767c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 37777c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_copy: started\n", 37787c478bd9Sstevel@tonic-gate instance)); 37797c478bd9Sstevel@tonic-gate 37807c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 37817c478bd9Sstevel@tonic-gate error = dprov_object_submit_req(DPROV_REQ_OBJECT_COPY, softc, req, 37827c478bd9Sstevel@tonic-gate session_id, object, template, attribute_count, new_object, 37837c478bd9Sstevel@tonic-gate NULL, NULL, NULL, 0, NULL, KM_NOSLEEP); 37847c478bd9Sstevel@tonic-gate 37857c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_copy: done err = 0x0%x\n", 37867c478bd9Sstevel@tonic-gate instance, error)); 37877c478bd9Sstevel@tonic-gate 37887c478bd9Sstevel@tonic-gate return (error); 37897c478bd9Sstevel@tonic-gate } 37907c478bd9Sstevel@tonic-gate 37917c478bd9Sstevel@tonic-gate static int 37927c478bd9Sstevel@tonic-gate dprov_object_destroy(crypto_provider_handle_t provider, 37937c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_object_id_t object, 37947c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 37957c478bd9Sstevel@tonic-gate { 37967c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 37977c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 37987c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 37997c478bd9Sstevel@tonic-gate int instance; 38007c478bd9Sstevel@tonic-gate 38017c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 38027c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_destroy: started\n", 38037c478bd9Sstevel@tonic-gate instance)); 38047c478bd9Sstevel@tonic-gate 38057c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 38067c478bd9Sstevel@tonic-gate error = dprov_object_submit_req(DPROV_REQ_OBJECT_DESTROY, softc, req, 38077c478bd9Sstevel@tonic-gate session_id, object, NULL, 0, NULL, NULL, NULL, NULL, 0, NULL, 38087c478bd9Sstevel@tonic-gate KM_NOSLEEP); 38097c478bd9Sstevel@tonic-gate 38107c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_destroy: done err = 0x0%x\n", 38117c478bd9Sstevel@tonic-gate instance, error)); 38127c478bd9Sstevel@tonic-gate 38137c478bd9Sstevel@tonic-gate return (error); 38147c478bd9Sstevel@tonic-gate } 38157c478bd9Sstevel@tonic-gate 38167c478bd9Sstevel@tonic-gate static int 38177c478bd9Sstevel@tonic-gate dprov_object_get_size(crypto_provider_handle_t provider, 38187c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_object_id_t object, 38197c478bd9Sstevel@tonic-gate size_t *size, crypto_req_handle_t req) 38207c478bd9Sstevel@tonic-gate { 38217c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 38227c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 38237c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 38247c478bd9Sstevel@tonic-gate int instance; 38257c478bd9Sstevel@tonic-gate 38267c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 38277c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_size: started\n", 38287c478bd9Sstevel@tonic-gate instance)); 38297c478bd9Sstevel@tonic-gate 38307c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 38317c478bd9Sstevel@tonic-gate error = dprov_object_submit_req(DPROV_REQ_OBJECT_GET_SIZE, softc, req, 38327c478bd9Sstevel@tonic-gate session_id, object, NULL, 0, NULL, size, NULL, NULL, 0, NULL, 38337c478bd9Sstevel@tonic-gate KM_NOSLEEP); 38347c478bd9Sstevel@tonic-gate 38357c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_size: done err = 0x0%x\n", 38367c478bd9Sstevel@tonic-gate instance, error)); 38377c478bd9Sstevel@tonic-gate 38387c478bd9Sstevel@tonic-gate return (error); 38397c478bd9Sstevel@tonic-gate } 38407c478bd9Sstevel@tonic-gate 38417c478bd9Sstevel@tonic-gate static int 38427c478bd9Sstevel@tonic-gate dprov_object_get_attribute_value(crypto_provider_handle_t provider, 38437c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_object_id_t object, 38447c478bd9Sstevel@tonic-gate crypto_object_attribute_t *template, uint_t attribute_count, 38457c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 38467c478bd9Sstevel@tonic-gate { 38477c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 38487c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 38497c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 38507c478bd9Sstevel@tonic-gate int instance; 38517c478bd9Sstevel@tonic-gate 38527c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 38537c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_attribute_value: " 38547c478bd9Sstevel@tonic-gate "started\n", instance)); 38557c478bd9Sstevel@tonic-gate 38567c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 38577c478bd9Sstevel@tonic-gate error = dprov_object_submit_req(DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE, 38587c478bd9Sstevel@tonic-gate softc, req, session_id, object, template, attribute_count, 38597c478bd9Sstevel@tonic-gate NULL, NULL, NULL, NULL, 0, NULL, KM_NOSLEEP); 38607c478bd9Sstevel@tonic-gate 38617c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_attribute_value: " 38627c478bd9Sstevel@tonic-gate "done err = 0x0%x\n", instance, error)); 38637c478bd9Sstevel@tonic-gate 38647c478bd9Sstevel@tonic-gate return (error); 38657c478bd9Sstevel@tonic-gate } 38667c478bd9Sstevel@tonic-gate 38677c478bd9Sstevel@tonic-gate static int 38687c478bd9Sstevel@tonic-gate dprov_object_set_attribute_value(crypto_provider_handle_t provider, 38697c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_object_id_t object, 38707c478bd9Sstevel@tonic-gate crypto_object_attribute_t *template, uint_t attribute_count, 38717c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 38727c478bd9Sstevel@tonic-gate { 38737c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 38747c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 38757c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 38767c478bd9Sstevel@tonic-gate int instance; 38777c478bd9Sstevel@tonic-gate 38787c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 38797c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_set_attribute_value: " 38807c478bd9Sstevel@tonic-gate "started\n", instance)); 38817c478bd9Sstevel@tonic-gate 38827c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 38837c478bd9Sstevel@tonic-gate error = dprov_object_submit_req(DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE, 38847c478bd9Sstevel@tonic-gate softc, req, session_id, object, template, attribute_count, 38857c478bd9Sstevel@tonic-gate NULL, NULL, NULL, NULL, 0, NULL, KM_NOSLEEP); 38867c478bd9Sstevel@tonic-gate 38877c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_set_attribute_value: " 38887c478bd9Sstevel@tonic-gate "done err = 0x0%x\n", instance, error)); 38897c478bd9Sstevel@tonic-gate 38907c478bd9Sstevel@tonic-gate return (error); 38917c478bd9Sstevel@tonic-gate } 38927c478bd9Sstevel@tonic-gate 38937c478bd9Sstevel@tonic-gate static int 38947c478bd9Sstevel@tonic-gate dprov_object_find_init(crypto_provider_handle_t provider, 38957c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_object_attribute_t *template, 38967c478bd9Sstevel@tonic-gate uint_t attribute_count, void **provider_private, 38977c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 38987c478bd9Sstevel@tonic-gate { 38997c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 39007c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 39017c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 39027c478bd9Sstevel@tonic-gate int instance; 39037c478bd9Sstevel@tonic-gate 39047c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 39057c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_init: started\n", 39067c478bd9Sstevel@tonic-gate instance)); 39077c478bd9Sstevel@tonic-gate 39087c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 39097c478bd9Sstevel@tonic-gate error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND_INIT, softc, req, 39107c478bd9Sstevel@tonic-gate session_id, 0, template, attribute_count, NULL, NULL, 39117c478bd9Sstevel@tonic-gate provider_private, NULL, 0, NULL, KM_SLEEP); 39127c478bd9Sstevel@tonic-gate 39137c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_init: done " 39147c478bd9Sstevel@tonic-gate "err = 0x0%x\n", instance, error)); 39157c478bd9Sstevel@tonic-gate 39167c478bd9Sstevel@tonic-gate return (error); 39177c478bd9Sstevel@tonic-gate } 39187c478bd9Sstevel@tonic-gate 39197c478bd9Sstevel@tonic-gate static int 39207c478bd9Sstevel@tonic-gate dprov_object_find(crypto_provider_handle_t provider, void *provider_private, 39217c478bd9Sstevel@tonic-gate crypto_object_id_t *objects, uint_t max_object_count, 39227c478bd9Sstevel@tonic-gate uint_t *object_count, crypto_req_handle_t req) 39237c478bd9Sstevel@tonic-gate { 39247c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 39257c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 39267c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 39277c478bd9Sstevel@tonic-gate int instance; 39287c478bd9Sstevel@tonic-gate 39297c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 39307c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find: started\n", 39317c478bd9Sstevel@tonic-gate instance)); 39327c478bd9Sstevel@tonic-gate 39337c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 39347c478bd9Sstevel@tonic-gate error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND, softc, req, 39357c478bd9Sstevel@tonic-gate 0, 0, NULL, 0, objects, NULL, NULL, provider_private, 39367c478bd9Sstevel@tonic-gate max_object_count, object_count, KM_NOSLEEP); 39377c478bd9Sstevel@tonic-gate 39387c478bd9Sstevel@tonic-gate 39397c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find: done err = 0x0%x\n", 39407c478bd9Sstevel@tonic-gate instance, error)); 39417c478bd9Sstevel@tonic-gate 39427c478bd9Sstevel@tonic-gate return (error); 39437c478bd9Sstevel@tonic-gate } 39447c478bd9Sstevel@tonic-gate 39457c478bd9Sstevel@tonic-gate static int 39467c478bd9Sstevel@tonic-gate dprov_object_find_final(crypto_provider_handle_t provider, 39477c478bd9Sstevel@tonic-gate void *provider_private, crypto_req_handle_t req) 39487c478bd9Sstevel@tonic-gate { 39497c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 39507c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 39517c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 39527c478bd9Sstevel@tonic-gate int instance; 39537c478bd9Sstevel@tonic-gate 39547c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 39557c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_final: started\n", 39567c478bd9Sstevel@tonic-gate instance)); 39577c478bd9Sstevel@tonic-gate 39587c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 39597c478bd9Sstevel@tonic-gate error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND_FINAL, softc, req, 39607c478bd9Sstevel@tonic-gate 0, 0, NULL, 0, NULL, NULL, NULL, provider_private, 39617c478bd9Sstevel@tonic-gate 0, NULL, KM_NOSLEEP); 39627c478bd9Sstevel@tonic-gate 39637c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_final: done " 39647c478bd9Sstevel@tonic-gate "err = 0x0%x\n", instance, error)); 39657c478bd9Sstevel@tonic-gate 39667c478bd9Sstevel@tonic-gate return (error); 39677c478bd9Sstevel@tonic-gate } 39687c478bd9Sstevel@tonic-gate 39697c478bd9Sstevel@tonic-gate /* 39707c478bd9Sstevel@tonic-gate * Key management entry points. 39717c478bd9Sstevel@tonic-gate */ 39727c478bd9Sstevel@tonic-gate 39737c478bd9Sstevel@tonic-gate static int 39747c478bd9Sstevel@tonic-gate dprov_key_generate(crypto_provider_handle_t provider, 39757c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 39767c478bd9Sstevel@tonic-gate crypto_object_attribute_t *template, uint_t attribute_count, 39777c478bd9Sstevel@tonic-gate crypto_object_id_t *object, crypto_req_handle_t req) 39787c478bd9Sstevel@tonic-gate { 39797c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 39807c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 39817c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 39827c478bd9Sstevel@tonic-gate int instance; 39837c478bd9Sstevel@tonic-gate 39847c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 39857c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate: started\n", 39867c478bd9Sstevel@tonic-gate instance)); 39877c478bd9Sstevel@tonic-gate 39887c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 39897c478bd9Sstevel@tonic-gate error = dprov_key_submit_req(DPROV_REQ_KEY_GENERATE, softc, req, 39907c478bd9Sstevel@tonic-gate session_id, mechanism, template, attribute_count, object, NULL, 3991034448feSmcpowers 0, NULL, NULL, NULL, 0, NULL, 0, NULL, 0); 39927c478bd9Sstevel@tonic-gate 39937c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate: done err = 0x0%x\n", 39947c478bd9Sstevel@tonic-gate instance, error)); 39957c478bd9Sstevel@tonic-gate 39967c478bd9Sstevel@tonic-gate return (error); 39977c478bd9Sstevel@tonic-gate } 39987c478bd9Sstevel@tonic-gate 39997c478bd9Sstevel@tonic-gate static int 40007c478bd9Sstevel@tonic-gate dprov_key_generate_pair(crypto_provider_handle_t provider, 40017c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 40027c478bd9Sstevel@tonic-gate crypto_object_attribute_t *public_key_template, 40037c478bd9Sstevel@tonic-gate uint_t public_key_attribute_count, 40047c478bd9Sstevel@tonic-gate crypto_object_attribute_t *private_key_template, 40057c478bd9Sstevel@tonic-gate uint_t private_key_attribute_count, 40067c478bd9Sstevel@tonic-gate crypto_object_id_t *public_key, crypto_object_id_t *private_key, 40077c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 40087c478bd9Sstevel@tonic-gate { 40097c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 40107c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 40117c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 40127c478bd9Sstevel@tonic-gate int instance; 40137c478bd9Sstevel@tonic-gate 40147c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 40157c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate_pair: started\n", 40167c478bd9Sstevel@tonic-gate instance)); 40177c478bd9Sstevel@tonic-gate 40187c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 40197c478bd9Sstevel@tonic-gate error = dprov_key_submit_req(DPROV_REQ_KEY_GENERATE_PAIR, softc, req, 40207c478bd9Sstevel@tonic-gate session_id, mechanism, public_key_template, 40217c478bd9Sstevel@tonic-gate public_key_attribute_count, public_key, private_key_template, 4022034448feSmcpowers private_key_attribute_count, private_key, NULL, NULL, 0, NULL, 0, 4023034448feSmcpowers NULL, 0); 40247c478bd9Sstevel@tonic-gate 40257c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate_pair: done err = 0x0%x\n", 40267c478bd9Sstevel@tonic-gate instance, error)); 40277c478bd9Sstevel@tonic-gate 40287c478bd9Sstevel@tonic-gate return (error); 40297c478bd9Sstevel@tonic-gate } 40307c478bd9Sstevel@tonic-gate 40317c478bd9Sstevel@tonic-gate static int 40327c478bd9Sstevel@tonic-gate dprov_key_wrap(crypto_provider_handle_t provider, 40337c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 40347c478bd9Sstevel@tonic-gate crypto_key_t *wrapping_key, crypto_object_id_t *key, 40357c478bd9Sstevel@tonic-gate uchar_t *wrapped_key, size_t *wrapped_key_len_ptr, crypto_req_handle_t req) 40367c478bd9Sstevel@tonic-gate { 40377c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 40387c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 40397c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 40407c478bd9Sstevel@tonic-gate int instance; 40417c478bd9Sstevel@tonic-gate 40427c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 40437c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_wrap: started\n", 40447c478bd9Sstevel@tonic-gate instance)); 40457c478bd9Sstevel@tonic-gate 40467c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 40477c478bd9Sstevel@tonic-gate error = dprov_key_submit_req(DPROV_REQ_KEY_WRAP, softc, req, 40487c478bd9Sstevel@tonic-gate session_id, mechanism, NULL, 0, key, NULL, 4049034448feSmcpowers 0, NULL, wrapping_key, wrapped_key, wrapped_key_len_ptr, 4050034448feSmcpowers NULL, 0, NULL, 0); 40517c478bd9Sstevel@tonic-gate 40527c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_wrap: done err = 0x0%x\n", 40537c478bd9Sstevel@tonic-gate instance, error)); 40547c478bd9Sstevel@tonic-gate 40557c478bd9Sstevel@tonic-gate return (error); 40567c478bd9Sstevel@tonic-gate } 40577c478bd9Sstevel@tonic-gate 40587c478bd9Sstevel@tonic-gate static int 40597c478bd9Sstevel@tonic-gate dprov_key_unwrap(crypto_provider_handle_t provider, 40607c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 40617c478bd9Sstevel@tonic-gate crypto_key_t *unwrapping_key, uchar_t *wrapped_key, 40627c478bd9Sstevel@tonic-gate size_t *wrapped_key_len_ptr, crypto_object_attribute_t *template, 40637c478bd9Sstevel@tonic-gate uint_t attribute_count, crypto_object_id_t *key, crypto_req_handle_t req) 40647c478bd9Sstevel@tonic-gate { 40657c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 40667c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 40677c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 40687c478bd9Sstevel@tonic-gate int instance; 40697c478bd9Sstevel@tonic-gate 40707c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 40717c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_unwrap: started\n", 40727c478bd9Sstevel@tonic-gate instance)); 40737c478bd9Sstevel@tonic-gate 40747c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 40757c478bd9Sstevel@tonic-gate error = dprov_key_submit_req(DPROV_REQ_KEY_UNWRAP, softc, req, 40767c478bd9Sstevel@tonic-gate session_id, mechanism, template, attribute_count, key, NULL, 4077034448feSmcpowers 0, NULL, unwrapping_key, wrapped_key, wrapped_key_len_ptr, 4078034448feSmcpowers NULL, 0, NULL, 0); 40797c478bd9Sstevel@tonic-gate 40807c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_unwrap: done err = 0x0%x\n", 40817c478bd9Sstevel@tonic-gate instance, error)); 40827c478bd9Sstevel@tonic-gate 40837c478bd9Sstevel@tonic-gate return (error); 40847c478bd9Sstevel@tonic-gate } 40857c478bd9Sstevel@tonic-gate 40867c478bd9Sstevel@tonic-gate static int 40877c478bd9Sstevel@tonic-gate dprov_key_derive(crypto_provider_handle_t provider, 40887c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 40897c478bd9Sstevel@tonic-gate crypto_key_t *base_key, crypto_object_attribute_t *template, 40907c478bd9Sstevel@tonic-gate uint_t attribute_count, crypto_object_id_t *key, crypto_req_handle_t req) 40917c478bd9Sstevel@tonic-gate { 40927c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 40937c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 40947c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 40957c478bd9Sstevel@tonic-gate int instance; 40967c478bd9Sstevel@tonic-gate 40977c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 40987c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_derive: started\n", 40997c478bd9Sstevel@tonic-gate instance)); 41007c478bd9Sstevel@tonic-gate 41017c478bd9Sstevel@tonic-gate /* submit request to the taskq */ 41027c478bd9Sstevel@tonic-gate error = dprov_key_submit_req(DPROV_REQ_KEY_DERIVE, softc, req, 41037c478bd9Sstevel@tonic-gate session_id, mechanism, template, attribute_count, key, NULL, 4104034448feSmcpowers 0, NULL, base_key, NULL, 0, NULL, 0, NULL, 0); 41057c478bd9Sstevel@tonic-gate 41067c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_derive: done err = 0x0%x\n", 41077c478bd9Sstevel@tonic-gate instance, error)); 41087c478bd9Sstevel@tonic-gate 41097c478bd9Sstevel@tonic-gate return (error); 41107c478bd9Sstevel@tonic-gate } 41117c478bd9Sstevel@tonic-gate 41127c478bd9Sstevel@tonic-gate /* 41137c478bd9Sstevel@tonic-gate * Provider management entry points. 41147c478bd9Sstevel@tonic-gate */ 41157c478bd9Sstevel@tonic-gate 41167c478bd9Sstevel@tonic-gate static int 41177c478bd9Sstevel@tonic-gate dprov_ext_info(crypto_provider_handle_t provider, 41187c478bd9Sstevel@tonic-gate crypto_provider_ext_info_t *ext_info, crypto_req_handle_t req) 41197c478bd9Sstevel@tonic-gate { 41207c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 41217c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 41227c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 41237c478bd9Sstevel@tonic-gate int instance; 41247c478bd9Sstevel@tonic-gate 41257c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 41267c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MGMT, ("(%d) dprov_ext_info: started\n", 41277c478bd9Sstevel@tonic-gate instance)); 41287c478bd9Sstevel@tonic-gate 41297c478bd9Sstevel@tonic-gate error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_EXTINFO, softc, req, 41307c478bd9Sstevel@tonic-gate 0, NULL, 0, NULL, 0, NULL, ext_info); 41317c478bd9Sstevel@tonic-gate 41327c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MGMT, ("(%d) dprov_ext_info: done err = 0x0%x\n", 41337c478bd9Sstevel@tonic-gate instance, error)); 41347c478bd9Sstevel@tonic-gate 41357c478bd9Sstevel@tonic-gate return (error); 41367c478bd9Sstevel@tonic-gate } 41377c478bd9Sstevel@tonic-gate 41387c478bd9Sstevel@tonic-gate static int 41397c478bd9Sstevel@tonic-gate dprov_init_token(crypto_provider_handle_t provider, char *pin, size_t pin_len, 41407c478bd9Sstevel@tonic-gate char *label, crypto_req_handle_t req) 41417c478bd9Sstevel@tonic-gate { 41427c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 41437c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 41447c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 41457c478bd9Sstevel@tonic-gate int instance; 41467c478bd9Sstevel@tonic-gate 41477c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 41487c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_token: started\n", 41497c478bd9Sstevel@tonic-gate instance)); 41507c478bd9Sstevel@tonic-gate 41517c478bd9Sstevel@tonic-gate error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_INITTOKEN, softc, req, 41527c478bd9Sstevel@tonic-gate 0, pin, pin_len, NULL, 0, label, NULL); 41537c478bd9Sstevel@tonic-gate 41547c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_token: done err = 0x0%x\n", 41557c478bd9Sstevel@tonic-gate instance, error)); 41567c478bd9Sstevel@tonic-gate 41577c478bd9Sstevel@tonic-gate return (error); 41587c478bd9Sstevel@tonic-gate } 41597c478bd9Sstevel@tonic-gate 41607c478bd9Sstevel@tonic-gate static int 41617c478bd9Sstevel@tonic-gate dprov_init_pin(crypto_provider_handle_t provider, 41627c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, char *pin, size_t pin_len, 41637c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 41647c478bd9Sstevel@tonic-gate { 41657c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 41667c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 41677c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 41687c478bd9Sstevel@tonic-gate int instance; 41697c478bd9Sstevel@tonic-gate 41707c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 41717c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_pin: started\n", 41727c478bd9Sstevel@tonic-gate instance)); 41737c478bd9Sstevel@tonic-gate 41747c478bd9Sstevel@tonic-gate error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_INITPIN, softc, req, 41757c478bd9Sstevel@tonic-gate session_id, pin, pin_len, NULL, 0, NULL, NULL); 41767c478bd9Sstevel@tonic-gate 41777c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_pin: done err = 0x0%x\n", 41787c478bd9Sstevel@tonic-gate instance, error)); 41797c478bd9Sstevel@tonic-gate 41807c478bd9Sstevel@tonic-gate return (error); 41817c478bd9Sstevel@tonic-gate } 41827c478bd9Sstevel@tonic-gate 41837c478bd9Sstevel@tonic-gate static int 41847c478bd9Sstevel@tonic-gate dprov_set_pin(crypto_provider_handle_t provider, crypto_session_id_t session_id, 41857c478bd9Sstevel@tonic-gate char *old_pin, size_t old_pin_len, char *new_pin, size_t new_pin_len, 41867c478bd9Sstevel@tonic-gate crypto_req_handle_t req) 41877c478bd9Sstevel@tonic-gate { 41887c478bd9Sstevel@tonic-gate int error = CRYPTO_FAILED; 41897c478bd9Sstevel@tonic-gate dprov_state_t *softc = (dprov_state_t *)provider; 41907c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 41917c478bd9Sstevel@tonic-gate int instance; 41927c478bd9Sstevel@tonic-gate 41937c478bd9Sstevel@tonic-gate instance = ddi_get_instance(softc->ds_dip); 41947c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MGMT, ("(%d) dprov_set_pin: started\n", 41957c478bd9Sstevel@tonic-gate instance)); 41967c478bd9Sstevel@tonic-gate 41977c478bd9Sstevel@tonic-gate error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_SETPIN, softc, req, 41987c478bd9Sstevel@tonic-gate session_id, new_pin, new_pin_len, old_pin, old_pin_len, NULL, NULL); 41997c478bd9Sstevel@tonic-gate 42007c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MGMT, ("(%d) dprov_set_pin: done err = 0x0%x\n", 42017c478bd9Sstevel@tonic-gate instance, error)); 42027c478bd9Sstevel@tonic-gate 42037c478bd9Sstevel@tonic-gate return (error); 42047c478bd9Sstevel@tonic-gate } 42057c478bd9Sstevel@tonic-gate 42067c478bd9Sstevel@tonic-gate 42077c478bd9Sstevel@tonic-gate /* 42087c478bd9Sstevel@tonic-gate * Context management entry points. 42097c478bd9Sstevel@tonic-gate */ 42107c478bd9Sstevel@tonic-gate 42117c478bd9Sstevel@tonic-gate /* 42127c478bd9Sstevel@tonic-gate * Allocate a dprov-private context based on the specified dprov request. 42137c478bd9Sstevel@tonic-gate * For dual cipher/mac requests, the allocated context will 42147c478bd9Sstevel@tonic-gate * contain a structure dprov_ctx_dual_t, for other request types, 42157c478bd9Sstevel@tonic-gate * it will contain a dprov_ctx_single. 42167c478bd9Sstevel@tonic-gate * Returns one of the CRYPTO_ status codes. 42177c478bd9Sstevel@tonic-gate */ 42187c478bd9Sstevel@tonic-gate static int 42197c478bd9Sstevel@tonic-gate dprov_alloc_context(dprov_req_type_t req_type, crypto_ctx_t *spi_ctx) 42207c478bd9Sstevel@tonic-gate { 42217c478bd9Sstevel@tonic-gate dprov_ctx_single_t *dprov_private; 42227c478bd9Sstevel@tonic-gate 42237c478bd9Sstevel@tonic-gate switch (req_type) { 42247c478bd9Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_MAC_INIT: 42257c478bd9Sstevel@tonic-gate case DPROV_REQ_MAC_DECRYPT_INIT: 42267c478bd9Sstevel@tonic-gate dprov_private = kmem_zalloc(sizeof (dprov_ctx_dual_t), 42277c478bd9Sstevel@tonic-gate KM_NOSLEEP); 42287c478bd9Sstevel@tonic-gate if (dprov_private == NULL) 42297c478bd9Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 42307c478bd9Sstevel@tonic-gate dprov_private->dc_type = DPROV_CTX_DUAL; 42317c478bd9Sstevel@tonic-gate break; 42327c478bd9Sstevel@tonic-gate default: 42337c478bd9Sstevel@tonic-gate dprov_private = kmem_zalloc(sizeof (dprov_ctx_single_t), 42347c478bd9Sstevel@tonic-gate KM_NOSLEEP); 42357c478bd9Sstevel@tonic-gate if (dprov_private == NULL) 42367c478bd9Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 42377c478bd9Sstevel@tonic-gate dprov_private->dc_type = DPROV_CTX_SINGLE; 4238ba5f469cSkrishna dprov_private->dc_svrfy_to_mac = B_FALSE; 42397c478bd9Sstevel@tonic-gate break; 42407c478bd9Sstevel@tonic-gate } 42417c478bd9Sstevel@tonic-gate 42427c478bd9Sstevel@tonic-gate spi_ctx->cc_provider_private = (void *)dprov_private; 42437c478bd9Sstevel@tonic-gate 42447c478bd9Sstevel@tonic-gate return (CRYPTO_SUCCESS); 42457c478bd9Sstevel@tonic-gate } 42467c478bd9Sstevel@tonic-gate 42477c478bd9Sstevel@tonic-gate static int 42487c478bd9Sstevel@tonic-gate dprov_free_context(crypto_ctx_t *ctx) 42497c478bd9Sstevel@tonic-gate { 42507c478bd9Sstevel@tonic-gate if (ctx->cc_provider_private == NULL) 42517c478bd9Sstevel@tonic-gate return (CRYPTO_SUCCESS); 42527c478bd9Sstevel@tonic-gate 42537c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CONTEXT, ("dprov_free_context\n")); 42547c478bd9Sstevel@tonic-gate 42557c478bd9Sstevel@tonic-gate { 42567c478bd9Sstevel@tonic-gate /* 42577c478bd9Sstevel@tonic-gate * The dprov private context could contain either 42587c478bd9Sstevel@tonic-gate * a dprov_ctx_single_t or a dprov_ctx_dual_t. Free 42597c478bd9Sstevel@tonic-gate * the context based on its type. The k-API contexts 42607c478bd9Sstevel@tonic-gate * that were attached to the dprov private context 42617c478bd9Sstevel@tonic-gate * are freed by the framework. 42627c478bd9Sstevel@tonic-gate */ 42637c478bd9Sstevel@tonic-gate dprov_ctx_single_t *ctx_single = 42647c478bd9Sstevel@tonic-gate (dprov_ctx_single_t *)(ctx->cc_provider_private); 42657c478bd9Sstevel@tonic-gate 42667c478bd9Sstevel@tonic-gate if (ctx_single->dc_type == DPROV_CTX_SINGLE) { 42677c478bd9Sstevel@tonic-gate crypto_context_t context = DPROV_CTX_SINGLE(ctx); 42687c478bd9Sstevel@tonic-gate 42697c478bd9Sstevel@tonic-gate /* 42707c478bd9Sstevel@tonic-gate * This case happens for the crypto_cancel_ctx() case. 42717c478bd9Sstevel@tonic-gate * We have to cancel the SW provider context also. 42727c478bd9Sstevel@tonic-gate */ 42737c478bd9Sstevel@tonic-gate if (context != NULL) 42747c478bd9Sstevel@tonic-gate crypto_cancel_ctx(context); 42757c478bd9Sstevel@tonic-gate 42767c478bd9Sstevel@tonic-gate kmem_free(ctx_single, sizeof (dprov_ctx_single_t)); 42777c478bd9Sstevel@tonic-gate } else { 42787c478bd9Sstevel@tonic-gate crypto_context_t cipher_context = 42797c478bd9Sstevel@tonic-gate DPROV_CTX_DUAL_CIPHER(ctx); 42807c478bd9Sstevel@tonic-gate crypto_context_t mac_context = DPROV_CTX_DUAL_MAC(ctx); 42817c478bd9Sstevel@tonic-gate 42827c478bd9Sstevel@tonic-gate /* See comments above. */ 42837c478bd9Sstevel@tonic-gate if (cipher_context != NULL) 42847c478bd9Sstevel@tonic-gate crypto_cancel_ctx(cipher_context); 42857c478bd9Sstevel@tonic-gate if (mac_context != NULL) 42867c478bd9Sstevel@tonic-gate crypto_cancel_ctx(mac_context); 42877c478bd9Sstevel@tonic-gate 42887c478bd9Sstevel@tonic-gate ASSERT(ctx_single->dc_type == DPROV_CTX_DUAL); 42897c478bd9Sstevel@tonic-gate kmem_free(ctx_single, sizeof (dprov_ctx_dual_t)); 42907c478bd9Sstevel@tonic-gate } 42917c478bd9Sstevel@tonic-gate ctx->cc_provider_private = NULL; 42927c478bd9Sstevel@tonic-gate } 42937c478bd9Sstevel@tonic-gate 42947c478bd9Sstevel@tonic-gate return (CRYPTO_SUCCESS); 42957c478bd9Sstevel@tonic-gate } 42967c478bd9Sstevel@tonic-gate 4297894b2776Smcpowers /* 4298894b2776Smcpowers * Resource control checks don't need to be done. Why? Because this routine 4299894b2776Smcpowers * knows the size of the structure, and it can't be overridden by a user. 4300894b2776Smcpowers * This is different from the crypto module, which has no knowledge of 4301894b2776Smcpowers * specific mechanisms, and therefore has to trust specified size of the 4302894b2776Smcpowers * parameter. This trust, or lack of trust, is why the size of the 4303894b2776Smcpowers * parameter has to be charged against the project resource control. 4304894b2776Smcpowers */ 4305894b2776Smcpowers static int 43062d864512Sdinak copyin_aes_ccm_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech, 43072d864512Sdinak int *out_error, int mode) 43082d864512Sdinak { 43092d864512Sdinak STRUCT_DECL(crypto_mechanism, mech); 43102d864512Sdinak STRUCT_DECL(CK_AES_CCM_PARAMS, params); 43112d864512Sdinak CK_AES_CCM_PARAMS *aes_ccm_params; 43122d864512Sdinak caddr_t pp; 43132d864512Sdinak size_t param_len; 43142d864512Sdinak int error = 0; 43152d864512Sdinak int rv = 0; 43162d864512Sdinak 43172d864512Sdinak STRUCT_INIT(mech, mode); 43182d864512Sdinak STRUCT_INIT(params, mode); 43192d864512Sdinak bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech)); 43202d864512Sdinak pp = STRUCT_FGETP(mech, cm_param); 43212d864512Sdinak param_len = STRUCT_FGET(mech, cm_param_len); 43222d864512Sdinak 43232d864512Sdinak if (param_len != STRUCT_SIZE(params)) { 43242d864512Sdinak rv = CRYPTO_ARGUMENTS_BAD; 43252d864512Sdinak goto out; 43262d864512Sdinak } 43272d864512Sdinak 43282d864512Sdinak out_mech->cm_type = STRUCT_FGET(mech, cm_type); 43292d864512Sdinak out_mech->cm_param = NULL; 43302d864512Sdinak out_mech->cm_param_len = 0; 43312d864512Sdinak if (pp != NULL) { 43322d864512Sdinak size_t nonce_len, auth_data_len, total_param_len; 43332d864512Sdinak 43342d864512Sdinak if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) { 43352d864512Sdinak out_mech->cm_param = NULL; 43362d864512Sdinak error = EFAULT; 43372d864512Sdinak goto out; 43382d864512Sdinak } 43392d864512Sdinak 43402d864512Sdinak nonce_len = STRUCT_FGET(params, ulNonceSize); 43412d864512Sdinak auth_data_len = STRUCT_FGET(params, ulAuthDataSize); 43422d864512Sdinak 43432d864512Sdinak /* allocate param structure */ 43442d864512Sdinak total_param_len = 43452d864512Sdinak sizeof (CK_AES_CCM_PARAMS) + nonce_len + auth_data_len; 43462d864512Sdinak aes_ccm_params = kmem_alloc(total_param_len, KM_NOSLEEP); 43472d864512Sdinak if (aes_ccm_params == NULL) { 43482d864512Sdinak rv = CRYPTO_HOST_MEMORY; 43492d864512Sdinak goto out; 43502d864512Sdinak } 43512d864512Sdinak aes_ccm_params->ulMACSize = STRUCT_FGET(params, ulMACSize); 43522d864512Sdinak aes_ccm_params->ulNonceSize = nonce_len; 43532d864512Sdinak aes_ccm_params->ulAuthDataSize = auth_data_len; 43542d864512Sdinak aes_ccm_params->ulDataSize 43552d864512Sdinak = STRUCT_FGET(params, ulDataSize); 43562d864512Sdinak aes_ccm_params->nonce 43572d864512Sdinak = (uchar_t *)aes_ccm_params + sizeof (CK_AES_CCM_PARAMS); 43582d864512Sdinak aes_ccm_params->authData 43592d864512Sdinak = aes_ccm_params->nonce + nonce_len; 43602d864512Sdinak 43612d864512Sdinak if (copyin((char *)STRUCT_FGETP(params, nonce), 43622d864512Sdinak aes_ccm_params->nonce, nonce_len) != 0) { 43632d864512Sdinak kmem_free(aes_ccm_params, total_param_len); 43642d864512Sdinak out_mech->cm_param = NULL; 43652d864512Sdinak error = EFAULT; 43662d864512Sdinak goto out; 43672d864512Sdinak } 43682d864512Sdinak if (copyin((char *)STRUCT_FGETP(params, authData), 43692d864512Sdinak aes_ccm_params->authData, auth_data_len) != 0) { 43702d864512Sdinak kmem_free(aes_ccm_params, total_param_len); 43712d864512Sdinak out_mech->cm_param = NULL; 43722d864512Sdinak error = EFAULT; 43732d864512Sdinak goto out; 43742d864512Sdinak } 43752d864512Sdinak out_mech->cm_param = (char *)aes_ccm_params; 43762d864512Sdinak out_mech->cm_param_len = sizeof (CK_AES_CCM_PARAMS); 43772d864512Sdinak } 43782d864512Sdinak out: 43792d864512Sdinak *out_error = error; 43802d864512Sdinak return (rv); 43812d864512Sdinak } 43822d864512Sdinak 43834d703b5cSMark Powers /* 43844d703b5cSMark Powers * Resource control checks don't need to be done. Why? Because this routine 43854d703b5cSMark Powers * knows the size of the structure, and it can't be overridden by a user. 43864d703b5cSMark Powers * This is different from the crypto module, which has no knowledge of 43874d703b5cSMark Powers * specific mechanisms, and therefore has to trust specified size of the 43884d703b5cSMark Powers * parameter. This trust, or lack of trust, is why the size of the 43894d703b5cSMark Powers * parameter has to be charged against the project resource control. 43904d703b5cSMark Powers */ 43914d703b5cSMark Powers static int 43924d703b5cSMark Powers copyin_aes_gcm_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech, 43934d703b5cSMark Powers int *out_error, int mode) 43944d703b5cSMark Powers { 43954d703b5cSMark Powers STRUCT_DECL(crypto_mechanism, mech); 43964d703b5cSMark Powers STRUCT_DECL(CK_AES_GCM_PARAMS, params); 43974d703b5cSMark Powers CK_AES_GCM_PARAMS *aes_gcm_params; 43984d703b5cSMark Powers caddr_t pp; 43994d703b5cSMark Powers size_t param_len; 44004d703b5cSMark Powers int error = 0; 44014d703b5cSMark Powers int rv = 0; 44024d703b5cSMark Powers 44034d703b5cSMark Powers STRUCT_INIT(mech, mode); 44044d703b5cSMark Powers STRUCT_INIT(params, mode); 44054d703b5cSMark Powers bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech)); 44064d703b5cSMark Powers pp = STRUCT_FGETP(mech, cm_param); 44074d703b5cSMark Powers param_len = STRUCT_FGET(mech, cm_param_len); 44084d703b5cSMark Powers 44094d703b5cSMark Powers if (param_len != STRUCT_SIZE(params)) { 44104d703b5cSMark Powers rv = CRYPTO_ARGUMENTS_BAD; 44114d703b5cSMark Powers goto out; 44124d703b5cSMark Powers } 44134d703b5cSMark Powers 44144d703b5cSMark Powers out_mech->cm_type = STRUCT_FGET(mech, cm_type); 44154d703b5cSMark Powers out_mech->cm_param = NULL; 44164d703b5cSMark Powers out_mech->cm_param_len = 0; 44174d703b5cSMark Powers if (pp != NULL) { 44184d703b5cSMark Powers size_t nonce_len, auth_data_len, total_param_len; 44194d703b5cSMark Powers 44204d703b5cSMark Powers if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) { 44214d703b5cSMark Powers out_mech->cm_param = NULL; 44224d703b5cSMark Powers error = EFAULT; 44234d703b5cSMark Powers goto out; 44244d703b5cSMark Powers } 44254d703b5cSMark Powers 44264d703b5cSMark Powers nonce_len = STRUCT_FGET(params, ulIvLen); 44274d703b5cSMark Powers auth_data_len = STRUCT_FGET(params, ulAADLen); 44284d703b5cSMark Powers 44294d703b5cSMark Powers /* allocate param structure */ 44304d703b5cSMark Powers total_param_len = 44314d703b5cSMark Powers sizeof (CK_AES_GCM_PARAMS) + nonce_len + auth_data_len; 44324d703b5cSMark Powers aes_gcm_params = kmem_alloc(total_param_len, KM_NOSLEEP); 44334d703b5cSMark Powers if (aes_gcm_params == NULL) { 44344d703b5cSMark Powers rv = CRYPTO_HOST_MEMORY; 44354d703b5cSMark Powers goto out; 44364d703b5cSMark Powers } 44374d703b5cSMark Powers aes_gcm_params->ulTagBits = STRUCT_FGET(params, ulTagBits); 44384d703b5cSMark Powers aes_gcm_params->ulIvLen = nonce_len; 44394d703b5cSMark Powers aes_gcm_params->ulAADLen = auth_data_len; 44404d703b5cSMark Powers aes_gcm_params->pIv 44414d703b5cSMark Powers = (uchar_t *)aes_gcm_params + sizeof (CK_AES_GCM_PARAMS); 44424d703b5cSMark Powers aes_gcm_params->pAAD = aes_gcm_params->pIv + nonce_len; 44434d703b5cSMark Powers 44444d703b5cSMark Powers if (copyin((char *)STRUCT_FGETP(params, pIv), 44454d703b5cSMark Powers aes_gcm_params->pIv, nonce_len) != 0) { 44464d703b5cSMark Powers kmem_free(aes_gcm_params, total_param_len); 44474d703b5cSMark Powers out_mech->cm_param = NULL; 44484d703b5cSMark Powers error = EFAULT; 44494d703b5cSMark Powers goto out; 44504d703b5cSMark Powers } 44514d703b5cSMark Powers if (copyin((char *)STRUCT_FGETP(params, pAAD), 44524d703b5cSMark Powers aes_gcm_params->pAAD, auth_data_len) != 0) { 44534d703b5cSMark Powers kmem_free(aes_gcm_params, total_param_len); 44544d703b5cSMark Powers out_mech->cm_param = NULL; 44554d703b5cSMark Powers error = EFAULT; 44564d703b5cSMark Powers goto out; 44574d703b5cSMark Powers } 44584d703b5cSMark Powers out_mech->cm_param = (char *)aes_gcm_params; 44594d703b5cSMark Powers out_mech->cm_param_len = sizeof (CK_AES_GCM_PARAMS); 44604d703b5cSMark Powers } 44614d703b5cSMark Powers out: 44624d703b5cSMark Powers *out_error = error; 44634d703b5cSMark Powers return (rv); 44644d703b5cSMark Powers } 44652d864512Sdinak 4466983a1033SMark Powers static int 4467983a1033SMark Powers copyin_aes_gmac_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech, 4468983a1033SMark Powers int *out_error, int mode) 4469983a1033SMark Powers { 4470983a1033SMark Powers STRUCT_DECL(crypto_mechanism, mech); 4471983a1033SMark Powers STRUCT_DECL(CK_AES_GMAC_PARAMS, params); 4472983a1033SMark Powers CK_AES_GMAC_PARAMS *aes_gmac_params; 4473983a1033SMark Powers caddr_t pp; 4474983a1033SMark Powers size_t param_len; 4475983a1033SMark Powers int error = 0; 4476983a1033SMark Powers int rv = 0; 4477983a1033SMark Powers 4478983a1033SMark Powers STRUCT_INIT(mech, mode); 4479983a1033SMark Powers STRUCT_INIT(params, mode); 4480983a1033SMark Powers bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech)); 4481983a1033SMark Powers pp = STRUCT_FGETP(mech, cm_param); 4482983a1033SMark Powers param_len = STRUCT_FGET(mech, cm_param_len); 4483983a1033SMark Powers 4484983a1033SMark Powers if (param_len != STRUCT_SIZE(params)) { 4485983a1033SMark Powers rv = CRYPTO_ARGUMENTS_BAD; 4486983a1033SMark Powers goto out; 4487983a1033SMark Powers } 4488983a1033SMark Powers 4489983a1033SMark Powers out_mech->cm_type = STRUCT_FGET(mech, cm_type); 4490983a1033SMark Powers out_mech->cm_param = NULL; 4491983a1033SMark Powers out_mech->cm_param_len = 0; 4492983a1033SMark Powers if (pp != NULL) { 4493983a1033SMark Powers size_t auth_data_len, total_param_len; 4494983a1033SMark Powers 4495983a1033SMark Powers if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) { 4496983a1033SMark Powers out_mech->cm_param = NULL; 4497983a1033SMark Powers error = EFAULT; 4498983a1033SMark Powers goto out; 4499983a1033SMark Powers } 4500983a1033SMark Powers 4501983a1033SMark Powers auth_data_len = STRUCT_FGET(params, ulAADLen); 4502983a1033SMark Powers 4503983a1033SMark Powers /* allocate param structure */ 4504983a1033SMark Powers total_param_len = sizeof (CK_AES_GMAC_PARAMS) + 4505983a1033SMark Powers AES_GMAC_IV_LEN + auth_data_len; 4506983a1033SMark Powers aes_gmac_params = kmem_alloc(total_param_len, KM_NOSLEEP); 4507983a1033SMark Powers if (aes_gmac_params == NULL) { 4508983a1033SMark Powers rv = CRYPTO_HOST_MEMORY; 4509983a1033SMark Powers goto out; 4510983a1033SMark Powers } 4511983a1033SMark Powers aes_gmac_params->ulAADLen = auth_data_len; 4512983a1033SMark Powers aes_gmac_params->pIv 4513983a1033SMark Powers = (uchar_t *)aes_gmac_params + sizeof (CK_AES_GMAC_PARAMS); 4514983a1033SMark Powers aes_gmac_params->pAAD = aes_gmac_params->pIv + AES_GMAC_IV_LEN; 4515983a1033SMark Powers 4516983a1033SMark Powers if (copyin((char *)STRUCT_FGETP(params, pIv), 4517983a1033SMark Powers aes_gmac_params->pIv, AES_GMAC_IV_LEN) != 0) { 4518983a1033SMark Powers kmem_free(aes_gmac_params, total_param_len); 4519983a1033SMark Powers out_mech->cm_param = NULL; 4520983a1033SMark Powers error = EFAULT; 4521983a1033SMark Powers goto out; 4522983a1033SMark Powers } 4523983a1033SMark Powers if (copyin((char *)STRUCT_FGETP(params, pAAD), 4524983a1033SMark Powers aes_gmac_params->pAAD, auth_data_len) != 0) { 4525983a1033SMark Powers kmem_free(aes_gmac_params, total_param_len); 4526983a1033SMark Powers out_mech->cm_param = NULL; 4527983a1033SMark Powers error = EFAULT; 4528983a1033SMark Powers goto out; 4529983a1033SMark Powers } 4530983a1033SMark Powers out_mech->cm_param = (char *)aes_gmac_params; 4531983a1033SMark Powers out_mech->cm_param_len = sizeof (CK_AES_GMAC_PARAMS); 4532983a1033SMark Powers } 4533983a1033SMark Powers out: 4534983a1033SMark Powers *out_error = error; 4535983a1033SMark Powers return (rv); 4536983a1033SMark Powers } 4537983a1033SMark Powers 45382d864512Sdinak /* 45392d864512Sdinak * Resource control checks don't need to be done. Why? Because this routine 45402d864512Sdinak * knows the size of the structure, and it can't be overridden by a user. 45412d864512Sdinak * This is different from the crypto module, which has no knowledge of 45422d864512Sdinak * specific mechanisms, and therefore has to trust specified size of the 45432d864512Sdinak * parameter. This trust, or lack of trust, is why the size of the 45442d864512Sdinak * parameter has to be charged against the project resource control. 45452d864512Sdinak */ 45462d864512Sdinak static int 4547894b2776Smcpowers copyin_aes_ctr_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech, 4548894b2776Smcpowers int *out_error, int mode) 4549894b2776Smcpowers { 4550894b2776Smcpowers STRUCT_DECL(crypto_mechanism, mech); 4551894b2776Smcpowers STRUCT_DECL(CK_AES_CTR_PARAMS, params); 4552894b2776Smcpowers CK_AES_CTR_PARAMS *aes_ctr_params; 4553894b2776Smcpowers caddr_t pp; 4554894b2776Smcpowers size_t param_len; 4555894b2776Smcpowers int error = 0; 4556894b2776Smcpowers int rv = 0; 4557894b2776Smcpowers 4558894b2776Smcpowers STRUCT_INIT(mech, mode); 4559894b2776Smcpowers STRUCT_INIT(params, mode); 4560894b2776Smcpowers bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech)); 4561894b2776Smcpowers pp = STRUCT_FGETP(mech, cm_param); 4562894b2776Smcpowers param_len = STRUCT_FGET(mech, cm_param_len); 4563894b2776Smcpowers 4564894b2776Smcpowers if (param_len != STRUCT_SIZE(params)) { 4565894b2776Smcpowers rv = CRYPTO_ARGUMENTS_BAD; 4566894b2776Smcpowers goto out; 4567894b2776Smcpowers } 4568894b2776Smcpowers 4569894b2776Smcpowers out_mech->cm_type = STRUCT_FGET(mech, cm_type); 4570894b2776Smcpowers out_mech->cm_param = NULL; 4571894b2776Smcpowers out_mech->cm_param_len = 0; 4572894b2776Smcpowers if (pp != NULL) { 4573894b2776Smcpowers if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) { 4574894b2776Smcpowers out_mech->cm_param = NULL; 4575894b2776Smcpowers error = EFAULT; 4576894b2776Smcpowers goto out; 4577894b2776Smcpowers } 4578894b2776Smcpowers /* allocate param structure and counter block */ 4579d2b32306Smcpowers aes_ctr_params = kmem_alloc(sizeof (CK_AES_CTR_PARAMS), 4580894b2776Smcpowers KM_NOSLEEP); 4581894b2776Smcpowers if (aes_ctr_params == NULL) { 4582894b2776Smcpowers rv = CRYPTO_HOST_MEMORY; 4583894b2776Smcpowers goto out; 4584894b2776Smcpowers } 4585894b2776Smcpowers aes_ctr_params->ulCounterBits = STRUCT_FGET(params, 4586894b2776Smcpowers ulCounterBits); 4587d2b32306Smcpowers bcopy(STRUCT_FGETP(params, cb), aes_ctr_params->cb, 16); 4588894b2776Smcpowers out_mech->cm_param = (char *)aes_ctr_params; 4589894b2776Smcpowers out_mech->cm_param_len = sizeof (CK_AES_CTR_PARAMS); 4590894b2776Smcpowers } 4591894b2776Smcpowers out: 4592894b2776Smcpowers *out_error = error; 4593894b2776Smcpowers return (rv); 4594894b2776Smcpowers } 4595894b2776Smcpowers 4596f9fbec18Smcpowers static int 4597f9fbec18Smcpowers copyin_ecc_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech, 4598f9fbec18Smcpowers int *out_error, int mode) 4599f9fbec18Smcpowers { 4600f9fbec18Smcpowers STRUCT_DECL(crypto_mechanism, mech); 4601f9fbec18Smcpowers STRUCT_DECL(CK_ECDH1_DERIVE_PARAMS, params); 4602f9fbec18Smcpowers CK_ECDH1_DERIVE_PARAMS *ecc_params; 4603f9fbec18Smcpowers caddr_t pp; 4604f9fbec18Smcpowers size_t param_len, shared_data_len, public_data_len; 4605f9fbec18Smcpowers int error = 0; 4606f9fbec18Smcpowers int rv = 0; 4607f9fbec18Smcpowers 4608f9fbec18Smcpowers STRUCT_INIT(mech, mode); 4609f9fbec18Smcpowers STRUCT_INIT(params, mode); 4610f9fbec18Smcpowers bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech)); 4611f9fbec18Smcpowers pp = STRUCT_FGETP(mech, cm_param); 4612f9fbec18Smcpowers param_len = STRUCT_FGET(mech, cm_param_len); 4613f9fbec18Smcpowers 4614f9fbec18Smcpowers if (param_len != STRUCT_SIZE(params)) { 4615f9fbec18Smcpowers rv = CRYPTO_ARGUMENTS_BAD; 4616f9fbec18Smcpowers goto out; 4617f9fbec18Smcpowers } 4618f9fbec18Smcpowers 4619f9fbec18Smcpowers out_mech->cm_type = STRUCT_FGET(mech, cm_type); 4620f9fbec18Smcpowers out_mech->cm_param = NULL; 4621f9fbec18Smcpowers out_mech->cm_param_len = 0; 4622f9fbec18Smcpowers if (pp != NULL) { 4623f9fbec18Smcpowers if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) { 4624f9fbec18Smcpowers out_mech->cm_param = NULL; 4625f9fbec18Smcpowers error = EFAULT; 4626f9fbec18Smcpowers goto out; 4627f9fbec18Smcpowers } 4628f9fbec18Smcpowers shared_data_len = STRUCT_FGET(params, ulSharedDataLen); 4629f9fbec18Smcpowers public_data_len = STRUCT_FGET(params, ulPublicDataLen); 4630f9fbec18Smcpowers /* allocate param structure and buffers */ 4631f9fbec18Smcpowers ecc_params = kmem_alloc(sizeof (CK_ECDH1_DERIVE_PARAMS) + 4632f9fbec18Smcpowers roundup(shared_data_len, sizeof (caddr_t)) + 4633f9fbec18Smcpowers roundup(public_data_len, sizeof (caddr_t)), KM_NOSLEEP); 4634f9fbec18Smcpowers if (ecc_params == NULL) { 4635f9fbec18Smcpowers rv = CRYPTO_HOST_MEMORY; 4636f9fbec18Smcpowers goto out; 4637f9fbec18Smcpowers } 4638f9fbec18Smcpowers ecc_params->pSharedData = (uchar_t *)ecc_params + 4639f9fbec18Smcpowers sizeof (CK_ECDH1_DERIVE_PARAMS); 4640f9fbec18Smcpowers ecc_params->pPublicData = (uchar_t *)ecc_params->pSharedData + 4641f9fbec18Smcpowers roundup(shared_data_len, sizeof (caddr_t)); 4642f9fbec18Smcpowers if (copyin((char *)STRUCT_FGETP(params, pSharedData), 4643f9fbec18Smcpowers ecc_params->pSharedData, shared_data_len) != 0) { 4644f9fbec18Smcpowers kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) + 4645f9fbec18Smcpowers roundup(shared_data_len, sizeof (caddr_t)) + 4646f9fbec18Smcpowers roundup(public_data_len, sizeof (caddr_t))); 4647f9fbec18Smcpowers out_mech->cm_param = NULL; 4648f9fbec18Smcpowers error = EFAULT; 4649f9fbec18Smcpowers goto out; 4650f9fbec18Smcpowers } 4651f9fbec18Smcpowers ecc_params->ulSharedDataLen = shared_data_len; 4652f9fbec18Smcpowers 4653f9fbec18Smcpowers if (copyin((char *)STRUCT_FGETP(params, pPublicData), 4654f9fbec18Smcpowers ecc_params->pPublicData, public_data_len) != 0) { 4655f9fbec18Smcpowers kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) + 4656f9fbec18Smcpowers roundup(shared_data_len, sizeof (caddr_t)) + 4657f9fbec18Smcpowers roundup(public_data_len, sizeof (caddr_t))); 4658f9fbec18Smcpowers out_mech->cm_param = NULL; 4659f9fbec18Smcpowers error = EFAULT; 4660f9fbec18Smcpowers goto out; 4661f9fbec18Smcpowers } 4662f9fbec18Smcpowers ecc_params->ulPublicDataLen = public_data_len; 4663f9fbec18Smcpowers ecc_params->kdf = STRUCT_FGET(params, kdf); 4664f9fbec18Smcpowers out_mech->cm_param = (char *)ecc_params; 4665f9fbec18Smcpowers out_mech->cm_param_len = sizeof (CK_ECDH1_DERIVE_PARAMS); 4666f9fbec18Smcpowers } 4667f9fbec18Smcpowers out: 4668f9fbec18Smcpowers *out_error = error; 4669f9fbec18Smcpowers return (rv); 4670f9fbec18Smcpowers } 4671f9fbec18Smcpowers 4672894b2776Smcpowers /* ARGSUSED */ 4673894b2776Smcpowers static int 4674894b2776Smcpowers copyout_aes_ctr_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech, 4675894b2776Smcpowers int *out_error, int mode) 4676894b2776Smcpowers { 4677894b2776Smcpowers STRUCT_DECL(crypto_mechanism, mech); 4678894b2776Smcpowers STRUCT_DECL(CK_AES_CTR_PARAMS, params); 4679894b2776Smcpowers caddr_t pp; 4680894b2776Smcpowers size_t param_len; 4681894b2776Smcpowers int error = 0; 4682894b2776Smcpowers int rv = 0; 4683894b2776Smcpowers 4684894b2776Smcpowers STRUCT_INIT(mech, mode); 4685894b2776Smcpowers STRUCT_INIT(params, mode); 4686894b2776Smcpowers bcopy(out_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech)); 4687894b2776Smcpowers pp = STRUCT_FGETP(mech, cm_param); 4688894b2776Smcpowers param_len = STRUCT_FGET(mech, cm_param_len); 4689894b2776Smcpowers if (param_len != STRUCT_SIZE(params)) { 4690894b2776Smcpowers rv = CRYPTO_ARGUMENTS_BAD; 4691894b2776Smcpowers goto out; 4692894b2776Smcpowers } 4693894b2776Smcpowers 4694894b2776Smcpowers if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) { 4695894b2776Smcpowers error = EFAULT; 4696894b2776Smcpowers goto out; 4697894b2776Smcpowers } 4698894b2776Smcpowers 4699894b2776Smcpowers /* for testing, overwrite the iv with 16 X 'A' */ 4700d2b32306Smcpowers (void) memset(STRUCT_FGETP(params, cb), 'A', 16); 4701d2b32306Smcpowers if (copyout((char *)pp, STRUCT_BUF(params), param_len) != 0) { 4702894b2776Smcpowers error = EFAULT; 4703894b2776Smcpowers goto out; 4704894b2776Smcpowers } 4705894b2776Smcpowers out: 4706894b2776Smcpowers *out_error = error; 4707894b2776Smcpowers return (rv); 4708894b2776Smcpowers } 4709894b2776Smcpowers 4710894b2776Smcpowers /* ARGSUSED */ 4711894b2776Smcpowers static int 4712894b2776Smcpowers dprov_copyin_mechanism(crypto_provider_handle_t provider, 4713894b2776Smcpowers crypto_mechanism_t *umech, crypto_mechanism_t *kmech, 4714894b2776Smcpowers int *out_error, int mode) 4715894b2776Smcpowers { 4716894b2776Smcpowers STRUCT_DECL(crypto_mechanism, mech); 4717894b2776Smcpowers size_t param_len, expected_param_len; 4718894b2776Smcpowers caddr_t pp; 4719894b2776Smcpowers char *param; 4720894b2776Smcpowers int rv; 4721894b2776Smcpowers int error = 0; 4722894b2776Smcpowers 4723894b2776Smcpowers ASSERT(!servicing_interrupt()); 4724894b2776Smcpowers 4725894b2776Smcpowers STRUCT_INIT(mech, mode); 4726894b2776Smcpowers bcopy(umech, STRUCT_BUF(mech), STRUCT_SIZE(mech)); 4727894b2776Smcpowers pp = STRUCT_FGETP(mech, cm_param); 4728894b2776Smcpowers param_len = STRUCT_FGET(mech, cm_param_len); 4729894b2776Smcpowers 4730894b2776Smcpowers kmech->cm_param = NULL; 4731894b2776Smcpowers kmech->cm_param_len = 0; 4732894b2776Smcpowers 4733894b2776Smcpowers switch (kmech->cm_type) { 4734894b2776Smcpowers case DES_CBC_MECH_INFO_TYPE: 4735894b2776Smcpowers case DES3_CBC_MECH_INFO_TYPE: 4736894b2776Smcpowers expected_param_len = DES_BLOCK_LEN; 4737894b2776Smcpowers break; 4738894b2776Smcpowers 4739894b2776Smcpowers case BLOWFISH_CBC_MECH_INFO_TYPE: 4740894b2776Smcpowers expected_param_len = BLOWFISH_BLOCK_LEN; 4741894b2776Smcpowers break; 4742894b2776Smcpowers 4743894b2776Smcpowers case AES_CBC_MECH_INFO_TYPE: 4744894b2776Smcpowers expected_param_len = AES_BLOCK_LEN; 4745894b2776Smcpowers break; 4746894b2776Smcpowers 4747894b2776Smcpowers case AES_CTR_MECH_INFO_TYPE: 4748894b2776Smcpowers case SHA1_KEY_DERIVATION_MECH_INFO_TYPE: /* for testing only */ 4749894b2776Smcpowers rv = copyin_aes_ctr_mech(umech, kmech, &error, mode); 4750894b2776Smcpowers goto out; 4751894b2776Smcpowers 4752f9fbec18Smcpowers case ECDH1_DERIVE_MECH_INFO_TYPE: 4753f9fbec18Smcpowers rv = copyin_ecc_mech(umech, kmech, &error, mode); 4754f9fbec18Smcpowers goto out; 4755f9fbec18Smcpowers 47562d864512Sdinak case AES_CCM_MECH_INFO_TYPE: 47572d864512Sdinak rv = copyin_aes_ccm_mech(umech, kmech, &error, mode); 47582d864512Sdinak goto out; 47592d864512Sdinak 47604d703b5cSMark Powers case AES_GCM_MECH_INFO_TYPE: 47614d703b5cSMark Powers rv = copyin_aes_gcm_mech(umech, kmech, &error, mode); 47624d703b5cSMark Powers goto out; 47634d703b5cSMark Powers 4764983a1033SMark Powers case AES_GMAC_MECH_INFO_TYPE: 4765983a1033SMark Powers rv = copyin_aes_gmac_mech(umech, kmech, &error, mode); 4766983a1033SMark Powers goto out; 4767983a1033SMark Powers 47685b0c7657Sizick case DH_PKCS_DERIVE_MECH_INFO_TYPE: 47695b0c7657Sizick expected_param_len = param_len; 47705b0c7657Sizick break; 47715b0c7657Sizick 4772894b2776Smcpowers default: 4773fd11a81eSmcpowers /* nothing to do - mechanism has no parameters */ 4774fd11a81eSmcpowers rv = CRYPTO_SUCCESS; 4775894b2776Smcpowers goto out; 4776894b2776Smcpowers } 4777894b2776Smcpowers 4778894b2776Smcpowers if (param_len != expected_param_len) { 4779894b2776Smcpowers rv = CRYPTO_MECHANISM_PARAM_INVALID; 4780894b2776Smcpowers goto out; 4781894b2776Smcpowers } 4782894b2776Smcpowers if (pp == NULL) { 4783894b2776Smcpowers rv = CRYPTO_MECHANISM_PARAM_INVALID; 4784894b2776Smcpowers goto out; 4785894b2776Smcpowers } 4786894b2776Smcpowers if ((param = kmem_alloc(param_len, KM_NOSLEEP)) == NULL) { 4787894b2776Smcpowers rv = CRYPTO_HOST_MEMORY; 4788894b2776Smcpowers goto out; 4789894b2776Smcpowers } 4790894b2776Smcpowers if (copyin((char *)pp, param, param_len) != 0) { 4791894b2776Smcpowers kmem_free(param, param_len); 4792894b2776Smcpowers error = EFAULT; 4793894b2776Smcpowers rv = CRYPTO_FAILED; 4794894b2776Smcpowers goto out; 4795894b2776Smcpowers } 4796894b2776Smcpowers kmech->cm_param = (char *)param; 4797894b2776Smcpowers kmech->cm_param_len = param_len; 4798894b2776Smcpowers rv = CRYPTO_SUCCESS; 4799894b2776Smcpowers out: 4800894b2776Smcpowers *out_error = error; 4801894b2776Smcpowers return (rv); 4802894b2776Smcpowers } 4803894b2776Smcpowers 4804894b2776Smcpowers /* ARGSUSED */ 4805894b2776Smcpowers static int 4806894b2776Smcpowers dprov_copyout_mechanism(crypto_provider_handle_t provider, 4807894b2776Smcpowers crypto_mechanism_t *kmech, crypto_mechanism_t *umech, 4808894b2776Smcpowers int *out_error, int mode) 4809894b2776Smcpowers { 4810894b2776Smcpowers ASSERT(!servicing_interrupt()); 4811894b2776Smcpowers 4812894b2776Smcpowers switch (kmech->cm_type) { 4813894b2776Smcpowers case AES_CTR_MECH_INFO_TYPE: 4814894b2776Smcpowers case SHA1_KEY_DERIVATION_MECH_INFO_TYPE: /* for testing only */ 4815894b2776Smcpowers return (copyout_aes_ctr_mech(kmech, umech, out_error, mode)); 4816f9fbec18Smcpowers case ECDH1_DERIVE_MECH_INFO_TYPE: 4817f9fbec18Smcpowers return (CRYPTO_SUCCESS); 4818894b2776Smcpowers default: 4819894b2776Smcpowers return (CRYPTO_MECHANISM_INVALID); 4820894b2776Smcpowers } 4821894b2776Smcpowers } 4822894b2776Smcpowers 4823894b2776Smcpowers /* 4824894b2776Smcpowers * Free mechanism parameter that was allocated by the provider. 4825894b2776Smcpowers */ 4826894b2776Smcpowers /* ARGSUSED */ 4827894b2776Smcpowers static int 4828894b2776Smcpowers dprov_free_mechanism(crypto_provider_handle_t provider, 4829894b2776Smcpowers crypto_mechanism_t *mech) 4830894b2776Smcpowers { 4831894b2776Smcpowers size_t len; 4832894b2776Smcpowers 4833894b2776Smcpowers if (mech->cm_param == NULL || mech->cm_param_len == 0) 4834894b2776Smcpowers return (CRYPTO_SUCCESS); 4835894b2776Smcpowers 4836f9fbec18Smcpowers switch (mech->cm_type) { 4837f9fbec18Smcpowers case AES_CTR_MECH_INFO_TYPE: 4838f9fbec18Smcpowers case SHA1_KEY_DERIVATION_MECH_INFO_TYPE: 4839d2b32306Smcpowers len = sizeof (CK_AES_CTR_PARAMS); 4840f9fbec18Smcpowers break; 4841f9fbec18Smcpowers case ECDH1_DERIVE_MECH_INFO_TYPE: { 4842f9fbec18Smcpowers CK_ECDH1_DERIVE_PARAMS *ecc_params; 4843f9fbec18Smcpowers 4844f9fbec18Smcpowers /* LINTED: pointer alignment */ 4845f9fbec18Smcpowers ecc_params = (CK_ECDH1_DERIVE_PARAMS *)mech->cm_param; 4846f9fbec18Smcpowers kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) + 4847f9fbec18Smcpowers roundup(ecc_params->ulSharedDataLen, sizeof (caddr_t)) + 4848f9fbec18Smcpowers roundup(ecc_params->ulPublicDataLen, sizeof (caddr_t))); 4849f9fbec18Smcpowers return (CRYPTO_SUCCESS); 4850f9fbec18Smcpowers } 485123c57df7Smcpowers case AES_CCM_MECH_INFO_TYPE: { 485223c57df7Smcpowers CK_AES_CCM_PARAMS *params; 485323c57df7Smcpowers size_t total_param_len; 485423c57df7Smcpowers 485523c57df7Smcpowers if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) { 485623c57df7Smcpowers /* LINTED: pointer alignment */ 485723c57df7Smcpowers params = (CK_AES_CCM_PARAMS *)mech->cm_param; 485823c57df7Smcpowers total_param_len = mech->cm_param_len + 485923c57df7Smcpowers params->ulNonceSize + params->ulAuthDataSize; 486023c57df7Smcpowers kmem_free(params, total_param_len); 486123c57df7Smcpowers mech->cm_param = NULL; 486223c57df7Smcpowers mech->cm_param_len = 0; 486323c57df7Smcpowers } 48644d703b5cSMark Powers return (CRYPTO_SUCCESS); 48654d703b5cSMark Powers } 4866983a1033SMark Powers case AES_GMAC_MECH_INFO_TYPE: { 4867983a1033SMark Powers CK_AES_GMAC_PARAMS *params; 4868983a1033SMark Powers size_t total_param_len; 4869983a1033SMark Powers 4870983a1033SMark Powers if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) { 4871983a1033SMark Powers /* LINTED: pointer alignment */ 4872983a1033SMark Powers params = (CK_AES_GMAC_PARAMS *)mech->cm_param; 4873983a1033SMark Powers total_param_len = mech->cm_param_len + 4874983a1033SMark Powers AES_GMAC_IV_LEN + params->ulAADLen; 4875983a1033SMark Powers kmem_free(params, total_param_len); 4876983a1033SMark Powers mech->cm_param = NULL; 4877983a1033SMark Powers mech->cm_param_len = 0; 4878983a1033SMark Powers } 4879983a1033SMark Powers return (CRYPTO_SUCCESS); 4880983a1033SMark Powers } 48814d703b5cSMark Powers case AES_GCM_MECH_INFO_TYPE: { 48824d703b5cSMark Powers CK_AES_GCM_PARAMS *params; 48834d703b5cSMark Powers size_t total_param_len; 48844d703b5cSMark Powers 48854d703b5cSMark Powers if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) { 48864d703b5cSMark Powers /* LINTED: pointer alignment */ 48874d703b5cSMark Powers params = (CK_AES_GCM_PARAMS *)mech->cm_param; 48884d703b5cSMark Powers total_param_len = mech->cm_param_len + 48894d703b5cSMark Powers params->ulIvLen + params->ulAADLen; 48904d703b5cSMark Powers kmem_free(params, total_param_len); 48914d703b5cSMark Powers mech->cm_param = NULL; 48924d703b5cSMark Powers mech->cm_param_len = 0; 48934d703b5cSMark Powers } 48944d703b5cSMark Powers return (CRYPTO_SUCCESS); 489523c57df7Smcpowers } 489623c57df7Smcpowers 4897f9fbec18Smcpowers default: 4898894b2776Smcpowers len = mech->cm_param_len; 4899894b2776Smcpowers } 4900894b2776Smcpowers kmem_free(mech->cm_param, len); 4901894b2776Smcpowers return (CRYPTO_SUCCESS); 4902894b2776Smcpowers } 49037c478bd9Sstevel@tonic-gate 49047c478bd9Sstevel@tonic-gate /* 4905034448feSmcpowers * No (Key)Store Key management entry point. 4906034448feSmcpowers */ 4907034448feSmcpowers static int 4908034448feSmcpowers dprov_nostore_key_generate(crypto_provider_handle_t provider, 4909034448feSmcpowers crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 4910034448feSmcpowers crypto_object_attribute_t *template, uint_t attribute_count, 4911034448feSmcpowers crypto_object_attribute_t *out_template, uint_t out_attribute_count, 4912034448feSmcpowers crypto_req_handle_t req) 4913034448feSmcpowers { 4914034448feSmcpowers int error = CRYPTO_FAILED; 4915034448feSmcpowers dprov_state_t *softc = (dprov_state_t *)provider; 4916034448feSmcpowers /* LINTED E_FUNC_SET_NOT_USED */ 4917034448feSmcpowers int instance; 4918034448feSmcpowers 4919034448feSmcpowers instance = ddi_get_instance(softc->ds_dip); 4920034448feSmcpowers DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate: started\n", 4921034448feSmcpowers instance)); 4922034448feSmcpowers 4923034448feSmcpowers /* submit request to the taskq */ 4924034448feSmcpowers error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_GENERATE, 4925034448feSmcpowers softc, req, session_id, mechanism, template, attribute_count, 4926034448feSmcpowers NULL, NULL, 0, NULL, NULL, NULL, 0, out_template, 4927034448feSmcpowers out_attribute_count, NULL, 0); 4928034448feSmcpowers 4929034448feSmcpowers DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate: " 4930034448feSmcpowers "done err = 0x0%x\n", instance, error)); 4931034448feSmcpowers 4932034448feSmcpowers return (error); 4933034448feSmcpowers } 4934034448feSmcpowers 49355b0c7657Sizick static int 49365b0c7657Sizick dprov_nostore_key_generate_pair(crypto_provider_handle_t provider, 49375b0c7657Sizick crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 49385b0c7657Sizick crypto_object_attribute_t *public_key_template, 49395b0c7657Sizick uint_t public_key_attribute_count, 49405b0c7657Sizick crypto_object_attribute_t *private_key_template, 49415b0c7657Sizick uint_t private_key_attribute_count, 49425b0c7657Sizick crypto_object_attribute_t *out_public_key_template, 49435b0c7657Sizick uint_t out_public_key_attribute_count, 49445b0c7657Sizick crypto_object_attribute_t *out_private_key_template, 49455b0c7657Sizick uint_t out_private_key_attribute_count, 49465b0c7657Sizick crypto_req_handle_t req) 49475b0c7657Sizick { 49485b0c7657Sizick int error = CRYPTO_FAILED; 49495b0c7657Sizick dprov_state_t *softc = (dprov_state_t *)provider; 49505b0c7657Sizick /* LINTED E_FUNC_SET_NOT_USED */ 49515b0c7657Sizick int instance; 49525b0c7657Sizick 49535b0c7657Sizick instance = ddi_get_instance(softc->ds_dip); 49545b0c7657Sizick DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate_pair: started\n", 49555b0c7657Sizick instance)); 49565b0c7657Sizick 49575b0c7657Sizick /* submit request to the taskq */ 49585b0c7657Sizick error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR, 49595b0c7657Sizick softc, req, session_id, mechanism, public_key_template, 49605b0c7657Sizick public_key_attribute_count, NULL, private_key_template, 49615b0c7657Sizick private_key_attribute_count, NULL, NULL, NULL, 0, 49625b0c7657Sizick out_public_key_template, out_public_key_attribute_count, 49635b0c7657Sizick out_private_key_template, out_private_key_attribute_count); 49645b0c7657Sizick 49655b0c7657Sizick DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate_pair: " 49665b0c7657Sizick "done err = 0x0%x\n", instance, error)); 49675b0c7657Sizick 49685b0c7657Sizick return (error); 49695b0c7657Sizick } 49705b0c7657Sizick 49715b0c7657Sizick static int 49725b0c7657Sizick dprov_nostore_key_derive(crypto_provider_handle_t provider, 49735b0c7657Sizick crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 49745b0c7657Sizick crypto_key_t *base_key, crypto_object_attribute_t *template, 49755b0c7657Sizick uint_t attribute_count, crypto_object_attribute_t *out_template, 49765b0c7657Sizick uint_t out_attribute_count, crypto_req_handle_t req) 49775b0c7657Sizick { 49785b0c7657Sizick int error = CRYPTO_FAILED; 49795b0c7657Sizick dprov_state_t *softc = (dprov_state_t *)provider; 49805b0c7657Sizick /* LINTED E_FUNC_SET_NOT_USED */ 49815b0c7657Sizick int instance; 49825b0c7657Sizick 49835b0c7657Sizick instance = ddi_get_instance(softc->ds_dip); 49845b0c7657Sizick DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_derive: started\n", 49855b0c7657Sizick instance)); 49865b0c7657Sizick 49875b0c7657Sizick /* submit request to the taskq */ 49885b0c7657Sizick error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_DERIVE, softc, req, 49895b0c7657Sizick session_id, mechanism, template, attribute_count, NULL, NULL, 49905b0c7657Sizick 0, NULL, base_key, NULL, 0, out_template, out_attribute_count, 49915b0c7657Sizick NULL, 0); 49925b0c7657Sizick 49935b0c7657Sizick DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_derive: " 49945b0c7657Sizick "done err = 0x0%x\n", instance, error)); 49955b0c7657Sizick 49965b0c7657Sizick return (error); 49975b0c7657Sizick } 49985b0c7657Sizick 4999034448feSmcpowers /* 50007c478bd9Sstevel@tonic-gate * Allocate a dprov taskq request and initialize the common fields. 50017c478bd9Sstevel@tonic-gate * Return NULL if the memory allocation failed. 50027c478bd9Sstevel@tonic-gate */ 50037c478bd9Sstevel@tonic-gate static dprov_req_t * 50047c478bd9Sstevel@tonic-gate dprov_alloc_req(dprov_req_type_t req_type, dprov_state_t *softc, 50057c478bd9Sstevel@tonic-gate crypto_req_handle_t kcf_req, int kmflag) 50067c478bd9Sstevel@tonic-gate { 50077c478bd9Sstevel@tonic-gate dprov_req_t *taskq_req; 50087c478bd9Sstevel@tonic-gate 50097c478bd9Sstevel@tonic-gate if ((taskq_req = kmem_alloc(sizeof (dprov_req_t), kmflag)) == NULL) 50107c478bd9Sstevel@tonic-gate return (NULL); 50117c478bd9Sstevel@tonic-gate 50127c478bd9Sstevel@tonic-gate taskq_req->dr_type = req_type; 50137c478bd9Sstevel@tonic-gate taskq_req->dr_softc = softc; 50147c478bd9Sstevel@tonic-gate taskq_req->dr_kcf_req = kcf_req; 50157c478bd9Sstevel@tonic-gate 50167c478bd9Sstevel@tonic-gate return (taskq_req); 50177c478bd9Sstevel@tonic-gate } 50187c478bd9Sstevel@tonic-gate 50197c478bd9Sstevel@tonic-gate /* 50207c478bd9Sstevel@tonic-gate * Dispatch a dprov request on the taskq associated with a softc. 50217c478bd9Sstevel@tonic-gate * Returns CRYPTO_HOST_MEMORY if the request cannot be queued, 50227c478bd9Sstevel@tonic-gate * CRYPTO_QUEUED on success. 50237c478bd9Sstevel@tonic-gate */ 50247c478bd9Sstevel@tonic-gate static int 50257c478bd9Sstevel@tonic-gate dprov_taskq_dispatch(dprov_state_t *softc, dprov_req_t *taskq_req, 50267c478bd9Sstevel@tonic-gate task_func_t *func, int kmflag) 50277c478bd9Sstevel@tonic-gate { 50287c478bd9Sstevel@tonic-gate if (taskq_dispatch(softc->ds_taskq, func, taskq_req, 50297c478bd9Sstevel@tonic-gate kmflag == KM_NOSLEEP ? TQ_NOSLEEP : TQ_SLEEP) == (taskqid_t)0) { 50307c478bd9Sstevel@tonic-gate kmem_free(taskq_req, sizeof (dprov_req_t)); 50317c478bd9Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 50327c478bd9Sstevel@tonic-gate } else 50337c478bd9Sstevel@tonic-gate return (CRYPTO_QUEUED); 50347c478bd9Sstevel@tonic-gate } 50357c478bd9Sstevel@tonic-gate 50367c478bd9Sstevel@tonic-gate /* 50377c478bd9Sstevel@tonic-gate * Helper function to submit digest operations to the taskq. 50387c478bd9Sstevel@tonic-gate * Returns one of the CRYPTO_ errors. 50397c478bd9Sstevel@tonic-gate */ 50407c478bd9Sstevel@tonic-gate static int 50417c478bd9Sstevel@tonic-gate dprov_digest_submit_req(dprov_req_type_t req_type, 50427c478bd9Sstevel@tonic-gate dprov_state_t *softc, crypto_req_handle_t req, 50437c478bd9Sstevel@tonic-gate crypto_mechanism_t *mechanism, crypto_data_t *data, crypto_key_t *key, 50447c478bd9Sstevel@tonic-gate crypto_data_t *digest, crypto_ctx_t *ctx, int kmflag) 50457c478bd9Sstevel@tonic-gate { 50467c478bd9Sstevel@tonic-gate dprov_req_t *taskq_req; 50477c478bd9Sstevel@tonic-gate 50487c478bd9Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL) 50497c478bd9Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 50507c478bd9Sstevel@tonic-gate 50517c478bd9Sstevel@tonic-gate taskq_req->dr_digest_req.dr_mechanism = mechanism; 50527c478bd9Sstevel@tonic-gate taskq_req->dr_digest_req.dr_ctx = ctx; 50537c478bd9Sstevel@tonic-gate taskq_req->dr_digest_req.dr_data = data; 50547c478bd9Sstevel@tonic-gate taskq_req->dr_digest_req.dr_key = key; 50557c478bd9Sstevel@tonic-gate taskq_req->dr_digest_req.dr_digest = digest; 50567c478bd9Sstevel@tonic-gate 50577c478bd9Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req, 50587c478bd9Sstevel@tonic-gate (task_func_t *)dprov_digest_task, kmflag)); 50597c478bd9Sstevel@tonic-gate } 50607c478bd9Sstevel@tonic-gate 50617c478bd9Sstevel@tonic-gate /* 50627c478bd9Sstevel@tonic-gate * Helper function to submit mac operations to the taskq. 50637c478bd9Sstevel@tonic-gate * Returns one of the CRYPTO_ errors. 50647c478bd9Sstevel@tonic-gate */ 50657c478bd9Sstevel@tonic-gate static int 50667c478bd9Sstevel@tonic-gate dprov_mac_submit_req(dprov_req_type_t req_type, 50677c478bd9Sstevel@tonic-gate dprov_state_t *softc, crypto_req_handle_t req, 50687c478bd9Sstevel@tonic-gate crypto_mechanism_t *mechanism, crypto_data_t *data, crypto_key_t *key, 50697c478bd9Sstevel@tonic-gate crypto_data_t *mac, crypto_ctx_t *ctx, crypto_session_id_t sid, int kmflag) 50707c478bd9Sstevel@tonic-gate { 50717c478bd9Sstevel@tonic-gate dprov_req_t *taskq_req; 50727c478bd9Sstevel@tonic-gate 50737c478bd9Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL) 50747c478bd9Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 50757c478bd9Sstevel@tonic-gate 50767c478bd9Sstevel@tonic-gate taskq_req->dr_mac_req.dr_mechanism = mechanism; 50777c478bd9Sstevel@tonic-gate taskq_req->dr_mac_req.dr_ctx = ctx; 50787c478bd9Sstevel@tonic-gate taskq_req->dr_mac_req.dr_data = data; 50797c478bd9Sstevel@tonic-gate taskq_req->dr_mac_req.dr_key = key; 50807c478bd9Sstevel@tonic-gate taskq_req->dr_mac_req.dr_mac = mac; 50817c478bd9Sstevel@tonic-gate taskq_req->dr_mac_req.dr_session_id = sid; 50827c478bd9Sstevel@tonic-gate 50837c478bd9Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req, 50847c478bd9Sstevel@tonic-gate (task_func_t *)dprov_mac_task, kmflag)); 50857c478bd9Sstevel@tonic-gate } 50867c478bd9Sstevel@tonic-gate 50877c478bd9Sstevel@tonic-gate /* 50887c478bd9Sstevel@tonic-gate * Helper function to submit sign operations to the taskq. 50897c478bd9Sstevel@tonic-gate * Returns one of the CRYPTO_ errors. 50907c478bd9Sstevel@tonic-gate */ 50917c478bd9Sstevel@tonic-gate static int 50927c478bd9Sstevel@tonic-gate dprov_sign_submit_req(dprov_req_type_t req_type, 50937c478bd9Sstevel@tonic-gate dprov_state_t *softc, crypto_req_handle_t req, 50947c478bd9Sstevel@tonic-gate crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data, 50957c478bd9Sstevel@tonic-gate crypto_data_t *signature, crypto_ctx_t *ctx, crypto_session_id_t sid, 50967c478bd9Sstevel@tonic-gate int kmflag) 50977c478bd9Sstevel@tonic-gate { 50987c478bd9Sstevel@tonic-gate dprov_req_t *taskq_req; 50997c478bd9Sstevel@tonic-gate 51007c478bd9Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL) 51017c478bd9Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 51027c478bd9Sstevel@tonic-gate 51037c478bd9Sstevel@tonic-gate taskq_req->dr_sign_req.sr_mechanism = mechanism; 51047c478bd9Sstevel@tonic-gate taskq_req->dr_sign_req.sr_ctx = ctx; 51057c478bd9Sstevel@tonic-gate taskq_req->dr_sign_req.sr_key = key; 51067c478bd9Sstevel@tonic-gate taskq_req->dr_sign_req.sr_data = data; 51077c478bd9Sstevel@tonic-gate taskq_req->dr_sign_req.sr_signature = signature; 51087c478bd9Sstevel@tonic-gate taskq_req->dr_sign_req.sr_session_id = sid; 51097c478bd9Sstevel@tonic-gate 51107c478bd9Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req, 51117c478bd9Sstevel@tonic-gate (task_func_t *)dprov_sign_task, kmflag)); 51127c478bd9Sstevel@tonic-gate } 51137c478bd9Sstevel@tonic-gate 51147c478bd9Sstevel@tonic-gate /* 51157c478bd9Sstevel@tonic-gate * Helper function to submit verify operations to the taskq. 51167c478bd9Sstevel@tonic-gate * Returns one of the CRYPTO_ errors. 51177c478bd9Sstevel@tonic-gate */ 51187c478bd9Sstevel@tonic-gate static int 51197c478bd9Sstevel@tonic-gate dprov_verify_submit_req(dprov_req_type_t req_type, 51207c478bd9Sstevel@tonic-gate dprov_state_t *softc, crypto_req_handle_t req, 51217c478bd9Sstevel@tonic-gate crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data, 51227c478bd9Sstevel@tonic-gate crypto_data_t *signature, crypto_ctx_t *ctx, crypto_session_id_t sid, 51237c478bd9Sstevel@tonic-gate int kmflag) 51247c478bd9Sstevel@tonic-gate { 51257c478bd9Sstevel@tonic-gate dprov_req_t *taskq_req; 51267c478bd9Sstevel@tonic-gate 51277c478bd9Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL) 51287c478bd9Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 51297c478bd9Sstevel@tonic-gate 51307c478bd9Sstevel@tonic-gate taskq_req->dr_verify_req.vr_mechanism = mechanism; 51317c478bd9Sstevel@tonic-gate taskq_req->dr_verify_req.vr_ctx = ctx; 51327c478bd9Sstevel@tonic-gate taskq_req->dr_verify_req.vr_key = key; 51337c478bd9Sstevel@tonic-gate taskq_req->dr_verify_req.vr_data = data; 51347c478bd9Sstevel@tonic-gate taskq_req->dr_verify_req.vr_signature = signature; 51357c478bd9Sstevel@tonic-gate taskq_req->dr_verify_req.vr_session_id = sid; 51367c478bd9Sstevel@tonic-gate 51377c478bd9Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req, 51387c478bd9Sstevel@tonic-gate (task_func_t *)dprov_verify_task, kmflag)); 51397c478bd9Sstevel@tonic-gate } 51407c478bd9Sstevel@tonic-gate 51417c478bd9Sstevel@tonic-gate /* 51427c478bd9Sstevel@tonic-gate * Helper function to submit dual operations to the taskq. 51437c478bd9Sstevel@tonic-gate * Returns one of the CRYPTO_ errors. 51447c478bd9Sstevel@tonic-gate */ 51457c478bd9Sstevel@tonic-gate static int 51467c478bd9Sstevel@tonic-gate dprov_dual_submit_req(dprov_req_type_t req_type, dprov_state_t *softc, 51477c478bd9Sstevel@tonic-gate crypto_req_handle_t req, crypto_ctx_t *signverify_ctx, 51487c478bd9Sstevel@tonic-gate crypto_ctx_t *cipher_ctx, crypto_data_t *plaintext, 51497c478bd9Sstevel@tonic-gate crypto_data_t *ciphertext) 51507c478bd9Sstevel@tonic-gate { 51517c478bd9Sstevel@tonic-gate dprov_req_t *taskq_req; 51527c478bd9Sstevel@tonic-gate 51537c478bd9Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req, 51547c478bd9Sstevel@tonic-gate KM_NOSLEEP)) == NULL) 51557c478bd9Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 51567c478bd9Sstevel@tonic-gate 51577c478bd9Sstevel@tonic-gate taskq_req->dr_dual_req.dr_signverify_ctx = signverify_ctx; 51587c478bd9Sstevel@tonic-gate taskq_req->dr_dual_req.dr_cipher_ctx = cipher_ctx; 51597c478bd9Sstevel@tonic-gate taskq_req->dr_dual_req.dr_plaintext = plaintext; 51607c478bd9Sstevel@tonic-gate taskq_req->dr_dual_req.dr_ciphertext = ciphertext; 51617c478bd9Sstevel@tonic-gate 51627c478bd9Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req, 51637c478bd9Sstevel@tonic-gate (task_func_t *)dprov_dual_task, KM_NOSLEEP)); 51647c478bd9Sstevel@tonic-gate } 51657c478bd9Sstevel@tonic-gate 51667c478bd9Sstevel@tonic-gate /* 51677c478bd9Sstevel@tonic-gate * Helper function to submit dual cipher/mac operations to the taskq. 51687c478bd9Sstevel@tonic-gate * Returns one of the CRYPTO_ errors. 51697c478bd9Sstevel@tonic-gate */ 51707c478bd9Sstevel@tonic-gate static int 51717c478bd9Sstevel@tonic-gate dprov_cipher_mac_submit_req(dprov_req_type_t req_type, 51727c478bd9Sstevel@tonic-gate dprov_state_t *softc, crypto_req_handle_t req, crypto_ctx_t *ctx, 51737c478bd9Sstevel@tonic-gate crypto_session_id_t sid, crypto_mechanism_t *cipher_mech, 51747c478bd9Sstevel@tonic-gate crypto_key_t *cipher_key, crypto_mechanism_t *mac_mech, 51757c478bd9Sstevel@tonic-gate crypto_key_t *mac_key, crypto_dual_data_t *dual_data, 51767c478bd9Sstevel@tonic-gate crypto_data_t *data, crypto_data_t *mac, int kmflag) 51777c478bd9Sstevel@tonic-gate { 51787c478bd9Sstevel@tonic-gate dprov_req_t *taskq_req; 51797c478bd9Sstevel@tonic-gate 51807c478bd9Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL) 51817c478bd9Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 51827c478bd9Sstevel@tonic-gate 51837c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_session_id = sid; 51847c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_ctx = ctx; 51857c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_cipher_mech = cipher_mech; 51867c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_cipher_key = cipher_key; 51877c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_mac_mech = mac_mech; 51887c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_mac_key = mac_key; 51897c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_dual_data = dual_data; 51907c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_data = data; 51917c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_mac = mac; 51927c478bd9Sstevel@tonic-gate 51937c478bd9Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req, 51947c478bd9Sstevel@tonic-gate (task_func_t *)dprov_cipher_mac_task, kmflag)); 51957c478bd9Sstevel@tonic-gate } 51967c478bd9Sstevel@tonic-gate 51977c478bd9Sstevel@tonic-gate /* 51987c478bd9Sstevel@tonic-gate * Helper function to submit cipher operations to the taskq. 51997c478bd9Sstevel@tonic-gate * Returns one of the CRYPTO_ errors. 52007c478bd9Sstevel@tonic-gate */ 52017c478bd9Sstevel@tonic-gate static int 52027c478bd9Sstevel@tonic-gate dprov_cipher_submit_req(dprov_req_type_t req_type, 52037c478bd9Sstevel@tonic-gate dprov_state_t *softc, crypto_req_handle_t req, 52047c478bd9Sstevel@tonic-gate crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *plaintext, 52057c478bd9Sstevel@tonic-gate crypto_data_t *ciphertext, crypto_ctx_t *ctx, crypto_session_id_t sid, 52067c478bd9Sstevel@tonic-gate int kmflag) 52077c478bd9Sstevel@tonic-gate { 52087c478bd9Sstevel@tonic-gate dprov_req_t *taskq_req; 52097c478bd9Sstevel@tonic-gate 52107c478bd9Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL) 52117c478bd9Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 52127c478bd9Sstevel@tonic-gate 52137c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_mechanism = mechanism; 52147c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_ctx = ctx; 52157c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_key = key; 52167c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_plaintext = plaintext; 52177c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_ciphertext = ciphertext; 52187c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_session_id = sid; 52197c478bd9Sstevel@tonic-gate 52207c478bd9Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req, 52217c478bd9Sstevel@tonic-gate (task_func_t *)dprov_cipher_task, kmflag)); 52227c478bd9Sstevel@tonic-gate } 52237c478bd9Sstevel@tonic-gate 52247c478bd9Sstevel@tonic-gate /* 52257c478bd9Sstevel@tonic-gate * Helper function to submit random number operations to the taskq. 52267c478bd9Sstevel@tonic-gate * Returns one of the CRYPTO_ errors. 52277c478bd9Sstevel@tonic-gate */ 52287c478bd9Sstevel@tonic-gate static int 52297c478bd9Sstevel@tonic-gate dprov_random_submit_req(dprov_req_type_t req_type, 52307c478bd9Sstevel@tonic-gate dprov_state_t *softc, crypto_req_handle_t req, uchar_t *buf, size_t len, 52318047c9fbSmcpowers crypto_session_id_t sid, uint_t entropy_est, uint32_t flags) 52327c478bd9Sstevel@tonic-gate { 52337c478bd9Sstevel@tonic-gate dprov_req_t *taskq_req; 52347c478bd9Sstevel@tonic-gate 52357c478bd9Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req, 52367c478bd9Sstevel@tonic-gate KM_NOSLEEP)) == NULL) 52377c478bd9Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 52387c478bd9Sstevel@tonic-gate 52397c478bd9Sstevel@tonic-gate taskq_req->dr_random_req.rr_buf = buf; 52407c478bd9Sstevel@tonic-gate taskq_req->dr_random_req.rr_len = len; 52417c478bd9Sstevel@tonic-gate taskq_req->dr_random_req.rr_session_id = sid; 52428047c9fbSmcpowers taskq_req->dr_random_req.rr_entropy_est = entropy_est; 52438047c9fbSmcpowers taskq_req->dr_random_req.rr_flags = flags; 52447c478bd9Sstevel@tonic-gate 52457c478bd9Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req, 52467c478bd9Sstevel@tonic-gate (task_func_t *)dprov_random_task, KM_NOSLEEP)); 52477c478bd9Sstevel@tonic-gate } 52487c478bd9Sstevel@tonic-gate 52497c478bd9Sstevel@tonic-gate 52507c478bd9Sstevel@tonic-gate /* 52517c478bd9Sstevel@tonic-gate * Helper function to submit session management operations to the taskq. 52527c478bd9Sstevel@tonic-gate * Returns one of the CRYPTO_ errors. 52537c478bd9Sstevel@tonic-gate */ 52547c478bd9Sstevel@tonic-gate static int 52557c478bd9Sstevel@tonic-gate dprov_session_submit_req(dprov_req_type_t req_type, 52567c478bd9Sstevel@tonic-gate dprov_state_t *softc, crypto_req_handle_t req, 52577c478bd9Sstevel@tonic-gate crypto_session_id_t *session_id_ptr, crypto_session_id_t session_id, 52587c478bd9Sstevel@tonic-gate crypto_user_type_t user_type, char *pin, size_t pin_len) 52597c478bd9Sstevel@tonic-gate { 52607c478bd9Sstevel@tonic-gate dprov_req_t *taskq_req; 52617c478bd9Sstevel@tonic-gate 52627c478bd9Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req, 52637c478bd9Sstevel@tonic-gate KM_NOSLEEP)) == NULL) 52647c478bd9Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 52657c478bd9Sstevel@tonic-gate 52667c478bd9Sstevel@tonic-gate taskq_req->dr_session_req.sr_session_id_ptr = session_id_ptr; 52677c478bd9Sstevel@tonic-gate taskq_req->dr_session_req.sr_session_id = session_id; 52687c478bd9Sstevel@tonic-gate taskq_req->dr_session_req.sr_user_type = user_type; 52697c478bd9Sstevel@tonic-gate taskq_req->dr_session_req.sr_pin = pin; 52707c478bd9Sstevel@tonic-gate taskq_req->dr_session_req.sr_pin_len = pin_len; 52717c478bd9Sstevel@tonic-gate 52727c478bd9Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req, 52737c478bd9Sstevel@tonic-gate (task_func_t *)dprov_session_task, KM_NOSLEEP)); 52747c478bd9Sstevel@tonic-gate } 52757c478bd9Sstevel@tonic-gate 52767c478bd9Sstevel@tonic-gate /* 52777c478bd9Sstevel@tonic-gate * Helper function to submit object management operations to the taskq. 52787c478bd9Sstevel@tonic-gate * Returns one of the CRYPTO_ errors. 52797c478bd9Sstevel@tonic-gate */ 52807c478bd9Sstevel@tonic-gate static int 52817c478bd9Sstevel@tonic-gate dprov_object_submit_req(dprov_req_type_t req_type, 52827c478bd9Sstevel@tonic-gate dprov_state_t *softc, crypto_req_handle_t req, 52837c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_object_id_t object_id, 52847c478bd9Sstevel@tonic-gate crypto_object_attribute_t *template, uint_t attribute_count, 52857c478bd9Sstevel@tonic-gate crypto_object_id_t *object_id_ptr, size_t *object_size, 52867c478bd9Sstevel@tonic-gate void **find_pp, void *find_p, uint_t max_object_count, 52877c478bd9Sstevel@tonic-gate uint_t *object_count_ptr, int kmflag) 52887c478bd9Sstevel@tonic-gate { 52897c478bd9Sstevel@tonic-gate dprov_req_t *taskq_req; 52907c478bd9Sstevel@tonic-gate 52917c478bd9Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req, 52927c478bd9Sstevel@tonic-gate kmflag)) == NULL) 52937c478bd9Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 52947c478bd9Sstevel@tonic-gate 52957c478bd9Sstevel@tonic-gate taskq_req->dr_object_req.or_session_id = session_id; 52967c478bd9Sstevel@tonic-gate taskq_req->dr_object_req.or_object_id = object_id; 52977c478bd9Sstevel@tonic-gate taskq_req->dr_object_req.or_template = template; 52987c478bd9Sstevel@tonic-gate taskq_req->dr_object_req.or_attribute_count = attribute_count; 52997c478bd9Sstevel@tonic-gate taskq_req->dr_object_req.or_object_id_ptr = object_id_ptr; 53007c478bd9Sstevel@tonic-gate taskq_req->dr_object_req.or_object_size = object_size; 53017c478bd9Sstevel@tonic-gate taskq_req->dr_object_req.or_find_pp = find_pp; 53027c478bd9Sstevel@tonic-gate taskq_req->dr_object_req.or_find_p = find_p; 53037c478bd9Sstevel@tonic-gate taskq_req->dr_object_req.or_max_object_count = max_object_count; 53047c478bd9Sstevel@tonic-gate taskq_req->dr_object_req.or_object_count_ptr = object_count_ptr; 53057c478bd9Sstevel@tonic-gate 53067c478bd9Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req, 53077c478bd9Sstevel@tonic-gate (task_func_t *)dprov_object_task, KM_NOSLEEP)); 53087c478bd9Sstevel@tonic-gate } 53097c478bd9Sstevel@tonic-gate 53107c478bd9Sstevel@tonic-gate /* 53117c478bd9Sstevel@tonic-gate * Helper function to submit key management operations to the taskq. 53127c478bd9Sstevel@tonic-gate * Returns one of the CRYPTO_ errors. 53137c478bd9Sstevel@tonic-gate */ 53147c478bd9Sstevel@tonic-gate static int 53157c478bd9Sstevel@tonic-gate dprov_key_submit_req(dprov_req_type_t req_type, 53167c478bd9Sstevel@tonic-gate dprov_state_t *softc, crypto_req_handle_t req, 53177c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 53187c478bd9Sstevel@tonic-gate crypto_object_attribute_t *template, uint_t attribute_count, 53197c478bd9Sstevel@tonic-gate crypto_object_id_t *object_id_ptr, 53207c478bd9Sstevel@tonic-gate crypto_object_attribute_t *private_key_template, 53217c478bd9Sstevel@tonic-gate uint_t private_key_attribute_count, 53227c478bd9Sstevel@tonic-gate crypto_object_id_t *private_key_object_id_ptr, crypto_key_t *key, 5323034448feSmcpowers uchar_t *wrapped_key, size_t *wrapped_key_len_ptr, 5324034448feSmcpowers crypto_object_attribute_t *out_template1, uint_t out_attribute_count1, 5325034448feSmcpowers crypto_object_attribute_t *out_template2, uint_t out_attribute_count2) 53267c478bd9Sstevel@tonic-gate { 53277c478bd9Sstevel@tonic-gate dprov_req_t *taskq_req; 53287c478bd9Sstevel@tonic-gate 53297c478bd9Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req, 53307c478bd9Sstevel@tonic-gate KM_NOSLEEP)) == NULL) 53317c478bd9Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 53327c478bd9Sstevel@tonic-gate 53337c478bd9Sstevel@tonic-gate taskq_req->dr_key_req.kr_session_id = session_id; 53347c478bd9Sstevel@tonic-gate taskq_req->dr_key_req.kr_mechanism = mechanism; 53357c478bd9Sstevel@tonic-gate taskq_req->dr_key_req.kr_template = template; 53367c478bd9Sstevel@tonic-gate taskq_req->dr_key_req.kr_attribute_count = attribute_count; 53377c478bd9Sstevel@tonic-gate taskq_req->dr_key_req.kr_object_id_ptr = object_id_ptr; 53387c478bd9Sstevel@tonic-gate taskq_req->dr_key_req.kr_private_key_template = private_key_template; 53397c478bd9Sstevel@tonic-gate taskq_req->dr_key_req.kr_private_key_attribute_count = 53407c478bd9Sstevel@tonic-gate private_key_attribute_count; 53417c478bd9Sstevel@tonic-gate taskq_req->dr_key_req.kr_private_key_object_id_ptr = 53427c478bd9Sstevel@tonic-gate private_key_object_id_ptr; 53437c478bd9Sstevel@tonic-gate taskq_req->dr_key_req.kr_key = key; 53447c478bd9Sstevel@tonic-gate taskq_req->dr_key_req.kr_wrapped_key = wrapped_key; 53457c478bd9Sstevel@tonic-gate taskq_req->dr_key_req.kr_wrapped_key_len_ptr = wrapped_key_len_ptr; 5346034448feSmcpowers taskq_req->dr_key_req.kr_out_template1 = out_template1; 5347034448feSmcpowers taskq_req->dr_key_req.kr_out_attribute_count1 = out_attribute_count1; 5348034448feSmcpowers taskq_req->dr_key_req.kr_out_template2 = out_template2; 5349034448feSmcpowers taskq_req->dr_key_req.kr_out_attribute_count2 = out_attribute_count2; 53507c478bd9Sstevel@tonic-gate 53517c478bd9Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req, 53527c478bd9Sstevel@tonic-gate (task_func_t *)dprov_key_task, KM_NOSLEEP)); 53537c478bd9Sstevel@tonic-gate } 53547c478bd9Sstevel@tonic-gate 53557c478bd9Sstevel@tonic-gate /* 53567c478bd9Sstevel@tonic-gate * Helper function to submit provider management operations to the taskq. 53577c478bd9Sstevel@tonic-gate * Returns one of the CRYPTO_ errors. 53587c478bd9Sstevel@tonic-gate */ 53597c478bd9Sstevel@tonic-gate static int 53607c478bd9Sstevel@tonic-gate dprov_mgmt_submit_req(dprov_req_type_t req_type, 53617c478bd9Sstevel@tonic-gate dprov_state_t *softc, crypto_req_handle_t req, 53627c478bd9Sstevel@tonic-gate crypto_session_id_t session_id, char *pin, size_t pin_len, 53637c478bd9Sstevel@tonic-gate char *old_pin, size_t old_pin_len, char *label, 53647c478bd9Sstevel@tonic-gate crypto_provider_ext_info_t *ext_info) 53657c478bd9Sstevel@tonic-gate { 53667c478bd9Sstevel@tonic-gate dprov_req_t *taskq_req; 53677c478bd9Sstevel@tonic-gate 53687c478bd9Sstevel@tonic-gate if ((taskq_req = dprov_alloc_req(req_type, softc, req, 53697c478bd9Sstevel@tonic-gate KM_NOSLEEP)) == NULL) 53707c478bd9Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 53717c478bd9Sstevel@tonic-gate 53727c478bd9Sstevel@tonic-gate taskq_req->dr_mgmt_req.mr_session_id = session_id; 53737c478bd9Sstevel@tonic-gate taskq_req->dr_mgmt_req.mr_pin = pin; 53747c478bd9Sstevel@tonic-gate taskq_req->dr_mgmt_req.mr_pin_len = pin_len; 53757c478bd9Sstevel@tonic-gate taskq_req->dr_mgmt_req.mr_old_pin = old_pin; 53767c478bd9Sstevel@tonic-gate taskq_req->dr_mgmt_req.mr_old_pin_len = old_pin_len; 53777c478bd9Sstevel@tonic-gate taskq_req->dr_mgmt_req.mr_label = label; 53787c478bd9Sstevel@tonic-gate taskq_req->dr_mgmt_req.mr_ext_info = ext_info; 53797c478bd9Sstevel@tonic-gate 53807c478bd9Sstevel@tonic-gate return (dprov_taskq_dispatch(softc, taskq_req, 53817c478bd9Sstevel@tonic-gate (task_func_t *)dprov_mgmt_task, KM_NOSLEEP)); 53827c478bd9Sstevel@tonic-gate } 53837c478bd9Sstevel@tonic-gate 53847c478bd9Sstevel@tonic-gate /* 53857c478bd9Sstevel@tonic-gate * Helper function for taskq dispatcher routines. Notify the framework 53867c478bd9Sstevel@tonic-gate * that the operation corresponding to the specified request is done, 53877c478bd9Sstevel@tonic-gate * and pass it the error code. Finally, free the taskq_req. 53887c478bd9Sstevel@tonic-gate */ 53897c478bd9Sstevel@tonic-gate static void 53907c478bd9Sstevel@tonic-gate dprov_op_done(dprov_req_t *taskq_req, int error) 53917c478bd9Sstevel@tonic-gate { 53927c478bd9Sstevel@tonic-gate /* notify framework that request is completed */ 53937c478bd9Sstevel@tonic-gate crypto_op_notification(taskq_req->dr_kcf_req, error); 53947c478bd9Sstevel@tonic-gate 53957c478bd9Sstevel@tonic-gate /* free taskq request structure */ 53967c478bd9Sstevel@tonic-gate kmem_free(taskq_req, sizeof (dprov_req_t)); 53977c478bd9Sstevel@tonic-gate } 53987c478bd9Sstevel@tonic-gate 53997c478bd9Sstevel@tonic-gate /* 54007c478bd9Sstevel@tonic-gate * taskq dispatcher function for digest operations. 54017c478bd9Sstevel@tonic-gate */ 54027c478bd9Sstevel@tonic-gate static void 54037c478bd9Sstevel@tonic-gate dprov_digest_task(dprov_req_t *taskq_req) 54047c478bd9Sstevel@tonic-gate { 54057c478bd9Sstevel@tonic-gate kcf_provider_desc_t *pd; 54067c478bd9Sstevel@tonic-gate dprov_state_t *softc; 54077c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 54087c478bd9Sstevel@tonic-gate int instance; 54097c478bd9Sstevel@tonic-gate int error = CRYPTO_NOT_SUPPORTED; 54107c478bd9Sstevel@tonic-gate crypto_ctx_t *ctx = taskq_req->dr_digest_req.dr_ctx; 54117c478bd9Sstevel@tonic-gate crypto_mechanism_t mech; 54127c478bd9Sstevel@tonic-gate 54137c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 54147c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_task: started\n", instance)); 54157c478bd9Sstevel@tonic-gate 54167c478bd9Sstevel@tonic-gate switch (taskq_req->dr_type) { 54177c478bd9Sstevel@tonic-gate 54187c478bd9Sstevel@tonic-gate case DPROV_REQ_DIGEST_INIT: 54197c478bd9Sstevel@tonic-gate /* allocate a dprov-private context */ 54207c478bd9Sstevel@tonic-gate if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) != 54217c478bd9Sstevel@tonic-gate CRYPTO_SUCCESS) 54227c478bd9Sstevel@tonic-gate break; 54237c478bd9Sstevel@tonic-gate 54247c478bd9Sstevel@tonic-gate /* structure assignment */ 54257c478bd9Sstevel@tonic-gate mech = *taskq_req->dr_digest_req.dr_mechanism; 54267c478bd9Sstevel@tonic-gate 54277c478bd9Sstevel@tonic-gate /* get the software provider for this mechanism */ 54287c478bd9Sstevel@tonic-gate if ((error = dprov_get_sw_prov( 54297c478bd9Sstevel@tonic-gate taskq_req->dr_digest_req.dr_mechanism, &pd, 54307c478bd9Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS) 54317c478bd9Sstevel@tonic-gate break; 54327c478bd9Sstevel@tonic-gate 54337c478bd9Sstevel@tonic-gate /* Use a session id of zero since we use a software provider */ 54347c478bd9Sstevel@tonic-gate error = crypto_digest_init_prov(pd, 0, &mech, 54357c478bd9Sstevel@tonic-gate &DPROV_CTX_SINGLE(ctx), NULL); 54367c478bd9Sstevel@tonic-gate 54377c478bd9Sstevel@tonic-gate /* release provider reference */ 54387c478bd9Sstevel@tonic-gate KCF_PROV_REFRELE(pd); 54397c478bd9Sstevel@tonic-gate break; 54407c478bd9Sstevel@tonic-gate 54417c478bd9Sstevel@tonic-gate case DPROV_REQ_DIGEST: 54427c478bd9Sstevel@tonic-gate error = crypto_digest_single(DPROV_CTX_SINGLE(ctx), 54437c478bd9Sstevel@tonic-gate taskq_req->dr_digest_req.dr_data, 54447c478bd9Sstevel@tonic-gate taskq_req->dr_digest_req.dr_digest, NULL); 54457c478bd9Sstevel@tonic-gate 54467c478bd9Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) { 54477c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL; 54487c478bd9Sstevel@tonic-gate (void) dprov_free_context(ctx); 54497c478bd9Sstevel@tonic-gate } 54507c478bd9Sstevel@tonic-gate break; 54517c478bd9Sstevel@tonic-gate 54527c478bd9Sstevel@tonic-gate case DPROV_REQ_DIGEST_UPDATE: 54537c478bd9Sstevel@tonic-gate error = crypto_digest_update(DPROV_CTX_SINGLE(ctx), 54547c478bd9Sstevel@tonic-gate taskq_req->dr_digest_req.dr_data, NULL); 54557c478bd9Sstevel@tonic-gate break; 54567c478bd9Sstevel@tonic-gate 54577c478bd9Sstevel@tonic-gate case DPROV_REQ_DIGEST_KEY: { 54587c478bd9Sstevel@tonic-gate crypto_data_t data; 54597c478bd9Sstevel@tonic-gate crypto_key_t key; 54607c478bd9Sstevel@tonic-gate size_t len; 54617c478bd9Sstevel@tonic-gate 54627c478bd9Sstevel@tonic-gate mutex_enter(&softc->ds_lock); 54637c478bd9Sstevel@tonic-gate error = dprov_key_value_secret(softc, ctx->cc_session, 54647c478bd9Sstevel@tonic-gate taskq_req->dr_type, taskq_req->dr_digest_req.dr_key, &key); 54657c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 54667c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) 54677c478bd9Sstevel@tonic-gate break; 54687c478bd9Sstevel@tonic-gate 54697c478bd9Sstevel@tonic-gate /* key lengths are specified in bits */ 54707c478bd9Sstevel@tonic-gate len = CRYPTO_BITS2BYTES(key.ck_length); 54717c478bd9Sstevel@tonic-gate data.cd_format = CRYPTO_DATA_RAW; 54727c478bd9Sstevel@tonic-gate data.cd_offset = 0; 54737c478bd9Sstevel@tonic-gate data.cd_length = len; 54747c478bd9Sstevel@tonic-gate data.cd_raw.iov_base = key.ck_data; 54757c478bd9Sstevel@tonic-gate data.cd_raw.iov_len = len; 54767c478bd9Sstevel@tonic-gate error = crypto_digest_update(DPROV_CTX_SINGLE(ctx), 54777c478bd9Sstevel@tonic-gate &data, NULL); 54787c478bd9Sstevel@tonic-gate break; 54797c478bd9Sstevel@tonic-gate } 54807c478bd9Sstevel@tonic-gate 54817c478bd9Sstevel@tonic-gate case DPROV_REQ_DIGEST_FINAL: 54827c478bd9Sstevel@tonic-gate error = crypto_digest_final(DPROV_CTX_SINGLE(ctx), 54837c478bd9Sstevel@tonic-gate taskq_req->dr_digest_req.dr_digest, NULL); 54847c478bd9Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) { 54857c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL; 54867c478bd9Sstevel@tonic-gate (void) dprov_free_context(ctx); 54877c478bd9Sstevel@tonic-gate } 54887c478bd9Sstevel@tonic-gate break; 54897c478bd9Sstevel@tonic-gate 54907c478bd9Sstevel@tonic-gate case DPROV_REQ_DIGEST_ATOMIC: 54917c478bd9Sstevel@tonic-gate /* structure assignment */ 54927c478bd9Sstevel@tonic-gate mech = *taskq_req->dr_digest_req.dr_mechanism; 54937c478bd9Sstevel@tonic-gate 54947c478bd9Sstevel@tonic-gate /* get the software provider for this mechanism */ 54957c478bd9Sstevel@tonic-gate if ((error = dprov_get_sw_prov( 54967c478bd9Sstevel@tonic-gate taskq_req->dr_digest_req.dr_mechanism, &pd, 54977c478bd9Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS) 54987c478bd9Sstevel@tonic-gate break; 54997c478bd9Sstevel@tonic-gate 55007c478bd9Sstevel@tonic-gate /* use a session id of zero since we use a software provider */ 5501894b2776Smcpowers error = crypto_digest_prov(pd, 0, &mech, 55027c478bd9Sstevel@tonic-gate taskq_req->dr_digest_req.dr_data, 5503894b2776Smcpowers taskq_req->dr_digest_req.dr_digest, NULL); 55047c478bd9Sstevel@tonic-gate 55057c478bd9Sstevel@tonic-gate /* release provider reference */ 55067c478bd9Sstevel@tonic-gate KCF_PROV_REFRELE(pd); 55077c478bd9Sstevel@tonic-gate 55087c478bd9Sstevel@tonic-gate break; 55097c478bd9Sstevel@tonic-gate } 55107c478bd9Sstevel@tonic-gate 55117c478bd9Sstevel@tonic-gate dprov_op_done(taskq_req, error); 55127c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_task: end\n", instance)); 55137c478bd9Sstevel@tonic-gate } 55147c478bd9Sstevel@tonic-gate 55157c478bd9Sstevel@tonic-gate /* 55167c478bd9Sstevel@tonic-gate * taskq dispatcher function for mac operations. 55177c478bd9Sstevel@tonic-gate */ 55187c478bd9Sstevel@tonic-gate static void 55197c478bd9Sstevel@tonic-gate dprov_mac_task(dprov_req_t *taskq_req) 55207c478bd9Sstevel@tonic-gate { 55217c478bd9Sstevel@tonic-gate kcf_provider_desc_t *pd; 55227c478bd9Sstevel@tonic-gate dprov_state_t *softc; 55237c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 55247c478bd9Sstevel@tonic-gate int instance; 55257c478bd9Sstevel@tonic-gate int error = CRYPTO_NOT_SUPPORTED; 55267c478bd9Sstevel@tonic-gate crypto_ctx_t *ctx = taskq_req->dr_mac_req.dr_ctx; 55277c478bd9Sstevel@tonic-gate crypto_key_t key; 55287c478bd9Sstevel@tonic-gate crypto_mechanism_t mech; 55297c478bd9Sstevel@tonic-gate 55307c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 55317c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: started\n", instance)); 55327c478bd9Sstevel@tonic-gate 55337c478bd9Sstevel@tonic-gate switch (taskq_req->dr_type) { 55347c478bd9Sstevel@tonic-gate 55357c478bd9Sstevel@tonic-gate case DPROV_REQ_MAC_INIT: 55367c478bd9Sstevel@tonic-gate /* allocate a dprov-private context */ 55377c478bd9Sstevel@tonic-gate if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) != 55387c478bd9Sstevel@tonic-gate CRYPTO_SUCCESS) 55397c478bd9Sstevel@tonic-gate break; 55407c478bd9Sstevel@tonic-gate 55417c478bd9Sstevel@tonic-gate /* get key value */ 55427c478bd9Sstevel@tonic-gate mutex_enter(&softc->ds_lock); 55437c478bd9Sstevel@tonic-gate error = dprov_key_value_secret(softc, ctx->cc_session, 55447c478bd9Sstevel@tonic-gate taskq_req->dr_type, taskq_req->dr_mac_req.dr_key, &key); 55457c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 55467c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) 55477c478bd9Sstevel@tonic-gate break; 55487c478bd9Sstevel@tonic-gate 55497c478bd9Sstevel@tonic-gate /* structure assignment */ 55507c478bd9Sstevel@tonic-gate mech = *taskq_req->dr_mac_req.dr_mechanism; 55517c478bd9Sstevel@tonic-gate 55527c478bd9Sstevel@tonic-gate /* get the software provider for this mechanism */ 55537c478bd9Sstevel@tonic-gate if ((error = dprov_get_sw_prov( 55547c478bd9Sstevel@tonic-gate taskq_req->dr_mac_req.dr_mechanism, &pd, 55557c478bd9Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS) 55567c478bd9Sstevel@tonic-gate break; 55577c478bd9Sstevel@tonic-gate 55587c478bd9Sstevel@tonic-gate /* Use a session id of zero since we use a software provider */ 55597c478bd9Sstevel@tonic-gate error = crypto_mac_init_prov(pd, 0, &mech, &key, NULL, 55607c478bd9Sstevel@tonic-gate &DPROV_CTX_SINGLE(ctx), NULL); 55617c478bd9Sstevel@tonic-gate 55627c478bd9Sstevel@tonic-gate /* release provider reference */ 55637c478bd9Sstevel@tonic-gate KCF_PROV_REFRELE(pd); 55647c478bd9Sstevel@tonic-gate break; 55657c478bd9Sstevel@tonic-gate 55667c478bd9Sstevel@tonic-gate case DPROV_REQ_MAC: 55677c478bd9Sstevel@tonic-gate error = crypto_mac_single(DPROV_CTX_SINGLE(ctx), 55687c478bd9Sstevel@tonic-gate taskq_req->dr_mac_req.dr_data, 55697c478bd9Sstevel@tonic-gate taskq_req->dr_mac_req.dr_mac, NULL); 55707c478bd9Sstevel@tonic-gate 55717c478bd9Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) { 55727c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL; 55737c478bd9Sstevel@tonic-gate (void) dprov_free_context(ctx); 55747c478bd9Sstevel@tonic-gate } 55757c478bd9Sstevel@tonic-gate break; 55767c478bd9Sstevel@tonic-gate 55777c478bd9Sstevel@tonic-gate case DPROV_REQ_MAC_UPDATE: 55787c478bd9Sstevel@tonic-gate error = crypto_mac_update(DPROV_CTX_SINGLE(ctx), 55797c478bd9Sstevel@tonic-gate taskq_req->dr_mac_req.dr_data, NULL); 55807c478bd9Sstevel@tonic-gate break; 55817c478bd9Sstevel@tonic-gate 55827c478bd9Sstevel@tonic-gate case DPROV_REQ_MAC_FINAL: 55837c478bd9Sstevel@tonic-gate error = crypto_mac_final(DPROV_CTX_SINGLE(ctx), 55847c478bd9Sstevel@tonic-gate taskq_req->dr_mac_req.dr_mac, NULL); 55857c478bd9Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) { 55867c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL; 55877c478bd9Sstevel@tonic-gate (void) dprov_free_context(ctx); 55887c478bd9Sstevel@tonic-gate } 55897c478bd9Sstevel@tonic-gate break; 55907c478bd9Sstevel@tonic-gate 55917c478bd9Sstevel@tonic-gate case DPROV_REQ_MAC_ATOMIC: 55927c478bd9Sstevel@tonic-gate case DPROV_REQ_MAC_VERIFY_ATOMIC: 55937c478bd9Sstevel@tonic-gate /* get key value */ 55947c478bd9Sstevel@tonic-gate mutex_enter(&softc->ds_lock); 55957c478bd9Sstevel@tonic-gate error = dprov_key_value_secret(softc, 55967c478bd9Sstevel@tonic-gate taskq_req->dr_mac_req.dr_session_id, 55977c478bd9Sstevel@tonic-gate taskq_req->dr_type, taskq_req->dr_mac_req.dr_key, &key); 55987c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 55997c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) 56007c478bd9Sstevel@tonic-gate break; 56017c478bd9Sstevel@tonic-gate 56027c478bd9Sstevel@tonic-gate /* structure assignment */ 56037c478bd9Sstevel@tonic-gate mech = *taskq_req->dr_mac_req.dr_mechanism; 56047c478bd9Sstevel@tonic-gate 56057c478bd9Sstevel@tonic-gate /* get the software provider for this mechanism */ 56067c478bd9Sstevel@tonic-gate if ((error = dprov_get_sw_prov( 56077c478bd9Sstevel@tonic-gate taskq_req->dr_mac_req.dr_mechanism, &pd, 56087c478bd9Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS) 56097c478bd9Sstevel@tonic-gate break; 56107c478bd9Sstevel@tonic-gate 56117c478bd9Sstevel@tonic-gate /* use a session id of zero since we use a software provider */ 56127c478bd9Sstevel@tonic-gate if (taskq_req->dr_type == DPROV_REQ_MAC_ATOMIC) 5613894b2776Smcpowers error = crypto_mac_prov(pd, 0, &mech, 56147c478bd9Sstevel@tonic-gate taskq_req->dr_mac_req.dr_data, 5615894b2776Smcpowers &key, NULL, taskq_req->dr_mac_req.dr_mac, NULL); 56167c478bd9Sstevel@tonic-gate else 5617894b2776Smcpowers error = crypto_mac_verify_prov(pd, 0, &mech, 56187c478bd9Sstevel@tonic-gate taskq_req->dr_mac_req.dr_data, 5619894b2776Smcpowers &key, NULL, taskq_req->dr_mac_req.dr_mac, NULL); 56207c478bd9Sstevel@tonic-gate 56217c478bd9Sstevel@tonic-gate /* release provider reference */ 56227c478bd9Sstevel@tonic-gate KCF_PROV_REFRELE(pd); 56237c478bd9Sstevel@tonic-gate 56247c478bd9Sstevel@tonic-gate break; 56257c478bd9Sstevel@tonic-gate } 56267c478bd9Sstevel@tonic-gate 56277c478bd9Sstevel@tonic-gate dprov_op_done(taskq_req, error); 56287c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: end\n", instance)); 56297c478bd9Sstevel@tonic-gate } 56307c478bd9Sstevel@tonic-gate 56317c478bd9Sstevel@tonic-gate /* 56327c478bd9Sstevel@tonic-gate * taskq dispatcher function for sign operations. 56337c478bd9Sstevel@tonic-gate */ 56347c478bd9Sstevel@tonic-gate static void 56357c478bd9Sstevel@tonic-gate dprov_sign_task(dprov_req_t *taskq_req) 56367c478bd9Sstevel@tonic-gate { 56377c478bd9Sstevel@tonic-gate kcf_provider_desc_t *pd; 56387c478bd9Sstevel@tonic-gate dprov_state_t *softc; 56397c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 56407c478bd9Sstevel@tonic-gate int instance; 56417c478bd9Sstevel@tonic-gate int error = CRYPTO_NOT_SUPPORTED; 5642ba5f469cSkrishna crypto_ctx_t *ctx = taskq_req->dr_sign_req.sr_ctx; 56437c478bd9Sstevel@tonic-gate crypto_key_t key, *keyp; 56447c478bd9Sstevel@tonic-gate crypto_mechanism_t mech; 56457c478bd9Sstevel@tonic-gate 56467c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 56477c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_task: started\n", instance)); 56487c478bd9Sstevel@tonic-gate 56497c478bd9Sstevel@tonic-gate switch (taskq_req->dr_type) { 56507c478bd9Sstevel@tonic-gate 56517c478bd9Sstevel@tonic-gate case DPROV_REQ_SIGN_INIT: 56527c478bd9Sstevel@tonic-gate case DPROV_REQ_SIGN_RECOVER_INIT: 56537c478bd9Sstevel@tonic-gate /* allocate a dprov-private context */ 56547c478bd9Sstevel@tonic-gate if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) != 56557c478bd9Sstevel@tonic-gate CRYPTO_SUCCESS) 56567c478bd9Sstevel@tonic-gate break; 56577c478bd9Sstevel@tonic-gate 56587c478bd9Sstevel@tonic-gate /* structure assignment */ 56597c478bd9Sstevel@tonic-gate mech = *taskq_req->dr_sign_req.sr_mechanism; 5660ba5f469cSkrishna if (dprov_valid_mac_mech(mech.cm_type)) { 5661ba5f469cSkrishna DPROV_CTX_P(ctx)->dc_svrfy_to_mac = B_TRUE; 5662ba5f469cSkrishna } 56637c478bd9Sstevel@tonic-gate 56647c478bd9Sstevel@tonic-gate mutex_enter(&softc->ds_lock); 56657c478bd9Sstevel@tonic-gate if (is_publickey_mech(mech.cm_type)) { 56667c478bd9Sstevel@tonic-gate if ((error = dprov_key_attr_asymmetric(softc, 56677c478bd9Sstevel@tonic-gate ctx->cc_session, taskq_req->dr_type, 56687c478bd9Sstevel@tonic-gate taskq_req->dr_sign_req.sr_key, &key)) 56697c478bd9Sstevel@tonic-gate != CRYPTO_SUCCESS) { 56707c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 56717c478bd9Sstevel@tonic-gate break; 56727c478bd9Sstevel@tonic-gate } 56737c478bd9Sstevel@tonic-gate keyp = &key; 56747c478bd9Sstevel@tonic-gate } else { 56757c478bd9Sstevel@tonic-gate if ((error = dprov_key_value_secret(softc, 56767c478bd9Sstevel@tonic-gate ctx->cc_session, taskq_req->dr_type, 56777c478bd9Sstevel@tonic-gate taskq_req->dr_sign_req.sr_key, &key)) 56787c478bd9Sstevel@tonic-gate != CRYPTO_SUCCESS) { 56797c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 56807c478bd9Sstevel@tonic-gate break; 56817c478bd9Sstevel@tonic-gate } 56827c478bd9Sstevel@tonic-gate keyp = &key; 56837c478bd9Sstevel@tonic-gate } 56847c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 56857c478bd9Sstevel@tonic-gate 56867c478bd9Sstevel@tonic-gate /* get the software provider for this mechanism */ 56877c478bd9Sstevel@tonic-gate if ((error = dprov_get_sw_prov( 56887c478bd9Sstevel@tonic-gate taskq_req->dr_sign_req.sr_mechanism, &pd, 56897c478bd9Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS) 56907c478bd9Sstevel@tonic-gate break; 56917c478bd9Sstevel@tonic-gate 5692ba5f469cSkrishna if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) { 5693ba5f469cSkrishna error = crypto_mac_init_prov(pd, 0, &mech, keyp, NULL, 5694ba5f469cSkrishna &DPROV_CTX_SINGLE(ctx), NULL); 5695ba5f469cSkrishna 5696ba5f469cSkrishna /* release provider reference */ 5697ba5f469cSkrishna KCF_PROV_REFRELE(pd); 5698ba5f469cSkrishna break; 5699ba5f469cSkrishna } 5700ba5f469cSkrishna 57017c478bd9Sstevel@tonic-gate /* Use a session id of zero since we use a software provider */ 57027c478bd9Sstevel@tonic-gate if (taskq_req->dr_type == DPROV_REQ_SIGN_INIT) 57037c478bd9Sstevel@tonic-gate error = crypto_sign_init_prov(pd, 0, &mech, keyp, 57047c478bd9Sstevel@tonic-gate NULL, &DPROV_CTX_SINGLE(ctx), NULL); 57057c478bd9Sstevel@tonic-gate else 57067c478bd9Sstevel@tonic-gate error = crypto_sign_recover_init_prov(pd, 0, &mech, 57077c478bd9Sstevel@tonic-gate keyp, NULL, &DPROV_CTX_SINGLE(ctx), NULL); 57087c478bd9Sstevel@tonic-gate 57097c478bd9Sstevel@tonic-gate /* release provider reference */ 57107c478bd9Sstevel@tonic-gate KCF_PROV_REFRELE(pd); 57117c478bd9Sstevel@tonic-gate 57127c478bd9Sstevel@tonic-gate break; 57137c478bd9Sstevel@tonic-gate 57147c478bd9Sstevel@tonic-gate case DPROV_REQ_SIGN: 5715ba5f469cSkrishna if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) { 5716ba5f469cSkrishna /* Emulate using update and final */ 5717ba5f469cSkrishna error = crypto_mac_update(DPROV_CTX_SINGLE(ctx), 5718ba5f469cSkrishna taskq_req->dr_mac_req.dr_data, NULL); 5719ba5f469cSkrishna if (error == CRYPTO_SUCCESS) { 5720ba5f469cSkrishna error = crypto_mac_final(DPROV_CTX_SINGLE(ctx), 5721ba5f469cSkrishna taskq_req->dr_mac_req.dr_mac, NULL); 5722ba5f469cSkrishna } 5723ba5f469cSkrishna } else { 57247c478bd9Sstevel@tonic-gate error = crypto_sign_single(DPROV_CTX_SINGLE(ctx), 57257c478bd9Sstevel@tonic-gate taskq_req->dr_sign_req.sr_data, 57267c478bd9Sstevel@tonic-gate taskq_req->dr_sign_req.sr_signature, NULL); 5727ba5f469cSkrishna } 57287c478bd9Sstevel@tonic-gate 57297c478bd9Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) { 57307c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL; 57317c478bd9Sstevel@tonic-gate (void) dprov_free_context(ctx); 57327c478bd9Sstevel@tonic-gate } 57337c478bd9Sstevel@tonic-gate break; 57347c478bd9Sstevel@tonic-gate 57357c478bd9Sstevel@tonic-gate case DPROV_REQ_SIGN_UPDATE: 5736ba5f469cSkrishna if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) { 5737ba5f469cSkrishna error = crypto_mac_update(DPROV_CTX_SINGLE(ctx), 5738ba5f469cSkrishna taskq_req->dr_mac_req.dr_data, NULL); 5739ba5f469cSkrishna } else { 57407c478bd9Sstevel@tonic-gate error = crypto_sign_update(DPROV_CTX_SINGLE(ctx), 57417c478bd9Sstevel@tonic-gate taskq_req->dr_sign_req.sr_data, NULL); 5742ba5f469cSkrishna } 57437c478bd9Sstevel@tonic-gate break; 57447c478bd9Sstevel@tonic-gate 57457c478bd9Sstevel@tonic-gate case DPROV_REQ_SIGN_FINAL: 5746ba5f469cSkrishna if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) { 5747ba5f469cSkrishna error = crypto_mac_final(DPROV_CTX_SINGLE(ctx), 5748ba5f469cSkrishna taskq_req->dr_mac_req.dr_mac, NULL); 5749ba5f469cSkrishna } else { 57507c478bd9Sstevel@tonic-gate error = crypto_sign_final(DPROV_CTX_SINGLE(ctx), 57517c478bd9Sstevel@tonic-gate taskq_req->dr_sign_req.sr_signature, NULL); 5752ba5f469cSkrishna } 57537c478bd9Sstevel@tonic-gate 57547c478bd9Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) { 57557c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL; 57567c478bd9Sstevel@tonic-gate (void) dprov_free_context(ctx); 57577c478bd9Sstevel@tonic-gate } 57587c478bd9Sstevel@tonic-gate break; 57597c478bd9Sstevel@tonic-gate 57607c478bd9Sstevel@tonic-gate case DPROV_REQ_SIGN_ATOMIC: 57617c478bd9Sstevel@tonic-gate case DPROV_REQ_SIGN_RECOVER_ATOMIC: 57627c478bd9Sstevel@tonic-gate /* structure assignment */ 57637c478bd9Sstevel@tonic-gate mech = *taskq_req->dr_sign_req.sr_mechanism; 57647c478bd9Sstevel@tonic-gate 57657c478bd9Sstevel@tonic-gate mutex_enter(&softc->ds_lock); 57667c478bd9Sstevel@tonic-gate /* get key value for secret key algorithms */ 57677c478bd9Sstevel@tonic-gate if (is_publickey_mech(mech.cm_type)) { 57687c478bd9Sstevel@tonic-gate if ((error = dprov_key_attr_asymmetric(softc, 57697c478bd9Sstevel@tonic-gate taskq_req->dr_sign_req.sr_session_id, 57707c478bd9Sstevel@tonic-gate taskq_req->dr_type, 57717c478bd9Sstevel@tonic-gate taskq_req->dr_sign_req.sr_key, &key)) 57727c478bd9Sstevel@tonic-gate != CRYPTO_SUCCESS) { 57737c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 57747c478bd9Sstevel@tonic-gate break; 57757c478bd9Sstevel@tonic-gate } 57767c478bd9Sstevel@tonic-gate keyp = &key; 57777c478bd9Sstevel@tonic-gate } else { 57787c478bd9Sstevel@tonic-gate if ((error = dprov_key_value_secret(softc, 57797c478bd9Sstevel@tonic-gate taskq_req->dr_sign_req.sr_session_id, 57807c478bd9Sstevel@tonic-gate taskq_req->dr_type, 57817c478bd9Sstevel@tonic-gate taskq_req->dr_sign_req.sr_key, &key)) 57827c478bd9Sstevel@tonic-gate != CRYPTO_SUCCESS) { 57837c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 57847c478bd9Sstevel@tonic-gate break; 57857c478bd9Sstevel@tonic-gate } 57867c478bd9Sstevel@tonic-gate keyp = &key; 57877c478bd9Sstevel@tonic-gate } 57887c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 57897c478bd9Sstevel@tonic-gate 57907c478bd9Sstevel@tonic-gate /* get the software provider for this mechanism */ 57917c478bd9Sstevel@tonic-gate if ((error = dprov_get_sw_prov( 57927c478bd9Sstevel@tonic-gate taskq_req->dr_sign_req.sr_mechanism, &pd, 57937c478bd9Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS) 57947c478bd9Sstevel@tonic-gate break; 57957c478bd9Sstevel@tonic-gate 57967c478bd9Sstevel@tonic-gate /* Use a session id of zero since we use a software provider */ 57977c478bd9Sstevel@tonic-gate if (taskq_req->dr_type == DPROV_REQ_SIGN_ATOMIC) 57987c478bd9Sstevel@tonic-gate error = crypto_sign_prov(pd, 0, &mech, keyp, 57997c478bd9Sstevel@tonic-gate taskq_req->dr_sign_req.sr_data, 58007c478bd9Sstevel@tonic-gate NULL, taskq_req->dr_sign_req.sr_signature, NULL); 58017c478bd9Sstevel@tonic-gate else 58027c478bd9Sstevel@tonic-gate error = crypto_sign_recover_prov(pd, 0, &mech, keyp, 58037c478bd9Sstevel@tonic-gate taskq_req->dr_sign_req.sr_data, 58047c478bd9Sstevel@tonic-gate NULL, taskq_req->dr_sign_req.sr_signature, NULL); 58057c478bd9Sstevel@tonic-gate 58067c478bd9Sstevel@tonic-gate /* release provider reference */ 58077c478bd9Sstevel@tonic-gate KCF_PROV_REFRELE(pd); 58087c478bd9Sstevel@tonic-gate break; 58097c478bd9Sstevel@tonic-gate 58107c478bd9Sstevel@tonic-gate case DPROV_REQ_SIGN_RECOVER: 58117c478bd9Sstevel@tonic-gate error = crypto_sign_recover_single(DPROV_CTX_SINGLE(ctx), 58127c478bd9Sstevel@tonic-gate taskq_req->dr_sign_req.sr_data, 58137c478bd9Sstevel@tonic-gate taskq_req->dr_sign_req.sr_signature, NULL); 58147c478bd9Sstevel@tonic-gate 58157c478bd9Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) { 58167c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL; 58177c478bd9Sstevel@tonic-gate (void) dprov_free_context(ctx); 58187c478bd9Sstevel@tonic-gate } 58197c478bd9Sstevel@tonic-gate break; 58207c478bd9Sstevel@tonic-gate } 58217c478bd9Sstevel@tonic-gate 58227c478bd9Sstevel@tonic-gate dprov_op_done(taskq_req, error); 58237c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_task: end\n", instance)); 58247c478bd9Sstevel@tonic-gate } 58257c478bd9Sstevel@tonic-gate 5826ba5f469cSkrishna static int 5827ba5f469cSkrishna emulate_verify_with_mac(crypto_ctx_t *ctx, crypto_data_t *in_mac) 5828ba5f469cSkrishna { 5829ba5f469cSkrishna int error; 5830ba5f469cSkrishna crypto_data_t tmpd; 5831ba5f469cSkrishna crypto_data_t *out_mac; 5832ba5f469cSkrishna char digest[SHA512_DIGEST_LENGTH]; 5833ba5f469cSkrishna 5834ba5f469cSkrishna bzero(&tmpd, sizeof (crypto_data_t)); 5835ba5f469cSkrishna tmpd.cd_format = CRYPTO_DATA_RAW; 5836ba5f469cSkrishna tmpd.cd_length = SHA512_DIGEST_LENGTH; 5837ba5f469cSkrishna tmpd.cd_raw.iov_base = digest; 5838ba5f469cSkrishna tmpd.cd_raw.iov_len = SHA512_DIGEST_LENGTH; 5839ba5f469cSkrishna out_mac = &tmpd; 5840ba5f469cSkrishna 5841ba5f469cSkrishna error = crypto_mac_final(DPROV_CTX_SINGLE(ctx), out_mac, NULL); 5842ba5f469cSkrishna if (in_mac->cd_length != out_mac->cd_length || 5843ba5f469cSkrishna (bcmp(digest, (unsigned char *)in_mac->cd_raw.iov_base + 5844ba5f469cSkrishna in_mac->cd_offset, out_mac->cd_length) != 0)) { 5845ba5f469cSkrishna error = CRYPTO_INVALID_MAC; 5846ba5f469cSkrishna } 5847ba5f469cSkrishna 5848ba5f469cSkrishna return (error); 5849ba5f469cSkrishna } 5850ba5f469cSkrishna 58517c478bd9Sstevel@tonic-gate /* 58527c478bd9Sstevel@tonic-gate * taskq dispatcher function for verify operations. 58537c478bd9Sstevel@tonic-gate */ 58547c478bd9Sstevel@tonic-gate static void 58557c478bd9Sstevel@tonic-gate dprov_verify_task(dprov_req_t *taskq_req) 58567c478bd9Sstevel@tonic-gate { 58577c478bd9Sstevel@tonic-gate kcf_provider_desc_t *pd; 58587c478bd9Sstevel@tonic-gate dprov_state_t *softc; 58597c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 58607c478bd9Sstevel@tonic-gate int instance; 58617c478bd9Sstevel@tonic-gate int error = CRYPTO_NOT_SUPPORTED; 58627c478bd9Sstevel@tonic-gate crypto_ctx_t *ctx = taskq_req->dr_verify_req.vr_ctx; 58637c478bd9Sstevel@tonic-gate crypto_key_t key, *keyp; 58647c478bd9Sstevel@tonic-gate crypto_mechanism_t mech; 58657c478bd9Sstevel@tonic-gate 58667c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 58677c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_task: started\n", instance)); 58687c478bd9Sstevel@tonic-gate 58697c478bd9Sstevel@tonic-gate switch (taskq_req->dr_type) { 58707c478bd9Sstevel@tonic-gate 58717c478bd9Sstevel@tonic-gate case DPROV_REQ_VERIFY_INIT: 58727c478bd9Sstevel@tonic-gate case DPROV_REQ_VERIFY_RECOVER_INIT: 58737c478bd9Sstevel@tonic-gate /* allocate a dprov-private context */ 58747c478bd9Sstevel@tonic-gate if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) != 58757c478bd9Sstevel@tonic-gate CRYPTO_SUCCESS) 58767c478bd9Sstevel@tonic-gate break; 58777c478bd9Sstevel@tonic-gate 58787c478bd9Sstevel@tonic-gate /* structure assignment */ 58797c478bd9Sstevel@tonic-gate mech = *taskq_req->dr_verify_req.vr_mechanism; 5880ba5f469cSkrishna if (dprov_valid_mac_mech(mech.cm_type)) { 5881ba5f469cSkrishna DPROV_CTX_P(ctx)->dc_svrfy_to_mac = B_TRUE; 5882ba5f469cSkrishna } 58837c478bd9Sstevel@tonic-gate 58847c478bd9Sstevel@tonic-gate mutex_enter(&softc->ds_lock); 58857c478bd9Sstevel@tonic-gate /* get key value for secret key algorithms */ 58867c478bd9Sstevel@tonic-gate if (is_publickey_mech(mech.cm_type)) { 58877c478bd9Sstevel@tonic-gate if ((error = dprov_key_attr_asymmetric(softc, 58887c478bd9Sstevel@tonic-gate ctx->cc_session, taskq_req->dr_type, 58897c478bd9Sstevel@tonic-gate taskq_req->dr_verify_req.vr_key, &key)) 58907c478bd9Sstevel@tonic-gate != CRYPTO_SUCCESS) { 58917c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 58927c478bd9Sstevel@tonic-gate break; 58937c478bd9Sstevel@tonic-gate } 58947c478bd9Sstevel@tonic-gate keyp = &key; 58957c478bd9Sstevel@tonic-gate } else { 58967c478bd9Sstevel@tonic-gate if ((error = dprov_key_value_secret(softc, 58977c478bd9Sstevel@tonic-gate ctx->cc_session, taskq_req->dr_type, 58987c478bd9Sstevel@tonic-gate taskq_req->dr_verify_req.vr_key, &key)) 58997c478bd9Sstevel@tonic-gate != CRYPTO_SUCCESS) { 59007c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 59017c478bd9Sstevel@tonic-gate break; 59027c478bd9Sstevel@tonic-gate } 59037c478bd9Sstevel@tonic-gate keyp = &key; 59047c478bd9Sstevel@tonic-gate } 59057c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 59067c478bd9Sstevel@tonic-gate 59077c478bd9Sstevel@tonic-gate /* get the software provider for this mechanism */ 59087c478bd9Sstevel@tonic-gate if ((error = dprov_get_sw_prov( 59097c478bd9Sstevel@tonic-gate taskq_req->dr_verify_req.vr_mechanism, &pd, 59107c478bd9Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS) 59117c478bd9Sstevel@tonic-gate break; 59127c478bd9Sstevel@tonic-gate 5913ba5f469cSkrishna 5914ba5f469cSkrishna if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) { 5915ba5f469cSkrishna error = crypto_mac_init_prov(pd, 0, &mech, keyp, NULL, 5916ba5f469cSkrishna &DPROV_CTX_SINGLE(ctx), NULL); 5917ba5f469cSkrishna 5918ba5f469cSkrishna /* release provider reference */ 5919ba5f469cSkrishna KCF_PROV_REFRELE(pd); 5920ba5f469cSkrishna break; 5921ba5f469cSkrishna } 5922ba5f469cSkrishna 59237c478bd9Sstevel@tonic-gate /* Use a session id of zero since we use a software provider */ 59247c478bd9Sstevel@tonic-gate if (taskq_req->dr_type == DPROV_REQ_VERIFY_INIT) 59257c478bd9Sstevel@tonic-gate error = crypto_verify_init_prov(pd, 0, &mech, keyp, 59267c478bd9Sstevel@tonic-gate NULL, &DPROV_CTX_SINGLE(ctx), NULL); 59277c478bd9Sstevel@tonic-gate else 59287c478bd9Sstevel@tonic-gate error = crypto_verify_recover_init_prov(pd, 0, &mech, 59297c478bd9Sstevel@tonic-gate keyp, NULL, &DPROV_CTX_SINGLE(ctx), NULL); 59307c478bd9Sstevel@tonic-gate 59317c478bd9Sstevel@tonic-gate /* release provider reference */ 59327c478bd9Sstevel@tonic-gate KCF_PROV_REFRELE(pd); 59337c478bd9Sstevel@tonic-gate 59347c478bd9Sstevel@tonic-gate break; 59357c478bd9Sstevel@tonic-gate 59367c478bd9Sstevel@tonic-gate case DPROV_REQ_VERIFY: 5937ba5f469cSkrishna if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) { 5938ba5f469cSkrishna /* Emulate using update and final */ 5939ba5f469cSkrishna error = crypto_mac_update(DPROV_CTX_SINGLE(ctx), 5940ba5f469cSkrishna taskq_req->dr_mac_req.dr_data, NULL); 5941ba5f469cSkrishna if (error == CRYPTO_SUCCESS) { 5942ba5f469cSkrishna error = emulate_verify_with_mac(ctx, 5943ba5f469cSkrishna taskq_req->dr_mac_req.dr_mac); 5944ba5f469cSkrishna } 5945ba5f469cSkrishna } else { 59467c478bd9Sstevel@tonic-gate error = crypto_verify_single(DPROV_CTX_SINGLE(ctx), 59477c478bd9Sstevel@tonic-gate taskq_req->dr_verify_req.vr_data, 59487c478bd9Sstevel@tonic-gate taskq_req->dr_verify_req.vr_signature, NULL); 5949ba5f469cSkrishna } 59507c478bd9Sstevel@tonic-gate 59517c478bd9Sstevel@tonic-gate ASSERT(error != CRYPTO_BUFFER_TOO_SMALL); 59527c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL; 59537c478bd9Sstevel@tonic-gate (void) dprov_free_context(ctx); 59547c478bd9Sstevel@tonic-gate break; 59557c478bd9Sstevel@tonic-gate 59567c478bd9Sstevel@tonic-gate case DPROV_REQ_VERIFY_UPDATE: 5957ba5f469cSkrishna if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) { 5958ba5f469cSkrishna error = crypto_mac_update(DPROV_CTX_SINGLE(ctx), 5959ba5f469cSkrishna taskq_req->dr_mac_req.dr_data, NULL); 5960ba5f469cSkrishna } else { 59617c478bd9Sstevel@tonic-gate error = crypto_verify_update(DPROV_CTX_SINGLE(ctx), 59627c478bd9Sstevel@tonic-gate taskq_req->dr_verify_req.vr_data, NULL); 5963ba5f469cSkrishna } 59647c478bd9Sstevel@tonic-gate break; 59657c478bd9Sstevel@tonic-gate 59667c478bd9Sstevel@tonic-gate case DPROV_REQ_VERIFY_FINAL: 5967ba5f469cSkrishna if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) { 5968ba5f469cSkrishna error = emulate_verify_with_mac(ctx, 5969ba5f469cSkrishna taskq_req->dr_mac_req.dr_mac); 5970ba5f469cSkrishna } else { 59717c478bd9Sstevel@tonic-gate error = crypto_verify_final(DPROV_CTX_SINGLE(ctx), 59727c478bd9Sstevel@tonic-gate taskq_req->dr_verify_req.vr_signature, NULL); 5973ba5f469cSkrishna } 59747c478bd9Sstevel@tonic-gate 59757c478bd9Sstevel@tonic-gate ASSERT(error != CRYPTO_BUFFER_TOO_SMALL); 59767c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL; 59777c478bd9Sstevel@tonic-gate (void) dprov_free_context(ctx); 59787c478bd9Sstevel@tonic-gate break; 59797c478bd9Sstevel@tonic-gate 59807c478bd9Sstevel@tonic-gate case DPROV_REQ_VERIFY_ATOMIC: 59817c478bd9Sstevel@tonic-gate case DPROV_REQ_VERIFY_RECOVER_ATOMIC: 59827c478bd9Sstevel@tonic-gate /* structure assignment */ 59837c478bd9Sstevel@tonic-gate mech = *taskq_req->dr_verify_req.vr_mechanism; 59847c478bd9Sstevel@tonic-gate 59857c478bd9Sstevel@tonic-gate mutex_enter(&softc->ds_lock); 59867c478bd9Sstevel@tonic-gate /* get key value for secret key algorithms */ 59877c478bd9Sstevel@tonic-gate if (is_publickey_mech(mech.cm_type)) { 59887c478bd9Sstevel@tonic-gate if ((error = dprov_key_attr_asymmetric(softc, 59897c478bd9Sstevel@tonic-gate taskq_req->dr_verify_req.vr_session_id, 59907c478bd9Sstevel@tonic-gate taskq_req->dr_type, 59917c478bd9Sstevel@tonic-gate taskq_req->dr_verify_req.vr_key, &key)) 59927c478bd9Sstevel@tonic-gate != CRYPTO_SUCCESS) { 59937c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 59947c478bd9Sstevel@tonic-gate break; 59957c478bd9Sstevel@tonic-gate } 59967c478bd9Sstevel@tonic-gate keyp = &key; 59977c478bd9Sstevel@tonic-gate } else { 59987c478bd9Sstevel@tonic-gate if ((error = dprov_key_value_secret(softc, 59997c478bd9Sstevel@tonic-gate taskq_req->dr_verify_req.vr_session_id, 60007c478bd9Sstevel@tonic-gate taskq_req->dr_type, 60017c478bd9Sstevel@tonic-gate taskq_req->dr_verify_req.vr_key, &key)) 60027c478bd9Sstevel@tonic-gate != CRYPTO_SUCCESS) { 60037c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 60047c478bd9Sstevel@tonic-gate break; 60057c478bd9Sstevel@tonic-gate } 60067c478bd9Sstevel@tonic-gate keyp = &key; 60077c478bd9Sstevel@tonic-gate } 60087c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 60097c478bd9Sstevel@tonic-gate 60107c478bd9Sstevel@tonic-gate /* get the software provider for this mechanism */ 60117c478bd9Sstevel@tonic-gate if ((error = dprov_get_sw_prov( 60127c478bd9Sstevel@tonic-gate taskq_req->dr_verify_req.vr_mechanism, &pd, 60137c478bd9Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS) 60147c478bd9Sstevel@tonic-gate break; 60157c478bd9Sstevel@tonic-gate 60167c478bd9Sstevel@tonic-gate /* Use a session id of zero since we use a software provider */ 60177c478bd9Sstevel@tonic-gate if (taskq_req->dr_type == DPROV_REQ_VERIFY_ATOMIC) 60187c478bd9Sstevel@tonic-gate error = crypto_verify_prov(pd, 0, &mech, keyp, 60197c478bd9Sstevel@tonic-gate taskq_req->dr_verify_req.vr_data, 60207c478bd9Sstevel@tonic-gate NULL, taskq_req->dr_verify_req.vr_signature, NULL); 60217c478bd9Sstevel@tonic-gate else 60227c478bd9Sstevel@tonic-gate /* 60237c478bd9Sstevel@tonic-gate * crypto_verify_recover_prov() has different argument 60247c478bd9Sstevel@tonic-gate * order than crypto_verify_prov(). 60257c478bd9Sstevel@tonic-gate */ 60267c478bd9Sstevel@tonic-gate error = crypto_verify_recover_prov(pd, 0, &mech, keyp, 60277c478bd9Sstevel@tonic-gate taskq_req->dr_verify_req.vr_signature, 60287c478bd9Sstevel@tonic-gate NULL, taskq_req->dr_verify_req.vr_data, NULL); 60297c478bd9Sstevel@tonic-gate 60307c478bd9Sstevel@tonic-gate /* release provider reference */ 60317c478bd9Sstevel@tonic-gate KCF_PROV_REFRELE(pd); 60327c478bd9Sstevel@tonic-gate break; 60337c478bd9Sstevel@tonic-gate 60347c478bd9Sstevel@tonic-gate case DPROV_REQ_VERIFY_RECOVER: 60357c478bd9Sstevel@tonic-gate /* 60367c478bd9Sstevel@tonic-gate * crypto_verify_recover_single() has different argument 60377c478bd9Sstevel@tonic-gate * order than crypto_verify_single(). 60387c478bd9Sstevel@tonic-gate */ 60397c478bd9Sstevel@tonic-gate error = crypto_verify_recover_single(DPROV_CTX_SINGLE(ctx), 60407c478bd9Sstevel@tonic-gate taskq_req->dr_verify_req.vr_signature, 60417c478bd9Sstevel@tonic-gate taskq_req->dr_verify_req.vr_data, NULL); 60427c478bd9Sstevel@tonic-gate 60437c478bd9Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) { 60447c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL; 60457c478bd9Sstevel@tonic-gate (void) dprov_free_context(ctx); 60467c478bd9Sstevel@tonic-gate } 60477c478bd9Sstevel@tonic-gate break; 60487c478bd9Sstevel@tonic-gate } 60497c478bd9Sstevel@tonic-gate 60507c478bd9Sstevel@tonic-gate dprov_op_done(taskq_req, error); 60517c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_task: end\n", instance)); 60527c478bd9Sstevel@tonic-gate } 60537c478bd9Sstevel@tonic-gate 60547c478bd9Sstevel@tonic-gate /* 60557c478bd9Sstevel@tonic-gate * taskq dispatcher function for dual operations. 60567c478bd9Sstevel@tonic-gate */ 60577c478bd9Sstevel@tonic-gate static void 60587c478bd9Sstevel@tonic-gate dprov_dual_task(dprov_req_t *taskq_req) 60597c478bd9Sstevel@tonic-gate { 60607c478bd9Sstevel@tonic-gate dprov_state_t *softc; 60617c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 60627c478bd9Sstevel@tonic-gate int instance; 60637c478bd9Sstevel@tonic-gate int error = CRYPTO_NOT_SUPPORTED; 60647c478bd9Sstevel@tonic-gate crypto_ctx_t *signverify_ctx = taskq_req->dr_dual_req.dr_signverify_ctx; 60657c478bd9Sstevel@tonic-gate crypto_ctx_t *cipher_ctx = taskq_req->dr_dual_req.dr_cipher_ctx; 60667c478bd9Sstevel@tonic-gate 60677c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 60687c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DUAL, ("(%d) dprov_dual_task: started\n", instance)); 60697c478bd9Sstevel@tonic-gate 60707c478bd9Sstevel@tonic-gate switch (taskq_req->dr_type) { 60717c478bd9Sstevel@tonic-gate 60727c478bd9Sstevel@tonic-gate case DPROV_REQ_DIGEST_ENCRYPT_UPDATE: 60737c478bd9Sstevel@tonic-gate error = crypto_digest_encrypt_update( 60747c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE(signverify_ctx), 60757c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE(cipher_ctx), 60767c478bd9Sstevel@tonic-gate taskq_req->dr_dual_req.dr_plaintext, 60777c478bd9Sstevel@tonic-gate taskq_req->dr_dual_req.dr_ciphertext, NULL); 60787c478bd9Sstevel@tonic-gate break; 60797c478bd9Sstevel@tonic-gate 60807c478bd9Sstevel@tonic-gate case DPROV_REQ_DECRYPT_DIGEST_UPDATE: 60817c478bd9Sstevel@tonic-gate error = crypto_decrypt_digest_update( 60827c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE(cipher_ctx), 60837c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE(signverify_ctx), 60847c478bd9Sstevel@tonic-gate taskq_req->dr_dual_req.dr_ciphertext, 60857c478bd9Sstevel@tonic-gate taskq_req->dr_dual_req.dr_plaintext, NULL); 60867c478bd9Sstevel@tonic-gate break; 60877c478bd9Sstevel@tonic-gate 60887c478bd9Sstevel@tonic-gate case DPROV_REQ_SIGN_ENCRYPT_UPDATE: 60897c478bd9Sstevel@tonic-gate error = crypto_sign_encrypt_update( 60907c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE(signverify_ctx), 60917c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE(cipher_ctx), 60927c478bd9Sstevel@tonic-gate taskq_req->dr_dual_req.dr_plaintext, 60937c478bd9Sstevel@tonic-gate taskq_req->dr_dual_req.dr_ciphertext, NULL); 60947c478bd9Sstevel@tonic-gate break; 60957c478bd9Sstevel@tonic-gate 60967c478bd9Sstevel@tonic-gate case DPROV_REQ_DECRYPT_VERIFY_UPDATE: 60977c478bd9Sstevel@tonic-gate error = crypto_decrypt_verify_update( 60987c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE(cipher_ctx), 60997c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE(signverify_ctx), 61007c478bd9Sstevel@tonic-gate taskq_req->dr_dual_req.dr_ciphertext, 61017c478bd9Sstevel@tonic-gate taskq_req->dr_dual_req.dr_plaintext, NULL); 61027c478bd9Sstevel@tonic-gate break; 61037c478bd9Sstevel@tonic-gate } 61047c478bd9Sstevel@tonic-gate 61057c478bd9Sstevel@tonic-gate dprov_op_done(taskq_req, error); 61067c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DUAL, ("(%d) dprov_dual_task: end\n", instance)); 61077c478bd9Sstevel@tonic-gate } 61087c478bd9Sstevel@tonic-gate 61097c478bd9Sstevel@tonic-gate /* 61107c478bd9Sstevel@tonic-gate * taskq dispatcher function for cipher operations. 61117c478bd9Sstevel@tonic-gate */ 61127c478bd9Sstevel@tonic-gate static void 61137c478bd9Sstevel@tonic-gate dprov_cipher_task(dprov_req_t *taskq_req) 61147c478bd9Sstevel@tonic-gate { 61157c478bd9Sstevel@tonic-gate kcf_provider_desc_t *pd; 61167c478bd9Sstevel@tonic-gate dprov_state_t *softc; 61177c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 61187c478bd9Sstevel@tonic-gate int instance; 61197c478bd9Sstevel@tonic-gate int error = CRYPTO_NOT_SUPPORTED; 61207c478bd9Sstevel@tonic-gate crypto_ctx_t *ctx = taskq_req->dr_cipher_req.dr_ctx; 61217c478bd9Sstevel@tonic-gate crypto_key_t key, *keyp; 61227c478bd9Sstevel@tonic-gate crypto_mechanism_t mech; 61237c478bd9Sstevel@tonic-gate 61247c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 61257c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER, ("(%d) dprov_cipher_task: started\n", instance)); 61267c478bd9Sstevel@tonic-gate 61277c478bd9Sstevel@tonic-gate switch (taskq_req->dr_type) { 61287c478bd9Sstevel@tonic-gate 61297c478bd9Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_INIT: 61307c478bd9Sstevel@tonic-gate case DPROV_REQ_DECRYPT_INIT: 61317c478bd9Sstevel@tonic-gate /* allocate a dprov-private context */ 61327c478bd9Sstevel@tonic-gate if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) != 61337c478bd9Sstevel@tonic-gate CRYPTO_SUCCESS) 61347c478bd9Sstevel@tonic-gate break; 61357c478bd9Sstevel@tonic-gate 61367c478bd9Sstevel@tonic-gate /* structure assignment */ 61377c478bd9Sstevel@tonic-gate mech = *taskq_req->dr_cipher_req.dr_mechanism; 61387c478bd9Sstevel@tonic-gate 61397c478bd9Sstevel@tonic-gate mutex_enter(&softc->ds_lock); 61407c478bd9Sstevel@tonic-gate /* get key value for secret key algorithms */ 61417c478bd9Sstevel@tonic-gate if (is_publickey_mech(mech.cm_type)) { 61427c478bd9Sstevel@tonic-gate if ((error = dprov_key_attr_asymmetric(softc, 61437c478bd9Sstevel@tonic-gate ctx->cc_session, taskq_req->dr_type, 61447c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_key, &key)) 61457c478bd9Sstevel@tonic-gate != CRYPTO_SUCCESS) { 61467c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 61477c478bd9Sstevel@tonic-gate break; 61487c478bd9Sstevel@tonic-gate } 61497c478bd9Sstevel@tonic-gate keyp = &key; 61507c478bd9Sstevel@tonic-gate } else { 61517c478bd9Sstevel@tonic-gate if ((error = dprov_key_value_secret(softc, 61527c478bd9Sstevel@tonic-gate ctx->cc_session, taskq_req->dr_type, 61537c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_key, &key)) 61547c478bd9Sstevel@tonic-gate != CRYPTO_SUCCESS) { 61557c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 61567c478bd9Sstevel@tonic-gate break; 61577c478bd9Sstevel@tonic-gate } 61587c478bd9Sstevel@tonic-gate keyp = &key; 61597c478bd9Sstevel@tonic-gate } 61607c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 61617c478bd9Sstevel@tonic-gate 61627c478bd9Sstevel@tonic-gate /* get the software provider for this mechanism */ 61637c478bd9Sstevel@tonic-gate if ((error = dprov_get_sw_prov( 61647c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_mechanism, &pd, 61657c478bd9Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS) 61667c478bd9Sstevel@tonic-gate break; 61677c478bd9Sstevel@tonic-gate 61687c478bd9Sstevel@tonic-gate /* Use a session id of zero since we use a software provider */ 61697c478bd9Sstevel@tonic-gate if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_INIT) 61707c478bd9Sstevel@tonic-gate error = crypto_encrypt_init_prov(pd, 0, &mech, keyp, 61717c478bd9Sstevel@tonic-gate NULL, &DPROV_CTX_SINGLE(ctx), NULL); 61727c478bd9Sstevel@tonic-gate else 61737c478bd9Sstevel@tonic-gate error = crypto_decrypt_init_prov(pd, 0, &mech, keyp, 61747c478bd9Sstevel@tonic-gate NULL, &DPROV_CTX_SINGLE(ctx), NULL); 61757c478bd9Sstevel@tonic-gate 61766a1073f8Skrishna if (ctx->cc_flags & CRYPTO_INIT_OPSTATE) { 61776a1073f8Skrishna crypto_ctx_t *lctx = 61786a1073f8Skrishna (crypto_ctx_t *)(DPROV_CTX_SINGLE(ctx)); 61796a1073f8Skrishna 61806a1073f8Skrishna ctx->cc_opstate = lctx->cc_provider_private; 61816a1073f8Skrishna ctx->cc_flags |= CRYPTO_USE_OPSTATE; 61826a1073f8Skrishna } 61836a1073f8Skrishna 61847c478bd9Sstevel@tonic-gate /* release provider reference */ 61857c478bd9Sstevel@tonic-gate KCF_PROV_REFRELE(pd); 61867c478bd9Sstevel@tonic-gate break; 61877c478bd9Sstevel@tonic-gate 61887c478bd9Sstevel@tonic-gate case DPROV_REQ_ENCRYPT: 61897c478bd9Sstevel@tonic-gate error = crypto_encrypt_single(DPROV_CTX_SINGLE(ctx), 61907c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_plaintext, 61917c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_ciphertext, NULL); 61927c478bd9Sstevel@tonic-gate 61937c478bd9Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) { 61947c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL; 61957c478bd9Sstevel@tonic-gate (void) dprov_free_context(ctx); 61967c478bd9Sstevel@tonic-gate } 61977c478bd9Sstevel@tonic-gate break; 61987c478bd9Sstevel@tonic-gate 61997c478bd9Sstevel@tonic-gate case DPROV_REQ_DECRYPT: 62007c478bd9Sstevel@tonic-gate error = crypto_decrypt_single(DPROV_CTX_SINGLE(ctx), 62017c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_ciphertext, 62027c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_plaintext, NULL); 62037c478bd9Sstevel@tonic-gate 62047c478bd9Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) { 62057c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL; 62067c478bd9Sstevel@tonic-gate (void) dprov_free_context(ctx); 62077c478bd9Sstevel@tonic-gate } 62087c478bd9Sstevel@tonic-gate break; 62097c478bd9Sstevel@tonic-gate 62107c478bd9Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_UPDATE: 62116a1073f8Skrishna ASSERT(!(ctx->cc_flags & CRYPTO_INIT_OPSTATE) || 62126a1073f8Skrishna (ctx->cc_flags & CRYPTO_USE_OPSTATE)); 62137c478bd9Sstevel@tonic-gate error = crypto_encrypt_update(DPROV_CTX_SINGLE(ctx), 62147c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_plaintext, 62157c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_ciphertext, NULL); 62167c478bd9Sstevel@tonic-gate break; 62177c478bd9Sstevel@tonic-gate 62187c478bd9Sstevel@tonic-gate case DPROV_REQ_DECRYPT_UPDATE: 62196a1073f8Skrishna ASSERT(!(ctx->cc_flags & CRYPTO_INIT_OPSTATE) || 62206a1073f8Skrishna (ctx->cc_flags & CRYPTO_USE_OPSTATE)); 62217c478bd9Sstevel@tonic-gate error = crypto_decrypt_update(DPROV_CTX_SINGLE(ctx), 62227c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_ciphertext, 62237c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_plaintext, NULL); 62247c478bd9Sstevel@tonic-gate break; 62257c478bd9Sstevel@tonic-gate 62267c478bd9Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_FINAL: 62277c478bd9Sstevel@tonic-gate error = crypto_encrypt_final(DPROV_CTX_SINGLE(ctx), 62287c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_ciphertext, NULL); 62297c478bd9Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) { 62307c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL; 62317c478bd9Sstevel@tonic-gate (void) dprov_free_context(ctx); 62327c478bd9Sstevel@tonic-gate } 62337c478bd9Sstevel@tonic-gate break; 62347c478bd9Sstevel@tonic-gate 62357c478bd9Sstevel@tonic-gate case DPROV_REQ_DECRYPT_FINAL: 62367c478bd9Sstevel@tonic-gate error = crypto_decrypt_final(DPROV_CTX_SINGLE(ctx), 62377c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_plaintext, NULL); 62387c478bd9Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) { 62397c478bd9Sstevel@tonic-gate DPROV_CTX_SINGLE(ctx) = NULL; 62407c478bd9Sstevel@tonic-gate (void) dprov_free_context(ctx); 62417c478bd9Sstevel@tonic-gate } 62427c478bd9Sstevel@tonic-gate break; 62437c478bd9Sstevel@tonic-gate 62447c478bd9Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_ATOMIC: 62457c478bd9Sstevel@tonic-gate case DPROV_REQ_DECRYPT_ATOMIC: 62467c478bd9Sstevel@tonic-gate /* structure assignment */ 62477c478bd9Sstevel@tonic-gate mech = *taskq_req->dr_cipher_req.dr_mechanism; 62487c478bd9Sstevel@tonic-gate 62497c478bd9Sstevel@tonic-gate mutex_enter(&softc->ds_lock); 62507c478bd9Sstevel@tonic-gate /* get key value for secret key algorithms */ 62517c478bd9Sstevel@tonic-gate if (is_publickey_mech(mech.cm_type)) { 62527c478bd9Sstevel@tonic-gate if ((error = dprov_key_attr_asymmetric(softc, 62537c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_session_id, 62547c478bd9Sstevel@tonic-gate taskq_req->dr_type, 62557c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_key, 62567c478bd9Sstevel@tonic-gate &key)) != CRYPTO_SUCCESS) { 62577c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 62587c478bd9Sstevel@tonic-gate break; 62597c478bd9Sstevel@tonic-gate } 62607c478bd9Sstevel@tonic-gate keyp = &key; 62617c478bd9Sstevel@tonic-gate } else { 62627c478bd9Sstevel@tonic-gate if ((error = dprov_key_value_secret(softc, 62637c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_session_id, 62647c478bd9Sstevel@tonic-gate taskq_req->dr_type, taskq_req->dr_cipher_req.dr_key, 62657c478bd9Sstevel@tonic-gate &key)) 62667c478bd9Sstevel@tonic-gate != CRYPTO_SUCCESS) { 62677c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 62687c478bd9Sstevel@tonic-gate break; 62697c478bd9Sstevel@tonic-gate } 62707c478bd9Sstevel@tonic-gate keyp = &key; 62717c478bd9Sstevel@tonic-gate } 62727c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 62737c478bd9Sstevel@tonic-gate 62747c478bd9Sstevel@tonic-gate /* get the software provider for this mechanism */ 62757c478bd9Sstevel@tonic-gate if ((error = dprov_get_sw_prov( 62767c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_mechanism, &pd, 62777c478bd9Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS) 62787c478bd9Sstevel@tonic-gate break; 62797c478bd9Sstevel@tonic-gate 62807c478bd9Sstevel@tonic-gate /* use a session id of zero since we use a software provider */ 62817c478bd9Sstevel@tonic-gate if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_ATOMIC) 6282894b2776Smcpowers error = crypto_encrypt_prov(pd, 0, &mech, 62837c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_plaintext, 62847c478bd9Sstevel@tonic-gate keyp, NULL, 6285894b2776Smcpowers taskq_req->dr_cipher_req.dr_ciphertext, NULL); 62867c478bd9Sstevel@tonic-gate else 6287894b2776Smcpowers error = crypto_decrypt_prov(pd, 0, &mech, 62887c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_req.dr_ciphertext, 62897c478bd9Sstevel@tonic-gate keyp, NULL, 6290894b2776Smcpowers taskq_req->dr_cipher_req.dr_plaintext, NULL); 62917c478bd9Sstevel@tonic-gate 62927c478bd9Sstevel@tonic-gate /* release provider reference */ 62937c478bd9Sstevel@tonic-gate KCF_PROV_REFRELE(pd); 62947c478bd9Sstevel@tonic-gate 62957c478bd9Sstevel@tonic-gate break; 62967c478bd9Sstevel@tonic-gate } 62977c478bd9Sstevel@tonic-gate 62987c478bd9Sstevel@tonic-gate dprov_op_done(taskq_req, error); 62997c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: end\n", instance)); 63007c478bd9Sstevel@tonic-gate } 63017c478bd9Sstevel@tonic-gate 63027c478bd9Sstevel@tonic-gate /* 63037c478bd9Sstevel@tonic-gate * Helper function for the cipher/mac dual operation taskq dispatch 63047c478bd9Sstevel@tonic-gate * function. Initialize the cipher and mac key values and find the 63057c478bd9Sstevel@tonic-gate * providers that can process the request for the specified mechanisms. 63067c478bd9Sstevel@tonic-gate */ 63077c478bd9Sstevel@tonic-gate static int 63087c478bd9Sstevel@tonic-gate dprov_cipher_mac_key_pd(dprov_state_t *softc, crypto_session_id_t sid, 63097c478bd9Sstevel@tonic-gate dprov_req_t *taskq_req, crypto_key_t *cipher_key, crypto_key_t *mac_key, 63107c478bd9Sstevel@tonic-gate kcf_provider_desc_t **cipher_pd, kcf_provider_desc_t **mac_pd, 63117c478bd9Sstevel@tonic-gate crypto_mech_type_t *cipher_mech_type, crypto_mech_type_t *mac_mech_type) 63127c478bd9Sstevel@tonic-gate { 63137c478bd9Sstevel@tonic-gate int error; 63147c478bd9Sstevel@tonic-gate 63157c478bd9Sstevel@tonic-gate /* get the cipher key value */ 63167c478bd9Sstevel@tonic-gate mutex_enter(&softc->ds_lock); 6317894b2776Smcpowers error = dprov_key_value_secret(softc, sid, DPROV_REQ_ENCRYPT_ATOMIC, 63187c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_cipher_key, cipher_key); 63197c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) { 63207c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 63217c478bd9Sstevel@tonic-gate return (error); 63227c478bd9Sstevel@tonic-gate } 63237c478bd9Sstevel@tonic-gate 63247c478bd9Sstevel@tonic-gate /* get the mac key value */ 6325894b2776Smcpowers error = dprov_key_value_secret(softc, sid, DPROV_REQ_MAC_ATOMIC, 63267c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_mac_key, mac_key); 63277c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 63287c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) 63297c478bd9Sstevel@tonic-gate return (error); 63307c478bd9Sstevel@tonic-gate 63317c478bd9Sstevel@tonic-gate /* get the SW provider to perform the cipher operation */ 63327c478bd9Sstevel@tonic-gate if ((error = dprov_get_sw_prov( 63337c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_cipher_mech, cipher_pd, 63347c478bd9Sstevel@tonic-gate cipher_mech_type)) != CRYPTO_SUCCESS) 63357c478bd9Sstevel@tonic-gate return (error); 63367c478bd9Sstevel@tonic-gate 63377c478bd9Sstevel@tonic-gate /* get the SW provider to perform the mac operation */ 63387c478bd9Sstevel@tonic-gate error = dprov_get_sw_prov(taskq_req->dr_cipher_mac_req.mr_mac_mech, 63397c478bd9Sstevel@tonic-gate mac_pd, mac_mech_type); 63407c478bd9Sstevel@tonic-gate 63417c478bd9Sstevel@tonic-gate return (error); 63427c478bd9Sstevel@tonic-gate } 63437c478bd9Sstevel@tonic-gate 63447c478bd9Sstevel@tonic-gate /* 63457c478bd9Sstevel@tonic-gate * taskq dispatcher function for cipher/mac dual operations. 63467c478bd9Sstevel@tonic-gate */ 63477c478bd9Sstevel@tonic-gate static void 63487c478bd9Sstevel@tonic-gate dprov_cipher_mac_task(dprov_req_t *taskq_req) 63497c478bd9Sstevel@tonic-gate { 63507c478bd9Sstevel@tonic-gate dprov_state_t *softc; 63517c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 63527c478bd9Sstevel@tonic-gate int instance; 63537c478bd9Sstevel@tonic-gate int error = CRYPTO_NOT_SUPPORTED; 63547c478bd9Sstevel@tonic-gate crypto_ctx_t *ctx = taskq_req->dr_cipher_mac_req.mr_ctx; 63557c478bd9Sstevel@tonic-gate kcf_provider_desc_t *cipher_pd; 63567c478bd9Sstevel@tonic-gate kcf_provider_desc_t *mac_pd; 63577c478bd9Sstevel@tonic-gate crypto_key_t cipher_key; 63587c478bd9Sstevel@tonic-gate crypto_key_t mac_key; 63597c478bd9Sstevel@tonic-gate crypto_dual_data_t *dual_data = 63607c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_dual_data; 63617c478bd9Sstevel@tonic-gate crypto_data_t cipher_data; 63627c478bd9Sstevel@tonic-gate crypto_data_t mac_data; 63637c478bd9Sstevel@tonic-gate crypto_mechanism_t cipher_mech, mac_mech; 63647c478bd9Sstevel@tonic-gate crypto_session_id_t session_id; 63657c478bd9Sstevel@tonic-gate 63667c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 63677c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_cipher_mac_task: started\n", 63687c478bd9Sstevel@tonic-gate instance)); 63697c478bd9Sstevel@tonic-gate 63707c478bd9Sstevel@tonic-gate switch (taskq_req->dr_type) { 63717c478bd9Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_MAC_INIT: 63727c478bd9Sstevel@tonic-gate case DPROV_REQ_MAC_DECRYPT_INIT: 63737c478bd9Sstevel@tonic-gate /* structure assignment */ 63747c478bd9Sstevel@tonic-gate cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech; 63757c478bd9Sstevel@tonic-gate mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech; 63767c478bd9Sstevel@tonic-gate 63777c478bd9Sstevel@tonic-gate /* get the keys values and providers to use for operations */ 63787c478bd9Sstevel@tonic-gate if ((error = dprov_cipher_mac_key_pd(softc, ctx->cc_session, 63797c478bd9Sstevel@tonic-gate taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd, 63807c478bd9Sstevel@tonic-gate &cipher_mech.cm_type, &mac_mech.cm_type)) != CRYPTO_SUCCESS) 63817c478bd9Sstevel@tonic-gate break; 63827c478bd9Sstevel@tonic-gate 63837c478bd9Sstevel@tonic-gate /* allocate a dprov-private context */ 63847c478bd9Sstevel@tonic-gate if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) != 63857c478bd9Sstevel@tonic-gate CRYPTO_SUCCESS) 63867c478bd9Sstevel@tonic-gate break; 63877c478bd9Sstevel@tonic-gate 63887c478bd9Sstevel@tonic-gate if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_MAC_INIT) 63897c478bd9Sstevel@tonic-gate /* do the encryption initialization */ 63907c478bd9Sstevel@tonic-gate error = crypto_encrypt_init_prov(cipher_pd, 0, 63917c478bd9Sstevel@tonic-gate &cipher_mech, &cipher_key, NULL, 63927c478bd9Sstevel@tonic-gate &DPROV_CTX_DUAL_CIPHER(ctx), NULL); 63937c478bd9Sstevel@tonic-gate else 63947c478bd9Sstevel@tonic-gate /* do the decryption initialization */ 63957c478bd9Sstevel@tonic-gate error = crypto_decrypt_init_prov(cipher_pd, 0, 63967c478bd9Sstevel@tonic-gate &cipher_mech, &cipher_key, NULL, 63977c478bd9Sstevel@tonic-gate &DPROV_CTX_DUAL_CIPHER(ctx), NULL); 63987c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) 63997c478bd9Sstevel@tonic-gate break; 64007c478bd9Sstevel@tonic-gate 64017c478bd9Sstevel@tonic-gate /* do the mac initialization */ 64027c478bd9Sstevel@tonic-gate if ((error = crypto_mac_init_prov(mac_pd, 0, 64037c478bd9Sstevel@tonic-gate &mac_mech, &mac_key, NULL, &DPROV_CTX_DUAL_MAC(ctx), 64047c478bd9Sstevel@tonic-gate NULL)) != CRYPTO_SUCCESS) 64057c478bd9Sstevel@tonic-gate break; 64067c478bd9Sstevel@tonic-gate 64077c478bd9Sstevel@tonic-gate /* release references to providers */ 64087c478bd9Sstevel@tonic-gate KCF_PROV_REFRELE(cipher_pd); 64097c478bd9Sstevel@tonic-gate KCF_PROV_REFRELE(mac_pd); 64107c478bd9Sstevel@tonic-gate 64117c478bd9Sstevel@tonic-gate break; 64127c478bd9Sstevel@tonic-gate 64137c478bd9Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_MAC: { 64147c478bd9Sstevel@tonic-gate size_t encrypted; 64157c478bd9Sstevel@tonic-gate boolean_t inplace; 64167c478bd9Sstevel@tonic-gate 64177c478bd9Sstevel@tonic-gate crypto_data_t *plaintext_tmp, *ciphertext_tmp; 64187c478bd9Sstevel@tonic-gate 64197c478bd9Sstevel@tonic-gate cipher_data = *((crypto_data_t *)dual_data); 64207c478bd9Sstevel@tonic-gate 64217c478bd9Sstevel@tonic-gate /* do an encrypt update */ 64227c478bd9Sstevel@tonic-gate inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL); 64237c478bd9Sstevel@tonic-gate if (inplace) { 64247c478bd9Sstevel@tonic-gate plaintext_tmp = &cipher_data; 64257c478bd9Sstevel@tonic-gate ciphertext_tmp = NULL; 64267c478bd9Sstevel@tonic-gate } else { 64277c478bd9Sstevel@tonic-gate plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data; 64287c478bd9Sstevel@tonic-gate ciphertext_tmp = &cipher_data; 64297c478bd9Sstevel@tonic-gate } 64307c478bd9Sstevel@tonic-gate if ((error = crypto_encrypt_update(DPROV_CTX_DUAL_CIPHER(ctx), 64317c478bd9Sstevel@tonic-gate plaintext_tmp, ciphertext_tmp, NULL)) != CRYPTO_SUCCESS) 64327c478bd9Sstevel@tonic-gate break; 64337c478bd9Sstevel@tonic-gate 64347c478bd9Sstevel@tonic-gate /* do an encrypt final */ 64357c478bd9Sstevel@tonic-gate encrypted = cipher_data.cd_length; 64367c478bd9Sstevel@tonic-gate 64377c478bd9Sstevel@tonic-gate cipher_data.cd_offset += encrypted; 64387c478bd9Sstevel@tonic-gate cipher_data.cd_length = dual_data->dd_len1 - encrypted; 64397c478bd9Sstevel@tonic-gate 64407c478bd9Sstevel@tonic-gate if ((error = crypto_encrypt_final(DPROV_CTX_DUAL_CIPHER(ctx), 64417c478bd9Sstevel@tonic-gate &cipher_data, NULL)) != CRYPTO_SUCCESS) 64427c478bd9Sstevel@tonic-gate break; 64437c478bd9Sstevel@tonic-gate 64447c478bd9Sstevel@tonic-gate /* 64457c478bd9Sstevel@tonic-gate * Do a mac update on the resulting ciphertext, but with no 64467c478bd9Sstevel@tonic-gate * more bytes than specified by dual_data, and starting at 64477c478bd9Sstevel@tonic-gate * offset specified by dual_data. For in-place operations, 64487c478bd9Sstevel@tonic-gate * we use the length specified by the dual_data. 64497c478bd9Sstevel@tonic-gate */ 64507c478bd9Sstevel@tonic-gate mac_data = cipher_data; 64517c478bd9Sstevel@tonic-gate mac_data.cd_offset = dual_data->dd_offset2; 64527c478bd9Sstevel@tonic-gate mac_data.cd_length = dual_data->dd_len2; 64537c478bd9Sstevel@tonic-gate if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx), 64547c478bd9Sstevel@tonic-gate &mac_data, NULL)) != CRYPTO_SUCCESS) 64557c478bd9Sstevel@tonic-gate break; 64567c478bd9Sstevel@tonic-gate 64577c478bd9Sstevel@tonic-gate /* do a mac final */ 64587c478bd9Sstevel@tonic-gate error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx), 64597c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_mac, NULL); 64607c478bd9Sstevel@tonic-gate 64617c478bd9Sstevel@tonic-gate /* Set the total size of the ciphertext, when successful */ 64627c478bd9Sstevel@tonic-gate if (error == CRYPTO_SUCCESS) 64637c478bd9Sstevel@tonic-gate dual_data->dd_len1 = encrypted + cipher_data.cd_length; 64647c478bd9Sstevel@tonic-gate 64657c478bd9Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) { 64667c478bd9Sstevel@tonic-gate DPROV_CTX_DUAL_CIPHER(ctx) = NULL; 64677c478bd9Sstevel@tonic-gate DPROV_CTX_DUAL_MAC(ctx) = NULL; 64687c478bd9Sstevel@tonic-gate (void) dprov_free_context(ctx); 64697c478bd9Sstevel@tonic-gate } 64707c478bd9Sstevel@tonic-gate break; 64717c478bd9Sstevel@tonic-gate } 64727c478bd9Sstevel@tonic-gate 64737c478bd9Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_MAC_UPDATE: { 64747c478bd9Sstevel@tonic-gate crypto_data_t *plaintext_tmp, *ciphertext_tmp; 64757c478bd9Sstevel@tonic-gate size_t encrypted; 64767c478bd9Sstevel@tonic-gate ssize_t maclen; 64777c478bd9Sstevel@tonic-gate boolean_t inplace; 64787c478bd9Sstevel@tonic-gate 64797c478bd9Sstevel@tonic-gate cipher_data = *((crypto_data_t *)dual_data); 64807c478bd9Sstevel@tonic-gate 64817c478bd9Sstevel@tonic-gate /* do an encrypt update */ 64827c478bd9Sstevel@tonic-gate inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL); 64837c478bd9Sstevel@tonic-gate if (inplace) { 64847c478bd9Sstevel@tonic-gate plaintext_tmp = &cipher_data; 64857c478bd9Sstevel@tonic-gate ciphertext_tmp = NULL; 64867c478bd9Sstevel@tonic-gate } else { 64877c478bd9Sstevel@tonic-gate plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data; 64887c478bd9Sstevel@tonic-gate ciphertext_tmp = &cipher_data; 64897c478bd9Sstevel@tonic-gate } 64907c478bd9Sstevel@tonic-gate if ((error = crypto_encrypt_update(DPROV_CTX_DUAL_CIPHER(ctx), 64917c478bd9Sstevel@tonic-gate plaintext_tmp, ciphertext_tmp, NULL)) != CRYPTO_SUCCESS) 64927c478bd9Sstevel@tonic-gate break; 64937c478bd9Sstevel@tonic-gate 64947c478bd9Sstevel@tonic-gate encrypted = cipher_data.cd_length; 64957c478bd9Sstevel@tonic-gate 64967c478bd9Sstevel@tonic-gate /* 64977c478bd9Sstevel@tonic-gate * Do a mac update on the resulting ciphertext, but with no 64987c478bd9Sstevel@tonic-gate * more bytes than specified by dual_data, and starting at 64997c478bd9Sstevel@tonic-gate * offset specified by dual_data. For in-place operations, 65007c478bd9Sstevel@tonic-gate * we use the length specified by the dual_data. 65017c478bd9Sstevel@tonic-gate * There is an edge case, when the encryption step produced 65027c478bd9Sstevel@tonic-gate * zero bytes in the ciphertext. Only the portion between 65037c478bd9Sstevel@tonic-gate * offset2 and offset1 is then thrown in the MAC mix. 65047c478bd9Sstevel@tonic-gate */ 65057c478bd9Sstevel@tonic-gate maclen = dual_data->dd_offset1 - dual_data->dd_offset2 + 65067c478bd9Sstevel@tonic-gate encrypted; 65077c478bd9Sstevel@tonic-gate if (maclen > 0) { 65087c478bd9Sstevel@tonic-gate mac_data = cipher_data; 65097c478bd9Sstevel@tonic-gate mac_data.cd_offset = dual_data->dd_offset2; 65107c478bd9Sstevel@tonic-gate mac_data.cd_length = min(dual_data->dd_len2, maclen); 65117c478bd9Sstevel@tonic-gate if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx), 65127c478bd9Sstevel@tonic-gate &mac_data, NULL)) != CRYPTO_SUCCESS) 65137c478bd9Sstevel@tonic-gate break; 65147c478bd9Sstevel@tonic-gate } 65157c478bd9Sstevel@tonic-gate /* Set the total size of the ciphertext, when successful */ 65167c478bd9Sstevel@tonic-gate if (error == CRYPTO_SUCCESS) 65177c478bd9Sstevel@tonic-gate dual_data->dd_len1 = encrypted; 65187c478bd9Sstevel@tonic-gate 65197c478bd9Sstevel@tonic-gate break; 65207c478bd9Sstevel@tonic-gate } 65217c478bd9Sstevel@tonic-gate 65227c478bd9Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_MAC_FINAL: 65237c478bd9Sstevel@tonic-gate cipher_data = *((crypto_data_t *)dual_data); 65247c478bd9Sstevel@tonic-gate 65257c478bd9Sstevel@tonic-gate /* do an encrypt final */ 65267c478bd9Sstevel@tonic-gate if ((error = crypto_encrypt_final(DPROV_CTX_DUAL_CIPHER(ctx), 65277c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_data == NULL ? 65287c478bd9Sstevel@tonic-gate &cipher_data : taskq_req->dr_cipher_mac_req.mr_data, 65297c478bd9Sstevel@tonic-gate NULL)) != CRYPTO_SUCCESS) 65307c478bd9Sstevel@tonic-gate break; 65317c478bd9Sstevel@tonic-gate 65327c478bd9Sstevel@tonic-gate /* 65337c478bd9Sstevel@tonic-gate * If ciphertext length is different from zero, do a mac 65347c478bd9Sstevel@tonic-gate * update on it. This does not apply to in-place since we 65357c478bd9Sstevel@tonic-gate * do not allow partial updates, hence no final residual. 65367c478bd9Sstevel@tonic-gate */ 65377c478bd9Sstevel@tonic-gate if (taskq_req->dr_cipher_mac_req.mr_data != NULL && 65387c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_data->cd_length > 0) 65397c478bd9Sstevel@tonic-gate if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx), 65407c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_data, NULL)) != 65417c478bd9Sstevel@tonic-gate CRYPTO_SUCCESS) 65427c478bd9Sstevel@tonic-gate break; 65437c478bd9Sstevel@tonic-gate 65447c478bd9Sstevel@tonic-gate /* do a mac final */ 65457c478bd9Sstevel@tonic-gate error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx), 65467c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_mac, NULL); 65477c478bd9Sstevel@tonic-gate 65487c478bd9Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) { 65497c478bd9Sstevel@tonic-gate DPROV_CTX_DUAL_CIPHER(ctx) = NULL; 65507c478bd9Sstevel@tonic-gate DPROV_CTX_DUAL_MAC(ctx) = NULL; 65517c478bd9Sstevel@tonic-gate (void) dprov_free_context(ctx); 65527c478bd9Sstevel@tonic-gate } 65537c478bd9Sstevel@tonic-gate break; 65547c478bd9Sstevel@tonic-gate 65557c478bd9Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_MAC_ATOMIC: { 65567c478bd9Sstevel@tonic-gate crypto_data_t *plaintext_tmp, *ciphertext_tmp; 65577c478bd9Sstevel@tonic-gate boolean_t inplace; 65587c478bd9Sstevel@tonic-gate 65597c478bd9Sstevel@tonic-gate cipher_data = *((crypto_data_t *)dual_data); 65607c478bd9Sstevel@tonic-gate 65617c478bd9Sstevel@tonic-gate /* do an encrypt atomic */ 65627c478bd9Sstevel@tonic-gate inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL); 65637c478bd9Sstevel@tonic-gate if (inplace) { 65647c478bd9Sstevel@tonic-gate plaintext_tmp = &cipher_data; 65657c478bd9Sstevel@tonic-gate ciphertext_tmp = NULL; 65667c478bd9Sstevel@tonic-gate } else { 65677c478bd9Sstevel@tonic-gate plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data; 65687c478bd9Sstevel@tonic-gate ciphertext_tmp = &cipher_data; 65697c478bd9Sstevel@tonic-gate } 65707c478bd9Sstevel@tonic-gate 65717c478bd9Sstevel@tonic-gate /* structure assignment */ 65727c478bd9Sstevel@tonic-gate cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech; 65737c478bd9Sstevel@tonic-gate mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech; 65747c478bd9Sstevel@tonic-gate session_id = taskq_req->dr_cipher_mac_req.mr_session_id; 65757c478bd9Sstevel@tonic-gate 65767c478bd9Sstevel@tonic-gate /* get the keys values and providers to use for operations */ 65777c478bd9Sstevel@tonic-gate if ((error = dprov_cipher_mac_key_pd(softc, session_id, 65787c478bd9Sstevel@tonic-gate taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd, 65797c478bd9Sstevel@tonic-gate &cipher_mech.cm_type, &mac_mech.cm_type)) != 65807c478bd9Sstevel@tonic-gate CRYPTO_SUCCESS) 65817c478bd9Sstevel@tonic-gate break; 65827c478bd9Sstevel@tonic-gate 65837c478bd9Sstevel@tonic-gate /* do the atomic encrypt */ 6584894b2776Smcpowers if ((error = crypto_encrypt_prov(cipher_pd, 0, 65857c478bd9Sstevel@tonic-gate &cipher_mech, plaintext_tmp, &cipher_key, NULL, 6586894b2776Smcpowers ciphertext_tmp, NULL)) != CRYPTO_SUCCESS) 65877c478bd9Sstevel@tonic-gate break; 65887c478bd9Sstevel@tonic-gate 65897c478bd9Sstevel@tonic-gate /* do the atomic mac */ 65907c478bd9Sstevel@tonic-gate mac_data = cipher_data; 65917c478bd9Sstevel@tonic-gate mac_data.cd_length = dual_data->dd_len2; 65927c478bd9Sstevel@tonic-gate mac_data.cd_offset = dual_data->dd_offset2; 6593894b2776Smcpowers error = crypto_mac_prov(mac_pd, 0, &mac_mech, &mac_data, 6594894b2776Smcpowers &mac_key, NULL, taskq_req->dr_cipher_mac_req.mr_mac, NULL); 65957c478bd9Sstevel@tonic-gate 65967c478bd9Sstevel@tonic-gate dual_data->dd_len1 = cipher_data.cd_length; 65977c478bd9Sstevel@tonic-gate 65987c478bd9Sstevel@tonic-gate break; 65997c478bd9Sstevel@tonic-gate } 66007c478bd9Sstevel@tonic-gate 66017c478bd9Sstevel@tonic-gate case DPROV_REQ_MAC_DECRYPT: { 66027c478bd9Sstevel@tonic-gate uint_t decrypted; 66037c478bd9Sstevel@tonic-gate crypto_data_t plaintext_tmp; 66047c478bd9Sstevel@tonic-gate 66057c478bd9Sstevel@tonic-gate cipher_data = *((crypto_data_t *)dual_data); 66067c478bd9Sstevel@tonic-gate 66077c478bd9Sstevel@tonic-gate /* do a mac update and final on the ciphertext */ 66087c478bd9Sstevel@tonic-gate if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx), 66097c478bd9Sstevel@tonic-gate &mac_data, NULL)) != CRYPTO_SUCCESS) 66107c478bd9Sstevel@tonic-gate break; 66117c478bd9Sstevel@tonic-gate 66127c478bd9Sstevel@tonic-gate /* do a mac final */ 66137c478bd9Sstevel@tonic-gate if ((error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx), 66147c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_mac, NULL)) != 66157c478bd9Sstevel@tonic-gate CRYPTO_SUCCESS) 66167c478bd9Sstevel@tonic-gate break; 66177c478bd9Sstevel@tonic-gate 66187c478bd9Sstevel@tonic-gate /* do an decrypt update */ 66197c478bd9Sstevel@tonic-gate cipher_data = mac_data; 66207c478bd9Sstevel@tonic-gate cipher_data.cd_length = dual_data->dd_len2; 66217c478bd9Sstevel@tonic-gate cipher_data.cd_offset = dual_data->dd_offset2; 66227c478bd9Sstevel@tonic-gate if (taskq_req->dr_cipher_mac_req.mr_data == NULL) 66237c478bd9Sstevel@tonic-gate /* in-place */ 66247c478bd9Sstevel@tonic-gate plaintext_tmp = cipher_data; 66257c478bd9Sstevel@tonic-gate else 66267c478bd9Sstevel@tonic-gate plaintext_tmp = *taskq_req->dr_cipher_mac_req.mr_data; 66277c478bd9Sstevel@tonic-gate 66287c478bd9Sstevel@tonic-gate if ((error = crypto_decrypt_update(DPROV_CTX_DUAL_CIPHER(ctx), 66297c478bd9Sstevel@tonic-gate &cipher_data, taskq_req->dr_cipher_mac_req.mr_data, 66307c478bd9Sstevel@tonic-gate NULL)) != CRYPTO_SUCCESS) 66317c478bd9Sstevel@tonic-gate break; 66327c478bd9Sstevel@tonic-gate 66337c478bd9Sstevel@tonic-gate /* do an decrypt final */ 66347c478bd9Sstevel@tonic-gate if (taskq_req->dr_cipher_mac_req.mr_data == NULL) 66357c478bd9Sstevel@tonic-gate /* in-place, everything must have been decrypted */ 66367c478bd9Sstevel@tonic-gate decrypted = cipher_data.cd_length; 66377c478bd9Sstevel@tonic-gate else 66387c478bd9Sstevel@tonic-gate decrypted = 66397c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_data->cd_length; 66407c478bd9Sstevel@tonic-gate plaintext_tmp.cd_offset += decrypted; 66417c478bd9Sstevel@tonic-gate plaintext_tmp.cd_length -= decrypted; 66427c478bd9Sstevel@tonic-gate 66437c478bd9Sstevel@tonic-gate error = crypto_decrypt_final(DPROV_CTX_DUAL_CIPHER(ctx), 66447c478bd9Sstevel@tonic-gate &plaintext_tmp, NULL); 66457c478bd9Sstevel@tonic-gate if (taskq_req->dr_cipher_mac_req.mr_data != NULL) 66467c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_data->cd_length += 66477c478bd9Sstevel@tonic-gate plaintext_tmp.cd_length; 66487c478bd9Sstevel@tonic-gate 66497c478bd9Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) { 66507c478bd9Sstevel@tonic-gate DPROV_CTX_DUAL_MAC(ctx) = NULL; 66517c478bd9Sstevel@tonic-gate DPROV_CTX_DUAL_CIPHER(ctx) = NULL; 66527c478bd9Sstevel@tonic-gate (void) dprov_free_context(ctx); 66537c478bd9Sstevel@tonic-gate } 66547c478bd9Sstevel@tonic-gate break; 66557c478bd9Sstevel@tonic-gate } 66567c478bd9Sstevel@tonic-gate 66577c478bd9Sstevel@tonic-gate case DPROV_REQ_MAC_DECRYPT_UPDATE: 66587c478bd9Sstevel@tonic-gate cipher_data = *((crypto_data_t *)dual_data); 66597c478bd9Sstevel@tonic-gate 66607c478bd9Sstevel@tonic-gate /* do mac update */ 66617c478bd9Sstevel@tonic-gate if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx), 66627c478bd9Sstevel@tonic-gate &cipher_data, NULL)) != CRYPTO_SUCCESS) 66637c478bd9Sstevel@tonic-gate break; 66647c478bd9Sstevel@tonic-gate 66657c478bd9Sstevel@tonic-gate /* do a decrypt update */ 66667c478bd9Sstevel@tonic-gate cipher_data.cd_length = dual_data->dd_len2; 66677c478bd9Sstevel@tonic-gate cipher_data.cd_offset = dual_data->dd_offset2; 66687c478bd9Sstevel@tonic-gate error = crypto_decrypt_update(DPROV_CTX_DUAL_CIPHER(ctx), 66697c478bd9Sstevel@tonic-gate &cipher_data, taskq_req->dr_cipher_mac_req.mr_data, NULL); 66707c478bd9Sstevel@tonic-gate 66717c478bd9Sstevel@tonic-gate break; 66727c478bd9Sstevel@tonic-gate 66737c478bd9Sstevel@tonic-gate case DPROV_REQ_MAC_DECRYPT_FINAL: 66747c478bd9Sstevel@tonic-gate /* do a mac final */ 66757c478bd9Sstevel@tonic-gate if ((error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx), 66767c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_mac, NULL)) != 66777c478bd9Sstevel@tonic-gate CRYPTO_SUCCESS) 66787c478bd9Sstevel@tonic-gate break; 66797c478bd9Sstevel@tonic-gate 66807c478bd9Sstevel@tonic-gate /* do a decrypt final */ 66817c478bd9Sstevel@tonic-gate error = crypto_decrypt_final(DPROV_CTX_DUAL_CIPHER(ctx), 66827c478bd9Sstevel@tonic-gate taskq_req->dr_cipher_mac_req.mr_data, NULL); 66837c478bd9Sstevel@tonic-gate 66847c478bd9Sstevel@tonic-gate if (error != CRYPTO_BUFFER_TOO_SMALL) { 66857c478bd9Sstevel@tonic-gate DPROV_CTX_DUAL_MAC(ctx) = NULL; 66867c478bd9Sstevel@tonic-gate DPROV_CTX_DUAL_CIPHER(ctx) = NULL; 66877c478bd9Sstevel@tonic-gate (void) dprov_free_context(ctx); 66887c478bd9Sstevel@tonic-gate } 66897c478bd9Sstevel@tonic-gate break; 66907c478bd9Sstevel@tonic-gate 66917c478bd9Sstevel@tonic-gate case DPROV_REQ_MAC_DECRYPT_ATOMIC: 66927c478bd9Sstevel@tonic-gate case DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC: 66937c478bd9Sstevel@tonic-gate cipher_data = *((crypto_data_t *)dual_data); 66947c478bd9Sstevel@tonic-gate 66957c478bd9Sstevel@tonic-gate /* structure assignment */ 66967c478bd9Sstevel@tonic-gate cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech; 66977c478bd9Sstevel@tonic-gate mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech; 66987c478bd9Sstevel@tonic-gate session_id = taskq_req->dr_cipher_mac_req.mr_session_id; 66997c478bd9Sstevel@tonic-gate 67007c478bd9Sstevel@tonic-gate /* get the keys values and providers to use for operations */ 67017c478bd9Sstevel@tonic-gate if ((error = dprov_cipher_mac_key_pd(softc, session_id, 67027c478bd9Sstevel@tonic-gate taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd, 67037c478bd9Sstevel@tonic-gate &cipher_mech.cm_type, &mac_mech.cm_type)) != CRYPTO_SUCCESS) 67047c478bd9Sstevel@tonic-gate break; 67057c478bd9Sstevel@tonic-gate 67067c478bd9Sstevel@tonic-gate /* do the atomic mac */ 67077c478bd9Sstevel@tonic-gate if (taskq_req->dr_type == DPROV_REQ_MAC_DECRYPT_ATOMIC) 6708894b2776Smcpowers error = crypto_mac_prov(mac_pd, 0, &mac_mech, 6709894b2776Smcpowers &cipher_data, &mac_key, NULL, 6710894b2776Smcpowers taskq_req->dr_cipher_mac_req.mr_mac, NULL); 67117c478bd9Sstevel@tonic-gate else 67127c478bd9Sstevel@tonic-gate /* DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC */ 6713894b2776Smcpowers error = crypto_mac_verify_prov(mac_pd, 0, &mac_mech, 6714894b2776Smcpowers &cipher_data, &mac_key, NULL, 6715894b2776Smcpowers taskq_req->dr_cipher_mac_req.mr_mac, NULL); 67167c478bd9Sstevel@tonic-gate 67177c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) 67187c478bd9Sstevel@tonic-gate break; 67197c478bd9Sstevel@tonic-gate 67207c478bd9Sstevel@tonic-gate /* do the atomic decrypt */ 67217c478bd9Sstevel@tonic-gate cipher_data.cd_length = dual_data->dd_len2; 67227c478bd9Sstevel@tonic-gate cipher_data.cd_offset = dual_data->dd_offset2; 6723894b2776Smcpowers error = crypto_decrypt_prov(cipher_pd, 0, &cipher_mech, 6724894b2776Smcpowers &cipher_data, &cipher_key, NULL, 6725894b2776Smcpowers taskq_req->dr_cipher_mac_req.mr_data, NULL); 67267c478bd9Sstevel@tonic-gate 67277c478bd9Sstevel@tonic-gate break; 67287c478bd9Sstevel@tonic-gate } 67297c478bd9Sstevel@tonic-gate 67307c478bd9Sstevel@tonic-gate dprov_op_done(taskq_req, error); 67317c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_cipher_mac_task: end\n", 67327c478bd9Sstevel@tonic-gate instance)); 67337c478bd9Sstevel@tonic-gate } 67347c478bd9Sstevel@tonic-gate 67357c478bd9Sstevel@tonic-gate /* 67367c478bd9Sstevel@tonic-gate * taskq dispatcher function for random number generation. 67377c478bd9Sstevel@tonic-gate */ 67387c478bd9Sstevel@tonic-gate static void 67397c478bd9Sstevel@tonic-gate dprov_random_task(dprov_req_t *taskq_req) 67407c478bd9Sstevel@tonic-gate { 67417c478bd9Sstevel@tonic-gate dprov_state_t *softc; 67427c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 67437c478bd9Sstevel@tonic-gate int instance; 67447c478bd9Sstevel@tonic-gate int error = CRYPTO_SUCCESS; 67457c478bd9Sstevel@tonic-gate 67467c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 67477c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_RANDOM, ("(%d) dprov_random_task: started\n", instance)); 67487c478bd9Sstevel@tonic-gate 67497c478bd9Sstevel@tonic-gate mutex_enter(&softc->ds_lock); 67507c478bd9Sstevel@tonic-gate 67517c478bd9Sstevel@tonic-gate switch (taskq_req->dr_type) { 67527c478bd9Sstevel@tonic-gate 67537c478bd9Sstevel@tonic-gate DPROV_REQ_RANDOM_SEED: 67547c478bd9Sstevel@tonic-gate /* 67557c478bd9Sstevel@tonic-gate * Since we don't really generate random numbers 67567c478bd9Sstevel@tonic-gate * nothing to do. 67577c478bd9Sstevel@tonic-gate */ 67587c478bd9Sstevel@tonic-gate break; 67597c478bd9Sstevel@tonic-gate 67607c478bd9Sstevel@tonic-gate case DPROV_REQ_RANDOM_GENERATE: { 67617c478bd9Sstevel@tonic-gate uint_t i; 67627c478bd9Sstevel@tonic-gate uchar_t c = 0; 67637c478bd9Sstevel@tonic-gate 67647c478bd9Sstevel@tonic-gate /* 67657c478bd9Sstevel@tonic-gate * We don't generate random numbers so that the result 67667c478bd9Sstevel@tonic-gate * of the operation can be checked during testing. 67677c478bd9Sstevel@tonic-gate */ 67687c478bd9Sstevel@tonic-gate 67697c478bd9Sstevel@tonic-gate for (i = 0; i < taskq_req->dr_random_req.rr_len; i++) 67707c478bd9Sstevel@tonic-gate taskq_req->dr_random_req.rr_buf[i] = c++; 67717c478bd9Sstevel@tonic-gate 67727c478bd9Sstevel@tonic-gate break; 67737c478bd9Sstevel@tonic-gate } 67747c478bd9Sstevel@tonic-gate } 67757c478bd9Sstevel@tonic-gate 67767c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 67777c478bd9Sstevel@tonic-gate dprov_op_done(taskq_req, error); 67787c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_RANDOM, ("(%d) dprov_random_task: end\n", instance)); 67797c478bd9Sstevel@tonic-gate } 67807c478bd9Sstevel@tonic-gate 67817c478bd9Sstevel@tonic-gate 67827c478bd9Sstevel@tonic-gate /* 67837c478bd9Sstevel@tonic-gate * taskq dispatcher function for session management operations. 67847c478bd9Sstevel@tonic-gate */ 67857c478bd9Sstevel@tonic-gate static void 67867c478bd9Sstevel@tonic-gate dprov_session_task(dprov_req_t *taskq_req) 67877c478bd9Sstevel@tonic-gate { 67887c478bd9Sstevel@tonic-gate dprov_state_t *softc; 67897c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 67907c478bd9Sstevel@tonic-gate int instance; 67917c478bd9Sstevel@tonic-gate int error = CRYPTO_NOT_SUPPORTED; 67927c478bd9Sstevel@tonic-gate crypto_session_id_t session_id = 67937c478bd9Sstevel@tonic-gate taskq_req->dr_session_req.sr_session_id; 67947c478bd9Sstevel@tonic-gate dprov_session_t *session; 67957c478bd9Sstevel@tonic-gate dprov_object_t *object; 67967c478bd9Sstevel@tonic-gate int i; 67977c478bd9Sstevel@tonic-gate 67987c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 67997c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_task: started\n", 68007c478bd9Sstevel@tonic-gate instance)); 68017c478bd9Sstevel@tonic-gate 68027c478bd9Sstevel@tonic-gate mutex_enter(&softc->ds_lock); 68037c478bd9Sstevel@tonic-gate 68047c478bd9Sstevel@tonic-gate if (taskq_req->dr_type != DPROV_REQ_SESSION_OPEN) 68057c478bd9Sstevel@tonic-gate /* validate session id and get ptr to session */ 68067c478bd9Sstevel@tonic-gate if ((session = softc->ds_sessions[session_id]) == NULL) { 68077c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 68087c478bd9Sstevel@tonic-gate dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID); 68097c478bd9Sstevel@tonic-gate return; 68107c478bd9Sstevel@tonic-gate } 68117c478bd9Sstevel@tonic-gate 68127c478bd9Sstevel@tonic-gate switch (taskq_req->dr_type) { 68137c478bd9Sstevel@tonic-gate 68147c478bd9Sstevel@tonic-gate case DPROV_REQ_SESSION_OPEN: { 68157c478bd9Sstevel@tonic-gate dprov_session_t **new_sessions; 68167c478bd9Sstevel@tonic-gate 68177c478bd9Sstevel@tonic-gate if (softc->ds_token_initialized == B_FALSE) { 68187c478bd9Sstevel@tonic-gate error = CRYPTO_OPERATION_NOT_INITIALIZED; 68197c478bd9Sstevel@tonic-gate break; 68207c478bd9Sstevel@tonic-gate } 68217c478bd9Sstevel@tonic-gate 68227c478bd9Sstevel@tonic-gate /* search for available session slot */ 68237c478bd9Sstevel@tonic-gate for (i = 0; i < softc->ds_sessions_slots; i++) 68247c478bd9Sstevel@tonic-gate if (softc->ds_sessions[i] == NULL) 68257c478bd9Sstevel@tonic-gate break; 68267c478bd9Sstevel@tonic-gate 68277c478bd9Sstevel@tonic-gate if (i == softc->ds_sessions_slots) { 68287c478bd9Sstevel@tonic-gate /* ran out of slots, grow sessions array */ 68291ae80171SKrishna Yenduri new_sessions = kmem_zalloc( 68301ae80171SKrishna Yenduri 2 * softc->ds_sessions_slots * 68311ae80171SKrishna Yenduri sizeof (dprov_session_t *), KM_NOSLEEP); 68327c478bd9Sstevel@tonic-gate if (new_sessions == NULL) { 68337c478bd9Sstevel@tonic-gate error = CRYPTO_SESSION_COUNT; 68347c478bd9Sstevel@tonic-gate break; 68357c478bd9Sstevel@tonic-gate } 68367c478bd9Sstevel@tonic-gate bcopy(softc->ds_sessions, new_sessions, 68371ae80171SKrishna Yenduri softc->ds_sessions_slots * 68381ae80171SKrishna Yenduri sizeof (dprov_session_t *)); 68397c478bd9Sstevel@tonic-gate kmem_free(softc->ds_sessions, softc->ds_sessions_slots * 68407c478bd9Sstevel@tonic-gate sizeof (dprov_session_t *)); 68417c478bd9Sstevel@tonic-gate softc->ds_sessions = new_sessions; 68427c478bd9Sstevel@tonic-gate softc->ds_sessions_slots *= 2; 68437c478bd9Sstevel@tonic-gate } 68447c478bd9Sstevel@tonic-gate 68457c478bd9Sstevel@tonic-gate /* allocate and initialize new session */ 68467c478bd9Sstevel@tonic-gate softc->ds_sessions[i] = kmem_zalloc( 68477c478bd9Sstevel@tonic-gate sizeof (dprov_session_t), KM_NOSLEEP); 68487c478bd9Sstevel@tonic-gate if (softc->ds_sessions[i] == NULL) { 68497c478bd9Sstevel@tonic-gate error = CRYPTO_HOST_MEMORY; 68507c478bd9Sstevel@tonic-gate break; 68517c478bd9Sstevel@tonic-gate } 68527c478bd9Sstevel@tonic-gate softc->ds_sessions_count++; 68537c478bd9Sstevel@tonic-gate 68547c478bd9Sstevel@tonic-gate /* initialize session state */ 68557c478bd9Sstevel@tonic-gate softc->ds_sessions[i]->ds_state = DPROV_SESSION_STATE_PUBLIC; 68567c478bd9Sstevel@tonic-gate 68577c478bd9Sstevel@tonic-gate /* return new session id to caller */ 68587c478bd9Sstevel@tonic-gate *(taskq_req->dr_session_req.sr_session_id_ptr) = i; 68597c478bd9Sstevel@tonic-gate 68607c478bd9Sstevel@tonic-gate error = CRYPTO_SUCCESS; 68617c478bd9Sstevel@tonic-gate break; 68627c478bd9Sstevel@tonic-gate } 68637c478bd9Sstevel@tonic-gate 68647c478bd9Sstevel@tonic-gate case DPROV_REQ_SESSION_CLOSE: 68657c478bd9Sstevel@tonic-gate softc->ds_sessions[session_id] = NULL; 68667c478bd9Sstevel@tonic-gate 68677c478bd9Sstevel@tonic-gate if (softc->ds_token_initialized == B_FALSE) { 68687c478bd9Sstevel@tonic-gate error = CRYPTO_OPERATION_NOT_INITIALIZED; 68697c478bd9Sstevel@tonic-gate break; 68707c478bd9Sstevel@tonic-gate } 68717c478bd9Sstevel@tonic-gate 68727c478bd9Sstevel@tonic-gate dprov_release_session_objects(session); 68737c478bd9Sstevel@tonic-gate 68747c478bd9Sstevel@tonic-gate /* free session state and corresponding slot */ 68757c478bd9Sstevel@tonic-gate kmem_free(session, sizeof (dprov_session_t)); 68767c478bd9Sstevel@tonic-gate softc->ds_sessions_count--; 68777c478bd9Sstevel@tonic-gate 68787c478bd9Sstevel@tonic-gate error = CRYPTO_SUCCESS; 68797c478bd9Sstevel@tonic-gate break; 68807c478bd9Sstevel@tonic-gate 68817c478bd9Sstevel@tonic-gate case DPROV_REQ_SESSION_LOGIN: { 68827c478bd9Sstevel@tonic-gate char *pin = taskq_req->dr_session_req.sr_pin; 68837c478bd9Sstevel@tonic-gate size_t pin_len = taskq_req->dr_session_req.sr_pin_len; 68847c478bd9Sstevel@tonic-gate crypto_user_type_t user_type = 68857c478bd9Sstevel@tonic-gate taskq_req->dr_session_req.sr_user_type; 68867c478bd9Sstevel@tonic-gate 68877c478bd9Sstevel@tonic-gate /* check user type */ 68887c478bd9Sstevel@tonic-gate if (user_type != CRYPTO_SO && user_type != CRYPTO_USER) { 68897c478bd9Sstevel@tonic-gate error = CRYPTO_USER_TYPE_INVALID; 68907c478bd9Sstevel@tonic-gate break; 68917c478bd9Sstevel@tonic-gate } 68927c478bd9Sstevel@tonic-gate 68937c478bd9Sstevel@tonic-gate /* check pin length */ 68947c478bd9Sstevel@tonic-gate if (pin_len > DPROV_MAX_PIN_LEN) { 68957c478bd9Sstevel@tonic-gate error = CRYPTO_PIN_LEN_RANGE; 68967c478bd9Sstevel@tonic-gate break; 68977c478bd9Sstevel@tonic-gate } 68987c478bd9Sstevel@tonic-gate 68997c478bd9Sstevel@tonic-gate /* check pin */ 69007c478bd9Sstevel@tonic-gate if (pin == NULL) { 69017c478bd9Sstevel@tonic-gate error = CRYPTO_PIN_INVALID; 69027c478bd9Sstevel@tonic-gate break; 69037c478bd9Sstevel@tonic-gate } 69047c478bd9Sstevel@tonic-gate 69057c478bd9Sstevel@tonic-gate /* validate PIN state */ 69067c478bd9Sstevel@tonic-gate if ((user_type == CRYPTO_SO) && !softc->ds_token_initialized || 69077c478bd9Sstevel@tonic-gate (user_type == CRYPTO_USER) && !softc->ds_user_pin_set) { 69087c478bd9Sstevel@tonic-gate error = CRYPTO_USER_PIN_NOT_INITIALIZED; 69097c478bd9Sstevel@tonic-gate break; 69107c478bd9Sstevel@tonic-gate } 69117c478bd9Sstevel@tonic-gate 69127c478bd9Sstevel@tonic-gate if ((user_type == CRYPTO_SO && 69137c478bd9Sstevel@tonic-gate softc->ds_sessions[session_id]->ds_state == 69147c478bd9Sstevel@tonic-gate DPROV_SESSION_STATE_SO) || 69157c478bd9Sstevel@tonic-gate (user_type == CRYPTO_USER && 69167c478bd9Sstevel@tonic-gate softc->ds_sessions[session_id]->ds_state == 69177c478bd9Sstevel@tonic-gate DPROV_SESSION_STATE_USER)) { 69187c478bd9Sstevel@tonic-gate /* SO or user already logged in */ 69197c478bd9Sstevel@tonic-gate error = CRYPTO_USER_ALREADY_LOGGED_IN; 69207c478bd9Sstevel@tonic-gate break; 69217c478bd9Sstevel@tonic-gate } 69227c478bd9Sstevel@tonic-gate 69237c478bd9Sstevel@tonic-gate if (softc->ds_sessions[session_id]->ds_state != 69247c478bd9Sstevel@tonic-gate DPROV_SESSION_STATE_PUBLIC) { 69257c478bd9Sstevel@tonic-gate /* another user already logged in */ 69267c478bd9Sstevel@tonic-gate error = CRYPTO_USER_ANOTHER_ALREADY_LOGGED_IN; 69277c478bd9Sstevel@tonic-gate break; 69287c478bd9Sstevel@tonic-gate } 69297c478bd9Sstevel@tonic-gate 69307c478bd9Sstevel@tonic-gate /* everything's fine, update session */ 69317c478bd9Sstevel@tonic-gate softc->ds_sessions[session_id]->ds_state = 69327c478bd9Sstevel@tonic-gate user_type == CRYPTO_SO ? 69337c478bd9Sstevel@tonic-gate DPROV_SESSION_STATE_SO : DPROV_SESSION_STATE_USER; 69347c478bd9Sstevel@tonic-gate 69357c478bd9Sstevel@tonic-gate error = CRYPTO_SUCCESS; 69367c478bd9Sstevel@tonic-gate break; 69377c478bd9Sstevel@tonic-gate } 69387c478bd9Sstevel@tonic-gate 69397c478bd9Sstevel@tonic-gate case DPROV_REQ_SESSION_LOGOUT: 69407c478bd9Sstevel@tonic-gate /* fail if not logged in */ 69417c478bd9Sstevel@tonic-gate if (softc->ds_sessions[session_id]->ds_state == 69427c478bd9Sstevel@tonic-gate DPROV_SESSION_STATE_PUBLIC) { 69437c478bd9Sstevel@tonic-gate error = CRYPTO_USER_NOT_LOGGED_IN; 69447c478bd9Sstevel@tonic-gate break; 69457c478bd9Sstevel@tonic-gate } 69467c478bd9Sstevel@tonic-gate 69477c478bd9Sstevel@tonic-gate /* 69487c478bd9Sstevel@tonic-gate * Destroy all private session objects. 69497c478bd9Sstevel@tonic-gate * Invalidate handles to all private objects. 69507c478bd9Sstevel@tonic-gate */ 69517c478bd9Sstevel@tonic-gate for (i = 0; i < DPROV_MAX_OBJECTS; i++) { 69527c478bd9Sstevel@tonic-gate object = softc->ds_sessions[session_id]->ds_objects[i]; 69537c478bd9Sstevel@tonic-gate if (object != NULL && dprov_object_is_private(object)) { 69547c478bd9Sstevel@tonic-gate if (!dprov_object_is_token(object)) 69557c478bd9Sstevel@tonic-gate /* It's a session object, free it */ 69567c478bd9Sstevel@tonic-gate DPROV_OBJECT_REFRELE(object); 69577c478bd9Sstevel@tonic-gate softc->ds_sessions[session_id]->ds_objects[i] = 69587c478bd9Sstevel@tonic-gate NULL; 69597c478bd9Sstevel@tonic-gate } 69607c478bd9Sstevel@tonic-gate } 69617c478bd9Sstevel@tonic-gate 69627c478bd9Sstevel@tonic-gate /* update session state */ 69637c478bd9Sstevel@tonic-gate softc->ds_sessions[session_id]->ds_state = 69647c478bd9Sstevel@tonic-gate DPROV_SESSION_STATE_PUBLIC; 69657c478bd9Sstevel@tonic-gate 69667c478bd9Sstevel@tonic-gate error = CRYPTO_SUCCESS; 69677c478bd9Sstevel@tonic-gate break; 69687c478bd9Sstevel@tonic-gate } 69697c478bd9Sstevel@tonic-gate 69707c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 69717c478bd9Sstevel@tonic-gate dprov_op_done(taskq_req, error); 69727c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_task: end\n", instance)); 69737c478bd9Sstevel@tonic-gate } 69747c478bd9Sstevel@tonic-gate 6975894b2776Smcpowers /* return true if attribute is defined to be a PKCS#11 long */ 6976894b2776Smcpowers static boolean_t 6977894b2776Smcpowers fixed_size_attribute(crypto_attr_type_t type) 6978894b2776Smcpowers { 6979894b2776Smcpowers return (type == DPROV_CKA_CLASS || 6980894b2776Smcpowers type == DPROV_CKA_CERTIFICATE_TYPE || 6981894b2776Smcpowers type == DPROV_CKA_KEY_TYPE || 6982894b2776Smcpowers type == DPROV_HW_FEATURE_TYPE); 6983894b2776Smcpowers } 6984894b2776Smcpowers 6985894b2776Smcpowers /* 6986894b2776Smcpowers * Attributes defined to be a PKCS#11 long causes problems for dprov 6987894b2776Smcpowers * because 32-bit applications set the size to 4 and 64-bit applications 6988894b2776Smcpowers * set the size to 8. dprov always stores these fixed-size attributes 6989894b2776Smcpowers * as uint32_t. 6990894b2776Smcpowers */ 6991894b2776Smcpowers static ssize_t 6992894b2776Smcpowers attribute_size(crypto_attr_type_t type, ssize_t len) 6993894b2776Smcpowers { 6994894b2776Smcpowers if (fixed_size_attribute(type)) 6995894b2776Smcpowers return (sizeof (uint32_t)); 6996894b2776Smcpowers 6997894b2776Smcpowers return (len); 6998894b2776Smcpowers } 6999894b2776Smcpowers 70007c478bd9Sstevel@tonic-gate /* 70017c478bd9Sstevel@tonic-gate * taskq dispatcher function for object management operations. 70027c478bd9Sstevel@tonic-gate */ 70037c478bd9Sstevel@tonic-gate static void 70047c478bd9Sstevel@tonic-gate dprov_object_task(dprov_req_t *taskq_req) 70057c478bd9Sstevel@tonic-gate { 70067c478bd9Sstevel@tonic-gate dprov_state_t *softc; 70077c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 70087c478bd9Sstevel@tonic-gate int instance; 70097c478bd9Sstevel@tonic-gate int error = CRYPTO_NOT_SUPPORTED; 70107c478bd9Sstevel@tonic-gate crypto_object_id_t object_id = taskq_req->dr_object_req.or_object_id; 70117c478bd9Sstevel@tonic-gate crypto_session_id_t session_id = taskq_req->dr_object_req.or_session_id; 70127c478bd9Sstevel@tonic-gate crypto_object_attribute_t *template = 70137c478bd9Sstevel@tonic-gate taskq_req->dr_object_req.or_template; 70147c478bd9Sstevel@tonic-gate uint_t attr_count = taskq_req->dr_object_req.or_attribute_count; 70157c478bd9Sstevel@tonic-gate dprov_object_t *object; 70167c478bd9Sstevel@tonic-gate dprov_session_t *session; 70177c478bd9Sstevel@tonic-gate 70187c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 70197c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_task: started\n", instance)); 70207c478bd9Sstevel@tonic-gate 70217c478bd9Sstevel@tonic-gate mutex_enter(&softc->ds_lock); 70227c478bd9Sstevel@tonic-gate 70237c478bd9Sstevel@tonic-gate /* validate session id and get ptr to session */ 70247c478bd9Sstevel@tonic-gate if ((session = softc->ds_sessions[session_id]) == NULL) { 70257c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 70267c478bd9Sstevel@tonic-gate dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID); 70277c478bd9Sstevel@tonic-gate return; 70287c478bd9Sstevel@tonic-gate } 70297c478bd9Sstevel@tonic-gate 70307c478bd9Sstevel@tonic-gate switch (taskq_req->dr_type) { 70317c478bd9Sstevel@tonic-gate 70327c478bd9Sstevel@tonic-gate case DPROV_REQ_OBJECT_CREATE: 70337c478bd9Sstevel@tonic-gate /* create the object from the specified template */ 70347c478bd9Sstevel@tonic-gate if ((error = dprov_create_object_from_template(softc, session, 70357c478bd9Sstevel@tonic-gate template, attr_count, 70367c478bd9Sstevel@tonic-gate taskq_req->dr_object_req.or_object_id_ptr, B_TRUE, 70377c478bd9Sstevel@tonic-gate B_FALSE)) != CRYPTO_SUCCESS) 70387c478bd9Sstevel@tonic-gate break; 70397c478bd9Sstevel@tonic-gate 70407c478bd9Sstevel@tonic-gate break; 70417c478bd9Sstevel@tonic-gate 70427c478bd9Sstevel@tonic-gate case DPROV_REQ_OBJECT_COPY: 70437c478bd9Sstevel@tonic-gate /* check object id */ 70447c478bd9Sstevel@tonic-gate if (object_id >= DPROV_MAX_OBJECTS || 70457c478bd9Sstevel@tonic-gate (object = session->ds_objects[object_id]) == NULL) { 70467c478bd9Sstevel@tonic-gate error = CRYPTO_OBJECT_HANDLE_INVALID; 70477c478bd9Sstevel@tonic-gate break; 70487c478bd9Sstevel@tonic-gate } 70497c478bd9Sstevel@tonic-gate 70507c478bd9Sstevel@tonic-gate /* 70517c478bd9Sstevel@tonic-gate * Create a new object from the object passed as 70527c478bd9Sstevel@tonic-gate * argument. 70537c478bd9Sstevel@tonic-gate */ 70547c478bd9Sstevel@tonic-gate if ((error = dprov_create_object_from_template(softc, session, 70557c478bd9Sstevel@tonic-gate object->do_attr, DPROV_MAX_ATTR, 70567c478bd9Sstevel@tonic-gate taskq_req->dr_object_req.or_object_id_ptr, B_TRUE, 70577c478bd9Sstevel@tonic-gate B_FALSE)) != CRYPTO_SUCCESS) 70587c478bd9Sstevel@tonic-gate break; 70597c478bd9Sstevel@tonic-gate 70607c478bd9Sstevel@tonic-gate /* 70617c478bd9Sstevel@tonic-gate * Add the attributes specified by the template to the 70627c478bd9Sstevel@tonic-gate * newly created object, replacing existing ones if needed. 70637c478bd9Sstevel@tonic-gate */ 70647c478bd9Sstevel@tonic-gate error = dprov_object_set_attr(session, 70657c478bd9Sstevel@tonic-gate *taskq_req->dr_object_req.or_object_id_ptr, 70667c478bd9Sstevel@tonic-gate taskq_req->dr_object_req.or_template, 70677c478bd9Sstevel@tonic-gate taskq_req->dr_object_req.or_attribute_count, B_TRUE); 70687c478bd9Sstevel@tonic-gate 70697c478bd9Sstevel@tonic-gate break; 70707c478bd9Sstevel@tonic-gate 70717c478bd9Sstevel@tonic-gate case DPROV_REQ_OBJECT_DESTROY: 70727c478bd9Sstevel@tonic-gate /* destroy the object */ 70737c478bd9Sstevel@tonic-gate error = dprov_destroy_object(softc, session, 70747c478bd9Sstevel@tonic-gate taskq_req->dr_object_req.or_object_id); 70757c478bd9Sstevel@tonic-gate 70767c478bd9Sstevel@tonic-gate break; 70777c478bd9Sstevel@tonic-gate 70787c478bd9Sstevel@tonic-gate case DPROV_REQ_OBJECT_GET_SIZE: 70797c478bd9Sstevel@tonic-gate /* get ptr to object */ 70807c478bd9Sstevel@tonic-gate if (object_id >= DPROV_MAX_OBJECTS || 70817c478bd9Sstevel@tonic-gate session->ds_objects[object_id] == NULL) { 70827c478bd9Sstevel@tonic-gate error = CRYPTO_OBJECT_HANDLE_INVALID; 70837c478bd9Sstevel@tonic-gate break; 70847c478bd9Sstevel@tonic-gate } 70857c478bd9Sstevel@tonic-gate 70867c478bd9Sstevel@tonic-gate /* 70877c478bd9Sstevel@tonic-gate * The PKCS11 specification does not specifies what 70887c478bd9Sstevel@tonic-gate * the object size really is, here we just return 70897c478bd9Sstevel@tonic-gate * the number of possible attributes of the object. 70907c478bd9Sstevel@tonic-gate */ 70917c478bd9Sstevel@tonic-gate *taskq_req->dr_object_req.or_object_size = DPROV_MAX_ATTR; 70927c478bd9Sstevel@tonic-gate 70937c478bd9Sstevel@tonic-gate error = CRYPTO_SUCCESS; 70947c478bd9Sstevel@tonic-gate break; 70957c478bd9Sstevel@tonic-gate 70967c478bd9Sstevel@tonic-gate case DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE: { 7097894b2776Smcpowers crypto_attr_type_t type; 7098894b2776Smcpowers size_t olen, tlen; 7099894b2776Smcpowers offset_t offset; 71007c478bd9Sstevel@tonic-gate int tmpl_idx; 71017c478bd9Sstevel@tonic-gate int object_idx; 71027c478bd9Sstevel@tonic-gate ulong_t class = DPROV_CKO_DATA; 71037c478bd9Sstevel@tonic-gate boolean_t extractable = B_TRUE; 71047c478bd9Sstevel@tonic-gate 71057c478bd9Sstevel@tonic-gate error = CRYPTO_SUCCESS; 71067c478bd9Sstevel@tonic-gate 71077c478bd9Sstevel@tonic-gate /* get ptr to object */ 71087c478bd9Sstevel@tonic-gate if (object_id >= DPROV_MAX_OBJECTS || 71097c478bd9Sstevel@tonic-gate (object = session->ds_objects[object_id]) == NULL) { 71107c478bd9Sstevel@tonic-gate error = CRYPTO_OBJECT_HANDLE_INVALID; 71117c478bd9Sstevel@tonic-gate break; 71127c478bd9Sstevel@tonic-gate } 71137c478bd9Sstevel@tonic-gate 71147c478bd9Sstevel@tonic-gate (void) dprov_get_object_attr_boolean(object, 71157c478bd9Sstevel@tonic-gate DPROV_CKA_EXTRACTABLE, &extractable); 71167c478bd9Sstevel@tonic-gate 71177c478bd9Sstevel@tonic-gate (void) dprov_get_object_attr_ulong(object, 71187c478bd9Sstevel@tonic-gate DPROV_CKA_CLASS, &class); 71197c478bd9Sstevel@tonic-gate 71207c478bd9Sstevel@tonic-gate /* return the specified attributes, when possible */ 71217c478bd9Sstevel@tonic-gate for (tmpl_idx = 0; tmpl_idx < attr_count; tmpl_idx++) { 71227c478bd9Sstevel@tonic-gate /* 71237c478bd9Sstevel@tonic-gate * Attribute can't be revealed if the CKA_EXTRACTABLE 71247c478bd9Sstevel@tonic-gate * attribute is set to false. 71257c478bd9Sstevel@tonic-gate */ 7126894b2776Smcpowers type = template[tmpl_idx].oa_type; 71277c478bd9Sstevel@tonic-gate if (!extractable && class == DPROV_CKO_SECRET_KEY) { 7128894b2776Smcpowers if (type == DPROV_CKA_VALUE) { 71297c478bd9Sstevel@tonic-gate template[tmpl_idx].oa_value_len = -1; 71307c478bd9Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_SENSITIVE; 71317c478bd9Sstevel@tonic-gate continue; 71327c478bd9Sstevel@tonic-gate } 71337c478bd9Sstevel@tonic-gate } 71347c478bd9Sstevel@tonic-gate if (!extractable && class == DPROV_CKO_PRIVATE_KEY) { 7135894b2776Smcpowers if (type == DPROV_CKA_PRIVATE_EXPONENT) { 71367c478bd9Sstevel@tonic-gate template[tmpl_idx].oa_value_len = -1; 71377c478bd9Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_SENSITIVE; 71387c478bd9Sstevel@tonic-gate continue; 71397c478bd9Sstevel@tonic-gate } 71407c478bd9Sstevel@tonic-gate } 71417c478bd9Sstevel@tonic-gate 71427c478bd9Sstevel@tonic-gate object_idx = dprov_find_attr(object->do_attr, 7143894b2776Smcpowers DPROV_MAX_ATTR, type); 71447c478bd9Sstevel@tonic-gate if (object_idx == -1) { 71457c478bd9Sstevel@tonic-gate /* attribute not found in object */ 71467c478bd9Sstevel@tonic-gate template[tmpl_idx].oa_value_len = -1; 71477c478bd9Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_TYPE_INVALID; 71487c478bd9Sstevel@tonic-gate continue; 71497c478bd9Sstevel@tonic-gate } 71507c478bd9Sstevel@tonic-gate 7151894b2776Smcpowers tlen = template[tmpl_idx].oa_value_len; 7152894b2776Smcpowers olen = object->do_attr[object_idx].oa_value_len; 71537c478bd9Sstevel@tonic-gate /* return attribute length */ 7154894b2776Smcpowers if (template[tmpl_idx].oa_value == NULL) { 7155894b2776Smcpowers /* 7156894b2776Smcpowers * The size of the attribute is set by the 7157894b2776Smcpowers * library according to the data model of the 7158894b2776Smcpowers * application, so don't overwrite it with 7159894b2776Smcpowers * dprov's size. 7160894b2776Smcpowers */ 7161894b2776Smcpowers if (!fixed_size_attribute(type)) 7162894b2776Smcpowers template[tmpl_idx].oa_value_len = olen; 71637c478bd9Sstevel@tonic-gate continue; 71647c478bd9Sstevel@tonic-gate } 7165894b2776Smcpowers 7166894b2776Smcpowers if (tlen < olen) { 71677c478bd9Sstevel@tonic-gate template[tmpl_idx].oa_value_len = -1; 71687c478bd9Sstevel@tonic-gate error = CRYPTO_BUFFER_TOO_SMALL; 71697c478bd9Sstevel@tonic-gate continue; 71707c478bd9Sstevel@tonic-gate } 7171894b2776Smcpowers 7172894b2776Smcpowers /* copy attribute value */ 7173894b2776Smcpowers bzero(template[tmpl_idx].oa_value, tlen); 7174894b2776Smcpowers 7175894b2776Smcpowers offset = 0; 7176894b2776Smcpowers #ifdef _BIG_ENDIAN 7177894b2776Smcpowers if (fixed_size_attribute(type)) { 7178894b2776Smcpowers offset = tlen - olen; 7179894b2776Smcpowers } 7180894b2776Smcpowers #endif 71817c478bd9Sstevel@tonic-gate bcopy(object->do_attr[object_idx].oa_value, 7182894b2776Smcpowers &template[tmpl_idx].oa_value[offset], olen); 7183894b2776Smcpowers 7184894b2776Smcpowers /* don't update length for fixed-size attributes */ 7185894b2776Smcpowers if (!fixed_size_attribute(type)) 7186894b2776Smcpowers template[tmpl_idx].oa_value_len = olen; 71877c478bd9Sstevel@tonic-gate } 71887c478bd9Sstevel@tonic-gate 71897c478bd9Sstevel@tonic-gate break; 71907c478bd9Sstevel@tonic-gate } 71917c478bd9Sstevel@tonic-gate 71927c478bd9Sstevel@tonic-gate case DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE: 71937c478bd9Sstevel@tonic-gate /* 71947c478bd9Sstevel@tonic-gate * Add the attributes specified by the template to the 71957c478bd9Sstevel@tonic-gate * newly created object, replacing existing ones if needed. 71967c478bd9Sstevel@tonic-gate */ 71977c478bd9Sstevel@tonic-gate error = dprov_object_set_attr(session, 71987c478bd9Sstevel@tonic-gate taskq_req->dr_object_req.or_object_id, 71997c478bd9Sstevel@tonic-gate taskq_req->dr_object_req.or_template, 72007c478bd9Sstevel@tonic-gate taskq_req->dr_object_req.or_attribute_count, B_TRUE); 72017c478bd9Sstevel@tonic-gate 72027c478bd9Sstevel@tonic-gate break; 72037c478bd9Sstevel@tonic-gate 72047c478bd9Sstevel@tonic-gate case DPROV_REQ_OBJECT_FIND_INIT: { 72057c478bd9Sstevel@tonic-gate dprov_find_ctx_t *find_ctx; 72067c478bd9Sstevel@tonic-gate int so_idx; /* session object index */ 72077c478bd9Sstevel@tonic-gate int to_idx; /* token object index */ 72087c478bd9Sstevel@tonic-gate 72097c478bd9Sstevel@tonic-gate error = CRYPTO_SUCCESS; 72107c478bd9Sstevel@tonic-gate /* allocate find context */ 72117c478bd9Sstevel@tonic-gate find_ctx = kmem_zalloc(sizeof (dprov_find_ctx_t), KM_SLEEP); 72127c478bd9Sstevel@tonic-gate *taskq_req->dr_object_req.or_find_pp = find_ctx; 72137c478bd9Sstevel@tonic-gate 72147c478bd9Sstevel@tonic-gate /* first go through the existing session objects */ 72157c478bd9Sstevel@tonic-gate for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++) { 72167c478bd9Sstevel@tonic-gate if ((object = session->ds_objects[so_idx]) == NULL) 72177c478bd9Sstevel@tonic-gate continue; 72187c478bd9Sstevel@tonic-gate 72197c478bd9Sstevel@tonic-gate /* setting count to zero means find all objects */ 72207c478bd9Sstevel@tonic-gate if (attr_count > 0) { 72217c478bd9Sstevel@tonic-gate if (!dprov_attributes_match(object, template, 72227c478bd9Sstevel@tonic-gate attr_count)) 72237c478bd9Sstevel@tonic-gate continue; 72247c478bd9Sstevel@tonic-gate } 72257c478bd9Sstevel@tonic-gate 72267c478bd9Sstevel@tonic-gate /* session object attributes matches template */ 72277c478bd9Sstevel@tonic-gate find_ctx->fc_ids[find_ctx->fc_nids] = so_idx; 72287c478bd9Sstevel@tonic-gate find_ctx->fc_nids++; 72297c478bd9Sstevel@tonic-gate } 72307c478bd9Sstevel@tonic-gate 72317c478bd9Sstevel@tonic-gate /* 72327c478bd9Sstevel@tonic-gate * Go through the token object. For each token object 72337c478bd9Sstevel@tonic-gate * that can be accessed: 72347c478bd9Sstevel@tonic-gate * If there was already an session object id assigned 72357c478bd9Sstevel@tonic-gate * to that token object, skip it, since it was returned 72367c478bd9Sstevel@tonic-gate * during the check of session objects, else, 72377c478bd9Sstevel@tonic-gate * assign a new object id for that token object and 72387c478bd9Sstevel@tonic-gate * add it to the array of matching objects. 72397c478bd9Sstevel@tonic-gate */ 72407c478bd9Sstevel@tonic-gate for (to_idx = 0; to_idx < DPROV_MAX_OBJECTS && 72417c478bd9Sstevel@tonic-gate error == CRYPTO_SUCCESS; to_idx++) { 72427c478bd9Sstevel@tonic-gate if ((object = softc->ds_objects[to_idx]) == NULL) 72437c478bd9Sstevel@tonic-gate continue; 72447c478bd9Sstevel@tonic-gate 72457c478bd9Sstevel@tonic-gate /* setting count to zero means find all objects */ 72467c478bd9Sstevel@tonic-gate if (attr_count > 0) { 72477c478bd9Sstevel@tonic-gate if (!dprov_attributes_match(object, template, 72487c478bd9Sstevel@tonic-gate attr_count)) 72497c478bd9Sstevel@tonic-gate continue; 72507c478bd9Sstevel@tonic-gate } 72517c478bd9Sstevel@tonic-gate 72527c478bd9Sstevel@tonic-gate /* if the the object has been destroyed, skip it */ 72537c478bd9Sstevel@tonic-gate if (object->do_destroyed) 72547c478bd9Sstevel@tonic-gate continue; 72557c478bd9Sstevel@tonic-gate 72567c478bd9Sstevel@tonic-gate /* skip object if it cannot be accessed from session */ 72577c478bd9Sstevel@tonic-gate if (dprov_object_is_private(object) && 72587c478bd9Sstevel@tonic-gate session->ds_state != DPROV_SESSION_STATE_USER) 72597c478bd9Sstevel@tonic-gate continue; 72607c478bd9Sstevel@tonic-gate 72617c478bd9Sstevel@tonic-gate /* 72627c478bd9Sstevel@tonic-gate * Is there already a session object id for this 72637c478bd9Sstevel@tonic-gate * token object? 72647c478bd9Sstevel@tonic-gate */ 72657c478bd9Sstevel@tonic-gate for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++) 72667c478bd9Sstevel@tonic-gate if (session->ds_objects[so_idx] != NULL && 72677c478bd9Sstevel@tonic-gate session->ds_objects[so_idx]->do_token_idx == 72687c478bd9Sstevel@tonic-gate to_idx) 72697c478bd9Sstevel@tonic-gate break; 72707c478bd9Sstevel@tonic-gate if (so_idx < DPROV_MAX_OBJECTS) 72717c478bd9Sstevel@tonic-gate /* object found in session table, skip it */ 72727c478bd9Sstevel@tonic-gate continue; 72737c478bd9Sstevel@tonic-gate 72747c478bd9Sstevel@tonic-gate /* find free session slot for this object */ 72757c478bd9Sstevel@tonic-gate for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++) 72767c478bd9Sstevel@tonic-gate if (session->ds_objects[so_idx] == NULL) 72777c478bd9Sstevel@tonic-gate break; 72787c478bd9Sstevel@tonic-gate if (so_idx == DPROV_MAX_OBJECTS) { 72797c478bd9Sstevel@tonic-gate /* ran out of session objects slots */ 72807c478bd9Sstevel@tonic-gate kmem_free(find_ctx, sizeof (dprov_find_ctx_t)); 72817c478bd9Sstevel@tonic-gate error = CRYPTO_HOST_MEMORY; 72827c478bd9Sstevel@tonic-gate break; 72837c478bd9Sstevel@tonic-gate } 72847c478bd9Sstevel@tonic-gate 72857c478bd9Sstevel@tonic-gate /* add object to session objects table */ 72867c478bd9Sstevel@tonic-gate session->ds_objects[so_idx] = object; 72877c478bd9Sstevel@tonic-gate DPROV_OBJECT_REFHOLD(object); 72887c478bd9Sstevel@tonic-gate 72897c478bd9Sstevel@tonic-gate /* add object to list of objects to return */ 72907c478bd9Sstevel@tonic-gate find_ctx->fc_ids[find_ctx->fc_nids] = so_idx; 72917c478bd9Sstevel@tonic-gate find_ctx->fc_nids++; 72927c478bd9Sstevel@tonic-gate } 72937c478bd9Sstevel@tonic-gate 72947c478bd9Sstevel@tonic-gate break; 72957c478bd9Sstevel@tonic-gate } 72967c478bd9Sstevel@tonic-gate 72977c478bd9Sstevel@tonic-gate case DPROV_REQ_OBJECT_FIND: { 72987c478bd9Sstevel@tonic-gate crypto_object_id_t *object_ids = 72997c478bd9Sstevel@tonic-gate taskq_req->dr_object_req.or_object_id_ptr; 73007c478bd9Sstevel@tonic-gate uint_t max_object_count = 73017c478bd9Sstevel@tonic-gate taskq_req->dr_object_req.or_max_object_count; 73027c478bd9Sstevel@tonic-gate dprov_find_ctx_t *find_ctx = 73037c478bd9Sstevel@tonic-gate taskq_req->dr_object_req.or_find_p; 73047c478bd9Sstevel@tonic-gate uint_t ret_oid_idx; 73057c478bd9Sstevel@tonic-gate 73067c478bd9Sstevel@tonic-gate /* return the desired number of object ids */ 73077c478bd9Sstevel@tonic-gate for (ret_oid_idx = 0; ret_oid_idx < max_object_count && 73087c478bd9Sstevel@tonic-gate find_ctx->fc_next < find_ctx->fc_nids; ret_oid_idx++) 73097c478bd9Sstevel@tonic-gate object_ids[ret_oid_idx] = 73107c478bd9Sstevel@tonic-gate find_ctx->fc_ids[find_ctx->fc_next++]; 73117c478bd9Sstevel@tonic-gate 73127c478bd9Sstevel@tonic-gate *taskq_req->dr_object_req.or_object_count_ptr = ret_oid_idx; 73137c478bd9Sstevel@tonic-gate 73147c478bd9Sstevel@tonic-gate error = CRYPTO_SUCCESS; 73157c478bd9Sstevel@tonic-gate break; 73167c478bd9Sstevel@tonic-gate } 73177c478bd9Sstevel@tonic-gate 73187c478bd9Sstevel@tonic-gate case DPROV_REQ_OBJECT_FIND_FINAL: 73197c478bd9Sstevel@tonic-gate kmem_free(taskq_req->dr_object_req.or_find_p, 73207c478bd9Sstevel@tonic-gate sizeof (dprov_find_ctx_t)); 73217c478bd9Sstevel@tonic-gate 73227c478bd9Sstevel@tonic-gate error = CRYPTO_SUCCESS; 73237c478bd9Sstevel@tonic-gate break; 73247c478bd9Sstevel@tonic-gate } 73257c478bd9Sstevel@tonic-gate 73267c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 73277c478bd9Sstevel@tonic-gate dprov_op_done(taskq_req, error); 73287c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_task: end\n", instance)); 73297c478bd9Sstevel@tonic-gate } 73307c478bd9Sstevel@tonic-gate 73317c478bd9Sstevel@tonic-gate /* 73325b0c7657Sizick * Copy attribute values into a template. RSA values are precomputed. 73335b0c7657Sizick */ 73345b0c7657Sizick static int 73355b0c7657Sizick nostore_copy_attribute(crypto_object_attribute_t *template, uint_t count, 73365b0c7657Sizick uint64_t attr_type) 73375b0c7657Sizick { 73385b0c7657Sizick void *value, *dprov_attribute_value; 73395b0c7657Sizick size_t dprov_attribute_size; 73405b0c7657Sizick size_t value_len = 0; 73415b0c7657Sizick int error; 73425b0c7657Sizick 73435b0c7657Sizick switch (attr_type) { 73445b0c7657Sizick case DPROV_CKA_VALUE: 73455b0c7657Sizick dprov_attribute_size = sizeof (dh_value); 73465b0c7657Sizick dprov_attribute_value = dh_value; 73475b0c7657Sizick break; 73485b0c7657Sizick 73495b0c7657Sizick case DPROV_CKA_MODULUS: 73505b0c7657Sizick dprov_attribute_size = sizeof (modulus); 73515b0c7657Sizick dprov_attribute_value = modulus; 73525b0c7657Sizick break; 73535b0c7657Sizick 73545b0c7657Sizick case DPROV_CKA_PUBLIC_EXPONENT: 73555b0c7657Sizick dprov_attribute_size = sizeof (public_exponent); 73565b0c7657Sizick dprov_attribute_value = public_exponent; 73575b0c7657Sizick break; 73585b0c7657Sizick 73595b0c7657Sizick case DPROV_CKA_PRIVATE_EXPONENT: 73605b0c7657Sizick dprov_attribute_size = sizeof (private_exponent); 73615b0c7657Sizick dprov_attribute_value = private_exponent; 73625b0c7657Sizick break; 73635b0c7657Sizick 73645b0c7657Sizick default: 73655b0c7657Sizick return (CRYPTO_ATTRIBUTE_TYPE_INVALID); 73665b0c7657Sizick } 73675b0c7657Sizick 73685b0c7657Sizick error = dprov_get_template_attr_array(template, count, attr_type, 73695b0c7657Sizick &value, &value_len); 73705b0c7657Sizick if (error != CRYPTO_SUCCESS) 73715b0c7657Sizick return (error); 73725b0c7657Sizick 73735b0c7657Sizick if (value_len < dprov_attribute_size) 73745b0c7657Sizick return (CRYPTO_BUFFER_TOO_SMALL); 73755b0c7657Sizick 73765b0c7657Sizick /* 73775b0c7657Sizick * The updated template will be returned to libpkcs11. 73785b0c7657Sizick */ 73795b0c7657Sizick bcopy(dprov_attribute_value, value, dprov_attribute_size); 73805b0c7657Sizick 73815b0c7657Sizick return (CRYPTO_SUCCESS); 73825b0c7657Sizick } 73835b0c7657Sizick 73845b0c7657Sizick static void 73855b0c7657Sizick fill_dh(void *value, size_t len) 73865b0c7657Sizick { 73875b0c7657Sizick int i = 0; 73885b0c7657Sizick char *p = value; 73895b0c7657Sizick while (i < len) { 73905b0c7657Sizick p[i++] = 'D'; 73915b0c7657Sizick if (i >= len) 73925b0c7657Sizick break; 73935b0c7657Sizick p[i++] = 'H'; 73945b0c7657Sizick } 73955b0c7657Sizick } 73965b0c7657Sizick 73975b0c7657Sizick /* 73987c478bd9Sstevel@tonic-gate * taskq dispatcher function for key management operations. 73997c478bd9Sstevel@tonic-gate */ 74007c478bd9Sstevel@tonic-gate static void 74017c478bd9Sstevel@tonic-gate dprov_key_task(dprov_req_t *taskq_req) 74027c478bd9Sstevel@tonic-gate { 74037c478bd9Sstevel@tonic-gate dprov_state_t *softc; 74047c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 74057c478bd9Sstevel@tonic-gate int instance; 74067c478bd9Sstevel@tonic-gate int error = CRYPTO_NOT_SUPPORTED; 74077c478bd9Sstevel@tonic-gate kcf_provider_desc_t *pd; 74087c478bd9Sstevel@tonic-gate crypto_session_id_t session_id = taskq_req->dr_key_req.kr_session_id; 74097c478bd9Sstevel@tonic-gate dprov_session_t *session; 74107c478bd9Sstevel@tonic-gate 74117c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 74127c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_task: started\n", instance)); 74137c478bd9Sstevel@tonic-gate 74147c478bd9Sstevel@tonic-gate mutex_enter(&softc->ds_lock); 74157c478bd9Sstevel@tonic-gate 74167c478bd9Sstevel@tonic-gate /* validate session id and get ptr to session */ 74177c478bd9Sstevel@tonic-gate if ((session = softc->ds_sessions[session_id]) == NULL) { 74187c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 74197c478bd9Sstevel@tonic-gate dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID); 74207c478bd9Sstevel@tonic-gate return; 74217c478bd9Sstevel@tonic-gate } 74227c478bd9Sstevel@tonic-gate 74237c478bd9Sstevel@tonic-gate switch (taskq_req->dr_type) { 74247c478bd9Sstevel@tonic-gate case DPROV_REQ_KEY_GENERATE: { 74257c478bd9Sstevel@tonic-gate crypto_mechanism_t *mechp; 74267c478bd9Sstevel@tonic-gate crypto_object_id_t *object_id_ptr; 74277c478bd9Sstevel@tonic-gate crypto_object_attribute_t *template; 74287c478bd9Sstevel@tonic-gate crypto_object_attribute_t attribute; 74297c478bd9Sstevel@tonic-gate uint_t attribute_count; 74307c478bd9Sstevel@tonic-gate ulong_t key_type = ~0UL, class = ~0UL; 74317c478bd9Sstevel@tonic-gate ulong_t value_len; 74327c478bd9Sstevel@tonic-gate size_t key_len = 0; 74337c478bd9Sstevel@tonic-gate 74347c478bd9Sstevel@tonic-gate error = CRYPTO_SUCCESS; 74357c478bd9Sstevel@tonic-gate 74367c478bd9Sstevel@tonic-gate template = taskq_req->dr_key_req.kr_template; 74377c478bd9Sstevel@tonic-gate attribute_count = taskq_req->dr_key_req.kr_attribute_count; 74387c478bd9Sstevel@tonic-gate object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr; 74397c478bd9Sstevel@tonic-gate mechp = taskq_req->dr_key_req.kr_mechanism; 74407c478bd9Sstevel@tonic-gate 74417c478bd9Sstevel@tonic-gate /* optional */ 74427c478bd9Sstevel@tonic-gate (void) dprov_get_template_attr_ulong(template, attribute_count, 74437c478bd9Sstevel@tonic-gate DPROV_CKA_CLASS, &class); 74447c478bd9Sstevel@tonic-gate 74457c478bd9Sstevel@tonic-gate /* optional */ 74467c478bd9Sstevel@tonic-gate (void) dprov_get_template_attr_ulong(template, attribute_count, 74477c478bd9Sstevel@tonic-gate DPROV_CKA_KEY_TYPE, &key_type); 74487c478bd9Sstevel@tonic-gate 74497c478bd9Sstevel@tonic-gate if (class != ~0UL && class != DPROV_CKO_SECRET_KEY) { 74507c478bd9Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT; 74517c478bd9Sstevel@tonic-gate break; 74527c478bd9Sstevel@tonic-gate } 74537c478bd9Sstevel@tonic-gate 74547c478bd9Sstevel@tonic-gate switch (mechp->cm_type) { 74557c478bd9Sstevel@tonic-gate case DES_KEY_GEN_MECH_INFO_TYPE: 74567c478bd9Sstevel@tonic-gate if (key_type != ~0UL && key_type != DPROV_CKK_DES) { 74577c478bd9Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT; 74587c478bd9Sstevel@tonic-gate break; 74597c478bd9Sstevel@tonic-gate } 74607c478bd9Sstevel@tonic-gate key_len = DES_KEY_LEN; 74617c478bd9Sstevel@tonic-gate key_type = DPROV_CKK_DES; 74627c478bd9Sstevel@tonic-gate break; 74637c478bd9Sstevel@tonic-gate 74647c478bd9Sstevel@tonic-gate case DES3_KEY_GEN_MECH_INFO_TYPE: 74657c478bd9Sstevel@tonic-gate if (key_type != ~0UL && key_type != DPROV_CKK_DES3) { 74667c478bd9Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT; 74677c478bd9Sstevel@tonic-gate break; 74687c478bd9Sstevel@tonic-gate } 74697c478bd9Sstevel@tonic-gate key_len = DES3_KEY_LEN; 74707c478bd9Sstevel@tonic-gate key_type = DPROV_CKK_DES3; 74717c478bd9Sstevel@tonic-gate break; 74727c478bd9Sstevel@tonic-gate 74737c478bd9Sstevel@tonic-gate case AES_KEY_GEN_MECH_INFO_TYPE: 74747c478bd9Sstevel@tonic-gate if (key_type != ~0UL && key_type != DPROV_CKK_AES) { 74757c478bd9Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT; 74767c478bd9Sstevel@tonic-gate break; 74777c478bd9Sstevel@tonic-gate } 74787c478bd9Sstevel@tonic-gate if (dprov_get_template_attr_ulong(template, 74797c478bd9Sstevel@tonic-gate attribute_count, DPROV_CKA_VALUE_LEN, 74807c478bd9Sstevel@tonic-gate &value_len) != CRYPTO_SUCCESS) { 74817c478bd9Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCOMPLETE; 74827c478bd9Sstevel@tonic-gate break; 74837c478bd9Sstevel@tonic-gate } 74847c478bd9Sstevel@tonic-gate if (value_len >= AES_MAX_KEY_LEN) { 74857c478bd9Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 74867c478bd9Sstevel@tonic-gate break; 74877c478bd9Sstevel@tonic-gate } 74887c478bd9Sstevel@tonic-gate key_len = value_len; 74897c478bd9Sstevel@tonic-gate key_type = DPROV_CKK_AES; 74907c478bd9Sstevel@tonic-gate break; 74917c478bd9Sstevel@tonic-gate 7492f66d273dSizick case BLOWFISH_KEY_GEN_MECH_INFO_TYPE: 7493f66d273dSizick if (key_type != ~0UL && 7494f66d273dSizick key_type != DPROV_CKK_BLOWFISH) { 7495f66d273dSizick error = CRYPTO_TEMPLATE_INCONSISTENT; 7496f66d273dSizick break; 7497f66d273dSizick } 7498f66d273dSizick if (dprov_get_template_attr_ulong(template, 7499f66d273dSizick attribute_count, DPROV_CKA_VALUE_LEN, 7500f66d273dSizick &value_len) != CRYPTO_SUCCESS) { 7501f66d273dSizick error = CRYPTO_TEMPLATE_INCOMPLETE; 7502f66d273dSizick break; 7503f66d273dSizick } 7504f66d273dSizick if (value_len >= BLOWFISH_MAX_KEY_LEN) { 7505f66d273dSizick error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 7506f66d273dSizick break; 7507f66d273dSizick } 7508f66d273dSizick key_len = value_len; 7509f66d273dSizick key_type = DPROV_CKK_BLOWFISH; 7510f66d273dSizick break; 7511f66d273dSizick 75127c478bd9Sstevel@tonic-gate case RC4_KEY_GEN_MECH_INFO_TYPE: 75137c478bd9Sstevel@tonic-gate if (key_type != ~0UL && key_type != DPROV_CKK_RC4) { 75147c478bd9Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT; 75157c478bd9Sstevel@tonic-gate break; 75167c478bd9Sstevel@tonic-gate } 75177c478bd9Sstevel@tonic-gate if (dprov_get_template_attr_ulong(template, 75187c478bd9Sstevel@tonic-gate attribute_count, DPROV_CKA_VALUE_LEN, 75197c478bd9Sstevel@tonic-gate &value_len) != CRYPTO_SUCCESS) { 75207c478bd9Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCOMPLETE; 75217c478bd9Sstevel@tonic-gate break; 75227c478bd9Sstevel@tonic-gate } 75237c478bd9Sstevel@tonic-gate if (value_len >= 75247c478bd9Sstevel@tonic-gate CRYPTO_BITS2BYTES(ARCFOUR_MAX_KEY_BITS)) { 75257c478bd9Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 75267c478bd9Sstevel@tonic-gate break; 75277c478bd9Sstevel@tonic-gate } 75287c478bd9Sstevel@tonic-gate key_len = value_len; 75297c478bd9Sstevel@tonic-gate key_type = DPROV_CKK_RC4; 75307c478bd9Sstevel@tonic-gate break; 75317c478bd9Sstevel@tonic-gate 75327c478bd9Sstevel@tonic-gate default: 75337c478bd9Sstevel@tonic-gate error = CRYPTO_MECHANISM_INVALID; 75347c478bd9Sstevel@tonic-gate } 75357c478bd9Sstevel@tonic-gate 75367c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) 75377c478bd9Sstevel@tonic-gate break; 75387c478bd9Sstevel@tonic-gate 75397c478bd9Sstevel@tonic-gate error = dprov_create_object_from_template(softc, session, 75407c478bd9Sstevel@tonic-gate template, attribute_count, object_id_ptr, B_FALSE, B_TRUE); 75417c478bd9Sstevel@tonic-gate 75427c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) 75437c478bd9Sstevel@tonic-gate break; 75447c478bd9Sstevel@tonic-gate 75457c478bd9Sstevel@tonic-gate /* make sure class is set */ 75467c478bd9Sstevel@tonic-gate attribute.oa_type = DPROV_CKA_CLASS; 75477c478bd9Sstevel@tonic-gate attribute.oa_value = (char *)&class; 75487c478bd9Sstevel@tonic-gate attribute.oa_value_len = sizeof (ulong_t); 75497c478bd9Sstevel@tonic-gate error = dprov_object_set_attr(session, *object_id_ptr, 75507c478bd9Sstevel@tonic-gate &attribute, 1, B_FALSE); 75517c478bd9Sstevel@tonic-gate 75527c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) { 75537c478bd9Sstevel@tonic-gate goto destroy_object; 75547c478bd9Sstevel@tonic-gate } 75557c478bd9Sstevel@tonic-gate 75567c478bd9Sstevel@tonic-gate /* make sure key_type is set */ 75577c478bd9Sstevel@tonic-gate attribute.oa_type = DPROV_CKA_KEY_TYPE; 75587c478bd9Sstevel@tonic-gate attribute.oa_value = (char *)&key_type; 75597c478bd9Sstevel@tonic-gate attribute.oa_value_len = sizeof (ulong_t); 75607c478bd9Sstevel@tonic-gate error = dprov_object_set_attr(session, *object_id_ptr, 75617c478bd9Sstevel@tonic-gate &attribute, 1, B_FALSE); 75627c478bd9Sstevel@tonic-gate 75637c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) { 75647c478bd9Sstevel@tonic-gate goto destroy_object; 75657c478bd9Sstevel@tonic-gate } 75667c478bd9Sstevel@tonic-gate 75677c478bd9Sstevel@tonic-gate attribute.oa_type = DPROV_CKA_VALUE; 75687c478bd9Sstevel@tonic-gate attribute.oa_value = kmem_alloc(key_len, KM_SLEEP); 75697c478bd9Sstevel@tonic-gate attribute.oa_value_len = key_len; 75707c478bd9Sstevel@tonic-gate 75717c478bd9Sstevel@tonic-gate if (random_get_pseudo_bytes((uchar_t *)attribute.oa_value, 75727c478bd9Sstevel@tonic-gate key_len) != 0) { 75737c478bd9Sstevel@tonic-gate bzero(attribute.oa_value, key_len); 75747c478bd9Sstevel@tonic-gate kmem_free(attribute.oa_value, key_len); 75757c478bd9Sstevel@tonic-gate goto destroy_object; 75767c478bd9Sstevel@tonic-gate } 75777c478bd9Sstevel@tonic-gate error = dprov_object_set_attr(session, *object_id_ptr, 75787c478bd9Sstevel@tonic-gate &attribute, 1, B_FALSE); 75797c478bd9Sstevel@tonic-gate 75807c478bd9Sstevel@tonic-gate bzero(attribute.oa_value, key_len); 75817c478bd9Sstevel@tonic-gate kmem_free(attribute.oa_value, key_len); 75827c478bd9Sstevel@tonic-gate 75837c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) { 75847c478bd9Sstevel@tonic-gate goto destroy_object; 75857c478bd9Sstevel@tonic-gate } 75867c478bd9Sstevel@tonic-gate break; 75877c478bd9Sstevel@tonic-gate 75887c478bd9Sstevel@tonic-gate destroy_object: 75897c478bd9Sstevel@tonic-gate (void) dprov_destroy_object(softc, session, *object_id_ptr); 75907c478bd9Sstevel@tonic-gate break; 75917c478bd9Sstevel@tonic-gate } 75927c478bd9Sstevel@tonic-gate 75937c478bd9Sstevel@tonic-gate case DPROV_REQ_KEY_GENERATE_PAIR: { 75947c478bd9Sstevel@tonic-gate crypto_mechanism_t *mechp; 75957c478bd9Sstevel@tonic-gate crypto_object_id_t *pub_object_id_ptr; 75967c478bd9Sstevel@tonic-gate crypto_object_id_t *pri_object_id_ptr; 75977c478bd9Sstevel@tonic-gate crypto_object_attribute_t *pub_template; 75987c478bd9Sstevel@tonic-gate crypto_object_attribute_t *pri_template; 75997c478bd9Sstevel@tonic-gate crypto_object_attribute_t attribute; 76007c478bd9Sstevel@tonic-gate uint_t pub_attribute_count; 76017c478bd9Sstevel@tonic-gate uint_t pri_attribute_count; 76027c478bd9Sstevel@tonic-gate ulong_t pub_key_type = ~0UL, pub_class = ~0UL; 76037c478bd9Sstevel@tonic-gate ulong_t pri_key_type = ~0UL, pri_class = ~0UL; 76047c478bd9Sstevel@tonic-gate 76057c478bd9Sstevel@tonic-gate pub_template = taskq_req->dr_key_req.kr_template; 76067c478bd9Sstevel@tonic-gate pub_attribute_count = taskq_req->dr_key_req.kr_attribute_count; 76077c478bd9Sstevel@tonic-gate pub_object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr; 76087c478bd9Sstevel@tonic-gate pri_template = taskq_req->dr_key_req.kr_private_key_template; 76097c478bd9Sstevel@tonic-gate pri_attribute_count = 76107c478bd9Sstevel@tonic-gate taskq_req->dr_key_req.kr_private_key_attribute_count; 76117c478bd9Sstevel@tonic-gate pri_object_id_ptr = 76127c478bd9Sstevel@tonic-gate taskq_req->dr_key_req.kr_private_key_object_id_ptr; 76137c478bd9Sstevel@tonic-gate mechp = taskq_req->dr_key_req.kr_mechanism; 76147c478bd9Sstevel@tonic-gate 76157c478bd9Sstevel@tonic-gate error = CRYPTO_SUCCESS; 76167c478bd9Sstevel@tonic-gate 76177c478bd9Sstevel@tonic-gate /* optional */ 76187c478bd9Sstevel@tonic-gate (void) dprov_get_template_attr_ulong(pub_template, 76197c478bd9Sstevel@tonic-gate pub_attribute_count, DPROV_CKA_CLASS, &pub_class); 76207c478bd9Sstevel@tonic-gate 76217c478bd9Sstevel@tonic-gate /* optional */ 76227c478bd9Sstevel@tonic-gate (void) dprov_get_template_attr_ulong(pri_template, 76237c478bd9Sstevel@tonic-gate pri_attribute_count, DPROV_CKA_CLASS, &pri_class); 76247c478bd9Sstevel@tonic-gate 76257c478bd9Sstevel@tonic-gate /* optional */ 76267c478bd9Sstevel@tonic-gate (void) dprov_get_template_attr_ulong(pub_template, 76277c478bd9Sstevel@tonic-gate pub_attribute_count, DPROV_CKA_KEY_TYPE, &pub_key_type); 76287c478bd9Sstevel@tonic-gate 76297c478bd9Sstevel@tonic-gate /* optional */ 76307c478bd9Sstevel@tonic-gate (void) dprov_get_template_attr_ulong(pri_template, 76317c478bd9Sstevel@tonic-gate pri_attribute_count, DPROV_CKA_KEY_TYPE, &pri_key_type); 76327c478bd9Sstevel@tonic-gate 76337c478bd9Sstevel@tonic-gate if (pub_class != ~0UL && pub_class != DPROV_CKO_PUBLIC_KEY) { 76347c478bd9Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT; 76357c478bd9Sstevel@tonic-gate break; 76367c478bd9Sstevel@tonic-gate } 76377c478bd9Sstevel@tonic-gate 76387c478bd9Sstevel@tonic-gate if (pri_class != ~0UL && pri_class != DPROV_CKO_PRIVATE_KEY) { 76397c478bd9Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT; 76407c478bd9Sstevel@tonic-gate break; 76417c478bd9Sstevel@tonic-gate } 76427c478bd9Sstevel@tonic-gate 76437c478bd9Sstevel@tonic-gate switch (mechp->cm_type) { 76447c478bd9Sstevel@tonic-gate case RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE: 76457c478bd9Sstevel@tonic-gate if (pub_key_type != ~0UL && 76467c478bd9Sstevel@tonic-gate pub_key_type != DPROV_CKK_RSA) { 76477c478bd9Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT; 76487c478bd9Sstevel@tonic-gate break; 76497c478bd9Sstevel@tonic-gate } 7650034448feSmcpowers pub_key_type = DPROV_CKK_RSA; 76517c478bd9Sstevel@tonic-gate 76527c478bd9Sstevel@tonic-gate if (pri_key_type != ~0UL && 76537c478bd9Sstevel@tonic-gate pri_key_type != DPROV_CKK_RSA) { 76547c478bd9Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT; 76557c478bd9Sstevel@tonic-gate break; 76567c478bd9Sstevel@tonic-gate } 76577c478bd9Sstevel@tonic-gate pri_key_type = DPROV_CKK_RSA; 76587c478bd9Sstevel@tonic-gate 76597c478bd9Sstevel@tonic-gate if (pub_class != ~0UL && 76607c478bd9Sstevel@tonic-gate pub_class != DPROV_CKO_PUBLIC_KEY) { 76617c478bd9Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT; 76627c478bd9Sstevel@tonic-gate break; 76637c478bd9Sstevel@tonic-gate } 76647c478bd9Sstevel@tonic-gate pub_class = DPROV_CKO_PUBLIC_KEY; 76657c478bd9Sstevel@tonic-gate 76667c478bd9Sstevel@tonic-gate if (pri_class != ~0UL && 76677c478bd9Sstevel@tonic-gate pri_class != DPROV_CKO_PRIVATE_KEY) { 76687c478bd9Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT; 76697c478bd9Sstevel@tonic-gate break; 76707c478bd9Sstevel@tonic-gate } 76717c478bd9Sstevel@tonic-gate pri_class = DPROV_CKO_PRIVATE_KEY; 76727c478bd9Sstevel@tonic-gate break; 76737c478bd9Sstevel@tonic-gate 76747c478bd9Sstevel@tonic-gate default: 76757c478bd9Sstevel@tonic-gate error = CRYPTO_MECHANISM_INVALID; 76767c478bd9Sstevel@tonic-gate } 76777c478bd9Sstevel@tonic-gate 76787c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) 76797c478bd9Sstevel@tonic-gate break; 76807c478bd9Sstevel@tonic-gate 76817c478bd9Sstevel@tonic-gate error = dprov_create_object_from_template(softc, session, 76827c478bd9Sstevel@tonic-gate pub_template, pub_attribute_count, pub_object_id_ptr, 76837c478bd9Sstevel@tonic-gate B_FALSE, B_TRUE); 76847c478bd9Sstevel@tonic-gate 76857c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) 76867c478bd9Sstevel@tonic-gate break; 76877c478bd9Sstevel@tonic-gate 76887c478bd9Sstevel@tonic-gate /* make sure class is set */ 76897c478bd9Sstevel@tonic-gate attribute.oa_type = DPROV_CKA_CLASS; 76907c478bd9Sstevel@tonic-gate attribute.oa_value = (char *)&pub_class; 76917c478bd9Sstevel@tonic-gate attribute.oa_value_len = sizeof (ulong_t); 76927c478bd9Sstevel@tonic-gate error = dprov_object_set_attr(session, *pub_object_id_ptr, 76937c478bd9Sstevel@tonic-gate &attribute, 1, B_FALSE); 76947c478bd9Sstevel@tonic-gate 76957c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) { 76967c478bd9Sstevel@tonic-gate goto destroy_public_object; 76977c478bd9Sstevel@tonic-gate } 76987c478bd9Sstevel@tonic-gate 76997c478bd9Sstevel@tonic-gate /* make sure key_type is set */ 77007c478bd9Sstevel@tonic-gate attribute.oa_type = DPROV_CKA_KEY_TYPE; 77017c478bd9Sstevel@tonic-gate attribute.oa_value = (char *)&pub_key_type; 77027c478bd9Sstevel@tonic-gate attribute.oa_value_len = sizeof (ulong_t); 77037c478bd9Sstevel@tonic-gate error = dprov_object_set_attr(session, *pub_object_id_ptr, 77047c478bd9Sstevel@tonic-gate &attribute, 1, B_FALSE); 77057c478bd9Sstevel@tonic-gate 77067c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) { 77077c478bd9Sstevel@tonic-gate goto destroy_public_object; 77087c478bd9Sstevel@tonic-gate } 77097c478bd9Sstevel@tonic-gate 77107c478bd9Sstevel@tonic-gate attribute.oa_type = DPROV_CKA_MODULUS; 77117c478bd9Sstevel@tonic-gate attribute.oa_value = (char *)modulus; 77127c478bd9Sstevel@tonic-gate attribute.oa_value_len = sizeof (modulus); 77137c478bd9Sstevel@tonic-gate error = dprov_object_set_attr(session, *pub_object_id_ptr, 77147c478bd9Sstevel@tonic-gate &attribute, 1, B_FALSE); 77157c478bd9Sstevel@tonic-gate 77167c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) { 77177c478bd9Sstevel@tonic-gate goto destroy_public_object; 77187c478bd9Sstevel@tonic-gate } 77197c478bd9Sstevel@tonic-gate 77207c478bd9Sstevel@tonic-gate attribute.oa_type = DPROV_CKA_PUBLIC_EXPONENT; 77217c478bd9Sstevel@tonic-gate attribute.oa_value = public_exponent; 77227c478bd9Sstevel@tonic-gate attribute.oa_value_len = sizeof (public_exponent); 77237c478bd9Sstevel@tonic-gate error = dprov_object_set_attr(session, *pub_object_id_ptr, 77247c478bd9Sstevel@tonic-gate &attribute, 1, B_FALSE); 77257c478bd9Sstevel@tonic-gate 77267c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) { 77277c478bd9Sstevel@tonic-gate goto destroy_public_object; 77287c478bd9Sstevel@tonic-gate } 77297c478bd9Sstevel@tonic-gate 77307c478bd9Sstevel@tonic-gate error = dprov_create_object_from_template(softc, session, 77317c478bd9Sstevel@tonic-gate pri_template, pri_attribute_count, pri_object_id_ptr, 77327c478bd9Sstevel@tonic-gate B_FALSE, B_TRUE); 77337c478bd9Sstevel@tonic-gate 77347c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) 77357c478bd9Sstevel@tonic-gate break; 77367c478bd9Sstevel@tonic-gate 77377c478bd9Sstevel@tonic-gate /* make sure class is set */ 77387c478bd9Sstevel@tonic-gate attribute.oa_type = DPROV_CKA_CLASS; 77397c478bd9Sstevel@tonic-gate attribute.oa_value = (char *)&pri_class; 77407c478bd9Sstevel@tonic-gate attribute.oa_value_len = sizeof (ulong_t); 77417c478bd9Sstevel@tonic-gate error = dprov_object_set_attr(session, *pri_object_id_ptr, 77427c478bd9Sstevel@tonic-gate &attribute, 1, B_FALSE); 77437c478bd9Sstevel@tonic-gate 77447c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) { 77457c478bd9Sstevel@tonic-gate goto destroy_private_object; 77467c478bd9Sstevel@tonic-gate } 77477c478bd9Sstevel@tonic-gate 77487c478bd9Sstevel@tonic-gate /* make sure key_type is set */ 77497c478bd9Sstevel@tonic-gate attribute.oa_type = DPROV_CKA_KEY_TYPE; 77507c478bd9Sstevel@tonic-gate attribute.oa_value = (char *)&pri_key_type; 77517c478bd9Sstevel@tonic-gate attribute.oa_value_len = sizeof (ulong_t); 77527c478bd9Sstevel@tonic-gate error = dprov_object_set_attr(session, *pri_object_id_ptr, 77537c478bd9Sstevel@tonic-gate &attribute, 1, B_FALSE); 77547c478bd9Sstevel@tonic-gate 77557c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) { 77567c478bd9Sstevel@tonic-gate goto destroy_private_object; 77577c478bd9Sstevel@tonic-gate } 77587c478bd9Sstevel@tonic-gate 77597c478bd9Sstevel@tonic-gate attribute.oa_type = DPROV_CKA_MODULUS; 77607c478bd9Sstevel@tonic-gate attribute.oa_value = (char *)modulus; 77617c478bd9Sstevel@tonic-gate attribute.oa_value_len = sizeof (modulus); 77627c478bd9Sstevel@tonic-gate error = dprov_object_set_attr(session, *pri_object_id_ptr, 77637c478bd9Sstevel@tonic-gate &attribute, 1, B_FALSE); 77647c478bd9Sstevel@tonic-gate 77657c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) { 77667c478bd9Sstevel@tonic-gate goto destroy_private_object; 77677c478bd9Sstevel@tonic-gate } 77687c478bd9Sstevel@tonic-gate 77697c478bd9Sstevel@tonic-gate attribute.oa_type = DPROV_CKA_PRIVATE_EXPONENT; 77707c478bd9Sstevel@tonic-gate attribute.oa_value = (char *)private_exponent; 77717c478bd9Sstevel@tonic-gate attribute.oa_value_len = sizeof (private_exponent); 77727c478bd9Sstevel@tonic-gate error = dprov_object_set_attr(session, *pri_object_id_ptr, 77737c478bd9Sstevel@tonic-gate &attribute, 1, B_FALSE); 77747c478bd9Sstevel@tonic-gate 77757c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) { 77767c478bd9Sstevel@tonic-gate goto destroy_private_object; 77777c478bd9Sstevel@tonic-gate } 77787c478bd9Sstevel@tonic-gate break; 77797c478bd9Sstevel@tonic-gate 77807c478bd9Sstevel@tonic-gate destroy_private_object: 77817c478bd9Sstevel@tonic-gate (void) dprov_destroy_object(softc, session, 77827c478bd9Sstevel@tonic-gate *pri_object_id_ptr); 77837c478bd9Sstevel@tonic-gate destroy_public_object: 77847c478bd9Sstevel@tonic-gate (void) dprov_destroy_object(softc, session, 77857c478bd9Sstevel@tonic-gate *pub_object_id_ptr); 77867c478bd9Sstevel@tonic-gate 77877c478bd9Sstevel@tonic-gate break; 77887c478bd9Sstevel@tonic-gate } 77897c478bd9Sstevel@tonic-gate 77907c478bd9Sstevel@tonic-gate case DPROV_REQ_KEY_WRAP: { 77917c478bd9Sstevel@tonic-gate crypto_mechanism_t mech, *mechp; 77927c478bd9Sstevel@tonic-gate crypto_key_t key, *keyp; 77937c478bd9Sstevel@tonic-gate crypto_object_id_t object_id; 77947c478bd9Sstevel@tonic-gate ulong_t class = DPROV_CKO_DATA; 77957c478bd9Sstevel@tonic-gate boolean_t extractable = B_TRUE; 77967c478bd9Sstevel@tonic-gate dprov_object_t *object; 77977c478bd9Sstevel@tonic-gate int object_idx; 77987c478bd9Sstevel@tonic-gate char *plaintext_key; 77997c478bd9Sstevel@tonic-gate size_t plaintext_key_len; 78007c478bd9Sstevel@tonic-gate crypto_data_t plaintext; 78017c478bd9Sstevel@tonic-gate crypto_data_t ciphertext; 78027c478bd9Sstevel@tonic-gate size_t *lenp; 78037c478bd9Sstevel@tonic-gate 78047c478bd9Sstevel@tonic-gate mechp = taskq_req->dr_key_req.kr_mechanism; 78057c478bd9Sstevel@tonic-gate /* structure assignment */ 78067c478bd9Sstevel@tonic-gate mech = *mechp; 78077c478bd9Sstevel@tonic-gate 78087c478bd9Sstevel@tonic-gate /* get wrapping key value */ 78097c478bd9Sstevel@tonic-gate if (is_publickey_mech(mech.cm_type)) { 78107c478bd9Sstevel@tonic-gate if ((error = dprov_key_attr_asymmetric(softc, 78117c478bd9Sstevel@tonic-gate session_id, taskq_req->dr_type, 78127c478bd9Sstevel@tonic-gate taskq_req->dr_key_req.kr_key, 78137c478bd9Sstevel@tonic-gate &key)) != CRYPTO_SUCCESS) 78147c478bd9Sstevel@tonic-gate break; 78157c478bd9Sstevel@tonic-gate keyp = &key; 78167c478bd9Sstevel@tonic-gate } else { 78177c478bd9Sstevel@tonic-gate if ((error = dprov_key_value_secret(softc, 78187c478bd9Sstevel@tonic-gate session_id, taskq_req->dr_type, 78197c478bd9Sstevel@tonic-gate taskq_req->dr_key_req.kr_key, 78207c478bd9Sstevel@tonic-gate &key)) != CRYPTO_SUCCESS) 78217c478bd9Sstevel@tonic-gate break; 78227c478bd9Sstevel@tonic-gate keyp = &key; 78237c478bd9Sstevel@tonic-gate } 78247c478bd9Sstevel@tonic-gate 78257c478bd9Sstevel@tonic-gate /* get the software provider for this mechanism */ 78267c478bd9Sstevel@tonic-gate if ((error = dprov_get_sw_prov(mechp, &pd, 78277c478bd9Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS) 78287c478bd9Sstevel@tonic-gate break; 78297c478bd9Sstevel@tonic-gate 78307c478bd9Sstevel@tonic-gate object_id = *taskq_req->dr_key_req.kr_object_id_ptr; 78317c478bd9Sstevel@tonic-gate if (object_id >= DPROV_MAX_OBJECTS) { 78327c478bd9Sstevel@tonic-gate error = CRYPTO_KEY_HANDLE_INVALID; 78337c478bd9Sstevel@tonic-gate break; 78347c478bd9Sstevel@tonic-gate } 78357c478bd9Sstevel@tonic-gate 78367c478bd9Sstevel@tonic-gate /* get ptr to object */ 78377c478bd9Sstevel@tonic-gate if ((object = session->ds_objects[object_id]) == NULL) { 78387c478bd9Sstevel@tonic-gate error = CRYPTO_OBJECT_HANDLE_INVALID; 78397c478bd9Sstevel@tonic-gate break; 78407c478bd9Sstevel@tonic-gate } 78417c478bd9Sstevel@tonic-gate 78427c478bd9Sstevel@tonic-gate (void) dprov_get_object_attr_boolean(object, 78437c478bd9Sstevel@tonic-gate DPROV_CKA_EXTRACTABLE, &extractable); 78447c478bd9Sstevel@tonic-gate 78457c478bd9Sstevel@tonic-gate if (!extractable) { 78467c478bd9Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_SENSITIVE; 78477c478bd9Sstevel@tonic-gate break; 78487c478bd9Sstevel@tonic-gate } 78497c478bd9Sstevel@tonic-gate 78507c478bd9Sstevel@tonic-gate (void) dprov_get_object_attr_ulong(object, 78517c478bd9Sstevel@tonic-gate DPROV_CKA_CLASS, &class); 78527c478bd9Sstevel@tonic-gate 78537c478bd9Sstevel@tonic-gate switch (class) { 78547c478bd9Sstevel@tonic-gate case DPROV_CKO_SECRET_KEY: 78557c478bd9Sstevel@tonic-gate object_idx = dprov_find_attr(object->do_attr, 78567c478bd9Sstevel@tonic-gate DPROV_MAX_ATTR, DPROV_CKA_VALUE); 78577c478bd9Sstevel@tonic-gate if (object_idx == -1) { 78587c478bd9Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_TYPE_INVALID; 78597c478bd9Sstevel@tonic-gate break; 78607c478bd9Sstevel@tonic-gate } 78617c478bd9Sstevel@tonic-gate break; 78627c478bd9Sstevel@tonic-gate 78637c478bd9Sstevel@tonic-gate case DPROV_CKO_PRIVATE_KEY: 78647c478bd9Sstevel@tonic-gate /* 78657c478bd9Sstevel@tonic-gate * PKCS#11 says that ASN.1 should be used to encode 78667c478bd9Sstevel@tonic-gate * specific attributes before encrypting the blob. 78677c478bd9Sstevel@tonic-gate * We only encrypt the private exponent for the 78687c478bd9Sstevel@tonic-gate * purpose of testing. 78697c478bd9Sstevel@tonic-gate */ 78707c478bd9Sstevel@tonic-gate object_idx = dprov_find_attr(object->do_attr, 78717c478bd9Sstevel@tonic-gate DPROV_MAX_ATTR, DPROV_CKA_PRIVATE_EXPONENT); 78727c478bd9Sstevel@tonic-gate if (object_idx == -1) { 78737c478bd9Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_TYPE_INVALID; 78747c478bd9Sstevel@tonic-gate break; 78757c478bd9Sstevel@tonic-gate } 78767c478bd9Sstevel@tonic-gate break; 78777c478bd9Sstevel@tonic-gate default: 78787c478bd9Sstevel@tonic-gate error = CRYPTO_KEY_NOT_WRAPPABLE; 78797c478bd9Sstevel@tonic-gate break; 78807c478bd9Sstevel@tonic-gate } 78817c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) 78827c478bd9Sstevel@tonic-gate break; 78837c478bd9Sstevel@tonic-gate 78847c478bd9Sstevel@tonic-gate plaintext_key = object->do_attr[object_idx].oa_value; 78857c478bd9Sstevel@tonic-gate plaintext_key_len = object->do_attr[object_idx].oa_value_len; 78867c478bd9Sstevel@tonic-gate lenp = taskq_req->dr_key_req.kr_wrapped_key_len_ptr; 78877c478bd9Sstevel@tonic-gate 78887c478bd9Sstevel@tonic-gate /* session id is 0 for software provider */ 78897c478bd9Sstevel@tonic-gate plaintext.cd_format = CRYPTO_DATA_RAW; 78907c478bd9Sstevel@tonic-gate plaintext.cd_offset = 0; 78917c478bd9Sstevel@tonic-gate plaintext.cd_length = plaintext_key_len; 78927c478bd9Sstevel@tonic-gate plaintext.cd_raw.iov_base = plaintext_key; 78937c478bd9Sstevel@tonic-gate plaintext.cd_raw.iov_len = plaintext_key_len; 78947c478bd9Sstevel@tonic-gate plaintext.cd_miscdata = NULL; 78957c478bd9Sstevel@tonic-gate 78967c478bd9Sstevel@tonic-gate ciphertext.cd_format = CRYPTO_DATA_RAW; 78977c478bd9Sstevel@tonic-gate ciphertext.cd_offset = 0; 78987c478bd9Sstevel@tonic-gate ciphertext.cd_length = *lenp; 78997c478bd9Sstevel@tonic-gate ciphertext.cd_raw.iov_base = 79007c478bd9Sstevel@tonic-gate (char *)taskq_req->dr_key_req.kr_wrapped_key; 79017c478bd9Sstevel@tonic-gate ciphertext.cd_raw.iov_len = ciphertext.cd_length; 79027c478bd9Sstevel@tonic-gate ciphertext.cd_miscdata = NULL; 79037c478bd9Sstevel@tonic-gate 7904894b2776Smcpowers error = crypto_encrypt_prov(pd, 0, &mech, &plaintext, keyp, 7905894b2776Smcpowers NULL, &ciphertext, NULL); 79067c478bd9Sstevel@tonic-gate 79077c478bd9Sstevel@tonic-gate KCF_PROV_REFRELE(pd); 79087c478bd9Sstevel@tonic-gate if (error == CRYPTO_SUCCESS || 79097c478bd9Sstevel@tonic-gate error == CRYPTO_BUFFER_TOO_SMALL) { 79107c478bd9Sstevel@tonic-gate *lenp = ciphertext.cd_length; 79117c478bd9Sstevel@tonic-gate } 79127c478bd9Sstevel@tonic-gate break; 79137c478bd9Sstevel@tonic-gate } 79147c478bd9Sstevel@tonic-gate 79157c478bd9Sstevel@tonic-gate case DPROV_REQ_KEY_UNWRAP: { 79167c478bd9Sstevel@tonic-gate crypto_mechanism_t mech, *mechp; 79177c478bd9Sstevel@tonic-gate crypto_key_t key, *keyp; 79187c478bd9Sstevel@tonic-gate crypto_object_id_t *object_id_ptr; 79197c478bd9Sstevel@tonic-gate ulong_t class = DPROV_CKO_DATA; 79207c478bd9Sstevel@tonic-gate uchar_t *wrapped_key; 79217c478bd9Sstevel@tonic-gate char *plaintext_buf; 79227c478bd9Sstevel@tonic-gate size_t wrapped_key_len; 79237c478bd9Sstevel@tonic-gate crypto_data_t plaintext; 79247c478bd9Sstevel@tonic-gate crypto_data_t ciphertext; 79257c478bd9Sstevel@tonic-gate crypto_object_attribute_t unwrapped_key; 79267c478bd9Sstevel@tonic-gate crypto_object_attribute_t *template; 79277c478bd9Sstevel@tonic-gate uint_t attribute_count; 79287c478bd9Sstevel@tonic-gate 79297c478bd9Sstevel@tonic-gate template = taskq_req->dr_key_req.kr_template; 79307c478bd9Sstevel@tonic-gate attribute_count = taskq_req->dr_key_req.kr_attribute_count; 79317c478bd9Sstevel@tonic-gate object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr; 79327c478bd9Sstevel@tonic-gate 79337c478bd9Sstevel@tonic-gate /* all objects must have an object class attribute */ 79347c478bd9Sstevel@tonic-gate if (dprov_get_template_attr_ulong(template, attribute_count, 79357c478bd9Sstevel@tonic-gate DPROV_CKA_CLASS, &class) != CRYPTO_SUCCESS) { 79367c478bd9Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCOMPLETE; 79377c478bd9Sstevel@tonic-gate break; 79387c478bd9Sstevel@tonic-gate } 79397c478bd9Sstevel@tonic-gate 79407c478bd9Sstevel@tonic-gate mechp = taskq_req->dr_key_req.kr_mechanism; 79417c478bd9Sstevel@tonic-gate /* structure assignment */ 79427c478bd9Sstevel@tonic-gate mech = *mechp; 79437c478bd9Sstevel@tonic-gate 79447c478bd9Sstevel@tonic-gate /* get unwrapping key value */ 79457c478bd9Sstevel@tonic-gate if (is_publickey_mech(mech.cm_type)) { 79467c478bd9Sstevel@tonic-gate if ((error = dprov_key_attr_asymmetric(softc, 79477c478bd9Sstevel@tonic-gate session_id, taskq_req->dr_type, 79487c478bd9Sstevel@tonic-gate taskq_req->dr_key_req.kr_key, 79497c478bd9Sstevel@tonic-gate &key)) != CRYPTO_SUCCESS) 79507c478bd9Sstevel@tonic-gate break; 79517c478bd9Sstevel@tonic-gate keyp = &key; 79527c478bd9Sstevel@tonic-gate } else { 79537c478bd9Sstevel@tonic-gate if ((error = dprov_key_value_secret(softc, 79547c478bd9Sstevel@tonic-gate session_id, taskq_req->dr_type, 79557c478bd9Sstevel@tonic-gate taskq_req->dr_key_req.kr_key, 79567c478bd9Sstevel@tonic-gate &key)) != CRYPTO_SUCCESS) 79577c478bd9Sstevel@tonic-gate break; 79587c478bd9Sstevel@tonic-gate keyp = &key; 79597c478bd9Sstevel@tonic-gate } 79607c478bd9Sstevel@tonic-gate 79617c478bd9Sstevel@tonic-gate /* get the software provider for this mechanism */ 79627c478bd9Sstevel@tonic-gate if ((error = dprov_get_sw_prov(mechp, &pd, 79637c478bd9Sstevel@tonic-gate &mech.cm_type)) != CRYPTO_SUCCESS) 79647c478bd9Sstevel@tonic-gate break; 79657c478bd9Sstevel@tonic-gate 79667c478bd9Sstevel@tonic-gate wrapped_key = taskq_req->dr_key_req.kr_wrapped_key; 79677c478bd9Sstevel@tonic-gate wrapped_key_len = *taskq_req->dr_key_req.kr_wrapped_key_len_ptr; 79687c478bd9Sstevel@tonic-gate ciphertext.cd_format = CRYPTO_DATA_RAW; 79697c478bd9Sstevel@tonic-gate ciphertext.cd_offset = 0; 79707c478bd9Sstevel@tonic-gate ciphertext.cd_length = wrapped_key_len; 79717c478bd9Sstevel@tonic-gate ciphertext.cd_raw.iov_base = (char *)wrapped_key; 79727c478bd9Sstevel@tonic-gate ciphertext.cd_raw.iov_len = wrapped_key_len; 79737c478bd9Sstevel@tonic-gate ciphertext.cd_miscdata = NULL; 79747c478bd9Sstevel@tonic-gate 79757c478bd9Sstevel@tonic-gate /* 79767c478bd9Sstevel@tonic-gate * Plaintext length is less than or equal to 79777c478bd9Sstevel@tonic-gate * the length of the ciphertext. 79787c478bd9Sstevel@tonic-gate */ 79797c478bd9Sstevel@tonic-gate plaintext_buf = kmem_alloc(wrapped_key_len, KM_SLEEP); 79807c478bd9Sstevel@tonic-gate plaintext.cd_format = CRYPTO_DATA_RAW; 79817c478bd9Sstevel@tonic-gate plaintext.cd_offset = 0; 79827c478bd9Sstevel@tonic-gate plaintext.cd_length = wrapped_key_len; 79837c478bd9Sstevel@tonic-gate plaintext.cd_raw.iov_base = plaintext_buf; 79847c478bd9Sstevel@tonic-gate plaintext.cd_raw.iov_len = wrapped_key_len; 79857c478bd9Sstevel@tonic-gate plaintext.cd_miscdata = NULL; 79867c478bd9Sstevel@tonic-gate 7987894b2776Smcpowers error = crypto_decrypt_prov(pd, 0, &mech, &ciphertext, keyp, 7988894b2776Smcpowers NULL, &plaintext, NULL); 79897c478bd9Sstevel@tonic-gate 79907c478bd9Sstevel@tonic-gate KCF_PROV_REFRELE(pd); 79917c478bd9Sstevel@tonic-gate 79927c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) 79937c478bd9Sstevel@tonic-gate goto free_unwrapped_key; 79947c478bd9Sstevel@tonic-gate 79957c478bd9Sstevel@tonic-gate error = dprov_create_object_from_template(softc, session, 79967c478bd9Sstevel@tonic-gate template, attribute_count, object_id_ptr, B_FALSE, B_FALSE); 79977c478bd9Sstevel@tonic-gate 79987c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) 79997c478bd9Sstevel@tonic-gate goto free_unwrapped_key; 80007c478bd9Sstevel@tonic-gate 80017c478bd9Sstevel@tonic-gate switch (class) { 80027c478bd9Sstevel@tonic-gate case DPROV_CKO_SECRET_KEY: 80037c478bd9Sstevel@tonic-gate unwrapped_key.oa_type = DPROV_CKA_VALUE; 80047c478bd9Sstevel@tonic-gate unwrapped_key.oa_value_len = plaintext.cd_length; 80057c478bd9Sstevel@tonic-gate unwrapped_key.oa_value = plaintext_buf; 80067c478bd9Sstevel@tonic-gate break; 80077c478bd9Sstevel@tonic-gate case DPROV_CKO_PRIVATE_KEY: 80087c478bd9Sstevel@tonic-gate /* 80097c478bd9Sstevel@tonic-gate * PKCS#11 says that ASN.1 should be used to encode 80107c478bd9Sstevel@tonic-gate * specific attributes before encrypting the blob. 80117c478bd9Sstevel@tonic-gate * We only encrypt the private exponent for the 80127c478bd9Sstevel@tonic-gate * purpose of testing. 80137c478bd9Sstevel@tonic-gate */ 80147c478bd9Sstevel@tonic-gate unwrapped_key.oa_type = DPROV_CKA_PRIVATE_EXPONENT; 80157c478bd9Sstevel@tonic-gate unwrapped_key.oa_value_len = plaintext.cd_length; 80167c478bd9Sstevel@tonic-gate unwrapped_key.oa_value = plaintext_buf; 80177c478bd9Sstevel@tonic-gate break; 80187c478bd9Sstevel@tonic-gate default: 80197c478bd9Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCONSISTENT; 80207c478bd9Sstevel@tonic-gate goto free_unwrapped_key; 80217c478bd9Sstevel@tonic-gate } 80227c478bd9Sstevel@tonic-gate 80237c478bd9Sstevel@tonic-gate if ((error = dprov_object_set_attr(session, *object_id_ptr, 80247c478bd9Sstevel@tonic-gate &unwrapped_key, 1, B_FALSE)) == CRYPTO_SUCCESS) 80257c478bd9Sstevel@tonic-gate break; /* don't free the unwrapped key */ 80267c478bd9Sstevel@tonic-gate 80277c478bd9Sstevel@tonic-gate /* failure */ 80287c478bd9Sstevel@tonic-gate (void) dprov_destroy_object(softc, session, *object_id_ptr); 80297c478bd9Sstevel@tonic-gate break; 80307c478bd9Sstevel@tonic-gate 80317c478bd9Sstevel@tonic-gate free_unwrapped_key: 80327c478bd9Sstevel@tonic-gate bzero(plaintext_buf, wrapped_key_len); 80337c478bd9Sstevel@tonic-gate kmem_free(plaintext_buf, wrapped_key_len); 80347c478bd9Sstevel@tonic-gate break; 80357c478bd9Sstevel@tonic-gate } 80367c478bd9Sstevel@tonic-gate 80377c478bd9Sstevel@tonic-gate case DPROV_REQ_KEY_DERIVE: { 80387c478bd9Sstevel@tonic-gate crypto_mechanism_t digest_mech, *mechp; 80397c478bd9Sstevel@tonic-gate crypto_key_t key, *base_keyp; 80407c478bd9Sstevel@tonic-gate crypto_object_id_t *object_id_ptr; 80417c478bd9Sstevel@tonic-gate crypto_data_t data; 80427c478bd9Sstevel@tonic-gate crypto_data_t digest; 80437c478bd9Sstevel@tonic-gate size_t hash_size; 80447c478bd9Sstevel@tonic-gate char *digest_buf; 80457c478bd9Sstevel@tonic-gate crypto_object_attribute_t derived_key; 80467c478bd9Sstevel@tonic-gate crypto_object_attribute_t *template; 80477c478bd9Sstevel@tonic-gate uint_t attribute_count; 80487c478bd9Sstevel@tonic-gate ulong_t key_type; 80497c478bd9Sstevel@tonic-gate void *value; 80507c478bd9Sstevel@tonic-gate size_t value_len = 0; 80517c478bd9Sstevel@tonic-gate 80527c478bd9Sstevel@tonic-gate error = CRYPTO_SUCCESS; 80537c478bd9Sstevel@tonic-gate 80547c478bd9Sstevel@tonic-gate template = taskq_req->dr_key_req.kr_template; 80557c478bd9Sstevel@tonic-gate attribute_count = taskq_req->dr_key_req.kr_attribute_count; 80567c478bd9Sstevel@tonic-gate object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr; 80577c478bd9Sstevel@tonic-gate 80587c478bd9Sstevel@tonic-gate /* required */ 80597c478bd9Sstevel@tonic-gate if (dprov_get_template_attr_ulong(template, attribute_count, 80607c478bd9Sstevel@tonic-gate DPROV_CKA_KEY_TYPE, &key_type) != CRYPTO_SUCCESS) { 80617c478bd9Sstevel@tonic-gate error = CRYPTO_TEMPLATE_INCOMPLETE; 80627c478bd9Sstevel@tonic-gate break; 80637c478bd9Sstevel@tonic-gate } 80647c478bd9Sstevel@tonic-gate 80657c478bd9Sstevel@tonic-gate mechp = taskq_req->dr_key_req.kr_mechanism; 80667c478bd9Sstevel@tonic-gate /* structure assignment */ 80677c478bd9Sstevel@tonic-gate digest_mech = *mechp; 80687c478bd9Sstevel@tonic-gate 80697c478bd9Sstevel@tonic-gate switch (digest_mech.cm_type) { 80707c478bd9Sstevel@tonic-gate case SHA1_KEY_DERIVATION_MECH_INFO_TYPE: 80717c478bd9Sstevel@tonic-gate hash_size = SHA1_DIGEST_LEN; 80727c478bd9Sstevel@tonic-gate digest_mech.cm_type = SHA1_MECH_INFO_TYPE; 80737c478bd9Sstevel@tonic-gate break; 80747c478bd9Sstevel@tonic-gate 8075f66d273dSizick case SHA256_KEY_DERIVATION_MECH_INFO_TYPE: 8076f66d273dSizick hash_size = SHA256_DIGEST_LENGTH; 8077f66d273dSizick digest_mech.cm_type = SHA256_MECH_INFO_TYPE; 8078f66d273dSizick break; 8079f66d273dSizick 8080f66d273dSizick case SHA384_KEY_DERIVATION_MECH_INFO_TYPE: 8081f66d273dSizick hash_size = SHA384_DIGEST_LENGTH; 8082f66d273dSizick digest_mech.cm_type = SHA384_MECH_INFO_TYPE; 8083f66d273dSizick break; 8084f66d273dSizick 8085f66d273dSizick case SHA512_KEY_DERIVATION_MECH_INFO_TYPE: 8086f66d273dSizick hash_size = SHA512_DIGEST_LENGTH; 8087f66d273dSizick digest_mech.cm_type = SHA512_MECH_INFO_TYPE; 8088f66d273dSizick break; 8089f66d273dSizick 80907c478bd9Sstevel@tonic-gate case MD5_KEY_DERIVATION_MECH_INFO_TYPE: 80917c478bd9Sstevel@tonic-gate hash_size = MD5_DIGEST_LEN; 80927c478bd9Sstevel@tonic-gate digest_mech.cm_type = MD5_MECH_INFO_TYPE; 80937c478bd9Sstevel@tonic-gate break; 80947c478bd9Sstevel@tonic-gate 80957c478bd9Sstevel@tonic-gate default: 80967c478bd9Sstevel@tonic-gate error = CRYPTO_MECHANISM_INVALID; 80977c478bd9Sstevel@tonic-gate } 80987c478bd9Sstevel@tonic-gate 80997c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) 81007c478bd9Sstevel@tonic-gate break; 81017c478bd9Sstevel@tonic-gate 81027c478bd9Sstevel@tonic-gate /* CKA_VALUE is optional */ 81037c478bd9Sstevel@tonic-gate (void) dprov_get_template_attr_array(template, attribute_count, 81047c478bd9Sstevel@tonic-gate DPROV_CKA_VALUE, &value, &value_len); 81057c478bd9Sstevel@tonic-gate 81067c478bd9Sstevel@tonic-gate /* check for inconsistent value length */ 81077c478bd9Sstevel@tonic-gate switch (key_type) { 81087c478bd9Sstevel@tonic-gate case DPROV_CKK_GENERIC_SECRET: 81097c478bd9Sstevel@tonic-gate if (value_len > 0) { 81107c478bd9Sstevel@tonic-gate if (value_len > hash_size) 81117c478bd9Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 81127c478bd9Sstevel@tonic-gate } else { 81137c478bd9Sstevel@tonic-gate value_len = hash_size; 81147c478bd9Sstevel@tonic-gate } 81157c478bd9Sstevel@tonic-gate break; 81167c478bd9Sstevel@tonic-gate 81177c478bd9Sstevel@tonic-gate case DPROV_CKK_RC4: 81187c478bd9Sstevel@tonic-gate case DPROV_CKK_AES: 81197c478bd9Sstevel@tonic-gate if (value_len == 0 || 81207c478bd9Sstevel@tonic-gate value_len > hash_size) { 81217c478bd9Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 81227c478bd9Sstevel@tonic-gate } 81237c478bd9Sstevel@tonic-gate break; 81247c478bd9Sstevel@tonic-gate 81257c478bd9Sstevel@tonic-gate case DPROV_CKK_DES: 81267c478bd9Sstevel@tonic-gate if (value_len > 0 && 81277c478bd9Sstevel@tonic-gate value_len != DES_KEY_LEN) { 81287c478bd9Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 81297c478bd9Sstevel@tonic-gate } 81307c478bd9Sstevel@tonic-gate value_len = DES_KEY_LEN; 81317c478bd9Sstevel@tonic-gate break; 81327c478bd9Sstevel@tonic-gate 81337c478bd9Sstevel@tonic-gate case DPROV_CKK_DES3: 81347c478bd9Sstevel@tonic-gate if (value_len > 0 && 81357c478bd9Sstevel@tonic-gate value_len != DES3_KEY_LEN) { 81367c478bd9Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 81377c478bd9Sstevel@tonic-gate } 81387c478bd9Sstevel@tonic-gate value_len = DES3_KEY_LEN; 81397c478bd9Sstevel@tonic-gate break; 81407c478bd9Sstevel@tonic-gate 81417c478bd9Sstevel@tonic-gate default: 81427c478bd9Sstevel@tonic-gate error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 81437c478bd9Sstevel@tonic-gate break; 81447c478bd9Sstevel@tonic-gate } 81457c478bd9Sstevel@tonic-gate 81467c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) 81477c478bd9Sstevel@tonic-gate break; 81487c478bd9Sstevel@tonic-gate 81497c478bd9Sstevel@tonic-gate /* get the software provider for this mechanism */ 81507c478bd9Sstevel@tonic-gate if ((error = dprov_get_sw_prov(&digest_mech, &pd, 81517c478bd9Sstevel@tonic-gate &digest_mech.cm_type)) != CRYPTO_SUCCESS) 81527c478bd9Sstevel@tonic-gate break; 81537c478bd9Sstevel@tonic-gate 81547c478bd9Sstevel@tonic-gate /* get the base key */ 81557c478bd9Sstevel@tonic-gate error = dprov_key_value_secret(softc, session_id, 81567c478bd9Sstevel@tonic-gate taskq_req->dr_type, taskq_req->dr_key_req.kr_key, &key); 81577c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) 81587c478bd9Sstevel@tonic-gate break; 81597c478bd9Sstevel@tonic-gate 81607c478bd9Sstevel@tonic-gate base_keyp = &key; 81617c478bd9Sstevel@tonic-gate 81627c478bd9Sstevel@tonic-gate data.cd_format = CRYPTO_DATA_RAW; 81637c478bd9Sstevel@tonic-gate data.cd_offset = 0; 81647c478bd9Sstevel@tonic-gate data.cd_length = CRYPTO_BITS2BYTES(base_keyp->ck_length); 81657c478bd9Sstevel@tonic-gate data.cd_raw.iov_base = base_keyp->ck_data; 81667c478bd9Sstevel@tonic-gate data.cd_raw.iov_len = data.cd_length; 81677c478bd9Sstevel@tonic-gate 81687c478bd9Sstevel@tonic-gate digest_buf = kmem_alloc(hash_size, KM_SLEEP); 81697c478bd9Sstevel@tonic-gate digest.cd_format = CRYPTO_DATA_RAW; 81707c478bd9Sstevel@tonic-gate digest.cd_offset = 0; 81717c478bd9Sstevel@tonic-gate digest.cd_length = hash_size; 81727c478bd9Sstevel@tonic-gate digest.cd_raw.iov_base = digest_buf; 81737c478bd9Sstevel@tonic-gate digest.cd_raw.iov_len = hash_size; 81747c478bd9Sstevel@tonic-gate 8175894b2776Smcpowers error = crypto_digest_prov(pd, 0, &digest_mech, &data, 8176894b2776Smcpowers &digest, NULL); 81777c478bd9Sstevel@tonic-gate 81787c478bd9Sstevel@tonic-gate KCF_PROV_REFRELE(pd); 81797c478bd9Sstevel@tonic-gate 81807c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) 81817c478bd9Sstevel@tonic-gate goto free_derived_key; 81827c478bd9Sstevel@tonic-gate 81837c478bd9Sstevel@tonic-gate error = dprov_create_object_from_template(softc, session, 81847c478bd9Sstevel@tonic-gate template, attribute_count, object_id_ptr, B_FALSE, B_FALSE); 81857c478bd9Sstevel@tonic-gate 81867c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) 81877c478bd9Sstevel@tonic-gate goto free_derived_key; 81887c478bd9Sstevel@tonic-gate 81897c478bd9Sstevel@tonic-gate derived_key.oa_type = DPROV_CKA_VALUE; 81907c478bd9Sstevel@tonic-gate derived_key.oa_value = digest_buf; 81917c478bd9Sstevel@tonic-gate derived_key.oa_value_len = value_len; 81927c478bd9Sstevel@tonic-gate 81937c478bd9Sstevel@tonic-gate error = dprov_object_set_attr(session, *object_id_ptr, 81947c478bd9Sstevel@tonic-gate &derived_key, 1, B_FALSE); 81957c478bd9Sstevel@tonic-gate 81967c478bd9Sstevel@tonic-gate if (error != CRYPTO_SUCCESS) { 81977c478bd9Sstevel@tonic-gate (void) dprov_destroy_object(softc, session, 81987c478bd9Sstevel@tonic-gate *object_id_ptr); 81997c478bd9Sstevel@tonic-gate } 82007c478bd9Sstevel@tonic-gate 82017c478bd9Sstevel@tonic-gate free_derived_key: 82027c478bd9Sstevel@tonic-gate bzero(digest_buf, hash_size); 82037c478bd9Sstevel@tonic-gate kmem_free(digest_buf, hash_size); 8204034448feSmcpowers break; 8205034448feSmcpowers } 8206034448feSmcpowers 8207034448feSmcpowers case DPROV_REQ_NOSTORE_KEY_GENERATE: { 8208034448feSmcpowers crypto_object_attribute_t *out_template; 8209034448feSmcpowers uint_t out_attribute_count; 8210034448feSmcpowers void *value; 8211034448feSmcpowers size_t value_len = 0; 8212034448feSmcpowers 8213034448feSmcpowers out_template = taskq_req->dr_key_req.kr_out_template1; 8214034448feSmcpowers out_attribute_count = 8215034448feSmcpowers taskq_req->dr_key_req.kr_out_attribute_count1; 8216034448feSmcpowers 8217034448feSmcpowers error = dprov_get_template_attr_array(out_template, 8218034448feSmcpowers out_attribute_count, DPROV_CKA_VALUE, &value, &value_len); 8219034448feSmcpowers if (error != CRYPTO_SUCCESS) 8220034448feSmcpowers break; 8221034448feSmcpowers 8222034448feSmcpowers /* fill the entire array with pattern */ 8223034448feSmcpowers { 8224034448feSmcpowers int i = 0; 8225034448feSmcpowers char *p = value; 8226034448feSmcpowers while (i < value_len) { 8227034448feSmcpowers p[i++] = 'A'; 8228034448feSmcpowers if (i >= value_len) 8229034448feSmcpowers break; 8230034448feSmcpowers p[i++] = 'B'; 8231034448feSmcpowers if (i >= value_len) 8232034448feSmcpowers break; 8233034448feSmcpowers p[i++] = 'C'; 82347c478bd9Sstevel@tonic-gate } 82357c478bd9Sstevel@tonic-gate } 82367c478bd9Sstevel@tonic-gate 8237034448feSmcpowers error = CRYPTO_SUCCESS; 8238034448feSmcpowers break; 8239034448feSmcpowers } 82405b0c7657Sizick 82415b0c7657Sizick case DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR: { 82425b0c7657Sizick crypto_mechanism_t *mechp; 82435b0c7657Sizick crypto_object_attribute_t *pub_template; 8244f9fbec18Smcpowers crypto_object_attribute_t *pri_template; 82455b0c7657Sizick uint_t pub_attribute_count; 8246f9fbec18Smcpowers uint_t pri_attribute_count; 82475b0c7657Sizick crypto_object_attribute_t *out_pub_template; 82485b0c7657Sizick crypto_object_attribute_t *out_pri_template; 82495b0c7657Sizick uint_t out_pub_attribute_count; 82505b0c7657Sizick uint_t out_pri_attribute_count; 82515b0c7657Sizick 82525b0c7657Sizick mechp = taskq_req->dr_key_req.kr_mechanism; 82535b0c7657Sizick pub_template = taskq_req->dr_key_req.kr_template; 82545b0c7657Sizick pub_attribute_count = taskq_req->dr_key_req.kr_attribute_count; 8255f9fbec18Smcpowers pri_template = taskq_req->dr_key_req.kr_private_key_template; 8256f9fbec18Smcpowers pri_attribute_count = 8257f9fbec18Smcpowers taskq_req->dr_key_req.kr_private_key_attribute_count; 82585b0c7657Sizick out_pub_template = taskq_req->dr_key_req.kr_out_template1; 82595b0c7657Sizick out_pub_attribute_count = 82605b0c7657Sizick taskq_req->dr_key_req.kr_out_attribute_count1; 82615b0c7657Sizick out_pri_template = taskq_req->dr_key_req.kr_out_template2; 82625b0c7657Sizick out_pri_attribute_count = 82635b0c7657Sizick taskq_req->dr_key_req.kr_out_attribute_count2; 82645b0c7657Sizick 82655b0c7657Sizick switch (mechp->cm_type) { 82665b0c7657Sizick case RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE: 82675b0c7657Sizick error = nostore_copy_attribute(out_pub_template, 82685b0c7657Sizick out_pub_attribute_count, DPROV_CKA_MODULUS); 82695b0c7657Sizick if (error != CRYPTO_SUCCESS) 82705b0c7657Sizick break; 82715b0c7657Sizick 82725b0c7657Sizick error = nostore_copy_attribute(out_pub_template, 82735b0c7657Sizick out_pub_attribute_count, DPROV_CKA_PUBLIC_EXPONENT); 82745b0c7657Sizick if (error == CRYPTO_ARGUMENTS_BAD) { 82755b0c7657Sizick size_t tmp_len = 0; 82765b0c7657Sizick void *tmp; 82775b0c7657Sizick 82785b0c7657Sizick /* public exponent must be here */ 82795b0c7657Sizick error = dprov_get_template_attr_array( 82805b0c7657Sizick pub_template, pub_attribute_count, 82815b0c7657Sizick DPROV_CKA_PUBLIC_EXPONENT, &tmp, &tmp_len); 82825b0c7657Sizick if (error != CRYPTO_SUCCESS) 82835b0c7657Sizick break; 82845b0c7657Sizick } 82855b0c7657Sizick error = nostore_copy_attribute(out_pri_template, 82865b0c7657Sizick out_pri_attribute_count, DPROV_CKA_MODULUS); 82875b0c7657Sizick if (error != CRYPTO_SUCCESS) 82885b0c7657Sizick break; 82895b0c7657Sizick 82905b0c7657Sizick error = nostore_copy_attribute(out_pri_template, 82915b0c7657Sizick out_pri_attribute_count, 82925b0c7657Sizick DPROV_CKA_PRIVATE_EXPONENT); 82935b0c7657Sizick break; 82945b0c7657Sizick 82955b0c7657Sizick case DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE: 82965b0c7657Sizick /* 82975b0c7657Sizick * There is no software provider for DH mechanism; 82985b0c7657Sizick * Just return pre-defined values. 82995b0c7657Sizick */ 83005b0c7657Sizick error = nostore_copy_attribute(out_pub_template, 83015b0c7657Sizick out_pub_attribute_count, DPROV_CKA_VALUE); 83025b0c7657Sizick error = nostore_copy_attribute(out_pri_template, 83035b0c7657Sizick out_pri_attribute_count, DPROV_CKA_VALUE); 83045b0c7657Sizick break; 83055b0c7657Sizick 8306f9fbec18Smcpowers case EC_KEY_PAIR_GEN_MECH_INFO_TYPE: { 8307f9fbec18Smcpowers crypto_mechanism_t mech, *mechp; 8308f9fbec18Smcpowers kcf_req_params_t params; 8309f9fbec18Smcpowers crypto_object_attribute_t *pub_template; 8310f9fbec18Smcpowers uint_t pub_attribute_count; 8311f9fbec18Smcpowers crypto_object_attribute_t *out_pub_template; 8312f9fbec18Smcpowers crypto_object_attribute_t *out_pri_template; 8313f9fbec18Smcpowers uint_t out_pub_attribute_count; 8314f9fbec18Smcpowers uint_t out_pri_attribute_count; 8315f9fbec18Smcpowers 8316f9fbec18Smcpowers mechp = taskq_req->dr_key_req.kr_mechanism; 8317f9fbec18Smcpowers pub_template = taskq_req->dr_key_req.kr_template; 8318f9fbec18Smcpowers pub_attribute_count = 8319f9fbec18Smcpowers taskq_req->dr_key_req.kr_attribute_count; 8320f9fbec18Smcpowers out_pub_template = 8321f9fbec18Smcpowers taskq_req->dr_key_req.kr_out_template1; 8322f9fbec18Smcpowers out_pub_attribute_count = 8323f9fbec18Smcpowers taskq_req->dr_key_req.kr_out_attribute_count1; 8324f9fbec18Smcpowers out_pri_template = 8325f9fbec18Smcpowers taskq_req->dr_key_req.kr_out_template2; 8326f9fbec18Smcpowers out_pri_attribute_count = 8327f9fbec18Smcpowers taskq_req->dr_key_req.kr_out_attribute_count2; 8328f9fbec18Smcpowers 8329f9fbec18Smcpowers /* get the software provider for this mechanism */ 8330f9fbec18Smcpowers mech = *mechp; 8331f9fbec18Smcpowers if ((error = dprov_get_sw_prov(mechp, &pd, 8332f9fbec18Smcpowers &mech.cm_type)) != CRYPTO_SUCCESS) 8333f9fbec18Smcpowers break; 8334f9fbec18Smcpowers /* 8335f9fbec18Smcpowers * Turn 32-bit values into 64-bit values for certain 8336f9fbec18Smcpowers * attributes like CKA_CLASS. 8337f9fbec18Smcpowers */ 8338f9fbec18Smcpowers dprov_adjust_attrs(pub_template, pub_attribute_count); 8339f9fbec18Smcpowers dprov_adjust_attrs(pri_template, pri_attribute_count); 8340f9fbec18Smcpowers 8341f9fbec18Smcpowers /* bypass the kernel API for now */ 8342f9fbec18Smcpowers KCF_WRAP_NOSTORE_KEY_OPS_PARAMS(¶ms, 8343f9fbec18Smcpowers KCF_OP_KEY_GENERATE_PAIR, 8344f9fbec18Smcpowers 0, /* session 0 for sw provider */ 8345f9fbec18Smcpowers &mech, pub_template, pub_attribute_count, 8346f9fbec18Smcpowers pri_template, pri_attribute_count, NULL, 8347f9fbec18Smcpowers out_pub_template, out_pub_attribute_count, 8348f9fbec18Smcpowers out_pri_template, out_pri_attribute_count); 8349f9fbec18Smcpowers 8350f9fbec18Smcpowers error = kcf_submit_request(pd, NULL, NULL, ¶ms, 8351f9fbec18Smcpowers B_FALSE); 8352f9fbec18Smcpowers 8353f9fbec18Smcpowers KCF_PROV_REFRELE(pd); 8354f9fbec18Smcpowers break; 8355f9fbec18Smcpowers } 83565b0c7657Sizick default: 83575b0c7657Sizick error = CRYPTO_MECHANISM_INVALID; 83585b0c7657Sizick } 83595b0c7657Sizick break; 83605b0c7657Sizick } 83615b0c7657Sizick 83625b0c7657Sizick case DPROV_REQ_NOSTORE_KEY_DERIVE: { 83635b0c7657Sizick crypto_mechanism_t *mechp; 83645b0c7657Sizick crypto_object_attribute_t *in_template, *out_template; 83655b0c7657Sizick crypto_key_t *base_key; 83665b0c7657Sizick uint_t in_attribute_count, out_attribute_count; 83675b0c7657Sizick ulong_t key_type; 83685b0c7657Sizick void *value; 83695b0c7657Sizick size_t value_len = 0; 83705b0c7657Sizick size_t value_len_value = 0; 83715b0c7657Sizick 83725b0c7657Sizick in_template = taskq_req->dr_key_req.kr_template; 83735b0c7657Sizick out_template = taskq_req->dr_key_req.kr_out_template1; 83745b0c7657Sizick in_attribute_count = taskq_req->dr_key_req.kr_attribute_count; 83755b0c7657Sizick out_attribute_count = 83765b0c7657Sizick taskq_req->dr_key_req.kr_out_attribute_count1; 83775b0c7657Sizick mechp = taskq_req->dr_key_req.kr_mechanism; 83785b0c7657Sizick base_key = taskq_req->dr_key_req.kr_key; 83795b0c7657Sizick 83805b0c7657Sizick /* 83815b0c7657Sizick * CKA_VALUE must be present so the derived key can 83825b0c7657Sizick * be returned by value. 83835b0c7657Sizick */ 83845b0c7657Sizick if (dprov_get_template_attr_array(out_template, 83855b0c7657Sizick out_attribute_count, DPROV_CKA_VALUE, &value, 83865b0c7657Sizick &value_len) != CRYPTO_SUCCESS) { 83875b0c7657Sizick error = CRYPTO_TEMPLATE_INCOMPLETE; 83885b0c7657Sizick break; 83895b0c7657Sizick } 83905b0c7657Sizick 83915b0c7657Sizick if (dprov_get_template_attr_ulong(in_template, 83925b0c7657Sizick in_attribute_count, DPROV_CKA_KEY_TYPE, 83935b0c7657Sizick &key_type) != CRYPTO_SUCCESS) { 83945b0c7657Sizick error = CRYPTO_TEMPLATE_INCOMPLETE; 83955b0c7657Sizick break; 83965b0c7657Sizick } 83975b0c7657Sizick switch (mechp->cm_type) { 83985b0c7657Sizick case DH_PKCS_DERIVE_MECH_INFO_TYPE: { 83995b0c7657Sizick size_t tmp_len = 0; 84005b0c7657Sizick void *tmp; 84015b0c7657Sizick 84025b0c7657Sizick if (base_key->ck_format != CRYPTO_KEY_ATTR_LIST) { 84035b0c7657Sizick error = CRYPTO_ARGUMENTS_BAD; 84045b0c7657Sizick break; 84055b0c7657Sizick } 84065b0c7657Sizick 84075b0c7657Sizick if ((dprov_get_template_attr_array(base_key->ck_attrs, 84085b0c7657Sizick base_key->ck_count, DPROV_CKA_BASE, &tmp, 84095b0c7657Sizick &tmp_len) != CRYPTO_SUCCESS) || 84105b0c7657Sizick (dprov_get_template_attr_array(base_key->ck_attrs, 84115b0c7657Sizick base_key->ck_count, DPROV_CKA_PRIME, &tmp, 84125b0c7657Sizick &tmp_len) != CRYPTO_SUCCESS) || 84135b0c7657Sizick (dprov_get_template_attr_array(base_key->ck_attrs, 84145b0c7657Sizick base_key->ck_count, DPROV_CKA_VALUE, &tmp, 84155b0c7657Sizick &tmp_len) != CRYPTO_SUCCESS)) { 84165b0c7657Sizick error = CRYPTO_TEMPLATE_INCOMPLETE; 84175b0c7657Sizick break; 84185b0c7657Sizick } 84195b0c7657Sizick 84205b0c7657Sizick /* 84215b0c7657Sizick * CKA_VALUE is added to the derived key template by 84225b0c7657Sizick * the library. 84235b0c7657Sizick */ 84245b0c7657Sizick error = CRYPTO_SUCCESS; 84255b0c7657Sizick switch (key_type) { 84265b0c7657Sizick case DPROV_CKK_AES: 84275b0c7657Sizick if (dprov_get_template_attr_ulong(in_template, 84285b0c7657Sizick in_attribute_count, DPROV_CKA_VALUE_LEN, 84295b0c7657Sizick &value_len_value) != CRYPTO_SUCCESS) { 84305b0c7657Sizick error = CRYPTO_TEMPLATE_INCOMPLETE; 84315b0c7657Sizick break; 84325b0c7657Sizick } 84335b0c7657Sizick if (value_len != value_len_value) { 84345b0c7657Sizick error = CRYPTO_TEMPLATE_INCONSISTENT; 84355b0c7657Sizick break; 84365b0c7657Sizick } 84375b0c7657Sizick default: 84385b0c7657Sizick error = CRYPTO_MECHANISM_INVALID; 84395b0c7657Sizick } 84405b0c7657Sizick if (error == CRYPTO_SUCCESS) 84415b0c7657Sizick fill_dh(value, value_len); 84425b0c7657Sizick break; 84435b0c7657Sizick } 8444f9fbec18Smcpowers case ECDH1_DERIVE_MECH_INFO_TYPE: { 8445f9fbec18Smcpowers crypto_mechanism_t mech; 8446f9fbec18Smcpowers kcf_req_params_t params; 8447f9fbec18Smcpowers 8448f9fbec18Smcpowers /* get the software provider for this mechanism */ 8449f9fbec18Smcpowers mech = *mechp; 8450f9fbec18Smcpowers if ((error = dprov_get_sw_prov(mechp, &pd, 8451f9fbec18Smcpowers &mech.cm_type)) != CRYPTO_SUCCESS) 8452f9fbec18Smcpowers break; 8453f9fbec18Smcpowers 8454f9fbec18Smcpowers /* 8455f9fbec18Smcpowers * Turn 32-bit values into 64-bit values for certain 8456f9fbec18Smcpowers * attributes like CKA_VALUE_LEN. 8457f9fbec18Smcpowers */ 8458f9fbec18Smcpowers dprov_adjust_attrs(in_template, in_attribute_count); 8459f9fbec18Smcpowers 8460f9fbec18Smcpowers /* bypass the kernel API for now */ 8461f9fbec18Smcpowers KCF_WRAP_NOSTORE_KEY_OPS_PARAMS(¶ms, 8462f9fbec18Smcpowers KCF_OP_KEY_DERIVE, 8463f9fbec18Smcpowers 0, /* session 0 for sw provider */ 8464f9fbec18Smcpowers &mech, in_template, in_attribute_count, 8465f9fbec18Smcpowers NULL, 0, base_key, 8466f9fbec18Smcpowers out_template, out_attribute_count, 8467f9fbec18Smcpowers NULL, 0); 8468f9fbec18Smcpowers 8469f9fbec18Smcpowers error = kcf_submit_request(pd, NULL, NULL, ¶ms, 8470f9fbec18Smcpowers B_FALSE); 8471f9fbec18Smcpowers 8472f9fbec18Smcpowers KCF_PROV_REFRELE(pd); 8473f9fbec18Smcpowers break; 8474f9fbec18Smcpowers } 8475f9fbec18Smcpowers 84765b0c7657Sizick default: 84775b0c7657Sizick error = CRYPTO_MECHANISM_INVALID; 84785b0c7657Sizick } 84795b0c7657Sizick break; 84805b0c7657Sizick default: 84815b0c7657Sizick error = CRYPTO_MECHANISM_INVALID; 84825b0c7657Sizick } 8483034448feSmcpowers } /* end case */ 8484034448feSmcpowers 84857c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 84867c478bd9Sstevel@tonic-gate dprov_op_done(taskq_req, error); 84877c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_KEY, ("(%d) dprov_key_task: end\n", instance)); 84887c478bd9Sstevel@tonic-gate } 84897c478bd9Sstevel@tonic-gate 84907c478bd9Sstevel@tonic-gate /* 84917c478bd9Sstevel@tonic-gate * taskq dispatcher function for provider management operations. 84927c478bd9Sstevel@tonic-gate */ 84937c478bd9Sstevel@tonic-gate static void 84947c478bd9Sstevel@tonic-gate dprov_mgmt_task(dprov_req_t *taskq_req) 84957c478bd9Sstevel@tonic-gate { 84967c478bd9Sstevel@tonic-gate dprov_state_t *softc; 84977c478bd9Sstevel@tonic-gate /* LINTED E_FUNC_SET_NOT_USED */ 84987c478bd9Sstevel@tonic-gate int instance; 84997c478bd9Sstevel@tonic-gate int error = CRYPTO_NOT_SUPPORTED; 85007c478bd9Sstevel@tonic-gate 85017c478bd9Sstevel@tonic-gate DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 85027c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_mgmt_task: started\n", instance)); 85037c478bd9Sstevel@tonic-gate 85047c478bd9Sstevel@tonic-gate mutex_enter(&softc->ds_lock); 85057c478bd9Sstevel@tonic-gate 85067c478bd9Sstevel@tonic-gate switch (taskq_req->dr_type) { 85077c478bd9Sstevel@tonic-gate case DPROV_REQ_MGMT_EXTINFO: { 85087c478bd9Sstevel@tonic-gate crypto_provider_ext_info_t *ext_info = 85097c478bd9Sstevel@tonic-gate taskq_req->dr_mgmt_req.mr_ext_info; 85107c478bd9Sstevel@tonic-gate 85117c478bd9Sstevel@tonic-gate (void) memset(ext_info->ei_label, ' ', CRYPTO_EXT_SIZE_LABEL); 85127c478bd9Sstevel@tonic-gate if (!softc->ds_token_initialized) { 85137c478bd9Sstevel@tonic-gate bcopy("(not initialized)", ext_info->ei_label, 85147c478bd9Sstevel@tonic-gate strlen("(not initialized)")); 85157c478bd9Sstevel@tonic-gate } else { 85167c478bd9Sstevel@tonic-gate bcopy(softc->ds_label, ext_info->ei_label, 85177c478bd9Sstevel@tonic-gate CRYPTO_EXT_SIZE_LABEL); 85187c478bd9Sstevel@tonic-gate } 85197c478bd9Sstevel@tonic-gate 85207c478bd9Sstevel@tonic-gate bcopy(DPROV_MANUFACTURER, ext_info->ei_manufacturerID, 85217c478bd9Sstevel@tonic-gate CRYPTO_EXT_SIZE_MANUF); 85227c478bd9Sstevel@tonic-gate bcopy(DPROV_MODEL, ext_info->ei_model, CRYPTO_EXT_SIZE_MODEL); 85237c478bd9Sstevel@tonic-gate 85247c478bd9Sstevel@tonic-gate (void) snprintf((char *)ext_info->ei_serial_number, 16, "%d%s", 85257c478bd9Sstevel@tonic-gate instance, DPROV_ALLSPACES); 85267c478bd9Sstevel@tonic-gate /* PKCS#11 blank padding */ 85277c478bd9Sstevel@tonic-gate ext_info->ei_serial_number[15] = ' '; 85287c478bd9Sstevel@tonic-gate ext_info->ei_max_session_count = CRYPTO_EFFECTIVELY_INFINITE; 85297c478bd9Sstevel@tonic-gate ext_info->ei_max_pin_len = (ulong_t)DPROV_MAX_PIN_LEN; 85307c478bd9Sstevel@tonic-gate ext_info->ei_min_pin_len = 1; 85317c478bd9Sstevel@tonic-gate ext_info->ei_total_public_memory = CRYPTO_EFFECTIVELY_INFINITE; 85327c478bd9Sstevel@tonic-gate ext_info->ei_free_public_memory = CRYPTO_EFFECTIVELY_INFINITE; 85337c478bd9Sstevel@tonic-gate ext_info->ei_total_private_memory = CRYPTO_EFFECTIVELY_INFINITE; 85347c478bd9Sstevel@tonic-gate ext_info->ei_free_private_memory = CRYPTO_EFFECTIVELY_INFINITE; 85357c478bd9Sstevel@tonic-gate ext_info->ei_hardware_version.cv_major = 1; 85367c478bd9Sstevel@tonic-gate ext_info->ei_hardware_version.cv_minor = 0; 85377c478bd9Sstevel@tonic-gate ext_info->ei_firmware_version.cv_major = 1; 85387c478bd9Sstevel@tonic-gate ext_info->ei_firmware_version.cv_minor = 0; 85397c478bd9Sstevel@tonic-gate 85407c478bd9Sstevel@tonic-gate ext_info->ei_flags = CRYPTO_EXTF_RNG | 8541c892ebf1Skrishna CRYPTO_EXTF_LOGIN_REQUIRED | 85427c478bd9Sstevel@tonic-gate CRYPTO_EXTF_DUAL_CRYPTO_OPERATIONS; 85437c478bd9Sstevel@tonic-gate if (softc->ds_user_pin_set) 85447c478bd9Sstevel@tonic-gate ext_info->ei_flags |= CRYPTO_EXTF_USER_PIN_INITIALIZED; 85457c478bd9Sstevel@tonic-gate if (softc->ds_token_initialized) 85467c478bd9Sstevel@tonic-gate ext_info->ei_flags |= CRYPTO_EXTF_TOKEN_INITIALIZED; 85477c478bd9Sstevel@tonic-gate 85484df55fdeSJanie Lu ext_info->ei_hash_max_input_len = dprov_max_digestsz; 85494df55fdeSJanie Lu ext_info->ei_hmac_max_input_len = dprov_max_digestsz; 85507c478bd9Sstevel@tonic-gate error = CRYPTO_SUCCESS; 85517c478bd9Sstevel@tonic-gate break; 85527c478bd9Sstevel@tonic-gate } 85537c478bd9Sstevel@tonic-gate case DPROV_REQ_MGMT_INITTOKEN: { 85547c478bd9Sstevel@tonic-gate char *pin = taskq_req->dr_mgmt_req.mr_pin; 85557c478bd9Sstevel@tonic-gate size_t pin_len = taskq_req->dr_mgmt_req.mr_pin_len; 85567c478bd9Sstevel@tonic-gate char *label = taskq_req->dr_mgmt_req.mr_label; 85577c478bd9Sstevel@tonic-gate 85587c478bd9Sstevel@tonic-gate /* cannot initialize token when a session is open */ 85597c478bd9Sstevel@tonic-gate if (softc->ds_sessions_count > 0) { 85607c478bd9Sstevel@tonic-gate error = CRYPTO_SESSION_EXISTS; 85617c478bd9Sstevel@tonic-gate break; 85627c478bd9Sstevel@tonic-gate } 85637c478bd9Sstevel@tonic-gate 85647c478bd9Sstevel@tonic-gate /* check PIN length */ 85657c478bd9Sstevel@tonic-gate if (pin_len > DPROV_MAX_PIN_LEN) { 85667c478bd9Sstevel@tonic-gate error = CRYPTO_PIN_LEN_RANGE; 85677c478bd9Sstevel@tonic-gate break; 85687c478bd9Sstevel@tonic-gate } 85697c478bd9Sstevel@tonic-gate 85707c478bd9Sstevel@tonic-gate /* check PIN */ 85717c478bd9Sstevel@tonic-gate if (pin == NULL) { 85727c478bd9Sstevel@tonic-gate error = CRYPTO_PIN_INVALID; 85737c478bd9Sstevel@tonic-gate break; 85747c478bd9Sstevel@tonic-gate } 85757c478bd9Sstevel@tonic-gate 85767c478bd9Sstevel@tonic-gate /* 85777c478bd9Sstevel@tonic-gate * If the token has already been initialized, need 85787c478bd9Sstevel@tonic-gate * to validate supplied PIN. 85797c478bd9Sstevel@tonic-gate */ 85807c478bd9Sstevel@tonic-gate if (softc->ds_token_initialized && 85817c478bd9Sstevel@tonic-gate (softc->ds_so_pin_len != pin_len || 85827c478bd9Sstevel@tonic-gate strncmp(softc->ds_so_pin, pin, pin_len) != 0)) { 85837c478bd9Sstevel@tonic-gate /* invalid SO PIN */ 85847c478bd9Sstevel@tonic-gate error = CRYPTO_PIN_INCORRECT; 85857c478bd9Sstevel@tonic-gate break; 85867c478bd9Sstevel@tonic-gate } 85877c478bd9Sstevel@tonic-gate 85887c478bd9Sstevel@tonic-gate /* set label */ 85897c478bd9Sstevel@tonic-gate bcopy(label, softc->ds_label, CRYPTO_EXT_SIZE_LABEL); 85907c478bd9Sstevel@tonic-gate 85917c478bd9Sstevel@tonic-gate /* set new SO PIN, update state */ 85927c478bd9Sstevel@tonic-gate bcopy(pin, softc->ds_so_pin, pin_len); 85937c478bd9Sstevel@tonic-gate softc->ds_so_pin_len = pin_len; 85947c478bd9Sstevel@tonic-gate softc->ds_token_initialized = B_TRUE; 85957c478bd9Sstevel@tonic-gate softc->ds_user_pin_set = B_FALSE; 85967c478bd9Sstevel@tonic-gate 85977c478bd9Sstevel@tonic-gate error = CRYPTO_SUCCESS; 85987c478bd9Sstevel@tonic-gate break; 85997c478bd9Sstevel@tonic-gate } 86007c478bd9Sstevel@tonic-gate case DPROV_REQ_MGMT_INITPIN: { 86017c478bd9Sstevel@tonic-gate char *pin = taskq_req->dr_mgmt_req.mr_pin; 86027c478bd9Sstevel@tonic-gate size_t pin_len = taskq_req->dr_mgmt_req.mr_pin_len; 86037c478bd9Sstevel@tonic-gate crypto_session_id_t session_id = 86047c478bd9Sstevel@tonic-gate taskq_req->dr_mgmt_req.mr_session_id; 86057c478bd9Sstevel@tonic-gate 86067c478bd9Sstevel@tonic-gate /* check session id */ 86077c478bd9Sstevel@tonic-gate if (softc->ds_sessions[session_id] == NULL) { 86087c478bd9Sstevel@tonic-gate error = CRYPTO_SESSION_HANDLE_INVALID; 86097c478bd9Sstevel@tonic-gate break; 86107c478bd9Sstevel@tonic-gate } 86117c478bd9Sstevel@tonic-gate 86127c478bd9Sstevel@tonic-gate /* fail if not logged in as SO */ 86137c478bd9Sstevel@tonic-gate if (softc->ds_sessions[session_id]->ds_state != 86147c478bd9Sstevel@tonic-gate DPROV_SESSION_STATE_SO) { 86157c478bd9Sstevel@tonic-gate error = CRYPTO_USER_NOT_LOGGED_IN; 86167c478bd9Sstevel@tonic-gate break; 86177c478bd9Sstevel@tonic-gate } 86187c478bd9Sstevel@tonic-gate 86197c478bd9Sstevel@tonic-gate /* check PIN length */ 86207c478bd9Sstevel@tonic-gate if (pin_len > DPROV_MAX_PIN_LEN) { 86217c478bd9Sstevel@tonic-gate error = CRYPTO_PIN_LEN_RANGE; 86227c478bd9Sstevel@tonic-gate break; 86237c478bd9Sstevel@tonic-gate } 86247c478bd9Sstevel@tonic-gate 86257c478bd9Sstevel@tonic-gate /* check PIN */ 86267c478bd9Sstevel@tonic-gate if (pin == NULL) { 86277c478bd9Sstevel@tonic-gate error = CRYPTO_PIN_INVALID; 86287c478bd9Sstevel@tonic-gate break; 86297c478bd9Sstevel@tonic-gate } 86307c478bd9Sstevel@tonic-gate 86317c478bd9Sstevel@tonic-gate /* set new normal user PIN */ 86327c478bd9Sstevel@tonic-gate bcopy(pin, softc->ds_user_pin, pin_len); 86337c478bd9Sstevel@tonic-gate softc->ds_user_pin_len = pin_len; 86347c478bd9Sstevel@tonic-gate softc->ds_user_pin_set = B_TRUE; 86357c478bd9Sstevel@tonic-gate 86367c478bd9Sstevel@tonic-gate error = CRYPTO_SUCCESS; 86377c478bd9Sstevel@tonic-gate break; 86387c478bd9Sstevel@tonic-gate } 86397c478bd9Sstevel@tonic-gate case DPROV_REQ_MGMT_SETPIN: { 86407c478bd9Sstevel@tonic-gate char *new_pin = taskq_req->dr_mgmt_req.mr_pin; 86417c478bd9Sstevel@tonic-gate size_t new_pin_len = taskq_req->dr_mgmt_req.mr_pin_len; 86427c478bd9Sstevel@tonic-gate char *old_pin = taskq_req->dr_mgmt_req.mr_old_pin; 86437c478bd9Sstevel@tonic-gate size_t old_pin_len = taskq_req->dr_mgmt_req.mr_old_pin_len; 86447c478bd9Sstevel@tonic-gate crypto_session_id_t session_id = 86457c478bd9Sstevel@tonic-gate taskq_req->dr_mgmt_req.mr_session_id; 86467c478bd9Sstevel@tonic-gate 86477c478bd9Sstevel@tonic-gate /* check session id */ 86487c478bd9Sstevel@tonic-gate if (softc->ds_sessions[session_id] == NULL) { 86497c478bd9Sstevel@tonic-gate error = CRYPTO_SESSION_HANDLE_INVALID; 86507c478bd9Sstevel@tonic-gate break; 86517c478bd9Sstevel@tonic-gate } 86527c478bd9Sstevel@tonic-gate 86537c478bd9Sstevel@tonic-gate /* check PIN length */ 86547c478bd9Sstevel@tonic-gate if (old_pin_len > DPROV_MAX_PIN_LEN || 86557c478bd9Sstevel@tonic-gate new_pin_len > DPROV_MAX_PIN_LEN) { 86567c478bd9Sstevel@tonic-gate error = CRYPTO_PIN_LEN_RANGE; 86577c478bd9Sstevel@tonic-gate break; 86587c478bd9Sstevel@tonic-gate } 86597c478bd9Sstevel@tonic-gate 86607c478bd9Sstevel@tonic-gate /* check PIN */ 86617c478bd9Sstevel@tonic-gate if (old_pin == NULL || new_pin == NULL) { 86627c478bd9Sstevel@tonic-gate error = CRYPTO_PIN_INVALID; 86637c478bd9Sstevel@tonic-gate break; 86647c478bd9Sstevel@tonic-gate } 86657c478bd9Sstevel@tonic-gate 86667c478bd9Sstevel@tonic-gate /* check user PIN state */ 86677c478bd9Sstevel@tonic-gate if (!softc->ds_user_pin_set) { 86687c478bd9Sstevel@tonic-gate error = CRYPTO_USER_PIN_NOT_INITIALIZED; 86697c478bd9Sstevel@tonic-gate break; 86707c478bd9Sstevel@tonic-gate } 86717c478bd9Sstevel@tonic-gate 86727c478bd9Sstevel@tonic-gate /* 86737c478bd9Sstevel@tonic-gate * If the token has already been initialized, need 86747c478bd9Sstevel@tonic-gate * to validate supplied PIN. 86757c478bd9Sstevel@tonic-gate */ 86767c478bd9Sstevel@tonic-gate if (softc->ds_user_pin_len != old_pin_len || 86777c478bd9Sstevel@tonic-gate strncmp(softc->ds_user_pin, old_pin, old_pin_len) != 0) { 86787c478bd9Sstevel@tonic-gate /* invalid SO PIN */ 86797c478bd9Sstevel@tonic-gate error = CRYPTO_PIN_INCORRECT; 86807c478bd9Sstevel@tonic-gate break; 86817c478bd9Sstevel@tonic-gate } 86827c478bd9Sstevel@tonic-gate 86837c478bd9Sstevel@tonic-gate /* set new PIN */ 86847c478bd9Sstevel@tonic-gate bcopy(new_pin, softc->ds_user_pin, new_pin_len); 86857c478bd9Sstevel@tonic-gate softc->ds_user_pin_len = new_pin_len; 86867c478bd9Sstevel@tonic-gate 86877c478bd9Sstevel@tonic-gate error = CRYPTO_SUCCESS; 86887c478bd9Sstevel@tonic-gate break; 86897c478bd9Sstevel@tonic-gate } 86907c478bd9Sstevel@tonic-gate } 86917c478bd9Sstevel@tonic-gate 86927c478bd9Sstevel@tonic-gate mutex_exit(&softc->ds_lock); 86937c478bd9Sstevel@tonic-gate dprov_op_done(taskq_req, error); 86947c478bd9Sstevel@tonic-gate DPROV_DEBUG(D_DIGEST, ("(%d) dprov_mgmt_task: end\n", instance)); 86957c478bd9Sstevel@tonic-gate } 86967c478bd9Sstevel@tonic-gate 86977c478bd9Sstevel@tonic-gate /* 86987c478bd9Sstevel@tonic-gate * Returns in the location pointed to by pd a pointer to the descriptor 86997c478bd9Sstevel@tonic-gate * for the software provider for the specified mechanism. 87007c478bd9Sstevel@tonic-gate * The provider descriptor is returned held. Returns one of the CRYPTO_ 87017c478bd9Sstevel@tonic-gate * error codes on failure, CRYPTO_SUCCESS on success. 87027c478bd9Sstevel@tonic-gate */ 87037c478bd9Sstevel@tonic-gate static int 87047c478bd9Sstevel@tonic-gate dprov_get_sw_prov(crypto_mechanism_t *mech, kcf_provider_desc_t **pd, 87057c478bd9Sstevel@tonic-gate crypto_mech_type_t *provider_mech_type) 87067c478bd9Sstevel@tonic-gate { 87077c478bd9Sstevel@tonic-gate crypto_mech_type_t kcf_mech_type = CRYPTO_MECH_INVALID; 87087c478bd9Sstevel@tonic-gate int i, rv; 87097c478bd9Sstevel@tonic-gate 87107c478bd9Sstevel@tonic-gate /* lookup the KCF mech type associated with our mech type */ 87117c478bd9Sstevel@tonic-gate for (i = 0; i < sizeof (dprov_mech_info_tab)/ 87127c478bd9Sstevel@tonic-gate sizeof (crypto_mech_info_t); i++) { 87137c478bd9Sstevel@tonic-gate if (mech->cm_type == dprov_mech_info_tab[i].cm_mech_number) { 87147c478bd9Sstevel@tonic-gate kcf_mech_type = crypto_mech2id_common( 87157c478bd9Sstevel@tonic-gate dprov_mech_info_tab[i].cm_mech_name, B_TRUE); 87167c478bd9Sstevel@tonic-gate } 87177c478bd9Sstevel@tonic-gate } 87187c478bd9Sstevel@tonic-gate 87196a1073f8Skrishna rv = kcf_get_sw_prov(kcf_mech_type, pd, NULL, B_TRUE); 87207c478bd9Sstevel@tonic-gate if (rv == CRYPTO_SUCCESS) 87217c478bd9Sstevel@tonic-gate *provider_mech_type = kcf_mech_type; 87227c478bd9Sstevel@tonic-gate 87237c478bd9Sstevel@tonic-gate return (rv); 87247c478bd9Sstevel@tonic-gate } 87257c478bd9Sstevel@tonic-gate 87267c478bd9Sstevel@tonic-gate /* 87277c478bd9Sstevel@tonic-gate * Object management helper functions. 87287c478bd9Sstevel@tonic-gate */ 87297c478bd9Sstevel@tonic-gate 87307c478bd9Sstevel@tonic-gate /* 87317c478bd9Sstevel@tonic-gate * Given a crypto_key_t, return whether the key can be used or not 87327c478bd9Sstevel@tonic-gate * for the specified request. The attributes used here are defined 87337c478bd9Sstevel@tonic-gate * in table 42 of the PKCS#11 spec (Common secret key attributes). 87347c478bd9Sstevel@tonic-gate */ 87357c478bd9Sstevel@tonic-gate static int 87367c478bd9Sstevel@tonic-gate dprov_key_can_use(dprov_object_t *object, dprov_req_type_t req_type) 87377c478bd9Sstevel@tonic-gate { 87387c478bd9Sstevel@tonic-gate boolean_t ret = 0; 87397c478bd9Sstevel@tonic-gate int rv = CRYPTO_SUCCESS; 87407c478bd9Sstevel@tonic-gate 87417c478bd9Sstevel@tonic-gate /* check if object is allowed for specified operation */ 87427c478bd9Sstevel@tonic-gate switch (req_type) { 87437c478bd9Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_INIT: 87447c478bd9Sstevel@tonic-gate case DPROV_REQ_ENCRYPT_ATOMIC: 87457c478bd9Sstevel@tonic-gate rv = dprov_get_object_attr_boolean(object, 87467c478bd9Sstevel@tonic-gate DPROV_CKA_ENCRYPT, &ret); 87477c478bd9Sstevel@tonic-gate break; 87487c478bd9Sstevel@tonic-gate case DPROV_REQ_DECRYPT_INIT: 87497c478bd9Sstevel@tonic-gate case DPROV_REQ_DECRYPT_ATOMIC: 87507c478bd9Sstevel@tonic-gate rv = dprov_get_object_attr_boolean(object, 87517c478bd9Sstevel@tonic-gate DPROV_CKA_DECRYPT, &ret); 87527c478bd9Sstevel@tonic-gate break; 87537c478bd9Sstevel@tonic-gate case DPROV_REQ_SIGN_INIT: 87547c478bd9Sstevel@tonic-gate case DPROV_REQ_SIGN_ATOMIC: 87557c478bd9Sstevel@tonic-gate case DPROV_REQ_MAC_INIT: 87567c478bd9Sstevel@tonic-gate case DPROV_REQ_MAC_ATOMIC: 8757894b2776Smcpowers case DPROV_REQ_MAC_VERIFY_ATOMIC: 87587c478bd9Sstevel@tonic-gate rv = dprov_get_object_attr_boolean(object, 87597c478bd9Sstevel@tonic-gate DPROV_CKA_SIGN, &ret); 87607c478bd9Sstevel@tonic-gate break; 87617c478bd9Sstevel@tonic-gate case DPROV_REQ_SIGN_RECOVER_INIT: 87627c478bd9Sstevel@tonic-gate case DPROV_REQ_SIGN_RECOVER_ATOMIC: 87637c478bd9Sstevel@tonic-gate rv = dprov_get_object_attr_boolean(object, 87647c478bd9Sstevel@tonic-gate DPROV_CKA_SIGN_RECOVER, &ret); 87657c478bd9Sstevel@tonic-gate break; 87667c478bd9Sstevel@tonic-gate case DPROV_REQ_VERIFY_INIT: 87677c478bd9Sstevel@tonic-gate case DPROV_REQ_VERIFY_ATOMIC: 87687c478bd9Sstevel@tonic-gate rv = dprov_get_object_attr_boolean(object, 87697c478bd9Sstevel@tonic-gate DPROV_CKA_VERIFY, &ret); 87707c478bd9Sstevel@tonic-gate break; 87717c478bd9Sstevel@tonic-gate case DPROV_REQ_VERIFY_RECOVER_INIT: 87727c478bd9Sstevel@tonic-gate case DPROV_REQ_VERIFY_RECOVER_ATOMIC: 87737c478bd9Sstevel@tonic-gate rv = dprov_get_object_attr_boolean(object, 87747c478bd9Sstevel@tonic-gate DPROV_CKA_VERIFY_RECOVER, &ret); 87757c478bd9Sstevel@tonic-gate break; 87767c478bd9Sstevel@tonic-gate case DPROV_REQ_KEY_WRAP: 87777c478bd9Sstevel@tonic-gate rv = dprov_get_object_attr_boolean(object, 87787c478bd9Sstevel@tonic-gate DPROV_CKA_WRAP, &ret); 87797c478bd9Sstevel@tonic-gate break; 87807c478bd9Sstevel@tonic-gate case DPROV_REQ_KEY_UNWRAP: 87817c478bd9Sstevel@tonic-gate rv = dprov_get_object_attr_boolean(object, 87827c478bd9Sstevel@tonic-gate DPROV_CKA_UNWRAP, &ret); 87837c478bd9Sstevel@tonic-gate break; 87847c478bd9Sstevel@tonic-gate case DPROV_REQ_DIGEST_KEY: 87857c478bd9Sstevel@tonic-gate /* 87867c478bd9Sstevel@tonic-gate * There is no attribute to check for; therefore, 87877c478bd9Sstevel@tonic-gate * any secret key can be used. 87887c478bd9Sstevel@tonic-gate */ 87897c478bd9Sstevel@tonic-gate ret = B_TRUE; 87907c478bd9Sstevel@tonic-gate rv = CRYPTO_SUCCESS; 87917c478bd9Sstevel@tonic-gate break; 87927c478bd9Sstevel@tonic-gate case DPROV_REQ_KEY_DERIVE: 87937c478bd9Sstevel@tonic-gate rv = dprov_get_object_attr_boolean(object, 87947c478bd9Sstevel@tonic-gate DPROV_CKA_DERIVE, &ret); 87957c478bd9Sstevel@tonic-gate break; 87967c478bd9Sstevel@tonic-gate } 87977c478bd9Sstevel@tonic-gate 87987c478bd9Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS || !ret) 87997c478bd9Sstevel@tonic-gate return (CRYPTO_KEY_FUNCTION_NOT_PERMITTED); 88007c478bd9Sstevel@tonic-gate 88017c478bd9Sstevel@tonic-gate return (CRYPTO_SUCCESS); 88027c478bd9Sstevel@tonic-gate } 88037c478bd9Sstevel@tonic-gate 88047c478bd9Sstevel@tonic-gate /* 88057c478bd9Sstevel@tonic-gate * Given a crypto_key_t corresponding to a secret key (i.e. for 88067c478bd9Sstevel@tonic-gate * use with symmetric crypto algorithms) specified in raw format, by 88077c478bd9Sstevel@tonic-gate * attribute, or by reference, initialize the ck_data and ck_length 88087c478bd9Sstevel@tonic-gate * fields of the ret_key argument so that they specify the key value 88097c478bd9Sstevel@tonic-gate * and length. 88107c478bd9Sstevel@tonic-gate * 88117c478bd9Sstevel@tonic-gate * For a key by value, this function uess the ck_data and ck_length, 88127c478bd9Sstevel@tonic-gate * for a key by reference, it looks up the corresponding object and 88137c478bd9Sstevel@tonic-gate * returns the appropriate attribute. For a key by attribute, it returns 88147c478bd9Sstevel@tonic-gate * the appropriate attribute. The attributes used are CKA_VALUE to retrieve 88157c478bd9Sstevel@tonic-gate * the value of the key, and CKA_VALUE_LEN to retrieve its length in bytes. 88167c478bd9Sstevel@tonic-gate */ 88177c478bd9Sstevel@tonic-gate static int 88187c478bd9Sstevel@tonic-gate dprov_key_value_secret(dprov_state_t *softc, crypto_session_id_t session_id, 88197c478bd9Sstevel@tonic-gate dprov_req_type_t req_type, crypto_key_t *key, crypto_key_t *ret_key) 88207c478bd9Sstevel@tonic-gate { 88217c478bd9Sstevel@tonic-gate ulong_t key_type; 88227c478bd9Sstevel@tonic-gate int ret = CRYPTO_SUCCESS; 88237c478bd9Sstevel@tonic-gate 88247c478bd9Sstevel@tonic-gate ret_key->ck_format = CRYPTO_KEY_RAW; 88257c478bd9Sstevel@tonic-gate 88267c478bd9Sstevel@tonic-gate switch (key->ck_format) { 88277c478bd9Sstevel@tonic-gate 88287c478bd9Sstevel@tonic-gate case CRYPTO_KEY_RAW: 88297c478bd9Sstevel@tonic-gate ret_key->ck_data = key->ck_data; 88307c478bd9Sstevel@tonic-gate ret_key->ck_length = key->ck_length; 88317c478bd9Sstevel@tonic-gate break; 88327c478bd9Sstevel@tonic-gate 88337c478bd9Sstevel@tonic-gate case CRYPTO_KEY_ATTR_LIST: { 88347c478bd9Sstevel@tonic-gate void *value; 88357c478bd9Sstevel@tonic-gate size_t len, value_len; 88367c478bd9Sstevel@tonic-gate 88377c478bd9Sstevel@tonic-gate if ((ret = dprov_get_key_attr_ulong(key, DPROV_CKA_KEY_TYPE, 88387c478bd9Sstevel@tonic-gate &key_type)) != CRYPTO_SUCCESS) 88397c478bd9Sstevel@tonic-gate break; 88407c478bd9Sstevel@tonic-gate 88417c478bd9Sstevel@tonic-gate if ((ret = dprov_get_key_attr_array(key, DPROV_CKA_VALUE, 88427c478bd9Sstevel@tonic-gate &value, &len)) != CRYPTO_SUCCESS) 88437c478bd9Sstevel@tonic-gate break; 88447c478bd9Sstevel@tonic-gate 88457c478bd9Sstevel@tonic-gate /* 88467c478bd9Sstevel@tonic-gate * The length of the array is expressed in bytes. 88477c478bd9Sstevel@tonic-gate * Convert to bits now since that's how keys are measured. 88487c478bd9Sstevel@tonic-gate */ 884995014fbbSDan OpenSolaris Anderson len = CRYPTO_BYTES2BITS(len); 88507c478bd9Sstevel@tonic-gate 88517c478bd9Sstevel@tonic-gate /* optional */ 88527c478bd9Sstevel@tonic-gate if ((dprov_get_key_attr_ulong(key, DPROV_CKA_VALUE_LEN, 88537c478bd9Sstevel@tonic-gate &value_len)) == CRYPTO_SUCCESS) { 88547c478bd9Sstevel@tonic-gate len = value_len; 88557c478bd9Sstevel@tonic-gate } 88567c478bd9Sstevel@tonic-gate 88577c478bd9Sstevel@tonic-gate ret_key->ck_data = value; 88587c478bd9Sstevel@tonic-gate ret_key->ck_length = (uint_t)len; 88597c478bd9Sstevel@tonic-gate 88607c478bd9Sstevel@tonic-gate break; 88617c478bd9Sstevel@tonic-gate } 88627c478bd9Sstevel@tonic-gate 88637c478bd9Sstevel@tonic-gate case CRYPTO_KEY_REFERENCE: { 88647c478bd9Sstevel@tonic-gate dprov_object_t *object; 88657c478bd9Sstevel@tonic-gate void *value; 88667c478bd9Sstevel@tonic-gate size_t len, value_len; 88677c478bd9Sstevel@tonic-gate 88687c478bd9Sstevel@tonic-gate /* check session id */ 88697c478bd9Sstevel@tonic-gate if (softc->ds_sessions[session_id] == NULL) { 88707c478bd9Sstevel@tonic-gate ret = CRYPTO_SESSION_HANDLE_INVALID; 88717c478bd9Sstevel@tonic-gate break; 88727c478bd9Sstevel@tonic-gate } 88737c478bd9Sstevel@tonic-gate 88747c478bd9Sstevel@tonic-gate if (key->ck_obj_id >= DPROV_MAX_OBJECTS) { 88757c478bd9Sstevel@tonic-gate ret = CRYPTO_KEY_HANDLE_INVALID; 88767c478bd9Sstevel@tonic-gate goto bail; 88777c478bd9Sstevel@tonic-gate } 88787c478bd9Sstevel@tonic-gate 88797c478bd9Sstevel@tonic-gate /* check if object id specified by key is valid */ 88807c478bd9Sstevel@tonic-gate object = softc->ds_sessions[session_id]-> 88817c478bd9Sstevel@tonic-gate ds_objects[key->ck_obj_id]; 88827c478bd9Sstevel@tonic-gate if (object == NULL) { 88837c478bd9Sstevel@tonic-gate ret = CRYPTO_KEY_HANDLE_INVALID; 88847c478bd9Sstevel@tonic-gate goto bail; 88857c478bd9Sstevel@tonic-gate } 88867c478bd9Sstevel@tonic-gate 88877c478bd9Sstevel@tonic-gate /* check if object can be used for operation */ 88887c478bd9Sstevel@tonic-gate if ((ret = dprov_key_can_use(object, req_type)) != 88897c478bd9Sstevel@tonic-gate CRYPTO_SUCCESS) 88907c478bd9Sstevel@tonic-gate goto bail; 88917c478bd9Sstevel@tonic-gate 88927c478bd9Sstevel@tonic-gate if ((ret = dprov_get_object_attr_ulong(object, 88937c478bd9Sstevel@tonic-gate DPROV_CKA_KEY_TYPE, &key_type)) != CRYPTO_SUCCESS) 88947c478bd9Sstevel@tonic-gate goto bail; 88957c478bd9Sstevel@tonic-gate 88967c478bd9Sstevel@tonic-gate if ((ret = dprov_get_object_attr_array(object, 88977c478bd9Sstevel@tonic-gate DPROV_CKA_VALUE, &value, &len)) != CRYPTO_SUCCESS) 88987c478bd9Sstevel@tonic-gate goto bail; 88997c478bd9Sstevel@tonic-gate 89007c478bd9Sstevel@tonic-gate /* optional */ 89017c478bd9Sstevel@tonic-gate if ((dprov_get_object_attr_ulong(object, DPROV_CKA_VALUE_LEN, 89027c478bd9Sstevel@tonic-gate &value_len)) == CRYPTO_SUCCESS) { 89037c478bd9Sstevel@tonic-gate len = value_len; 89047c478bd9Sstevel@tonic-gate } 89057c478bd9Sstevel@tonic-gate 89067c478bd9Sstevel@tonic-gate /* 89077c478bd9Sstevel@tonic-gate * The length of attributes are in bytes. 89087c478bd9Sstevel@tonic-gate * Convert to bits now since that's how keys are measured. 89097c478bd9Sstevel@tonic-gate */ 891095014fbbSDan OpenSolaris Anderson len = CRYPTO_BYTES2BITS(len); 89117c478bd9Sstevel@tonic-gate 89127c478bd9Sstevel@tonic-gate ret_key->ck_data = value; 89137c478bd9Sstevel@tonic-gate ret_key->ck_length = (uint_t)len; 89147c478bd9Sstevel@tonic-gate bail: 89157c478bd9Sstevel@tonic-gate break; 89167c478bd9Sstevel@tonic-gate } 89177c478bd9Sstevel@tonic-gate 89187c478bd9Sstevel@tonic-gate default: 89197c478bd9Sstevel@tonic-gate ret = CRYPTO_ARGUMENTS_BAD; 89207c478bd9Sstevel@tonic-gate break; 89217c478bd9Sstevel@tonic-gate } 89227c478bd9Sstevel@tonic-gate 89237c478bd9Sstevel@tonic-gate return (ret); 89247c478bd9Sstevel@tonic-gate } 89257c478bd9Sstevel@tonic-gate 89267c478bd9Sstevel@tonic-gate /* 89277c478bd9Sstevel@tonic-gate * Get the attribute list for the specified asymmetric key. 89287c478bd9Sstevel@tonic-gate */ 89297c478bd9Sstevel@tonic-gate static int 89307c478bd9Sstevel@tonic-gate dprov_key_attr_asymmetric(dprov_state_t *softc, crypto_session_id_t session_id, 89317c478bd9Sstevel@tonic-gate dprov_req_type_t req_type, crypto_key_t *key, crypto_key_t *ret_key) 89327c478bd9Sstevel@tonic-gate { 89337c478bd9Sstevel@tonic-gate int ret = CRYPTO_SUCCESS; 89347c478bd9Sstevel@tonic-gate 89357c478bd9Sstevel@tonic-gate ret_key->ck_format = CRYPTO_KEY_ATTR_LIST; 89367c478bd9Sstevel@tonic-gate 89377c478bd9Sstevel@tonic-gate switch (key->ck_format) { 89387c478bd9Sstevel@tonic-gate 89397c478bd9Sstevel@tonic-gate case CRYPTO_KEY_ATTR_LIST: 89407c478bd9Sstevel@tonic-gate ret_key->ck_attrs = key->ck_attrs; 89417c478bd9Sstevel@tonic-gate ret_key->ck_count = key->ck_count; 89427c478bd9Sstevel@tonic-gate break; 89437c478bd9Sstevel@tonic-gate 89447c478bd9Sstevel@tonic-gate case CRYPTO_KEY_REFERENCE: { 89457c478bd9Sstevel@tonic-gate dprov_object_t *object; 89467c478bd9Sstevel@tonic-gate 89477c478bd9Sstevel@tonic-gate /* check session id */ 89487c478bd9Sstevel@tonic-gate if (softc->ds_sessions[session_id] == NULL) { 89497c478bd9Sstevel@tonic-gate ret = CRYPTO_SESSION_HANDLE_INVALID; 89507c478bd9Sstevel@tonic-gate break; 89517c478bd9Sstevel@tonic-gate } 89527c478bd9Sstevel@tonic-gate 89537c478bd9Sstevel@tonic-gate /* check if object id specified by key is valid */ 89547c478bd9Sstevel@tonic-gate object = softc->ds_sessions[session_id]-> 89557c478bd9Sstevel@tonic-gate ds_objects[key->ck_obj_id]; 89567c478bd9Sstevel@tonic-gate if (object == NULL) { 89577c478bd9Sstevel@tonic-gate ret = CRYPTO_KEY_HANDLE_INVALID; 89587c478bd9Sstevel@tonic-gate break; 89597c478bd9Sstevel@tonic-gate } 89607c478bd9Sstevel@tonic-gate 89617c478bd9Sstevel@tonic-gate /* check if object can be used for operation */ 89627c478bd9Sstevel@tonic-gate if ((ret = dprov_key_can_use(object, req_type)) != 89637c478bd9Sstevel@tonic-gate CRYPTO_SUCCESS) 89647c478bd9Sstevel@tonic-gate break; 89657c478bd9Sstevel@tonic-gate 89667c478bd9Sstevel@tonic-gate ret_key->ck_attrs = object->do_attr; 89677c478bd9Sstevel@tonic-gate ret_key->ck_count = DPROV_MAX_ATTR; 89687c478bd9Sstevel@tonic-gate break; 89697c478bd9Sstevel@tonic-gate } 89707c478bd9Sstevel@tonic-gate 89717c478bd9Sstevel@tonic-gate default: 89727c478bd9Sstevel@tonic-gate ret = CRYPTO_ARGUMENTS_BAD; 89737c478bd9Sstevel@tonic-gate } 89747c478bd9Sstevel@tonic-gate 89757c478bd9Sstevel@tonic-gate return (ret); 89767c478bd9Sstevel@tonic-gate } 89777c478bd9Sstevel@tonic-gate 89787c478bd9Sstevel@tonic-gate /* 89797c478bd9Sstevel@tonic-gate * Return the index of an attribute of specified type found in 89807c478bd9Sstevel@tonic-gate * the specified array of attributes. If the attribute cannot 89817c478bd9Sstevel@tonic-gate * found, return -1. 89827c478bd9Sstevel@tonic-gate */ 89837c478bd9Sstevel@tonic-gate static int 89847c478bd9Sstevel@tonic-gate dprov_find_attr(crypto_object_attribute_t *attr, uint_t nattr, 89857c478bd9Sstevel@tonic-gate uint64_t attr_type) 89867c478bd9Sstevel@tonic-gate { 89877c478bd9Sstevel@tonic-gate int i; 89887c478bd9Sstevel@tonic-gate 89897c478bd9Sstevel@tonic-gate for (i = 0; i < nattr; i++) 89907c478bd9Sstevel@tonic-gate if (attr[i].oa_value != NULL && 89917c478bd9Sstevel@tonic-gate attr[i].oa_type == attr_type) 89927c478bd9Sstevel@tonic-gate return (i); 89937c478bd9Sstevel@tonic-gate 89947c478bd9Sstevel@tonic-gate return (-1); 89957c478bd9Sstevel@tonic-gate } 89967c478bd9Sstevel@tonic-gate 89977c478bd9Sstevel@tonic-gate /* 89987c478bd9Sstevel@tonic-gate * Given the given object template and session, return whether 89997c478bd9Sstevel@tonic-gate * an object can be created from that template according to the 90007c478bd9Sstevel@tonic-gate * following rules: 90017c478bd9Sstevel@tonic-gate * - private objects can be created only by a logged-in user 90027c478bd9Sstevel@tonic-gate */ 90037c478bd9Sstevel@tonic-gate static int 90047c478bd9Sstevel@tonic-gate dprov_template_can_create(dprov_session_t *session, 90057c478bd9Sstevel@tonic-gate crypto_object_attribute_t *template, uint_t nattr, 90067c478bd9Sstevel@tonic-gate boolean_t check_for_secret) 90077c478bd9Sstevel@tonic-gate { 90087c478bd9Sstevel@tonic-gate boolean_t is_private = B_FALSE; 90097c478bd9Sstevel@tonic-gate ulong_t key_type, class; 90107c478bd9Sstevel@tonic-gate int error; 90117c478bd9Sstevel@tonic-gate 90127c478bd9Sstevel@tonic-gate /* check CKA_PRIVATE attribute value */ 90137c478bd9Sstevel@tonic-gate error = dprov_get_template_attr_boolean(template, nattr, 90147c478bd9Sstevel@tonic-gate DPROV_CKA_PRIVATE, &is_private); 90157c478bd9Sstevel@tonic-gate if (error == CRYPTO_SUCCESS && is_private) { 90167c478bd9Sstevel@tonic-gate /* it's a private object */ 90177c478bd9Sstevel@tonic-gate if (session->ds_state != DPROV_SESSION_STATE_USER) { 90187c478bd9Sstevel@tonic-gate /* 90197c478bd9Sstevel@tonic-gate * Cannot create private object with SO or public 90207c478bd9Sstevel@tonic-gate * sessions. 90217c478bd9Sstevel@tonic-gate */ 90227c478bd9Sstevel@tonic-gate return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 90237c478bd9Sstevel@tonic-gate } 90247c478bd9Sstevel@tonic-gate } 90257c478bd9Sstevel@tonic-gate 90267c478bd9Sstevel@tonic-gate /* all objects must have an object class attribute */ 90277c478bd9Sstevel@tonic-gate if (dprov_get_template_attr_ulong(template, nattr, DPROV_CKA_CLASS, 90287c478bd9Sstevel@tonic-gate &class) != CRYPTO_SUCCESS) { 90297c478bd9Sstevel@tonic-gate return (CRYPTO_TEMPLATE_INCOMPLETE); 90307c478bd9Sstevel@tonic-gate } 90317c478bd9Sstevel@tonic-gate 90327c478bd9Sstevel@tonic-gate /* key objects must have a key type attribute */ 90337c478bd9Sstevel@tonic-gate if (class == DPROV_CKO_SECRET_KEY || 90347c478bd9Sstevel@tonic-gate class == DPROV_CKO_PUBLIC_KEY || 90357c478bd9Sstevel@tonic-gate class == DPROV_CKO_PRIVATE_KEY) { 90367c478bd9Sstevel@tonic-gate if (!dprov_template_attr_present(template, nattr, 90377c478bd9Sstevel@tonic-gate DPROV_CKA_KEY_TYPE)) { 90387c478bd9Sstevel@tonic-gate return (CRYPTO_TEMPLATE_INCOMPLETE); 90397c478bd9Sstevel@tonic-gate } 90407c478bd9Sstevel@tonic-gate } 90417c478bd9Sstevel@tonic-gate 90427c478bd9Sstevel@tonic-gate /* check for RSA public key attributes that must be present */ 90437c478bd9Sstevel@tonic-gate if (class == DPROV_CKO_PUBLIC_KEY) { 90447c478bd9Sstevel@tonic-gate if (dprov_get_template_attr_ulong(template, nattr, 90457c478bd9Sstevel@tonic-gate DPROV_CKA_KEY_TYPE, &key_type) == CRYPTO_SUCCESS) { 90467c478bd9Sstevel@tonic-gate if (key_type == DPROV_CKK_RSA) { 90477c478bd9Sstevel@tonic-gate if (!dprov_template_attr_present(template, 90487c478bd9Sstevel@tonic-gate nattr, DPROV_CKA_MODULUS) || 90497c478bd9Sstevel@tonic-gate !dprov_template_attr_present(template, 90507c478bd9Sstevel@tonic-gate nattr, DPROV_CKA_PUBLIC_EXPONENT)) { 90517c478bd9Sstevel@tonic-gate return (CRYPTO_TEMPLATE_INCOMPLETE); 90527c478bd9Sstevel@tonic-gate } 90537c478bd9Sstevel@tonic-gate 90547c478bd9Sstevel@tonic-gate /* these attributes should not be present */ 90557c478bd9Sstevel@tonic-gate if (dprov_template_attr_present(template, nattr, 90567c478bd9Sstevel@tonic-gate DPROV_CKA_MODULUS_BITS)) { 90577c478bd9Sstevel@tonic-gate return (CRYPTO_TEMPLATE_INCONSISTENT); 90587c478bd9Sstevel@tonic-gate } 90597c478bd9Sstevel@tonic-gate } 90607c478bd9Sstevel@tonic-gate } 90617c478bd9Sstevel@tonic-gate } 90627c478bd9Sstevel@tonic-gate 90637c478bd9Sstevel@tonic-gate /* check for RSA private key attributes that must be present */ 90647c478bd9Sstevel@tonic-gate if (class == DPROV_CKO_PRIVATE_KEY) { 90657c478bd9Sstevel@tonic-gate if (dprov_get_template_attr_ulong(template, nattr, 90667c478bd9Sstevel@tonic-gate DPROV_CKA_KEY_TYPE, &key_type) == CRYPTO_SUCCESS) { 90677c478bd9Sstevel@tonic-gate if (key_type == DPROV_CKK_RSA) { 90687c478bd9Sstevel@tonic-gate if (!dprov_template_attr_present(template, 90697c478bd9Sstevel@tonic-gate nattr, DPROV_CKA_MODULUS)) 90707c478bd9Sstevel@tonic-gate return (CRYPTO_TEMPLATE_INCOMPLETE); 90717c478bd9Sstevel@tonic-gate 90727c478bd9Sstevel@tonic-gate if (check_for_secret) { 90737c478bd9Sstevel@tonic-gate if (!dprov_template_attr_present( 90747c478bd9Sstevel@tonic-gate template, nattr, 90757c478bd9Sstevel@tonic-gate DPROV_CKA_PRIVATE_EXPONENT)) 90767c478bd9Sstevel@tonic-gate return ( 90777c478bd9Sstevel@tonic-gate CRYPTO_TEMPLATE_INCOMPLETE); 90787c478bd9Sstevel@tonic-gate } 90797c478bd9Sstevel@tonic-gate } 90807c478bd9Sstevel@tonic-gate } 90817c478bd9Sstevel@tonic-gate } 90827c478bd9Sstevel@tonic-gate 90837c478bd9Sstevel@tonic-gate /* check for secret key attributes that must be present */ 90847c478bd9Sstevel@tonic-gate if (class == DPROV_CKO_SECRET_KEY) { 90857c478bd9Sstevel@tonic-gate if (check_for_secret) { 90867c478bd9Sstevel@tonic-gate if (!dprov_template_attr_present(template, nattr, 90877c478bd9Sstevel@tonic-gate DPROV_CKA_VALUE)) { 90887c478bd9Sstevel@tonic-gate return (CRYPTO_TEMPLATE_INCOMPLETE); 90897c478bd9Sstevel@tonic-gate } 90907c478bd9Sstevel@tonic-gate } 90917c478bd9Sstevel@tonic-gate 90927c478bd9Sstevel@tonic-gate /* these attributes should not be present */ 90937c478bd9Sstevel@tonic-gate if (dprov_template_attr_present(template, nattr, 90947c478bd9Sstevel@tonic-gate DPROV_CKA_VALUE_LEN)) { 90957c478bd9Sstevel@tonic-gate return (CRYPTO_TEMPLATE_INCONSISTENT); 90967c478bd9Sstevel@tonic-gate } 90977c478bd9Sstevel@tonic-gate } 90987c478bd9Sstevel@tonic-gate 90997c478bd9Sstevel@tonic-gate return (CRYPTO_SUCCESS); 91007c478bd9Sstevel@tonic-gate } 91017c478bd9Sstevel@tonic-gate 91027c478bd9Sstevel@tonic-gate /* 91037c478bd9Sstevel@tonic-gate * Create an object from the specified template. Checks whether the 91047c478bd9Sstevel@tonic-gate * object can be created according to its attributes and the state 91057c478bd9Sstevel@tonic-gate * of the session. The new session object id is returned. If the 91067c478bd9Sstevel@tonic-gate * object is a token object, it is added to the per-instance object 91077c478bd9Sstevel@tonic-gate * table as well. 91087c478bd9Sstevel@tonic-gate */ 91097c478bd9Sstevel@tonic-gate static int 91107c478bd9Sstevel@tonic-gate dprov_create_object_from_template(dprov_state_t *softc, 91117c478bd9Sstevel@tonic-gate dprov_session_t *session, crypto_object_attribute_t *template, 91127c478bd9Sstevel@tonic-gate uint_t nattr, crypto_object_id_t *object_id, boolean_t check_for_secret, 91137c478bd9Sstevel@tonic-gate boolean_t force) 91147c478bd9Sstevel@tonic-gate { 91157c478bd9Sstevel@tonic-gate dprov_object_t *object; 91167c478bd9Sstevel@tonic-gate boolean_t is_token = B_FALSE; 91177c478bd9Sstevel@tonic-gate boolean_t extractable_attribute_present = B_FALSE; 9118034448feSmcpowers boolean_t sensitive_attribute_present = B_FALSE; 91197c478bd9Sstevel@tonic-gate boolean_t private_attribute_present = B_FALSE; 9120034448feSmcpowers boolean_t token_attribute_present = B_FALSE; 91217c478bd9Sstevel@tonic-gate uint_t i; 91227c478bd9Sstevel@tonic-gate int error; 91237c478bd9Sstevel@tonic-gate uint_t attr; 91247c478bd9Sstevel@tonic-gate uint_t oattr; 9125894b2776Smcpowers crypto_attr_type_t type; 9126894b2776Smcpowers size_t old_len, new_len; 9127894b2776Smcpowers offset_t offset; 91287c478bd9Sstevel@tonic-gate 91297c478bd9Sstevel@tonic-gate if (nattr > DPROV_MAX_ATTR) 91307c478bd9Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 91317c478bd9Sstevel@tonic-gate 91327c478bd9Sstevel@tonic-gate if (!force) { 91337c478bd9Sstevel@tonic-gate /* verify that object can be created */ 91347c478bd9Sstevel@tonic-gate if ((error = dprov_template_can_create(session, template, 91357c478bd9Sstevel@tonic-gate nattr, check_for_secret)) != CRYPTO_SUCCESS) 91367c478bd9Sstevel@tonic-gate return (error); 91377c478bd9Sstevel@tonic-gate } 91387c478bd9Sstevel@tonic-gate 91397c478bd9Sstevel@tonic-gate /* allocate new object */ 91407c478bd9Sstevel@tonic-gate object = kmem_zalloc(sizeof (dprov_object_t), KM_SLEEP); 91417c478bd9Sstevel@tonic-gate if (object == NULL) 91427c478bd9Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 91437c478bd9Sstevel@tonic-gate 91447c478bd9Sstevel@tonic-gate /* is it a token object? */ 91457c478bd9Sstevel@tonic-gate /* check CKA_TOKEN attribute value */ 91467c478bd9Sstevel@tonic-gate error = dprov_get_template_attr_boolean(template, nattr, 91477c478bd9Sstevel@tonic-gate DPROV_CKA_TOKEN, &is_token); 91487c478bd9Sstevel@tonic-gate if (error == CRYPTO_SUCCESS && is_token) { 91497c478bd9Sstevel@tonic-gate /* token object, add it to the per-instance object table */ 91507c478bd9Sstevel@tonic-gate for (i = 0; i < DPROV_MAX_OBJECTS; i++) 91517c478bd9Sstevel@tonic-gate if (softc->ds_objects[i] == NULL) 91527c478bd9Sstevel@tonic-gate break; 91537c478bd9Sstevel@tonic-gate if (i == DPROV_MAX_OBJECTS) 91547c478bd9Sstevel@tonic-gate /* no free slot */ 91557c478bd9Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 91567c478bd9Sstevel@tonic-gate softc->ds_objects[i] = object; 91577c478bd9Sstevel@tonic-gate object->do_token_idx = i; 91587c478bd9Sstevel@tonic-gate DPROV_OBJECT_REFHOLD(object); 91597c478bd9Sstevel@tonic-gate } 91607c478bd9Sstevel@tonic-gate 91617c478bd9Sstevel@tonic-gate /* add object to session object table */ 91627c478bd9Sstevel@tonic-gate for (i = 0; i < DPROV_MAX_OBJECTS; i++) 91637c478bd9Sstevel@tonic-gate if (session->ds_objects[i] == NULL) 91647c478bd9Sstevel@tonic-gate break; 91657c478bd9Sstevel@tonic-gate if (i == DPROV_MAX_OBJECTS) { 91667c478bd9Sstevel@tonic-gate /* no more session object slots */ 91677c478bd9Sstevel@tonic-gate DPROV_OBJECT_REFRELE(object); 91687c478bd9Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 91697c478bd9Sstevel@tonic-gate } 91707c478bd9Sstevel@tonic-gate session->ds_objects[i] = object; 91717c478bd9Sstevel@tonic-gate DPROV_OBJECT_REFHOLD(object); 91727c478bd9Sstevel@tonic-gate *object_id = i; 91737c478bd9Sstevel@tonic-gate 91747c478bd9Sstevel@tonic-gate /* initialize object from template */ 91757c478bd9Sstevel@tonic-gate for (attr = 0, oattr = 0; attr < nattr; attr++) { 91767c478bd9Sstevel@tonic-gate if (template[attr].oa_value == NULL) 91777c478bd9Sstevel@tonic-gate continue; 9178894b2776Smcpowers type = template[attr].oa_type; 9179894b2776Smcpowers old_len = template[attr].oa_value_len; 9180894b2776Smcpowers new_len = attribute_size(type, old_len); 9181894b2776Smcpowers 9182894b2776Smcpowers if (type == DPROV_CKA_EXTRACTABLE) { 91837c478bd9Sstevel@tonic-gate extractable_attribute_present = B_TRUE; 9184894b2776Smcpowers } else if (type == DPROV_CKA_PRIVATE) { 91857c478bd9Sstevel@tonic-gate private_attribute_present = B_TRUE; 9186034448feSmcpowers } else if (type == DPROV_CKA_TOKEN) { 9187034448feSmcpowers token_attribute_present = B_TRUE; 91887c478bd9Sstevel@tonic-gate } 9189894b2776Smcpowers object->do_attr[oattr].oa_type = type; 9190894b2776Smcpowers object->do_attr[oattr].oa_value_len = new_len; 91917c478bd9Sstevel@tonic-gate 9192894b2776Smcpowers object->do_attr[oattr].oa_value = kmem_zalloc(new_len, 9193894b2776Smcpowers KM_SLEEP); 9194894b2776Smcpowers 9195894b2776Smcpowers offset = 0; 9196894b2776Smcpowers #ifdef _BIG_ENDIAN 9197894b2776Smcpowers if (fixed_size_attribute(type)) { 9198894b2776Smcpowers offset = old_len - new_len; 9199894b2776Smcpowers } 9200894b2776Smcpowers #endif 9201894b2776Smcpowers bcopy(&template[attr].oa_value[offset], 9202894b2776Smcpowers object->do_attr[oattr].oa_value, new_len); 92037c478bd9Sstevel@tonic-gate oattr++; 92047c478bd9Sstevel@tonic-gate } 92057c478bd9Sstevel@tonic-gate 92067c478bd9Sstevel@tonic-gate /* add boolean attributes that must be present */ 92077c478bd9Sstevel@tonic-gate if (extractable_attribute_present == B_FALSE) { 92087c478bd9Sstevel@tonic-gate object->do_attr[oattr].oa_type = DPROV_CKA_EXTRACTABLE; 92097c478bd9Sstevel@tonic-gate object->do_attr[oattr].oa_value_len = 1; 92107c478bd9Sstevel@tonic-gate object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP); 92117c478bd9Sstevel@tonic-gate object->do_attr[oattr].oa_value[0] = B_TRUE; 92127c478bd9Sstevel@tonic-gate oattr++; 92137c478bd9Sstevel@tonic-gate } 92147c478bd9Sstevel@tonic-gate 92157c478bd9Sstevel@tonic-gate if (private_attribute_present == B_FALSE) { 92167c478bd9Sstevel@tonic-gate object->do_attr[oattr].oa_type = DPROV_CKA_PRIVATE; 92177c478bd9Sstevel@tonic-gate object->do_attr[oattr].oa_value_len = 1; 92187c478bd9Sstevel@tonic-gate object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP); 92197c478bd9Sstevel@tonic-gate object->do_attr[oattr].oa_value[0] = B_FALSE; 92207c478bd9Sstevel@tonic-gate oattr++; 92217c478bd9Sstevel@tonic-gate } 92227c478bd9Sstevel@tonic-gate 9223034448feSmcpowers if (token_attribute_present == B_FALSE) { 9224034448feSmcpowers object->do_attr[oattr].oa_type = DPROV_CKA_TOKEN; 9225034448feSmcpowers object->do_attr[oattr].oa_value_len = 1; 9226034448feSmcpowers object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP); 9227034448feSmcpowers object->do_attr[oattr].oa_value[0] = B_FALSE; 9228034448feSmcpowers oattr++; 9229034448feSmcpowers } 9230034448feSmcpowers 9231034448feSmcpowers if (sensitive_attribute_present == B_FALSE) { 9232034448feSmcpowers object->do_attr[oattr].oa_type = DPROV_CKA_SENSITIVE; 9233034448feSmcpowers object->do_attr[oattr].oa_value_len = 1; 9234034448feSmcpowers object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP); 9235034448feSmcpowers object->do_attr[oattr].oa_value[0] = B_FALSE; 9236034448feSmcpowers oattr++; 9237034448feSmcpowers } 92387c478bd9Sstevel@tonic-gate return (CRYPTO_SUCCESS); 92397c478bd9Sstevel@tonic-gate } 92407c478bd9Sstevel@tonic-gate 92417c478bd9Sstevel@tonic-gate /* 92427c478bd9Sstevel@tonic-gate * Checks whether or not the object matches the specified attributes. 9243894b2776Smcpowers * 9244894b2776Smcpowers * PKCS#11 attributes which are longs are stored in uint32_t containers 9245894b2776Smcpowers * so they can be matched by both 32 and 64-bit applications. 92467c478bd9Sstevel@tonic-gate */ 92477c478bd9Sstevel@tonic-gate static boolean_t 92487c478bd9Sstevel@tonic-gate dprov_attributes_match(dprov_object_t *object, 92497c478bd9Sstevel@tonic-gate crypto_object_attribute_t *template, uint_t nattr) 92507c478bd9Sstevel@tonic-gate { 9251894b2776Smcpowers crypto_attr_type_t type; 9252894b2776Smcpowers size_t tlen, olen, diff; 92537c478bd9Sstevel@tonic-gate int ta_idx; /* template attribute index */ 92547c478bd9Sstevel@tonic-gate int oa_idx; /* object attribute index */ 92557c478bd9Sstevel@tonic-gate 92567c478bd9Sstevel@tonic-gate for (ta_idx = 0; ta_idx < nattr; ta_idx++) { 92577c478bd9Sstevel@tonic-gate /* no value for template attribute */ 92587c478bd9Sstevel@tonic-gate if (template[ta_idx].oa_value == NULL) 92597c478bd9Sstevel@tonic-gate continue; 92607c478bd9Sstevel@tonic-gate 92617c478bd9Sstevel@tonic-gate /* find attribute in object */ 9262894b2776Smcpowers type = template[ta_idx].oa_type; 9263894b2776Smcpowers oa_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR, type); 92647c478bd9Sstevel@tonic-gate 92657c478bd9Sstevel@tonic-gate if (oa_idx == -1) 92667c478bd9Sstevel@tonic-gate /* attribute not found in object */ 92677c478bd9Sstevel@tonic-gate return (B_FALSE); 92687c478bd9Sstevel@tonic-gate 9269894b2776Smcpowers tlen = template[ta_idx].oa_value_len; 9270894b2776Smcpowers olen = object->do_attr[oa_idx].oa_value_len; 9271894b2776Smcpowers if (tlen < olen) 92727c478bd9Sstevel@tonic-gate return (B_FALSE); 92737c478bd9Sstevel@tonic-gate 9274894b2776Smcpowers diff = 0; 9275894b2776Smcpowers #ifdef _BIG_ENDIAN 9276894b2776Smcpowers /* application may think attribute is 8 bytes */ 9277894b2776Smcpowers if (fixed_size_attribute(type)) 9278894b2776Smcpowers diff = tlen - olen; 9279894b2776Smcpowers #endif 9280894b2776Smcpowers 9281894b2776Smcpowers if (bcmp(&template[ta_idx].oa_value[diff], 9282894b2776Smcpowers object->do_attr[oa_idx].oa_value, olen) != 0) 92837c478bd9Sstevel@tonic-gate /* value mismatch */ 92847c478bd9Sstevel@tonic-gate return (B_FALSE); 92857c478bd9Sstevel@tonic-gate } 92867c478bd9Sstevel@tonic-gate 92877c478bd9Sstevel@tonic-gate return (B_TRUE); 92887c478bd9Sstevel@tonic-gate } 92897c478bd9Sstevel@tonic-gate 92907c478bd9Sstevel@tonic-gate /* 92917c478bd9Sstevel@tonic-gate * Destroy the object specified by its session and object id. 92927c478bd9Sstevel@tonic-gate */ 92937c478bd9Sstevel@tonic-gate static int 92947c478bd9Sstevel@tonic-gate dprov_destroy_object(dprov_state_t *softc, dprov_session_t *session, 92957c478bd9Sstevel@tonic-gate crypto_object_id_t object_id) 92967c478bd9Sstevel@tonic-gate { 92977c478bd9Sstevel@tonic-gate dprov_object_t *object; 92987c478bd9Sstevel@tonic-gate 92997c478bd9Sstevel@tonic-gate if ((object = session->ds_objects[object_id]) == NULL) 93007c478bd9Sstevel@tonic-gate return (CRYPTO_OBJECT_HANDLE_INVALID); 93017c478bd9Sstevel@tonic-gate 93027c478bd9Sstevel@tonic-gate /* remove from session table */ 93037c478bd9Sstevel@tonic-gate session->ds_objects[object_id] = NULL; 93041c02caffSmcpowers 93051c02caffSmcpowers if (dprov_object_is_token(object)) { 93061c02caffSmcpowers if (!object->do_destroyed) { 93071c02caffSmcpowers object->do_destroyed = B_TRUE; 93081c02caffSmcpowers /* remove from per-instance token table */ 93091c02caffSmcpowers softc->ds_objects[object->do_token_idx] = NULL; 93101c02caffSmcpowers DPROV_OBJECT_REFRELE(object); 93111c02caffSmcpowers } else { 93121c02caffSmcpowers DPROV_DEBUG(D_OBJECT, ("dprov_destroy_object: " 93131c02caffSmcpowers "object %p already destroyed\n", (void *)object)); 93141c02caffSmcpowers } 93151c02caffSmcpowers } 93161c02caffSmcpowers 93177c478bd9Sstevel@tonic-gate DPROV_OBJECT_REFRELE(object); 93187c478bd9Sstevel@tonic-gate return (CRYPTO_SUCCESS); 93197c478bd9Sstevel@tonic-gate } 93207c478bd9Sstevel@tonic-gate 93217c478bd9Sstevel@tonic-gate static int 93227c478bd9Sstevel@tonic-gate dprov_object_can_modify(dprov_object_t *object, 93237c478bd9Sstevel@tonic-gate crypto_object_attribute_t *template, uint_t nattr) 93247c478bd9Sstevel@tonic-gate { 93257c478bd9Sstevel@tonic-gate ulong_t object_class; 93267c478bd9Sstevel@tonic-gate 93277c478bd9Sstevel@tonic-gate /* all objects should have an object class attribute */ 93287c478bd9Sstevel@tonic-gate if (dprov_get_object_attr_ulong(object, DPROV_CKA_CLASS, 93297c478bd9Sstevel@tonic-gate &object_class) != CRYPTO_SUCCESS) { 93307c478bd9Sstevel@tonic-gate return (CRYPTO_SUCCESS); 93317c478bd9Sstevel@tonic-gate } 93327c478bd9Sstevel@tonic-gate 93337c478bd9Sstevel@tonic-gate if (object_class == DPROV_CKO_SECRET_KEY || 93347c478bd9Sstevel@tonic-gate object_class == DPROV_CKO_PUBLIC_KEY || 93357c478bd9Sstevel@tonic-gate object_class == DPROV_CKO_PRIVATE_KEY) { 93367c478bd9Sstevel@tonic-gate if (dprov_template_attr_present(template, nattr, 93377c478bd9Sstevel@tonic-gate DPROV_CKA_CLASS) || 93387c478bd9Sstevel@tonic-gate dprov_template_attr_present(template, nattr, 93397c478bd9Sstevel@tonic-gate DPROV_CKA_KEY_TYPE)) 93407c478bd9Sstevel@tonic-gate return (CRYPTO_TEMPLATE_INCONSISTENT); 93417c478bd9Sstevel@tonic-gate } 93427c478bd9Sstevel@tonic-gate 93437c478bd9Sstevel@tonic-gate switch (object_class) { 93447c478bd9Sstevel@tonic-gate case DPROV_CKO_SECRET_KEY: 93457c478bd9Sstevel@tonic-gate if (dprov_template_attr_present(template, nattr, 93467c478bd9Sstevel@tonic-gate DPROV_CKA_VALUE)) 93477c478bd9Sstevel@tonic-gate return (CRYPTO_TEMPLATE_INCONSISTENT); 93487c478bd9Sstevel@tonic-gate break; 93497c478bd9Sstevel@tonic-gate 93507c478bd9Sstevel@tonic-gate case DPROV_CKO_PUBLIC_KEY: 93517c478bd9Sstevel@tonic-gate if (dprov_template_attr_present(template, nattr, 93527c478bd9Sstevel@tonic-gate DPROV_CKA_MODULUS) || 93537c478bd9Sstevel@tonic-gate dprov_template_attr_present(template, nattr, 93547c478bd9Sstevel@tonic-gate DPROV_CKA_PUBLIC_EXPONENT)) 93557c478bd9Sstevel@tonic-gate return (CRYPTO_TEMPLATE_INCONSISTENT); 93567c478bd9Sstevel@tonic-gate break; 93577c478bd9Sstevel@tonic-gate 93587c478bd9Sstevel@tonic-gate case DPROV_CKO_PRIVATE_KEY: 93597c478bd9Sstevel@tonic-gate if (dprov_template_attr_present(template, nattr, 93607c478bd9Sstevel@tonic-gate DPROV_CKA_MODULUS) || 93617c478bd9Sstevel@tonic-gate dprov_template_attr_present(template, nattr, 93627c478bd9Sstevel@tonic-gate DPROV_CKA_PRIVATE_EXPONENT)) 93637c478bd9Sstevel@tonic-gate return (CRYPTO_TEMPLATE_INCONSISTENT); 93647c478bd9Sstevel@tonic-gate break; 93657c478bd9Sstevel@tonic-gate 93667c478bd9Sstevel@tonic-gate default: 93677c478bd9Sstevel@tonic-gate return (CRYPTO_SUCCESS); 93687c478bd9Sstevel@tonic-gate } 93697c478bd9Sstevel@tonic-gate 93707c478bd9Sstevel@tonic-gate return (CRYPTO_SUCCESS); 93717c478bd9Sstevel@tonic-gate } 93727c478bd9Sstevel@tonic-gate 93737c478bd9Sstevel@tonic-gate /* 93747c478bd9Sstevel@tonic-gate * Set the attributes specified by the template in the specified object, 93757c478bd9Sstevel@tonic-gate * replacing existing ones if needed. 93767c478bd9Sstevel@tonic-gate */ 93777c478bd9Sstevel@tonic-gate static int 93787c478bd9Sstevel@tonic-gate dprov_object_set_attr(dprov_session_t *session, crypto_object_id_t object_id, 93797c478bd9Sstevel@tonic-gate crypto_object_attribute_t *template, uint_t nattr, 93807c478bd9Sstevel@tonic-gate boolean_t check_attributes) 93817c478bd9Sstevel@tonic-gate { 9382894b2776Smcpowers crypto_attr_type_t type; 93837c478bd9Sstevel@tonic-gate dprov_object_t *object; 9384894b2776Smcpowers size_t old_len, new_len; 93857c478bd9Sstevel@tonic-gate uint_t i, j; 93867c478bd9Sstevel@tonic-gate int error; 93877c478bd9Sstevel@tonic-gate 93887c478bd9Sstevel@tonic-gate if ((object = session->ds_objects[object_id]) == NULL) 93897c478bd9Sstevel@tonic-gate return (CRYPTO_OBJECT_HANDLE_INVALID); 93907c478bd9Sstevel@tonic-gate 93917c478bd9Sstevel@tonic-gate if (check_attributes) { 93927c478bd9Sstevel@tonic-gate /* verify that attributes in the template can be modified */ 93937c478bd9Sstevel@tonic-gate if ((error = dprov_object_can_modify(object, template, nattr)) 93947c478bd9Sstevel@tonic-gate != CRYPTO_SUCCESS) 93957c478bd9Sstevel@tonic-gate return (error); 93967c478bd9Sstevel@tonic-gate } 93977c478bd9Sstevel@tonic-gate 93987c478bd9Sstevel@tonic-gate /* go through the attributes specified in the template */ 93997c478bd9Sstevel@tonic-gate for (i = 0; i < nattr; i++) { 94007c478bd9Sstevel@tonic-gate if (template[i].oa_value == NULL) 94017c478bd9Sstevel@tonic-gate continue; 94027c478bd9Sstevel@tonic-gate 94037c478bd9Sstevel@tonic-gate /* find attribute in object */ 9404894b2776Smcpowers type = template[i].oa_type; 9405894b2776Smcpowers j = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR, type); 94067c478bd9Sstevel@tonic-gate 94077c478bd9Sstevel@tonic-gate if (j != -1) { 94087c478bd9Sstevel@tonic-gate /* attribute already exists, free old value */ 94097c478bd9Sstevel@tonic-gate kmem_free(object->do_attr[j].oa_value, 94107c478bd9Sstevel@tonic-gate object->do_attr[j].oa_value_len); 94117c478bd9Sstevel@tonic-gate } else { 94127c478bd9Sstevel@tonic-gate /* attribute does not exist, create it */ 94137c478bd9Sstevel@tonic-gate for (j = 0; j < DPROV_MAX_ATTR; j++) 94147c478bd9Sstevel@tonic-gate if (object->do_attr[j].oa_value == NULL) 94157c478bd9Sstevel@tonic-gate break; 94167c478bd9Sstevel@tonic-gate if (j == DPROV_MAX_ATTR) 94177c478bd9Sstevel@tonic-gate /* ran out of attribute slots */ 94187c478bd9Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 94197c478bd9Sstevel@tonic-gate } 94207c478bd9Sstevel@tonic-gate 9421894b2776Smcpowers old_len = template[i].oa_value_len; 9422894b2776Smcpowers new_len = attribute_size(type, old_len); 9423894b2776Smcpowers 94247c478bd9Sstevel@tonic-gate /* set object attribute value */ 9425894b2776Smcpowers object->do_attr[j].oa_value = kmem_alloc(new_len, KM_SLEEP); 9426894b2776Smcpowers bcopy(&template[i].oa_value[old_len - new_len], 9427894b2776Smcpowers object->do_attr[j].oa_value, new_len); 9428894b2776Smcpowers object->do_attr[j].oa_value_len = new_len; 94297c478bd9Sstevel@tonic-gate 94307c478bd9Sstevel@tonic-gate /* and the type */ 9431894b2776Smcpowers object->do_attr[j].oa_type = type; 94327c478bd9Sstevel@tonic-gate } 94337c478bd9Sstevel@tonic-gate 94347c478bd9Sstevel@tonic-gate return (CRYPTO_SUCCESS); 94357c478bd9Sstevel@tonic-gate } 94367c478bd9Sstevel@tonic-gate 94377c478bd9Sstevel@tonic-gate 94387c478bd9Sstevel@tonic-gate /* 94397c478bd9Sstevel@tonic-gate * Free the specified object. 94407c478bd9Sstevel@tonic-gate */ 94417c478bd9Sstevel@tonic-gate static void 94427c478bd9Sstevel@tonic-gate dprov_free_object(dprov_object_t *object) 94437c478bd9Sstevel@tonic-gate { 94447c478bd9Sstevel@tonic-gate int i; 94457c478bd9Sstevel@tonic-gate 94467c478bd9Sstevel@tonic-gate /* free the object attributes values */ 94477c478bd9Sstevel@tonic-gate for (i = 0; i < DPROV_MAX_ATTR; i++) 94487c478bd9Sstevel@tonic-gate if (object->do_attr[i].oa_value != NULL) 94497c478bd9Sstevel@tonic-gate kmem_free(object->do_attr[i].oa_value, 94507c478bd9Sstevel@tonic-gate object->do_attr[i].oa_value_len); 94517c478bd9Sstevel@tonic-gate 94527c478bd9Sstevel@tonic-gate /* free the object */ 94537c478bd9Sstevel@tonic-gate kmem_free(object, sizeof (dprov_object_t)); 94547c478bd9Sstevel@tonic-gate } 94557c478bd9Sstevel@tonic-gate 94567c478bd9Sstevel@tonic-gate /* 94577c478bd9Sstevel@tonic-gate * Checks whether the specified object is a private or public object. 94587c478bd9Sstevel@tonic-gate */ 94597c478bd9Sstevel@tonic-gate static boolean_t 94607c478bd9Sstevel@tonic-gate dprov_object_is_private(dprov_object_t *object) 94617c478bd9Sstevel@tonic-gate { 94627c478bd9Sstevel@tonic-gate boolean_t ret; 94637c478bd9Sstevel@tonic-gate int err; 94647c478bd9Sstevel@tonic-gate 94657c478bd9Sstevel@tonic-gate err = dprov_get_object_attr_boolean(object, DPROV_CKA_PRIVATE, &ret); 94667c478bd9Sstevel@tonic-gate 94677c478bd9Sstevel@tonic-gate if (err != CRYPTO_SUCCESS) 94687c478bd9Sstevel@tonic-gate /* by default, CKA_PRIVATE is false */ 94697c478bd9Sstevel@tonic-gate ret = B_FALSE; 94707c478bd9Sstevel@tonic-gate 94717c478bd9Sstevel@tonic-gate return (ret); 94727c478bd9Sstevel@tonic-gate } 94737c478bd9Sstevel@tonic-gate 94747c478bd9Sstevel@tonic-gate /* 94757c478bd9Sstevel@tonic-gate * Checks whether the specified object is a token or session object. 94767c478bd9Sstevel@tonic-gate */ 94777c478bd9Sstevel@tonic-gate static boolean_t 94787c478bd9Sstevel@tonic-gate dprov_object_is_token(dprov_object_t *object) 94797c478bd9Sstevel@tonic-gate { 94807c478bd9Sstevel@tonic-gate boolean_t ret; 94817c478bd9Sstevel@tonic-gate int err; 94827c478bd9Sstevel@tonic-gate 94837c478bd9Sstevel@tonic-gate err = dprov_get_object_attr_boolean(object, DPROV_CKA_TOKEN, &ret); 94847c478bd9Sstevel@tonic-gate 94857c478bd9Sstevel@tonic-gate if (err != CRYPTO_SUCCESS) 94867c478bd9Sstevel@tonic-gate /* by default, CKA_TOKEN is false */ 94877c478bd9Sstevel@tonic-gate ret = B_FALSE; 94887c478bd9Sstevel@tonic-gate 94897c478bd9Sstevel@tonic-gate return (ret); 94907c478bd9Sstevel@tonic-gate } 94917c478bd9Sstevel@tonic-gate 94927c478bd9Sstevel@tonic-gate /* 94937c478bd9Sstevel@tonic-gate * Common function used by the dprov_get_object_attr_*() family of 94947c478bd9Sstevel@tonic-gate * functions. Returns the value of the specified attribute of specified 94957c478bd9Sstevel@tonic-gate * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID 94967c478bd9Sstevel@tonic-gate * if the length of the attribute does not match the specified length, 94977c478bd9Sstevel@tonic-gate * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found. 94987c478bd9Sstevel@tonic-gate */ 94997c478bd9Sstevel@tonic-gate static int 95007c478bd9Sstevel@tonic-gate dprov_get_object_attr_scalar_common(dprov_object_t *object, uint64_t attr_type, 95017c478bd9Sstevel@tonic-gate void *value, size_t value_len) 95027c478bd9Sstevel@tonic-gate { 95037c478bd9Sstevel@tonic-gate int attr_idx; 95047c478bd9Sstevel@tonic-gate size_t oa_value_len; 95057c478bd9Sstevel@tonic-gate size_t offset = 0; 95067c478bd9Sstevel@tonic-gate 95077c478bd9Sstevel@tonic-gate if ((attr_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR, 95087c478bd9Sstevel@tonic-gate attr_type)) == -1) 95097c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 95107c478bd9Sstevel@tonic-gate 95117c478bd9Sstevel@tonic-gate oa_value_len = object->do_attr[attr_idx].oa_value_len; 95127c478bd9Sstevel@tonic-gate if (oa_value_len != value_len) { 95137c478bd9Sstevel@tonic-gate /* 95147c478bd9Sstevel@tonic-gate * For some attributes, it's okay to copy the value 95157c478bd9Sstevel@tonic-gate * into a larger container, e.g. copy an unsigned 95167c478bd9Sstevel@tonic-gate * 32-bit integer into a 64-bit container. 95177c478bd9Sstevel@tonic-gate */ 95187c478bd9Sstevel@tonic-gate if (attr_type == DPROV_CKA_VALUE_LEN || 95197c478bd9Sstevel@tonic-gate attr_type == DPROV_CKA_KEY_TYPE || 95207c478bd9Sstevel@tonic-gate attr_type == DPROV_CKA_CLASS) { 95217c478bd9Sstevel@tonic-gate if (oa_value_len < value_len) { 95227c478bd9Sstevel@tonic-gate #ifdef _BIG_ENDIAN 95237c478bd9Sstevel@tonic-gate offset = value_len - oa_value_len; 95247c478bd9Sstevel@tonic-gate #endif 95257c478bd9Sstevel@tonic-gate bzero(value, value_len); 95267c478bd9Sstevel@tonic-gate goto do_copy; 95277c478bd9Sstevel@tonic-gate } 95287c478bd9Sstevel@tonic-gate } 95297c478bd9Sstevel@tonic-gate /* incorrect attribute value length */ 95307c478bd9Sstevel@tonic-gate return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 95317c478bd9Sstevel@tonic-gate } 95327c478bd9Sstevel@tonic-gate 95337c478bd9Sstevel@tonic-gate do_copy: 95347c478bd9Sstevel@tonic-gate bcopy(object->do_attr[attr_idx].oa_value, (uchar_t *)value + offset, 95357c478bd9Sstevel@tonic-gate oa_value_len); 95367c478bd9Sstevel@tonic-gate 95377c478bd9Sstevel@tonic-gate return (CRYPTO_SUCCESS); 95387c478bd9Sstevel@tonic-gate } 95397c478bd9Sstevel@tonic-gate 95407c478bd9Sstevel@tonic-gate /* 95417c478bd9Sstevel@tonic-gate * Get the value of the a boolean attribute from the specified object. 95427c478bd9Sstevel@tonic-gate */ 95437c478bd9Sstevel@tonic-gate static int 95447c478bd9Sstevel@tonic-gate dprov_get_object_attr_boolean(dprov_object_t *object, uint64_t attr_type, 95457c478bd9Sstevel@tonic-gate boolean_t *attr_value) 95467c478bd9Sstevel@tonic-gate { 95477c478bd9Sstevel@tonic-gate uchar_t val; 95487c478bd9Sstevel@tonic-gate int ret; 95497c478bd9Sstevel@tonic-gate 95507c478bd9Sstevel@tonic-gate /* PKCS#11 defines a boolean as one byte */ 95517c478bd9Sstevel@tonic-gate ret = dprov_get_object_attr_scalar_common(object, attr_type, &val, 1); 95527c478bd9Sstevel@tonic-gate if (ret == CRYPTO_SUCCESS) { 95537c478bd9Sstevel@tonic-gate *attr_value = (val == '\0') ? B_FALSE : B_TRUE; 95547c478bd9Sstevel@tonic-gate } 95557c478bd9Sstevel@tonic-gate return (ret); 95567c478bd9Sstevel@tonic-gate } 95577c478bd9Sstevel@tonic-gate 95587c478bd9Sstevel@tonic-gate /* 95597c478bd9Sstevel@tonic-gate * Get the value of a ulong_t attribute from the specified object. 95607c478bd9Sstevel@tonic-gate */ 95617c478bd9Sstevel@tonic-gate static int 95627c478bd9Sstevel@tonic-gate dprov_get_object_attr_ulong(dprov_object_t *object, uint64_t attr_type, 95637c478bd9Sstevel@tonic-gate ulong_t *attr_value) 95647c478bd9Sstevel@tonic-gate { 95657c478bd9Sstevel@tonic-gate return (dprov_get_object_attr_scalar_common(object, attr_type, 95667c478bd9Sstevel@tonic-gate attr_value, sizeof (ulong_t))); 95677c478bd9Sstevel@tonic-gate } 95687c478bd9Sstevel@tonic-gate 95697c478bd9Sstevel@tonic-gate /* 95707c478bd9Sstevel@tonic-gate * Find the specified byte array attribute of specified type in 95717c478bd9Sstevel@tonic-gate * the specified object. Returns CRYPTO_SUCCESS 95727c478bd9Sstevel@tonic-gate * on success or CRYPTO_ARGUMENTS_BAD if the specified 95737c478bd9Sstevel@tonic-gate * attribute cannot be found. 95747c478bd9Sstevel@tonic-gate */ 95757c478bd9Sstevel@tonic-gate static int 95767c478bd9Sstevel@tonic-gate dprov_get_object_attr_array(dprov_object_t *object, uint64_t attr_type, 95777c478bd9Sstevel@tonic-gate void **array, size_t *len) 95787c478bd9Sstevel@tonic-gate { 95797c478bd9Sstevel@tonic-gate int attr_idx; 95807c478bd9Sstevel@tonic-gate 95817c478bd9Sstevel@tonic-gate if ((attr_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR, 95827c478bd9Sstevel@tonic-gate attr_type)) == -1) 95837c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 95847c478bd9Sstevel@tonic-gate 95857c478bd9Sstevel@tonic-gate *array = object->do_attr[attr_idx].oa_value; 95867c478bd9Sstevel@tonic-gate *len = object->do_attr[attr_idx].oa_value_len; 95877c478bd9Sstevel@tonic-gate 95887c478bd9Sstevel@tonic-gate return (CRYPTO_SUCCESS); 95897c478bd9Sstevel@tonic-gate } 95907c478bd9Sstevel@tonic-gate 95917c478bd9Sstevel@tonic-gate /* 95927c478bd9Sstevel@tonic-gate * Common function used by the dprov_get_template_attr_*() family of 95937c478bd9Sstevel@tonic-gate * functions. Returns the value of the specified attribute of specified 95947c478bd9Sstevel@tonic-gate * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID 95957c478bd9Sstevel@tonic-gate * if the length of the attribute does not match the specified length, 95967c478bd9Sstevel@tonic-gate * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found. 95977c478bd9Sstevel@tonic-gate */ 95987c478bd9Sstevel@tonic-gate static int 95997c478bd9Sstevel@tonic-gate dprov_get_template_attr_scalar_common(crypto_object_attribute_t *template, 96007c478bd9Sstevel@tonic-gate uint_t nattr, uint64_t attr_type, void *value, size_t value_len) 96017c478bd9Sstevel@tonic-gate { 96027c478bd9Sstevel@tonic-gate size_t oa_value_len; 96037c478bd9Sstevel@tonic-gate size_t offset = 0; 96047c478bd9Sstevel@tonic-gate int attr_idx; 96057c478bd9Sstevel@tonic-gate 96067c478bd9Sstevel@tonic-gate if ((attr_idx = dprov_find_attr(template, nattr, attr_type)) == -1) 96077c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 96087c478bd9Sstevel@tonic-gate 96097c478bd9Sstevel@tonic-gate oa_value_len = template[attr_idx].oa_value_len; 96107c478bd9Sstevel@tonic-gate if (oa_value_len != value_len) { 96117c478bd9Sstevel@tonic-gate /* 96127c478bd9Sstevel@tonic-gate * For some attributes, it's okay to copy the value 96137c478bd9Sstevel@tonic-gate * into a larger container, e.g. copy an unsigned 96147c478bd9Sstevel@tonic-gate * 32-bit integer into a 64-bit container. 96157c478bd9Sstevel@tonic-gate */ 96167c478bd9Sstevel@tonic-gate if (attr_type == DPROV_CKA_VALUE_LEN || 96177c478bd9Sstevel@tonic-gate attr_type == DPROV_CKA_KEY_TYPE || 96187c478bd9Sstevel@tonic-gate attr_type == DPROV_CKA_CLASS) { 96197c478bd9Sstevel@tonic-gate if (oa_value_len < value_len) { 96207c478bd9Sstevel@tonic-gate #ifdef _BIG_ENDIAN 96217c478bd9Sstevel@tonic-gate offset = value_len - oa_value_len; 96227c478bd9Sstevel@tonic-gate #endif 96237c478bd9Sstevel@tonic-gate bzero(value, value_len); 96247c478bd9Sstevel@tonic-gate goto do_copy; 96257c478bd9Sstevel@tonic-gate } 96267c478bd9Sstevel@tonic-gate } 96277c478bd9Sstevel@tonic-gate /* incorrect attribute value length */ 96287c478bd9Sstevel@tonic-gate return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 96297c478bd9Sstevel@tonic-gate } 96307c478bd9Sstevel@tonic-gate 96317c478bd9Sstevel@tonic-gate do_copy: 96327c478bd9Sstevel@tonic-gate bcopy(template[attr_idx].oa_value, (uchar_t *)value + offset, 96337c478bd9Sstevel@tonic-gate oa_value_len); 96347c478bd9Sstevel@tonic-gate 96357c478bd9Sstevel@tonic-gate return (CRYPTO_SUCCESS); 96367c478bd9Sstevel@tonic-gate } 96377c478bd9Sstevel@tonic-gate 96387c478bd9Sstevel@tonic-gate /* 96397c478bd9Sstevel@tonic-gate * Get the value of the a boolean attribute from the specified template 96407c478bd9Sstevel@tonic-gate */ 96417c478bd9Sstevel@tonic-gate static int 96427c478bd9Sstevel@tonic-gate dprov_get_template_attr_boolean(crypto_object_attribute_t *template, 96437c478bd9Sstevel@tonic-gate uint_t nattr, uint64_t attr_type, boolean_t *attr_value) 96447c478bd9Sstevel@tonic-gate { 96457c478bd9Sstevel@tonic-gate uchar_t val; 96467c478bd9Sstevel@tonic-gate int ret; 96477c478bd9Sstevel@tonic-gate 96487c478bd9Sstevel@tonic-gate /* PKCS#11 defines a boolean as one byte */ 96497c478bd9Sstevel@tonic-gate ret = dprov_get_template_attr_scalar_common(template, nattr, 96507c478bd9Sstevel@tonic-gate attr_type, &val, 1); 96517c478bd9Sstevel@tonic-gate if (ret == CRYPTO_SUCCESS) { 96527c478bd9Sstevel@tonic-gate *attr_value = (val == '\0') ? B_FALSE : B_TRUE; 96537c478bd9Sstevel@tonic-gate } 96547c478bd9Sstevel@tonic-gate return (ret); 96557c478bd9Sstevel@tonic-gate } 96567c478bd9Sstevel@tonic-gate 96577c478bd9Sstevel@tonic-gate /* 96587c478bd9Sstevel@tonic-gate * Get the value of a ulong_t attribute from the specified template. 96597c478bd9Sstevel@tonic-gate */ 96607c478bd9Sstevel@tonic-gate static int 96617c478bd9Sstevel@tonic-gate dprov_get_template_attr_ulong(crypto_object_attribute_t *template, 96627c478bd9Sstevel@tonic-gate uint_t nattr, uint64_t attr_type, ulong_t *attr_value) 96637c478bd9Sstevel@tonic-gate { 96647c478bd9Sstevel@tonic-gate return (dprov_get_template_attr_scalar_common(template, nattr, 96657c478bd9Sstevel@tonic-gate attr_type, attr_value, sizeof (ulong_t))); 96667c478bd9Sstevel@tonic-gate } 96677c478bd9Sstevel@tonic-gate 96687c478bd9Sstevel@tonic-gate static int 96697c478bd9Sstevel@tonic-gate dprov_template_attr_present(crypto_object_attribute_t *template, 96707c478bd9Sstevel@tonic-gate uint_t nattr, uint64_t attr_type) 96717c478bd9Sstevel@tonic-gate { 96727c478bd9Sstevel@tonic-gate return (dprov_find_attr(template, nattr, 96737c478bd9Sstevel@tonic-gate attr_type) == -1 ? B_FALSE : B_TRUE); 96747c478bd9Sstevel@tonic-gate } 96757c478bd9Sstevel@tonic-gate 96767c478bd9Sstevel@tonic-gate /* 96777c478bd9Sstevel@tonic-gate * Find the specified byte array attribute of specified type in 96787c478bd9Sstevel@tonic-gate * the specified template. Returns CRYPTO_SUCCESS on success or 96797c478bd9Sstevel@tonic-gate * CRYPTO_ARGUMENTS_BAD if the specified attribute cannot be found. 96807c478bd9Sstevel@tonic-gate */ 96817c478bd9Sstevel@tonic-gate static int 96827c478bd9Sstevel@tonic-gate dprov_get_template_attr_array(crypto_object_attribute_t *template, 96837c478bd9Sstevel@tonic-gate uint_t nattr, uint64_t attr_type, void **array, size_t *len) 96847c478bd9Sstevel@tonic-gate { 96857c478bd9Sstevel@tonic-gate int attr_idx; 96867c478bd9Sstevel@tonic-gate 96877c478bd9Sstevel@tonic-gate if ((attr_idx = dprov_find_attr(template, nattr, attr_type)) == -1) 96887c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 96897c478bd9Sstevel@tonic-gate 96907c478bd9Sstevel@tonic-gate *array = template[attr_idx].oa_value; 96917c478bd9Sstevel@tonic-gate *len = template[attr_idx].oa_value_len; 96927c478bd9Sstevel@tonic-gate 96937c478bd9Sstevel@tonic-gate return (CRYPTO_SUCCESS); 96947c478bd9Sstevel@tonic-gate } 96957c478bd9Sstevel@tonic-gate 96967c478bd9Sstevel@tonic-gate /* 96977c478bd9Sstevel@tonic-gate * Common function used by the dprov_get_key_attr_*() family of 96987c478bd9Sstevel@tonic-gate * functions. Returns the value of the specified attribute of specified 96997c478bd9Sstevel@tonic-gate * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID 97007c478bd9Sstevel@tonic-gate * if the length of the attribute does not match the specified length, 97017c478bd9Sstevel@tonic-gate * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found. 97027c478bd9Sstevel@tonic-gate */ 97037c478bd9Sstevel@tonic-gate static int 97047c478bd9Sstevel@tonic-gate dprov_get_key_attr_scalar_common(crypto_key_t *key, uint64_t attr_type, 97057c478bd9Sstevel@tonic-gate void *value, size_t value_len) 97067c478bd9Sstevel@tonic-gate { 97077c478bd9Sstevel@tonic-gate int attr_idx; 97087c478bd9Sstevel@tonic-gate 97097c478bd9Sstevel@tonic-gate ASSERT(key->ck_format == CRYPTO_KEY_ATTR_LIST); 97107c478bd9Sstevel@tonic-gate 97117c478bd9Sstevel@tonic-gate if ((attr_idx = dprov_find_attr(key->ck_attrs, key->ck_count, 97127c478bd9Sstevel@tonic-gate attr_type)) == -1) 97137c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 97147c478bd9Sstevel@tonic-gate 97157c478bd9Sstevel@tonic-gate if (key->ck_attrs[attr_idx].oa_value_len != value_len) 97167c478bd9Sstevel@tonic-gate /* incorrect attribute value length */ 97177c478bd9Sstevel@tonic-gate return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 97187c478bd9Sstevel@tonic-gate 97197c478bd9Sstevel@tonic-gate bcopy(key->ck_attrs[attr_idx].oa_value, value, value_len); 97207c478bd9Sstevel@tonic-gate 97217c478bd9Sstevel@tonic-gate return (CRYPTO_SUCCESS); 97227c478bd9Sstevel@tonic-gate } 97237c478bd9Sstevel@tonic-gate 97247c478bd9Sstevel@tonic-gate /* 97257c478bd9Sstevel@tonic-gate * Get the value of a ulong_t attribute from the specified key. 97267c478bd9Sstevel@tonic-gate */ 97277c478bd9Sstevel@tonic-gate static int 97287c478bd9Sstevel@tonic-gate dprov_get_key_attr_ulong(crypto_key_t *key, uint64_t attr_type, 97297c478bd9Sstevel@tonic-gate ulong_t *attr_value) 97307c478bd9Sstevel@tonic-gate { 97317c478bd9Sstevel@tonic-gate return (dprov_get_key_attr_scalar_common(key, attr_type, 97327c478bd9Sstevel@tonic-gate attr_value, sizeof (ulong_t))); 97337c478bd9Sstevel@tonic-gate } 97347c478bd9Sstevel@tonic-gate 97357c478bd9Sstevel@tonic-gate /* 97367c478bd9Sstevel@tonic-gate * Find the specified byte array attribute of specified type in 97377c478bd9Sstevel@tonic-gate * the specified key by attributes. Returns CRYPTO_SUCCESS 97387c478bd9Sstevel@tonic-gate * on success or CRYPTO_ARGUMENTS_BAD if the specified 97397c478bd9Sstevel@tonic-gate * attribute cannot be found. 97407c478bd9Sstevel@tonic-gate */ 97417c478bd9Sstevel@tonic-gate static int 97427c478bd9Sstevel@tonic-gate dprov_get_key_attr_array(crypto_key_t *key, uint64_t attr_type, 97437c478bd9Sstevel@tonic-gate void **array, size_t *len) 97447c478bd9Sstevel@tonic-gate { 97457c478bd9Sstevel@tonic-gate int attr_idx; 97467c478bd9Sstevel@tonic-gate 97477c478bd9Sstevel@tonic-gate ASSERT(key->ck_format == CRYPTO_KEY_ATTR_LIST); 97487c478bd9Sstevel@tonic-gate 97497c478bd9Sstevel@tonic-gate if ((attr_idx = dprov_find_attr(key->ck_attrs, key->ck_count, 97507c478bd9Sstevel@tonic-gate attr_type)) == -1) 97517c478bd9Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 97527c478bd9Sstevel@tonic-gate 97537c478bd9Sstevel@tonic-gate *array = key->ck_attrs[attr_idx].oa_value; 97547c478bd9Sstevel@tonic-gate *len = key->ck_attrs[attr_idx].oa_value_len; 97557c478bd9Sstevel@tonic-gate 97567c478bd9Sstevel@tonic-gate return (CRYPTO_SUCCESS); 97577c478bd9Sstevel@tonic-gate } 97587c478bd9Sstevel@tonic-gate 97597c478bd9Sstevel@tonic-gate static void 97607c478bd9Sstevel@tonic-gate dprov_release_session_objects(dprov_session_t *session) 97617c478bd9Sstevel@tonic-gate { 97627c478bd9Sstevel@tonic-gate dprov_object_t *object; 97637c478bd9Sstevel@tonic-gate int i; 97647c478bd9Sstevel@tonic-gate 97657c478bd9Sstevel@tonic-gate for (i = 0; i < DPROV_MAX_OBJECTS; i++) { 97667c478bd9Sstevel@tonic-gate object = session->ds_objects[i]; 97677c478bd9Sstevel@tonic-gate if (object != NULL) { 97687c478bd9Sstevel@tonic-gate DPROV_OBJECT_REFRELE(object); 97697c478bd9Sstevel@tonic-gate } 97707c478bd9Sstevel@tonic-gate } 97717c478bd9Sstevel@tonic-gate } 9772f9fbec18Smcpowers 9773f9fbec18Smcpowers /* 9774f9fbec18Smcpowers * Adjust an attribute list by turning 32-bit values into 64-bit values 9775f9fbec18Smcpowers * for certain attributes like CKA_CLASS. Assumes that at least 8 bytes 9776f9fbec18Smcpowers * of storage have been allocated for all attributes. 9777f9fbec18Smcpowers */ 9778f9fbec18Smcpowers static void 9779f9fbec18Smcpowers dprov_adjust_attrs(crypto_object_attribute_t *in, int in_count) 9780f9fbec18Smcpowers { 9781f9fbec18Smcpowers int i; 9782f9fbec18Smcpowers size_t offset = 0; 9783f9fbec18Smcpowers ulong_t tmp = 0; 9784f9fbec18Smcpowers 9785f9fbec18Smcpowers for (i = 0; i < in_count; i++) { 9786f9fbec18Smcpowers /* 9787f9fbec18Smcpowers * For some attributes, it's okay to copy the value 9788f9fbec18Smcpowers * into a larger container, e.g. copy an unsigned 9789f9fbec18Smcpowers * 32-bit integer into a 64-bit container. 9790f9fbec18Smcpowers */ 9791f9fbec18Smcpowers if (in[i].oa_type == CKA_VALUE_LEN || 9792f9fbec18Smcpowers in[i].oa_type == CKA_KEY_TYPE || 9793f9fbec18Smcpowers in[i].oa_type == CKA_CLASS) { 9794f9fbec18Smcpowers if (in[i].oa_value_len < sizeof (ulong_t)) { 9795f9fbec18Smcpowers #ifdef _BIG_ENDIAN 9796f9fbec18Smcpowers offset = sizeof (ulong_t) - in[i].oa_value_len; 9797f9fbec18Smcpowers #endif 9798f9fbec18Smcpowers bcopy(in[i].oa_value, (uchar_t *)&tmp + offset, 9799f9fbec18Smcpowers in[i].oa_value_len); 9800f9fbec18Smcpowers bcopy(&tmp, in[i].oa_value, sizeof (ulong_t)); 9801f9fbec18Smcpowers in[i].oa_value_len = sizeof (ulong_t); 9802f9fbec18Smcpowers } 9803f9fbec18Smcpowers } 9804f9fbec18Smcpowers } 9805f9fbec18Smcpowers } 9806