1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 23 * Copyright 2015 Nexenta Systems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 28 /* 29 * Dummy Cryptographic Provider: 30 * 31 * This file implements a "dummy" cryptographic provider. It is implemented 32 * as a pseudo device driver. 33 * 34 */ 35 36 /* 37 * This driver implements a KEF provider with the following capabilities: 38 * 39 * - registration/unregistration with KEF 40 * - digest entry points 41 * - mac entry points 42 * - ctx management 43 * - support for async requests 44 * - cipher entry points 45 * - dual entry points 46 * - sign entry points 47 * - verify entry points 48 * - dual operations entry points 49 * - dual cipher/mac operation entry points 50 * - session management 51 * - object management 52 * - key management 53 * - provider management 54 * 55 * In order to avoid duplicating the implementation of algorithms 56 * provided by software providers, this pseudo driver acts as 57 * a consumer of the framework. When invoking one of the framework's 58 * entry points, the driver specifies the software provider to 59 * be used for the operation. 60 * 61 * User management: we implement a PKCS#11 style provider which supports: 62 * - one normal user with a PIN, and 63 * - one SO user with a PIN. 64 * These values are kept in the per-instance structure, and are initialized 65 * with the provider management entry points. 66 * 67 */ 68 69 70 #include <sys/types.h> 71 #include <sys/modctl.h> 72 #include <sys/conf.h> 73 #include <sys/stat.h> 74 #include <sys/ddi.h> 75 #include <sys/sunddi.h> 76 #include <sys/kmem.h> 77 #include <sys/errno.h> 78 #include <sys/ksynch.h> 79 #include <sys/file.h> 80 #include <sys/open.h> 81 #include <sys/cred.h> 82 #include <sys/model.h> 83 #include <sys/note.h> 84 #include <sys/random.h> 85 #include <sys/byteorder.h> 86 #include <sys/crypto/common.h> 87 #include <sys/crypto/spi.h> 88 89 #include <sys/taskq.h> 90 #include <sys/disp.h> 91 #include <sys/sysmacros.h> 92 #include <sys/crypto/impl.h> 93 #include <sys/crypto/sched_impl.h> 94 95 #include <sys/sha2.h> 96 #include <modes/modes.h> 97 #include <aes/aes_impl.h> 98 #include <des/des_impl.h> 99 #include <ecc/ecc_impl.h> 100 #include <blowfish/blowfish_impl.h> 101 102 /* 103 * Debugging macros. 104 */ 105 #ifdef DEBUG 106 #define D_INIT 0x00000001 /* _init/_fini/_info */ 107 #define D_ATTACH 0x00000002 /* attach/detach */ 108 #define D_DIGEST 0x00000010 /* digest entry points */ 109 #define D_MAC 0x00000020 /* mac entry points */ 110 #define D_CONTEXT 0x00000040 /* context entry points */ 111 #define D_CIPHER 0x00000080 /* cipher entry points */ 112 #define D_SIGN 0x00000100 /* sign entry points */ 113 #define D_VERIFY 0x00000200 /* verify entry points */ 114 #define D_SESSION 0x00000400 /* session management entry points */ 115 #define D_MGMT 0x00000800 /* provider management entry points */ 116 #define D_DUAL 0x00001000 /* dual ops */ 117 #define D_CIPHER_MAC 0x00002000 /* cipher/mac dual ops */ 118 #define D_OBJECT 0x00004000 /* object management */ 119 #define D_RANDOM 0x00008000 /* random number generation */ 120 #define D_KEY 0x00010000 /* key management */ 121 122 static uint32_t dprov_debug = 0; 123 124 #define DPROV_DEBUG(f, x) if (dprov_debug & (f)) { (void) printf x; } 125 #define DPROV_CALL(f, r, x) if (dprov_debug & (f)) { (void) r x; } 126 #else /* DEBUG */ 127 #define DPROV_DEBUG(f, x) 128 #define DPROV_CALL(f, r, x) 129 #endif /* DEBUG */ 130 131 static int nostore_key_gen; 132 static boolean_t dprov_no_multipart = B_FALSE; 133 static int dprov_max_digestsz = INT_MAX; 134 135 /* 136 * DDI entry points. 137 */ 138 static int dprov_attach(dev_info_t *, ddi_attach_cmd_t); 139 static int dprov_detach(dev_info_t *, ddi_detach_cmd_t); 140 static int dprov_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 141 142 /* 143 * Module linkage. 144 */ 145 static struct cb_ops cbops = { 146 nodev, /* cb_open */ 147 nodev, /* cb_close */ 148 nodev, /* cb_strategy */ 149 nodev, /* cb_print */ 150 nodev, /* cb_dump */ 151 nodev, /* cb_read */ 152 nodev, /* cb_write */ 153 nodev, /* cb_ioctl */ 154 nodev, /* cb_devmap */ 155 nodev, /* cb_mmap */ 156 nodev, /* cb_segmap */ 157 nochpoll, /* cb_chpoll */ 158 ddi_prop_op, /* cb_prop_op */ 159 NULL, /* cb_streamtab */ 160 D_MP, /* cb_flag */ 161 CB_REV, /* cb_rev */ 162 nodev, /* cb_aread */ 163 nodev, /* cb_awrite */ 164 }; 165 166 static struct dev_ops devops = { 167 DEVO_REV, /* devo_rev */ 168 0, /* devo_refcnt */ 169 dprov_getinfo, /* devo_getinfo */ 170 nulldev, /* devo_identify */ 171 nulldev, /* devo_probe */ 172 dprov_attach, /* devo_attach */ 173 dprov_detach, /* devo_detach */ 174 nodev, /* devo_reset */ 175 &cbops, /* devo_cb_ops */ 176 NULL, /* devo_bus_ops */ 177 NULL, /* devo_power */ 178 ddi_quiesce_not_needed, /* devo_quiesce */ 179 }; 180 181 static struct modldrv modldrv = { 182 &mod_driverops, 183 "Pseudo KCF Prov (drv)", 184 &devops 185 }; 186 187 static struct modlcrypto modlcrypto = { 188 &mod_cryptoops, 189 "Pseudo KCF Prov (crypto)" 190 }; 191 192 static struct modlinkage modlinkage = { 193 MODREV_1, 194 &modldrv, 195 &modlcrypto, 196 NULL 197 }; 198 199 /* 200 * CSPI information (entry points, provider info, etc.) 201 */ 202 203 typedef enum dprov_mech_type { 204 MD4_MECH_INFO_TYPE, /* SUN_CKM_MD4 */ 205 206 MD5_MECH_INFO_TYPE, /* SUN_CKM_MD5 */ 207 MD5_HMAC_MECH_INFO_TYPE, /* SUN_CKM_MD5_HMAC */ 208 MD5_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_MD5_HMAC_GENERAL */ 209 210 SHA1_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA1_HMAC */ 211 SHA1_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA1_HMAC_GENERAL */ 212 SHA1_MECH_INFO_TYPE, /* SUN_CKM_SHA1 */ 213 214 SHA256_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA256_HMAC */ 215 SHA256_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA256_HMAC_GENERAL */ 216 SHA256_MECH_INFO_TYPE, /* SUN_CKM_SHA256 */ 217 SHA384_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA384_HMAC */ 218 SHA384_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA384_HMAC_GENERAL */ 219 SHA384_MECH_INFO_TYPE, /* SUN_CKM_SHA384 */ 220 SHA512_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA512_HMAC */ 221 SHA512_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA512_HMAC_GENERAL */ 222 SHA512_MECH_INFO_TYPE, /* SUN_CKM_SHA512 */ 223 224 DES_CBC_MECH_INFO_TYPE, /* SUN_CKM_DES_CBC */ 225 DES3_CBC_MECH_INFO_TYPE, /* SUN_CKM_DES3_CBC */ 226 DES_ECB_MECH_INFO_TYPE, /* SUN_CKM_DES_ECB */ 227 DES3_ECB_MECH_INFO_TYPE, /* SUN_CKM_DES3_ECB */ 228 229 BLOWFISH_CBC_MECH_INFO_TYPE, /* SUN_CKM_BLOWFISH_CBC */ 230 BLOWFISH_ECB_MECH_INFO_TYPE, /* SUN_CKM_BLOWFISH_ECB */ 231 AES_CBC_MECH_INFO_TYPE, /* SUN_CKM_AES_CBC */ 232 AES_CMAC_MECH_INFO_TYPE, /* SUN_CKM_AES_CMAC */ 233 AES_ECB_MECH_INFO_TYPE, /* SUN_CKM_AES_ECB */ 234 AES_CTR_MECH_INFO_TYPE, /* SUN_CKM_AES_CTR */ 235 AES_CCM_MECH_INFO_TYPE, /* SUN_CKM_AES_CCM */ 236 AES_GCM_MECH_INFO_TYPE, /* SUN_CKM_AES_GCM */ 237 AES_GMAC_MECH_INFO_TYPE, /* SUN_CKM_AES_GMAC */ 238 RC4_MECH_INFO_TYPE, /* SUN_CKM_RC4 */ 239 RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_RSA_PKCS */ 240 RSA_X_509_MECH_INFO_TYPE, /* SUN_CKM_RSA_X_509 */ 241 MD5_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_MD5_RSA_PKCS */ 242 SHA1_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_SHA1_RSA_PKCS */ 243 SHA256_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_SHA256_RSA_PKCS */ 244 SHA384_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_SHA384_RSA_PKCS */ 245 SHA512_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_SHA512_RSA_PKCS */ 246 MD5_KEY_DERIVATION_MECH_INFO_TYPE, /* SUN_CKM_MD5_KEY_DERIVATION */ 247 SHA1_KEY_DERIVATION_MECH_INFO_TYPE, /* SUN_CKM_SHA1_KEY_DERIVATION */ 248 /* SUN_CKM_SHA256_KEY_DERIVATION */ 249 SHA256_KEY_DERIVATION_MECH_INFO_TYPE, 250 /* SUN_CKM_SHA384_KEY_DERIVATION */ 251 SHA384_KEY_DERIVATION_MECH_INFO_TYPE, 252 /* SUN_CKM_SHA512_KEY_DERIVATION */ 253 SHA512_KEY_DERIVATION_MECH_INFO_TYPE, 254 DES_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_DES_KEY_GEN */ 255 DES3_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_DES3_KEY_GEN */ 256 AES_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_AES_KEY_GEN */ 257 BLOWFISH_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_BLOWFISH_KEY_GEN */ 258 RC4_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_RC4_KEY_GEN */ 259 EC_KEY_PAIR_GEN_MECH_INFO_TYPE, /* SUN_CKM_EC_KEY_PAIR_GEN */ 260 ECDSA_MECH_INFO_TYPE, /* SUN_CKM_ECDSA */ 261 ECDSA_SHA1_MECH_INFO_TYPE, /* SUN_CKM_ECDSA_SHA1 */ 262 ECDH1_DERIVE_MECH_INFO_TYPE, /* SUN_CKM_ECDH1_DERIVE */ 263 DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE, /* SUN_CKM_DH_PKCS_KEY_PAIR_GEN */ 264 DH_PKCS_DERIVE_MECH_INFO_TYPE, /* SUN_CKM_DH_PKCS_DERIVE */ 265 RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE /* SUN_CKM_RSA_PKCS_KEY_PAIR_GEN */ 266 } dprov_mech_type_t; 267 268 /* 269 * Mechanism info structure passed to KCF during registration. 270 */ 271 #define MD5_DIGEST_LEN 16 /* MD5 digest size */ 272 #define MD5_HMAC_BLOCK_SIZE 64 /* MD5-HMAC block size */ 273 #define MD5_HMAC_MIN_KEY_LEN 1 /* MD5-HMAC min key length in bytes */ 274 #define MD5_HMAC_MAX_KEY_LEN INT_MAX /* MD5-HMAC max key length in bytes */ 275 276 #define SHA1_DIGEST_LEN 20 /* SHA1 digest size */ 277 #define SHA1_HMAC_BLOCK_SIZE 64 /* SHA1-HMAC block size */ 278 #define SHA1_HMAC_MIN_KEY_LEN 1 /* SHA1-HMAC min key length in bytes */ 279 #define SHA1_HMAC_MAX_KEY_LEN INT_MAX /* SHA1-HMAC max key length in bytes */ 280 281 #define DES_KEY_LEN 8 /* DES key length in bytes */ 282 #define DES3_KEY_LEN 24 /* DES3 key length in bytes */ 283 284 #define BLOWFISH_MIN_KEY_LEN 32 /* Blowfish min key length in bits */ 285 #define BLOWFISH_MAX_KEY_LEN 448 /* Blowfish max key length in bits */ 286 287 #define AES_MIN_KEY_LEN 16 /* AES min key length in bytes */ 288 #define AES_MAX_KEY_LEN 32 /* AES max key length in bytes */ 289 290 #define ARCFOUR_MIN_KEY_BITS 40 /* RC4 min supported key size */ 291 #define ARCFOUR_MAX_KEY_BITS 2048 /* RC4 max supported key size */ 292 293 #define RSA_MIN_KEY_LEN 256 /* RSA min key length in bits */ 294 #define RSA_MAX_KEY_LEN 4096 /* RSA max key length in bits */ 295 296 #define DH_MIN_KEY_LEN 64 /* DH min key length in bits */ 297 #define DH_MAX_KEY_LEN 4096 /* DH max key length in bits */ 298 299 #define DPROV_CKM_MD5_KEY_DERIVATION "CKM_MD5_KEY_DERIVATION" 300 #define DPROV_CKM_SHA1_KEY_DERIVATION "CKM_SHA1_KEY_DERIVATION" 301 #define DPROV_CKM_SHA256_KEY_DERIVATION "CKM_SHA256_KEY_DERIVATION" 302 #define DPROV_CKM_SHA384_KEY_DERIVATION "CKM_SHA384_KEY_DERIVATION" 303 #define DPROV_CKM_SHA512_KEY_DERIVATION "CKM_SHA512_KEY_DERIVATION" 304 #define DPROV_CKM_DES_KEY_GEN "CKM_DES_KEY_GEN" 305 #define DPROV_CKM_DES3_KEY_GEN "CKM_DES3_KEY_GEN" 306 #define DPROV_CKM_AES_KEY_GEN "CKM_AES_KEY_GEN" 307 #define DPROV_CKM_BLOWFISH_KEY_GEN "CKM_BLOWFISH_KEY_GEN" 308 #define DPROV_CKM_RC4_KEY_GEN "CKM_RC4_KEY_GEN" 309 #define DPROV_CKM_RSA_PKCS_KEY_PAIR_GEN "CKM_RSA_PKCS_KEY_PAIR_GEN" 310 #define DPROV_CKM_EC_KEY_PAIR_GEN "CKM_EC_KEY_PAIR_GEN" 311 #define DPROV_CKM_ECDSA "CKM_ECDSA" 312 #define DPROV_CKM_ECDSA_SHA1 "CKM_ECDSA_SHA1" 313 #define DPROV_CKM_ECDH1_DERIVE "CKM_ECDH1_DERIVE" 314 #define DPROV_CKM_DH_PKCS_KEY_PAIR_GEN "CKM_DH_PKCS_KEY_PAIR_GEN" 315 #define DPROV_CKM_DH_PKCS_DERIVE "CKM_DH_PKCS_DERIVE" 316 317 static crypto_mech_info_t dprov_mech_info_tab[] = { 318 /* MD4 */ 319 {SUN_CKM_MD4, MD4_MECH_INFO_TYPE, 320 CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0, 321 CRYPTO_KEYSIZE_UNIT_IN_BITS}, 322 /* MD5 */ 323 {SUN_CKM_MD5, MD5_MECH_INFO_TYPE, 324 CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0, 325 CRYPTO_KEYSIZE_UNIT_IN_BITS}, 326 /* MD5-HMAC */ 327 {SUN_CKM_MD5_HMAC, MD5_HMAC_MECH_INFO_TYPE, 328 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | 329 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 330 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 331 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT | 332 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, 333 MD5_HMAC_MIN_KEY_LEN, MD5_HMAC_MAX_KEY_LEN, 334 CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 335 /* MD5-HMAC GENERAL */ 336 {SUN_CKM_MD5_HMAC_GENERAL, MD5_HMAC_GEN_MECH_INFO_TYPE, 337 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | 338 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 339 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 340 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT | 341 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, 342 MD5_HMAC_MIN_KEY_LEN, MD5_HMAC_MAX_KEY_LEN, 343 CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 344 /* SHA1 */ 345 {SUN_CKM_SHA1, SHA1_MECH_INFO_TYPE, 346 CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0, 347 CRYPTO_KEYSIZE_UNIT_IN_BITS}, 348 /* SHA1-HMAC */ 349 {SUN_CKM_SHA1_HMAC, SHA1_HMAC_MECH_INFO_TYPE, 350 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | 351 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 352 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 353 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT | 354 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, 355 SHA1_HMAC_MIN_KEY_LEN, SHA1_HMAC_MAX_KEY_LEN, 356 CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 357 /* SHA1-HMAC GENERAL */ 358 {SUN_CKM_SHA1_HMAC_GENERAL, SHA1_HMAC_GEN_MECH_INFO_TYPE, 359 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | 360 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 361 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 362 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT | 363 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, 364 SHA1_HMAC_MIN_KEY_LEN, SHA1_HMAC_MAX_KEY_LEN, 365 CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 366 /* SHA256 */ 367 {SUN_CKM_SHA256, SHA256_MECH_INFO_TYPE, 368 CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0, 369 CRYPTO_KEYSIZE_UNIT_IN_BITS}, 370 /* SHA256-HMAC */ 371 {SUN_CKM_SHA256_HMAC, SHA256_HMAC_MECH_INFO_TYPE, 372 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | 373 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 374 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 375 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT | 376 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, 377 SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN, 378 CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 379 /* SHA256-HMAC GENERAL */ 380 {SUN_CKM_SHA256_HMAC_GENERAL, SHA256_HMAC_GEN_MECH_INFO_TYPE, 381 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | 382 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 383 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 384 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT | 385 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, 386 SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN, 387 CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 388 /* SHA384 */ 389 {SUN_CKM_SHA384, SHA384_MECH_INFO_TYPE, 390 CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0, 391 CRYPTO_KEYSIZE_UNIT_IN_BITS}, 392 /* SHA384-HMAC */ 393 {SUN_CKM_SHA384_HMAC, SHA384_HMAC_MECH_INFO_TYPE, 394 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | 395 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 396 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 397 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT | 398 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, 399 SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN, 400 CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 401 /* SHA384-HMAC GENERAL */ 402 {SUN_CKM_SHA384_HMAC_GENERAL, SHA384_HMAC_GEN_MECH_INFO_TYPE, 403 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | 404 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 405 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 406 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT | 407 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, 408 SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN, 409 CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 410 /* SHA512 */ 411 {SUN_CKM_SHA512, SHA512_MECH_INFO_TYPE, 412 CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0, 413 CRYPTO_KEYSIZE_UNIT_IN_BITS}, 414 /* SHA512-HMAC */ 415 {SUN_CKM_SHA512_HMAC, SHA512_HMAC_MECH_INFO_TYPE, 416 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | 417 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 418 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 419 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT | 420 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, 421 SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN, 422 CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 423 /* SHA512-HMAC GENERAL */ 424 {SUN_CKM_SHA512_HMAC_GENERAL, SHA512_HMAC_GEN_MECH_INFO_TYPE, 425 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | 426 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 427 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 428 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT | 429 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC, 430 SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN, 431 CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 432 /* DES-CBC */ 433 {SUN_CKM_DES_CBC, DES_CBC_MECH_INFO_TYPE, 434 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 435 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 436 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 437 CRYPTO_FG_MAC_DECRYPT_ATOMIC, 438 DES_KEY_LEN, DES_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 439 /* DES3-CBC */ 440 {SUN_CKM_DES3_CBC, DES3_CBC_MECH_INFO_TYPE, 441 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 442 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 443 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 444 CRYPTO_FG_MAC_DECRYPT_ATOMIC, 445 DES3_KEY_LEN, DES3_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 446 /* DES-ECB */ 447 {SUN_CKM_DES_ECB, DES_ECB_MECH_INFO_TYPE, 448 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 449 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 450 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 451 CRYPTO_FG_MAC_DECRYPT_ATOMIC, 452 DES_KEY_LEN, DES_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 453 /* DES3-ECB */ 454 {SUN_CKM_DES3_ECB, DES3_ECB_MECH_INFO_TYPE, 455 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 456 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 457 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 458 CRYPTO_FG_MAC_DECRYPT_ATOMIC, 459 DES3_KEY_LEN, DES3_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 460 /* BLOWFISH-CBC */ 461 {SUN_CKM_BLOWFISH_CBC, BLOWFISH_CBC_MECH_INFO_TYPE, 462 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 463 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 464 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 465 CRYPTO_FG_MAC_DECRYPT_ATOMIC, BLOWFISH_MIN_KEY_LEN, 466 BLOWFISH_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 467 /* BLOWFISH-ECB */ 468 {SUN_CKM_BLOWFISH_ECB, BLOWFISH_ECB_MECH_INFO_TYPE, 469 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 470 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 471 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 472 CRYPTO_FG_MAC_DECRYPT_ATOMIC, BLOWFISH_MIN_KEY_LEN, 473 BLOWFISH_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 474 /* AES-CBC */ 475 {SUN_CKM_AES_CBC, AES_CBC_MECH_INFO_TYPE, 476 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 477 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 478 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 479 CRYPTO_FG_MAC_DECRYPT_ATOMIC, 480 AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 481 /* AES-CMAC */ 482 {SUN_CKM_AES_CMAC, AES_CMAC_MECH_INFO_TYPE, 483 CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_MAC | 484 CRYPTO_FG_ENCRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 485 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | 486 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 487 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 488 AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 489 /* AES-ECB */ 490 {SUN_CKM_AES_ECB, AES_ECB_MECH_INFO_TYPE, 491 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 492 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 493 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 494 CRYPTO_FG_MAC_DECRYPT_ATOMIC, 495 AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 496 /* AES-CTR */ 497 {SUN_CKM_AES_CTR, AES_CTR_MECH_INFO_TYPE, 498 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 499 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 500 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 501 CRYPTO_FG_MAC_DECRYPT_ATOMIC, 502 AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 503 /* AES-CCM */ 504 {SUN_CKM_AES_CCM, AES_CCM_MECH_INFO_TYPE, 505 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 506 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 507 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 508 CRYPTO_FG_MAC_DECRYPT_ATOMIC, 509 AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 510 /* AES-GCM */ 511 {SUN_CKM_AES_GCM, AES_GCM_MECH_INFO_TYPE, 512 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 513 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 514 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 515 CRYPTO_FG_MAC_DECRYPT_ATOMIC, 516 AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 517 /* AES-GMAC */ 518 {SUN_CKM_AES_GMAC, AES_GMAC_MECH_INFO_TYPE, 519 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC | 520 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 521 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC | 522 CRYPTO_FG_MAC_DECRYPT_ATOMIC | 523 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 524 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 525 AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 526 /* RC4 */ 527 {SUN_CKM_RC4, RC4_MECH_INFO_TYPE, 528 CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 529 CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC, 530 ARCFOUR_MIN_KEY_BITS, ARCFOUR_MAX_KEY_BITS, 531 CRYPTO_KEYSIZE_UNIT_IN_BITS | CRYPTO_CAN_SHARE_OPSTATE}, 532 /* RSA_PKCS */ 533 {SUN_CKM_RSA_PKCS, RSA_PKCS_MECH_INFO_TYPE, 534 CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 535 CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC | 536 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 537 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 538 CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC | 539 CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC, 540 RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 541 /* RSA_X_509 */ 542 {SUN_CKM_RSA_X_509, RSA_X_509_MECH_INFO_TYPE, 543 CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 544 CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC | 545 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 546 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 547 CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC | 548 CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC, 549 RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 550 /* MD5_RSA_PKCS */ 551 {SUN_CKM_MD5_RSA_PKCS, MD5_RSA_PKCS_MECH_INFO_TYPE, 552 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 553 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 554 RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 555 /* SHA1_RSA_PKCS */ 556 {SUN_CKM_SHA1_RSA_PKCS, SHA1_RSA_PKCS_MECH_INFO_TYPE, 557 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 558 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 559 RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 560 /* SHA256_RSA_PKCS */ 561 {SUN_CKM_SHA256_RSA_PKCS, SHA256_RSA_PKCS_MECH_INFO_TYPE, 562 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 563 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 564 RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 565 /* SHA384_RSA_PKCS */ 566 {SUN_CKM_SHA384_RSA_PKCS, SHA384_RSA_PKCS_MECH_INFO_TYPE, 567 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 568 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 569 RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 570 /* SHA512_RSA_PKCS */ 571 {SUN_CKM_SHA512_RSA_PKCS, SHA512_RSA_PKCS_MECH_INFO_TYPE, 572 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 573 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 574 RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 575 /* MD5_KEY_DERIVATION */ 576 {DPROV_CKM_MD5_KEY_DERIVATION, MD5_KEY_DERIVATION_MECH_INFO_TYPE, 577 CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 578 /* SHA1_KEY_DERIVATION */ 579 {DPROV_CKM_SHA1_KEY_DERIVATION, SHA1_KEY_DERIVATION_MECH_INFO_TYPE, 580 CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 581 /* SHA256_KEY_DERIVATION */ 582 {DPROV_CKM_SHA256_KEY_DERIVATION, SHA256_KEY_DERIVATION_MECH_INFO_TYPE, 583 CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 584 /* SHA384_KEY_DERIVATION */ 585 {DPROV_CKM_SHA384_KEY_DERIVATION, SHA384_KEY_DERIVATION_MECH_INFO_TYPE, 586 CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 587 /* SHA512_KEY_DERIVATION */ 588 {DPROV_CKM_SHA512_KEY_DERIVATION, SHA512_KEY_DERIVATION_MECH_INFO_TYPE, 589 CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 590 /* DES_KEY_GENERATION */ 591 {DPROV_CKM_DES_KEY_GEN, DES_KEY_GEN_MECH_INFO_TYPE, 592 CRYPTO_FG_GENERATE, DES_KEY_LEN, DES_KEY_LEN, 593 CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 594 /* DES3_KEY_GENERATION */ 595 {DPROV_CKM_DES3_KEY_GEN, DES3_KEY_GEN_MECH_INFO_TYPE, 596 CRYPTO_FG_GENERATE, DES3_KEY_LEN, DES3_KEY_LEN, 597 CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 598 /* AES_KEY_GENERATION */ 599 {DPROV_CKM_AES_KEY_GEN, AES_KEY_GEN_MECH_INFO_TYPE, 600 CRYPTO_FG_GENERATE, AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, 601 CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 602 /* BLOWFISH_KEY_GENERATION */ 603 {DPROV_CKM_BLOWFISH_KEY_GEN, BLOWFISH_KEY_GEN_MECH_INFO_TYPE, 604 CRYPTO_FG_GENERATE, BLOWFISH_MIN_KEY_LEN, BLOWFISH_MAX_KEY_LEN, 605 CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 606 /* RC4_KEY_GENERATION */ 607 {DPROV_CKM_RC4_KEY_GEN, RC4_KEY_GEN_MECH_INFO_TYPE, 608 CRYPTO_FG_GENERATE, ARCFOUR_MIN_KEY_BITS, ARCFOUR_MAX_KEY_BITS, 609 CRYPTO_KEYSIZE_UNIT_IN_BITS}, 610 /* DH_PKCS_KEY_PAIR_GEN */ 611 {DPROV_CKM_DH_PKCS_KEY_PAIR_GEN, DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE, 612 CRYPTO_FG_GENERATE_KEY_PAIR, DH_MIN_KEY_LEN, DH_MAX_KEY_LEN, 613 CRYPTO_KEYSIZE_UNIT_IN_BITS}, 614 /* DH_PKCS_DERIVE */ 615 {DPROV_CKM_DH_PKCS_DERIVE, DH_PKCS_DERIVE_MECH_INFO_TYPE, 616 CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 617 /* RSA_PKCS_KEY_PAIR_GEN */ 618 {DPROV_CKM_RSA_PKCS_KEY_PAIR_GEN, RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE, 619 CRYPTO_FG_GENERATE_KEY_PAIR, RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, 620 CRYPTO_KEYSIZE_UNIT_IN_BITS}, 621 /* EC_KEY_PAIR_GEN */ 622 {DPROV_CKM_EC_KEY_PAIR_GEN, EC_KEY_PAIR_GEN_MECH_INFO_TYPE, 623 CRYPTO_FG_GENERATE_KEY_PAIR, EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, 624 CRYPTO_KEYSIZE_UNIT_IN_BITS}, 625 /* ECDSA */ 626 {DPROV_CKM_ECDSA, ECDSA_MECH_INFO_TYPE, 627 CRYPTO_FG_SIGN | CRYPTO_FG_VERIFY | 628 CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC | 629 EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 630 /* ECDSA_SHA1 */ 631 {DPROV_CKM_ECDSA_SHA1, ECDSA_SHA1_MECH_INFO_TYPE, 632 CRYPTO_FG_SIGN | CRYPTO_FG_VERIFY | 633 CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC | 634 EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 635 /* ECDH1_DERIVE */ 636 {DPROV_CKM_ECDH1_DERIVE, ECDH1_DERIVE_MECH_INFO_TYPE, 637 CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS} 638 }; 639 640 /* 641 * Crypto Values 642 * 643 * These values are the used in the STC ef test suite. If they are changed 644 * the test suite needs to be changed. 645 */ 646 static uchar_t dh_value[8] = { 'd', 'h', 'd', 'h', 'd', 'h', 'd', '\0' }; 647 char public_exponent[3] = { 0x01, 0x00, 0x01 }; 648 static uchar_t private_exponent[128] = { 649 0x8e, 0xc9, 0x70, 0x57, 0x6b, 0xcd, 0xfb, 0xa9, 650 0x19, 0xad, 0xcd, 0x91, 0x69, 0xd5, 0x52, 0xec, 651 0x72, 0x1e, 0x45, 0x15, 0x06, 0xdc, 0x65, 0x2d, 652 0x98, 0xc4, 0xce, 0x33, 0x54, 0x15, 0x70, 0x8d, 653 0xfa, 0x65, 0xea, 0x53, 0x44, 0xf3, 0x3e, 0x3f, 654 0xb4, 0x4c, 0x60, 0xd5, 0x01, 0x2d, 0xa4, 0x12, 655 0x99, 0xbf, 0x3f, 0x0b, 0xcd, 0xbb, 0x24, 0x10, 656 0x60, 0x30, 0x5e, 0x58, 0xf8, 0x59, 0xaa, 0xd1, 657 0x63, 0x3b, 0xbc, 0xcb, 0x94, 0x58, 0x38, 0x24, 658 0xfc, 0x65, 0x25, 0xc5, 0xa6, 0x51, 0xa2, 0x2e, 659 0xf1, 0x5e, 0xf5, 0xc1, 0xf5, 0x46, 0xf7, 0xbd, 660 0xc7, 0x62, 0xa8, 0xe2, 0x27, 0xd6, 0x94, 0x5b, 661 0xd3, 0xa2, 0xb5, 0x76, 0x42, 0x67, 0x6b, 0x86, 662 0x91, 0x97, 0x4d, 0x07, 0x92, 0x00, 0x4a, 0xdf, 663 0x0b, 0x65, 0x64, 0x05, 0x03, 0x48, 0x27, 0xeb, 664 0xce, 0x9a, 0x49, 0x7f, 0x3e, 0x10, 0xe0, 0x01 665 }; 666 667 static uchar_t modulus[128] = { 668 0x94, 0x32, 0xb9, 0x12, 0x1d, 0x68, 0x2c, 0xda, 669 0x2b, 0xe0, 0xe4, 0x97, 0x1b, 0x4d, 0xdc, 0x43, 670 0xdf, 0x38, 0x6e, 0x7b, 0x9f, 0x07, 0x58, 0xae, 671 0x9d, 0x82, 0x1e, 0xc7, 0xbc, 0x92, 0xbf, 0xd3, 672 0xce, 0x00, 0xbb, 0x91, 0xc9, 0x79, 0x06, 0x03, 673 0x1f, 0xbc, 0x9f, 0x94, 0x75, 0x29, 0x5f, 0xd7, 674 0xc5, 0xf3, 0x73, 0x8a, 0xa4, 0x35, 0x43, 0x7a, 675 0x00, 0x32, 0x97, 0x3e, 0x86, 0xef, 0x70, 0x6f, 676 0x18, 0x56, 0x15, 0xaa, 0x6a, 0x87, 0xe7, 0x8d, 677 0x7d, 0xdd, 0x1f, 0xa4, 0xe4, 0x31, 0xd4, 0x7a, 678 0x8c, 0x0e, 0x20, 0xd2, 0x23, 0xf5, 0x57, 0x3c, 679 0x1b, 0xa8, 0x44, 0xa4, 0x57, 0x8f, 0x33, 0x52, 680 0xad, 0x83, 0xae, 0x4a, 0x97, 0xa6, 0x1e, 0xa6, 681 0x2b, 0xfa, 0xea, 0xeb, 0x6e, 0x71, 0xb8, 0xb6, 682 0x0a, 0x36, 0xed, 0x83, 0xce, 0xb0, 0xdf, 0xc1, 683 0xd4, 0x3a, 0xe9, 0x99, 0x6f, 0xf3, 0x96, 0xb7 684 }; 685 686 687 static void dprov_provider_status(crypto_provider_handle_t, uint_t *); 688 689 static crypto_control_ops_t dprov_control_ops = { 690 dprov_provider_status 691 }; 692 693 #define DPROV_MANUFACTURER "SUNW " 694 #define DPROV_MODEL "dprov " 695 #define DPROV_ALLSPACES " " 696 697 static int dprov_digest_init(crypto_ctx_t *, crypto_mechanism_t *, 698 crypto_req_handle_t); 699 static int dprov_digest(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 700 crypto_req_handle_t); 701 static int dprov_digest_update(crypto_ctx_t *, crypto_data_t *, 702 crypto_req_handle_t); 703 static int dprov_digest_key(crypto_ctx_t *, crypto_key_t *, 704 crypto_req_handle_t); 705 static int dprov_digest_final(crypto_ctx_t *, crypto_data_t *, 706 crypto_req_handle_t); 707 static int dprov_digest_atomic(crypto_provider_handle_t, crypto_session_id_t, 708 crypto_mechanism_t *, crypto_data_t *, crypto_data_t *, 709 crypto_req_handle_t); 710 711 static crypto_digest_ops_t dprov_digest_ops = { 712 dprov_digest_init, 713 dprov_digest, 714 dprov_digest_update, 715 dprov_digest_key, 716 dprov_digest_final, 717 dprov_digest_atomic 718 }; 719 720 static int dprov_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *, 721 crypto_spi_ctx_template_t, crypto_req_handle_t); 722 static int dprov_mac(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 723 crypto_req_handle_t); 724 static int dprov_mac_update(crypto_ctx_t *, crypto_data_t *, 725 crypto_req_handle_t); 726 static int dprov_mac_final(crypto_ctx_t *, crypto_data_t *, 727 crypto_req_handle_t); 728 static int dprov_mac_atomic(crypto_provider_handle_t, crypto_session_id_t, 729 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 730 crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 731 static int dprov_mac_verify_atomic(crypto_provider_handle_t, 732 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 733 crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 734 735 static crypto_mac_ops_t dprov_mac_ops = { 736 dprov_mac_init, 737 dprov_mac, 738 dprov_mac_update, 739 dprov_mac_final, 740 dprov_mac_atomic, 741 dprov_mac_verify_atomic 742 }; 743 744 static int dprov_encrypt_init(crypto_ctx_t *, crypto_mechanism_t *, 745 crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 746 static int dprov_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 747 crypto_req_handle_t); 748 static int dprov_encrypt_update(crypto_ctx_t *, crypto_data_t *, 749 crypto_data_t *, crypto_req_handle_t); 750 static int dprov_encrypt_final(crypto_ctx_t *, crypto_data_t *, 751 crypto_req_handle_t); 752 static int dprov_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t, 753 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 754 crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 755 756 static int dprov_decrypt_init(crypto_ctx_t *, crypto_mechanism_t *, 757 crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 758 static int dprov_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 759 crypto_req_handle_t); 760 static int dprov_decrypt_update(crypto_ctx_t *, crypto_data_t *, 761 crypto_data_t *, crypto_req_handle_t); 762 static int dprov_decrypt_final(crypto_ctx_t *, crypto_data_t *, 763 crypto_req_handle_t); 764 static int dprov_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t, 765 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 766 crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 767 768 static crypto_cipher_ops_t dprov_cipher_ops = { 769 dprov_encrypt_init, 770 dprov_encrypt, 771 dprov_encrypt_update, 772 dprov_encrypt_final, 773 dprov_encrypt_atomic, 774 dprov_decrypt_init, 775 dprov_decrypt, 776 dprov_decrypt_update, 777 dprov_decrypt_final, 778 dprov_decrypt_atomic 779 }; 780 781 static int dprov_sign_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *, 782 crypto_spi_ctx_template_t, crypto_req_handle_t); 783 static int dprov_sign(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 784 crypto_req_handle_t); 785 static int dprov_sign_update(crypto_ctx_t *, crypto_data_t *, 786 crypto_req_handle_t); 787 static int dprov_sign_final(crypto_ctx_t *, crypto_data_t *, 788 crypto_req_handle_t); 789 static int dprov_sign_atomic(crypto_provider_handle_t, crypto_session_id_t, 790 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *, 791 crypto_spi_ctx_template_t, crypto_req_handle_t); 792 static int dprov_sign_recover_init(crypto_ctx_t *, crypto_mechanism_t *, 793 crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 794 static int dprov_sign_recover(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 795 crypto_req_handle_t); 796 static int dprov_sign_recover_atomic(crypto_provider_handle_t, 797 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, 798 crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t, 799 crypto_req_handle_t); 800 801 static crypto_sign_ops_t dprov_sign_ops = { 802 dprov_sign_init, 803 dprov_sign, 804 dprov_sign_update, 805 dprov_sign_final, 806 dprov_sign_atomic, 807 dprov_sign_recover_init, 808 dprov_sign_recover, 809 dprov_sign_recover_atomic 810 }; 811 812 static int dprov_verify_init(crypto_ctx_t *, crypto_mechanism_t *, 813 crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 814 static int dprov_verify(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 815 crypto_req_handle_t); 816 static int dprov_verify_update(crypto_ctx_t *, crypto_data_t *, 817 crypto_req_handle_t); 818 static int dprov_verify_final(crypto_ctx_t *, crypto_data_t *, 819 crypto_req_handle_t); 820 static int dprov_verify_atomic(crypto_provider_handle_t, crypto_session_id_t, 821 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 822 crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 823 static int dprov_verify_recover_init(crypto_ctx_t *, crypto_mechanism_t *, 824 crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 825 static int dprov_verify_recover(crypto_ctx_t *, crypto_data_t *, 826 crypto_data_t *, crypto_req_handle_t); 827 static int dprov_verify_recover_atomic(crypto_provider_handle_t, 828 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, 829 crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t, 830 crypto_req_handle_t); 831 832 static crypto_verify_ops_t dprov_verify_ops = { 833 dprov_verify_init, 834 dprov_verify, 835 dprov_verify_update, 836 dprov_verify_final, 837 dprov_verify_atomic, 838 dprov_verify_recover_init, 839 dprov_verify_recover, 840 dprov_verify_recover_atomic 841 }; 842 843 static int dprov_digest_encrypt_update(crypto_ctx_t *, crypto_ctx_t *, 844 crypto_data_t *, crypto_data_t *, crypto_req_handle_t); 845 static int dprov_decrypt_digest_update(crypto_ctx_t *, crypto_ctx_t *, 846 crypto_data_t *, crypto_data_t *, crypto_req_handle_t); 847 static int dprov_sign_encrypt_update(crypto_ctx_t *, crypto_ctx_t *, 848 crypto_data_t *, crypto_data_t *, crypto_req_handle_t); 849 static int dprov_decrypt_verify_update(crypto_ctx_t *, crypto_ctx_t *, 850 crypto_data_t *, crypto_data_t *, crypto_req_handle_t); 851 852 static crypto_dual_ops_t dprov_dual_ops = { 853 dprov_digest_encrypt_update, 854 dprov_decrypt_digest_update, 855 dprov_sign_encrypt_update, 856 dprov_decrypt_verify_update 857 }; 858 859 static int dprov_encrypt_mac_init(crypto_ctx_t *, 860 crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *, 861 crypto_key_t *, crypto_spi_ctx_template_t, 862 crypto_spi_ctx_template_t, crypto_req_handle_t); 863 static int dprov_encrypt_mac(crypto_ctx_t *, 864 crypto_data_t *, crypto_dual_data_t *, crypto_data_t *, 865 crypto_req_handle_t); 866 static int dprov_encrypt_mac_update(crypto_ctx_t *, 867 crypto_data_t *, crypto_dual_data_t *, crypto_req_handle_t); 868 static int dprov_encrypt_mac_final(crypto_ctx_t *, 869 crypto_dual_data_t *, crypto_data_t *, crypto_req_handle_t); 870 static int dprov_encrypt_mac_atomic(crypto_provider_handle_t, 871 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, 872 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 873 crypto_dual_data_t *, crypto_data_t *, crypto_spi_ctx_template_t, 874 crypto_spi_ctx_template_t, crypto_req_handle_t); 875 876 static int dprov_mac_decrypt_init(crypto_ctx_t *, 877 crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *, 878 crypto_key_t *, crypto_spi_ctx_template_t, 879 crypto_spi_ctx_template_t, crypto_req_handle_t); 880 static int dprov_mac_decrypt(crypto_ctx_t *, 881 crypto_dual_data_t *, crypto_data_t *, crypto_data_t *, 882 crypto_req_handle_t); 883 static int dprov_mac_decrypt_update(crypto_ctx_t *, 884 crypto_dual_data_t *, crypto_data_t *, crypto_req_handle_t); 885 static int dprov_mac_decrypt_final(crypto_ctx_t *, 886 crypto_data_t *, crypto_data_t *, crypto_req_handle_t); 887 static int dprov_mac_decrypt_atomic(crypto_provider_handle_t, 888 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, 889 crypto_mechanism_t *, crypto_key_t *, crypto_dual_data_t *, 890 crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t, 891 crypto_spi_ctx_template_t, crypto_req_handle_t); 892 static int dprov_mac_verify_decrypt_atomic(crypto_provider_handle_t, 893 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, 894 crypto_mechanism_t *, crypto_key_t *, crypto_dual_data_t *, 895 crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t, 896 crypto_spi_ctx_template_t, crypto_req_handle_t); 897 898 static crypto_dual_cipher_mac_ops_t dprov_cipher_mac_ops = { 899 dprov_encrypt_mac_init, 900 dprov_encrypt_mac, 901 dprov_encrypt_mac_update, 902 dprov_encrypt_mac_final, 903 dprov_encrypt_mac_atomic, 904 dprov_mac_decrypt_init, 905 dprov_mac_decrypt, 906 dprov_mac_decrypt_update, 907 dprov_mac_decrypt_final, 908 dprov_mac_decrypt_atomic, 909 dprov_mac_verify_decrypt_atomic 910 }; 911 912 static int dprov_seed_random(crypto_provider_handle_t, crypto_session_id_t, 913 uchar_t *, size_t, uint_t, uint32_t, crypto_req_handle_t); 914 static int dprov_generate_random(crypto_provider_handle_t, crypto_session_id_t, 915 uchar_t *, size_t, crypto_req_handle_t); 916 917 static crypto_random_number_ops_t dprov_random_number_ops = { 918 dprov_seed_random, 919 dprov_generate_random 920 }; 921 922 static int dprov_session_open(crypto_provider_handle_t, crypto_session_id_t *, 923 crypto_req_handle_t); 924 static int dprov_session_close(crypto_provider_handle_t, crypto_session_id_t, 925 crypto_req_handle_t); 926 static int dprov_session_login(crypto_provider_handle_t, crypto_session_id_t, 927 crypto_user_type_t, char *, size_t, crypto_req_handle_t); 928 static int dprov_session_logout(crypto_provider_handle_t, crypto_session_id_t, 929 crypto_req_handle_t); 930 931 static crypto_session_ops_t dprov_session_ops = { 932 dprov_session_open, 933 dprov_session_close, 934 dprov_session_login, 935 dprov_session_logout 936 }; 937 938 static int dprov_object_create(crypto_provider_handle_t, crypto_session_id_t, 939 crypto_object_attribute_t *, uint_t, crypto_object_id_t *, 940 crypto_req_handle_t); 941 static int dprov_object_copy(crypto_provider_handle_t, crypto_session_id_t, 942 crypto_object_id_t, crypto_object_attribute_t *, uint_t, 943 crypto_object_id_t *, crypto_req_handle_t); 944 static int dprov_object_destroy(crypto_provider_handle_t, crypto_session_id_t, 945 crypto_object_id_t, crypto_req_handle_t); 946 static int dprov_object_get_size(crypto_provider_handle_t, crypto_session_id_t, 947 crypto_object_id_t, size_t *, crypto_req_handle_t); 948 static int dprov_object_get_attribute_value(crypto_provider_handle_t, 949 crypto_session_id_t, crypto_object_id_t, 950 crypto_object_attribute_t *, uint_t, crypto_req_handle_t); 951 static int dprov_object_set_attribute_value(crypto_provider_handle_t, 952 crypto_session_id_t, crypto_object_id_t, 953 crypto_object_attribute_t *, uint_t, crypto_req_handle_t); 954 static int dprov_object_find_init(crypto_provider_handle_t, crypto_session_id_t, 955 crypto_object_attribute_t *, uint_t, void **, 956 crypto_req_handle_t); 957 static int dprov_object_find(crypto_provider_handle_t, void *, 958 crypto_object_id_t *, uint_t, uint_t *, crypto_req_handle_t); 959 static int dprov_object_find_final(crypto_provider_handle_t, void *, 960 crypto_req_handle_t); 961 962 static crypto_object_ops_t dprov_object_ops = { 963 dprov_object_create, 964 dprov_object_copy, 965 dprov_object_destroy, 966 dprov_object_get_size, 967 dprov_object_get_attribute_value, 968 dprov_object_set_attribute_value, 969 dprov_object_find_init, 970 dprov_object_find, 971 dprov_object_find_final 972 }; 973 974 static int dprov_key_generate(crypto_provider_handle_t, crypto_session_id_t, 975 crypto_mechanism_t *, crypto_object_attribute_t *, uint_t, 976 crypto_object_id_t *, crypto_req_handle_t); 977 static int dprov_key_generate_pair(crypto_provider_handle_t, 978 crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *, 979 uint_t, crypto_object_attribute_t *, uint_t, crypto_object_id_t *, 980 crypto_object_id_t *, crypto_req_handle_t); 981 static int dprov_key_wrap(crypto_provider_handle_t, crypto_session_id_t, 982 crypto_mechanism_t *, crypto_key_t *, crypto_object_id_t *, 983 uchar_t *, size_t *, crypto_req_handle_t); 984 static int dprov_key_unwrap(crypto_provider_handle_t, crypto_session_id_t, 985 crypto_mechanism_t *, crypto_key_t *, uchar_t *, size_t *, 986 crypto_object_attribute_t *, uint_t, 987 crypto_object_id_t *, crypto_req_handle_t); 988 static int dprov_key_derive(crypto_provider_handle_t, crypto_session_id_t, 989 crypto_mechanism_t *, crypto_key_t *, crypto_object_attribute_t *, 990 uint_t, crypto_object_id_t *, crypto_req_handle_t); 991 992 static crypto_key_ops_t dprov_key_ops = { 993 dprov_key_generate, 994 dprov_key_generate_pair, 995 dprov_key_wrap, 996 dprov_key_unwrap, 997 dprov_key_derive 998 }; 999 1000 static int dprov_ext_info(crypto_provider_handle_t, 1001 crypto_provider_ext_info_t *, crypto_req_handle_t); 1002 static int dprov_init_token(crypto_provider_handle_t, char *, size_t, 1003 char *, crypto_req_handle_t); 1004 static int dprov_init_pin(crypto_provider_handle_t, crypto_session_id_t, 1005 char *, size_t, crypto_req_handle_t); 1006 static int dprov_set_pin(crypto_provider_handle_t, crypto_session_id_t, 1007 char *, size_t, char *, size_t, crypto_req_handle_t); 1008 1009 static crypto_provider_management_ops_t dprov_management_ops = { 1010 dprov_ext_info, 1011 dprov_init_token, 1012 dprov_init_pin, 1013 dprov_set_pin 1014 }; 1015 1016 static int dprov_free_context(crypto_ctx_t *); 1017 static int dprov_copyin_mechanism(crypto_provider_handle_t, 1018 crypto_mechanism_t *, crypto_mechanism_t *, int *error, int); 1019 static int dprov_copyout_mechanism(crypto_provider_handle_t, 1020 crypto_mechanism_t *, crypto_mechanism_t *, int *error, int); 1021 static int dprov_free_mechanism(crypto_provider_handle_t, 1022 crypto_mechanism_t *); 1023 1024 static crypto_ctx_ops_t dprov_ctx_ops = { 1025 NULL, 1026 dprov_free_context 1027 }; 1028 1029 static crypto_mech_ops_t dprov_mech_ops = { 1030 dprov_copyin_mechanism, 1031 dprov_copyout_mechanism, 1032 dprov_free_mechanism 1033 }; 1034 1035 static int dprov_nostore_key_generate(crypto_provider_handle_t, 1036 crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *, 1037 uint_t, crypto_object_attribute_t *, uint_t, crypto_req_handle_t); 1038 static int dprov_nostore_key_generate_pair(crypto_provider_handle_t, 1039 crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *, 1040 uint_t, crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *, 1041 uint_t, crypto_object_attribute_t *, uint_t, crypto_req_handle_t); 1042 static int dprov_nostore_key_derive(crypto_provider_handle_t, 1043 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, 1044 crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *, 1045 uint_t, crypto_req_handle_t); 1046 1047 static crypto_nostore_key_ops_t dprov_nostore_key_ops = { 1048 dprov_nostore_key_generate, 1049 dprov_nostore_key_generate_pair, 1050 dprov_nostore_key_derive 1051 }; 1052 1053 static crypto_ops_t dprov_crypto_ops = { 1054 &dprov_control_ops, 1055 &dprov_digest_ops, 1056 &dprov_cipher_ops, 1057 &dprov_mac_ops, 1058 &dprov_sign_ops, 1059 &dprov_verify_ops, 1060 &dprov_dual_ops, 1061 &dprov_cipher_mac_ops, 1062 &dprov_random_number_ops, 1063 &dprov_session_ops, 1064 &dprov_object_ops, 1065 &dprov_key_ops, 1066 &dprov_management_ops, 1067 &dprov_ctx_ops, 1068 &dprov_mech_ops 1069 }; 1070 1071 1072 /* maximum SO and user PIN lengths */ 1073 #define DPROV_MAX_PIN_LEN 128 1074 1075 /* 1076 * Objects: each session is associated with an array of objects. 1077 * Unlike PKCS#11, the objects cannot be shared between sessions. 1078 * The ioctl driver multiplexes PKCS#11 sessions to providers 1079 * sessions in order to support this semantic. This simplifies 1080 * the CSPI greatly since the provider does not have to associate 1081 * sessions with a user space process. 1082 * There is also a per-instance array of objects, which correspond 1083 * to PKCS#11 token objects. These objects can be shared by multiple 1084 * sesions. 1085 * 1086 * Token objects are identified by having a CKA_TOKEN attribute B_TRUE. 1087 * Private objects are identified by having a CKA_PRIVATE attribute 1088 * set to B_TRUE. 1089 */ 1090 1091 #define DPROV_MAX_OBJECTS 128 /* max # of objects */ 1092 #define DPROV_MAX_ATTR 64 /* max # of attributes per object */ 1093 1094 /* object description */ 1095 typedef struct dprov_object { 1096 crypto_object_attribute_t do_attr[DPROV_MAX_ATTR]; /* attributes */ 1097 uint_t do_token_idx; /* index in per-instance table */ 1098 /* for token objects. */ 1099 boolean_t do_destroyed; /* object has been destroyed. */ 1100 /* keep object around until all */ 1101 /* sessions that refer to it */ 1102 /* are closed, but mark it */ 1103 /* destroyed so that references */ 1104 /* to the object fail. */ 1105 /* used for token objects only */ 1106 uint_t do_refcnt; 1107 } dprov_object_t; 1108 1109 /* 1110 * If a session has a reference to a dprov_object_t, 1111 * it REFHOLD()s. 1112 */ 1113 #define DPROV_OBJECT_REFHOLD(object) { \ 1114 atomic_inc_32(&(object)->do_refcnt); \ 1115 ASSERT((object)->do_refcnt != 0); \ 1116 } 1117 1118 /* 1119 * Releases a reference to an object. When the last 1120 * reference is released, the object is freed. 1121 */ 1122 #define DPROV_OBJECT_REFRELE(object) { \ 1123 ASSERT((object)->do_refcnt != 0); \ 1124 membar_exit(); \ 1125 if (atomic_dec_32_nv(&(object)->do_refcnt) == 0) \ 1126 dprov_free_object(object); \ 1127 } 1128 1129 /* 1130 * Object attributes are passed to the provider using crypto_object_attribute 1131 * structures, which contain the type of the attribute, a pointer to 1132 * it's value, and the length of its value. The attribute types values 1133 * are defined by the PKCS#11 specification. This provider only cares 1134 * about a subset of these attributes. In order to avoid having to 1135 * include the PKCS#11 header files, we define here the attributes values 1136 * which are used by the provider. 1137 */ 1138 1139 #define DPROV_CKA_CLASS 0x00000000 1140 #define DPROV_CKA_TOKEN 0x00000001 1141 #define DPROV_CKA_PRIVATE 0x00000002 1142 #define DPROV_CKA_VALUE 0x00000011 1143 #define DPROV_CKA_CERTIFICATE_TYPE 0x00000080 1144 #define DPROV_CKA_KEY_TYPE 0x00000100 1145 #define DPROV_CKA_SENSITIVE 0x00000103 1146 #define DPROV_CKA_ENCRYPT 0x00000104 1147 #define DPROV_CKA_DECRYPT 0x00000105 1148 #define DPROV_CKA_WRAP 0x00000106 1149 #define DPROV_CKA_UNWRAP 0x00000107 1150 #define DPROV_CKA_SIGN 0x00000108 1151 #define DPROV_CKA_SIGN_RECOVER 0x00000109 1152 #define DPROV_CKA_VERIFY 0x0000010A 1153 #define DPROV_CKA_VERIFY_RECOVER 0x0000010B 1154 #define DPROV_CKA_DERIVE 0x0000010C 1155 #define DPROV_CKA_MODULUS 0x00000120 1156 #define DPROV_CKA_MODULUS_BITS 0x00000121 1157 #define DPROV_CKA_PUBLIC_EXPONENT 0x00000122 1158 #define DPROV_CKA_PRIVATE_EXPONENT 0x00000123 1159 #define DPROV_CKA_PRIME 0x00000130 1160 #define DPROV_CKA_BASE 0x00000132 1161 #define DPROV_CKA_VALUE_BITS 0x00000160 1162 #define DPROV_CKA_VALUE_LEN 0x00000161 1163 #define DPROV_CKA_EXTRACTABLE 0x00000162 1164 #define DPROV_CKA_EC_PARAMS 0x00000180 1165 #define DPROV_CKA_EC_POINT 0x00000181 1166 #define DPROV_HW_FEATURE_TYPE 0x00000300 1167 1168 /* 1169 * Object classes from PKCS#11 1170 */ 1171 #define DPROV_CKO_DATA 0x00000000 1172 #define DPROV_CKO_CERTIFICATE 0x00000001 1173 #define DPROV_CKO_PUBLIC_KEY 0x00000002 1174 #define DPROV_CKO_PRIVATE_KEY 0x00000003 1175 #define DPROV_CKO_SECRET_KEY 0x00000004 1176 #define DPROV_CKO_HW_FEATURE 0x00000005 1177 #define DPROV_CKO_DOMAIN_PARAMETERS 0x00000006 1178 #define DPROV_CKO_VENDOR_DEFINED 0x80000000 1179 1180 /* 1181 * A few key types from PKCS#11 1182 */ 1183 #define DPROV_CKK_RSA 0x00000000 1184 #define DPROV_CKK_GENERIC_SECRET 0x00000010 1185 #define DPROV_CKK_RC4 0x00000012 1186 #define DPROV_CKK_DES 0x00000013 1187 #define DPROV_CKK_DES3 0x00000015 1188 #define DPROV_CKK_AES 0x0000001F 1189 #define DPROV_CKK_BLOWFISH 0x00000020 1190 1191 /* 1192 * Find object context. Allows the find object init/find/final 1193 * to store data persistent across calls. 1194 */ 1195 typedef struct dprov_find_ctx { 1196 crypto_object_id_t fc_ids[DPROV_MAX_OBJECTS]; /* object ids */ 1197 uint_t fc_nids; /* number of ids in fc_ids */ 1198 uint_t fc_next; /* next id to return */ 1199 } dprov_find_ctx_t; 1200 1201 /* 1202 * Session management: each instance is associated with an array 1203 * of sessions. KEF providers sessions are always R/W the library and 1204 * the ioctl maintain the PKCS#11 R/W attributes for the session. 1205 */ 1206 1207 #define DPROV_MIN_SESSIONS 32 /* # of sessions to start with */ 1208 1209 typedef enum dprov_session_state { 1210 DPROV_SESSION_STATE_PUBLIC, /* public (default) */ 1211 DPROV_SESSION_STATE_SO, /* SO logged in */ 1212 DPROV_SESSION_STATE_USER /* user logged in */ 1213 } dprov_session_state_t; 1214 1215 /* session description */ 1216 typedef struct dprov_session { 1217 dprov_session_state_t ds_state; /* session state */ 1218 dprov_object_t *ds_objects[DPROV_MAX_OBJECTS]; /* session objects */ 1219 } dprov_session_t; 1220 1221 1222 static crypto_provider_info_t dprov_prov_info = { 1223 CRYPTO_SPI_VERSION_2, 1224 "Dummy Pseudo HW Provider", 1225 CRYPTO_HW_PROVIDER, 1226 NULL, /* pi_provider_dev */ 1227 NULL, /* pi_provider_handle */ 1228 &dprov_crypto_ops, 1229 sizeof (dprov_mech_info_tab)/sizeof (crypto_mech_info_t), 1230 dprov_mech_info_tab, 1231 0, /* pi_logical_provider_count */ 1232 NULL, /* pi_logical_providers */ 1233 0 /* pi_flags */ 1234 }; 1235 1236 /* 1237 * Per-instance info. 1238 */ 1239 typedef struct dprov_state { 1240 kmutex_t ds_lock; /* per-instance lock */ 1241 dev_info_t *ds_dip; /* device info */ 1242 crypto_kcf_provider_handle_t ds_prov_handle; /* framework handle */ 1243 taskq_t *ds_taskq; /* taskq for async behavior */ 1244 char ds_user_pin[DPROV_MAX_PIN_LEN]; /* normal user PIN */ 1245 uint_t ds_user_pin_len; 1246 char ds_so_pin[DPROV_MAX_PIN_LEN]; /* SO PIN */ 1247 uint_t ds_so_pin_len; 1248 dprov_session_t **ds_sessions; /* sessions for this instance */ 1249 uint_t ds_sessions_slots; /* number of session slots */ 1250 uint_t ds_sessions_count; /* number of open sessions */ 1251 boolean_t ds_token_initialized; /* provider initialized? */ 1252 boolean_t ds_user_pin_set; /* user pin set? */ 1253 char ds_label[CRYPTO_EXT_SIZE_LABEL]; /* "token" label */ 1254 dprov_object_t *ds_objects[DPROV_MAX_OBJECTS]; /* "token" objects */ 1255 } dprov_state_t; 1256 1257 1258 /* 1259 * A taskq is associated with each instance of the pseudo driver in order 1260 * to simulate the asynchronous execution of requests. 1261 * The following defines the taskq request structures. 1262 */ 1263 1264 /* request types */ 1265 typedef enum dprov_req_type { 1266 /* digest requests */ 1267 DPROV_REQ_DIGEST_INIT = 1, 1268 DPROV_REQ_DIGEST, 1269 DPROV_REQ_DIGEST_UPDATE, 1270 DPROV_REQ_DIGEST_KEY, 1271 DPROV_REQ_DIGEST_FINAL, 1272 DPROV_REQ_DIGEST_ATOMIC, 1273 /* cipher requests */ 1274 DPROV_REQ_ENCRYPT_INIT, 1275 DPROV_REQ_ENCRYPT, 1276 DPROV_REQ_ENCRYPT_UPDATE, 1277 DPROV_REQ_ENCRYPT_FINAL, 1278 DPROV_REQ_ENCRYPT_ATOMIC, 1279 DPROV_REQ_DECRYPT_INIT, 1280 DPROV_REQ_DECRYPT, 1281 DPROV_REQ_DECRYPT_UPDATE, 1282 DPROV_REQ_DECRYPT_FINAL, 1283 DPROV_REQ_DECRYPT_ATOMIC, 1284 /* mac requests */ 1285 DPROV_REQ_MAC_INIT, 1286 DPROV_REQ_MAC, 1287 DPROV_REQ_MAC_UPDATE, 1288 DPROV_REQ_MAC_FINAL, 1289 DPROV_REQ_MAC_ATOMIC, 1290 DPROV_REQ_MAC_VERIFY_ATOMIC, 1291 /* sign requests */ 1292 DPROV_REQ_SIGN_INIT, 1293 DPROV_REQ_SIGN, 1294 DPROV_REQ_SIGN_UPDATE, 1295 DPROV_REQ_SIGN_FINAL, 1296 DPROV_REQ_SIGN_ATOMIC, 1297 DPROV_REQ_SIGN_RECOVER_INIT, 1298 DPROV_REQ_SIGN_RECOVER, 1299 DPROV_REQ_SIGN_RECOVER_ATOMIC, 1300 /* verify requests */ 1301 DPROV_REQ_VERIFY_INIT, 1302 DPROV_REQ_VERIFY, 1303 DPROV_REQ_VERIFY_UPDATE, 1304 DPROV_REQ_VERIFY_FINAL, 1305 DPROV_REQ_VERIFY_ATOMIC, 1306 DPROV_REQ_VERIFY_RECOVER_INIT, 1307 DPROV_REQ_VERIFY_RECOVER, 1308 DPROV_REQ_VERIFY_RECOVER_ATOMIC, 1309 /* dual ops requests */ 1310 DPROV_REQ_DIGEST_ENCRYPT_UPDATE, 1311 DPROV_REQ_DECRYPT_DIGEST_UPDATE, 1312 DPROV_REQ_SIGN_ENCRYPT_UPDATE, 1313 DPROV_REQ_DECRYPT_VERIFY_UPDATE, 1314 /* dual cipher/mac requests */ 1315 DPROV_REQ_ENCRYPT_MAC_INIT, 1316 DPROV_REQ_ENCRYPT_MAC, 1317 DPROV_REQ_ENCRYPT_MAC_UPDATE, 1318 DPROV_REQ_ENCRYPT_MAC_FINAL, 1319 DPROV_REQ_ENCRYPT_MAC_ATOMIC, 1320 DPROV_REQ_MAC_DECRYPT_INIT, 1321 DPROV_REQ_MAC_DECRYPT, 1322 DPROV_REQ_MAC_DECRYPT_UPDATE, 1323 DPROV_REQ_MAC_DECRYPT_FINAL, 1324 DPROV_REQ_MAC_DECRYPT_ATOMIC, 1325 DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC, 1326 /* random number ops */ 1327 DPROV_REQ_RANDOM_SEED, 1328 DPROV_REQ_RANDOM_GENERATE, 1329 /* session management requests */ 1330 DPROV_REQ_SESSION_OPEN, 1331 DPROV_REQ_SESSION_CLOSE, 1332 DPROV_REQ_SESSION_LOGIN, 1333 DPROV_REQ_SESSION_LOGOUT, 1334 /* object management requests */ 1335 DPROV_REQ_OBJECT_CREATE, 1336 DPROV_REQ_OBJECT_COPY, 1337 DPROV_REQ_OBJECT_DESTROY, 1338 DPROV_REQ_OBJECT_GET_SIZE, 1339 DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE, 1340 DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE, 1341 DPROV_REQ_OBJECT_FIND_INIT, 1342 DPROV_REQ_OBJECT_FIND, 1343 DPROV_REQ_OBJECT_FIND_FINAL, 1344 /* key management requests */ 1345 DPROV_REQ_KEY_GENERATE, 1346 DPROV_REQ_KEY_GENERATE_PAIR, 1347 DPROV_REQ_KEY_WRAP, 1348 DPROV_REQ_KEY_UNWRAP, 1349 DPROV_REQ_KEY_DERIVE, 1350 /* provider management requests */ 1351 DPROV_REQ_MGMT_EXTINFO, 1352 DPROV_REQ_MGMT_INITTOKEN, 1353 DPROV_REQ_MGMT_INITPIN, 1354 DPROV_REQ_MGMT_SETPIN, 1355 /* no (key)store key management requests */ 1356 DPROV_REQ_NOSTORE_KEY_GENERATE, 1357 DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR, 1358 DPROV_REQ_NOSTORE_KEY_DERIVE 1359 } dprov_req_type_t; 1360 1361 /* for DPROV_REQ_DIGEST requests */ 1362 typedef struct dprov_digest_req { 1363 crypto_mechanism_t *dr_mechanism; 1364 crypto_ctx_t *dr_ctx; 1365 crypto_data_t *dr_data; 1366 crypto_key_t *dr_key; 1367 crypto_data_t *dr_digest; 1368 } dprov_digest_req_t; 1369 1370 /* for DPROV_REQ_MAC requests */ 1371 typedef struct dprov_mac_req { 1372 crypto_mechanism_t *dr_mechanism; 1373 crypto_ctx_t *dr_ctx; 1374 crypto_key_t *dr_key; 1375 crypto_data_t *dr_data; 1376 crypto_data_t *dr_mac; 1377 crypto_session_id_t dr_session_id; 1378 } dprov_mac_req_t; 1379 1380 /* for DPROV_REQ_ENCRYPT and DPROV_REQ_DECRYPT requests */ 1381 typedef struct dprov_cipher_req { 1382 crypto_mechanism_t *dr_mechanism; 1383 crypto_ctx_t *dr_ctx; 1384 crypto_key_t *dr_key; 1385 crypto_data_t *dr_plaintext; 1386 crypto_data_t *dr_ciphertext; 1387 crypto_session_id_t dr_session_id; 1388 } dprov_cipher_req_t; 1389 1390 /* for DPROV_REQ_SIGN requests */ 1391 typedef struct dprov_sign_req { 1392 crypto_mechanism_t *sr_mechanism; 1393 crypto_ctx_t *sr_ctx; 1394 crypto_key_t *sr_key; 1395 crypto_data_t *sr_data; 1396 crypto_data_t *sr_signature; 1397 crypto_session_id_t sr_session_id; 1398 } dprov_sign_req_t; 1399 1400 /* for DPROV_REQ_VERIFY requests */ 1401 typedef struct dprov_verify_req { 1402 crypto_mechanism_t *vr_mechanism; 1403 crypto_ctx_t *vr_ctx; 1404 crypto_key_t *vr_key; 1405 crypto_data_t *vr_data; 1406 crypto_data_t *vr_signature; 1407 crypto_session_id_t vr_session_id; 1408 } dprov_verify_req_t; 1409 1410 /* for dual ops requests */ 1411 typedef struct dprov_dual_req { 1412 crypto_ctx_t *dr_signverify_ctx; 1413 crypto_ctx_t *dr_cipher_ctx; 1414 crypto_data_t *dr_plaintext; 1415 crypto_data_t *dr_ciphertext; 1416 } dprov_dual_req_t; 1417 1418 /* for cipher/mac dual ops requests */ 1419 typedef struct dprov_cipher_mac_req { 1420 crypto_session_id_t mr_session_id; 1421 crypto_ctx_t *mr_ctx; 1422 crypto_mechanism_t *mr_cipher_mech; 1423 crypto_key_t *mr_cipher_key; 1424 crypto_mechanism_t *mr_mac_mech; 1425 crypto_key_t *mr_mac_key; 1426 crypto_dual_data_t *mr_dual_data; 1427 crypto_data_t *mr_data; 1428 crypto_data_t *mr_mac; 1429 } dprov_cipher_mac_req_t; 1430 1431 /* for DPROV_REQ_RANDOM requests */ 1432 typedef struct dprov_random_req { 1433 uchar_t *rr_buf; 1434 size_t rr_len; 1435 crypto_session_id_t rr_session_id; 1436 uint_t rr_entropy_est; 1437 uint32_t rr_flags; 1438 } dprov_random_req_t; 1439 1440 /* for DPROV_REQ_SESSION requests */ 1441 typedef struct dprov_session_req { 1442 crypto_session_id_t *sr_session_id_ptr; 1443 crypto_session_id_t sr_session_id; 1444 crypto_user_type_t sr_user_type; 1445 char *sr_pin; 1446 size_t sr_pin_len; 1447 } dprov_session_req_t; 1448 1449 /* for DPROV_REQ_OBJECT requests */ 1450 typedef struct dprov_object_req { 1451 crypto_session_id_t or_session_id; 1452 crypto_object_id_t or_object_id; 1453 crypto_object_attribute_t *or_template; 1454 uint_t or_attribute_count; 1455 crypto_object_id_t *or_object_id_ptr; 1456 size_t *or_object_size; 1457 void **or_find_pp; 1458 void *or_find_p; 1459 uint_t or_max_object_count; 1460 uint_t *or_object_count_ptr; 1461 } dprov_object_req_t; 1462 1463 /* for DPROV_REQ_KEY requests */ 1464 typedef struct dprov_key_req { 1465 crypto_session_id_t kr_session_id; 1466 crypto_mechanism_t *kr_mechanism; 1467 crypto_object_attribute_t *kr_template; 1468 uint_t kr_attribute_count; 1469 crypto_object_id_t *kr_object_id_ptr; 1470 crypto_object_attribute_t *kr_private_key_template; 1471 uint_t kr_private_key_attribute_count; 1472 crypto_object_id_t *kr_private_key_object_id_ptr; 1473 crypto_key_t *kr_key; 1474 uchar_t *kr_wrapped_key; 1475 size_t *kr_wrapped_key_len_ptr; 1476 crypto_object_attribute_t *kr_out_template1; 1477 crypto_object_attribute_t *kr_out_template2; 1478 uint_t kr_out_attribute_count1; 1479 uint_t kr_out_attribute_count2; 1480 } dprov_key_req_t; 1481 1482 /* for DPROV_REQ_MGMT requests */ 1483 typedef struct dprov_mgmt_req { 1484 crypto_session_id_t mr_session_id; 1485 char *mr_pin; 1486 size_t mr_pin_len; 1487 char *mr_old_pin; 1488 size_t mr_old_pin_len; 1489 char *mr_label; 1490 crypto_provider_ext_info_t *mr_ext_info; 1491 } dprov_mgmt_req_t; 1492 1493 /* request, as queued on taskq */ 1494 typedef struct dprov_req { 1495 dprov_req_type_t dr_type; 1496 dprov_state_t *dr_softc; 1497 crypto_req_handle_t dr_kcf_req; 1498 union { 1499 dprov_digest_req_t dru_digest_req; 1500 dprov_mac_req_t dru_mac_req; 1501 dprov_cipher_req_t dru_cipher_req; 1502 dprov_sign_req_t dru_sign_req; 1503 dprov_verify_req_t dru_verify_req; 1504 dprov_dual_req_t dru_dual_req; 1505 dprov_cipher_mac_req_t dru_cipher_mac_req; 1506 dprov_random_req_t dru_random_req; 1507 dprov_session_req_t dru_session_req; 1508 dprov_object_req_t dru_object_req; 1509 dprov_key_req_t dru_key_req; 1510 dprov_mgmt_req_t dru_mgmt_req; 1511 } dr_req; 1512 } dprov_req_t; 1513 1514 /* shortcuts for union fields */ 1515 #define dr_digest_req dr_req.dru_digest_req 1516 #define dr_mac_req dr_req.dru_mac_req 1517 #define dr_cipher_req dr_req.dru_cipher_req 1518 #define dr_sign_req dr_req.dru_sign_req 1519 #define dr_verify_req dr_req.dru_verify_req 1520 #define dr_dual_req dr_req.dru_dual_req 1521 #define dr_cipher_mac_req dr_req.dru_cipher_mac_req 1522 #define dr_random_req dr_req.dru_random_req 1523 #define dr_session_req dr_req.dru_session_req 1524 #define dr_object_req dr_req.dru_object_req 1525 #define dr_key_req dr_req.dru_key_req 1526 #define dr_mgmt_req dr_req.dru_mgmt_req 1527 1528 /* prototypes for the tasq dispatcher functions */ 1529 static void dprov_digest_task(dprov_req_t *); 1530 static void dprov_mac_task(dprov_req_t *); 1531 static void dprov_sign_task(dprov_req_t *); 1532 static void dprov_verify_task(dprov_req_t *); 1533 static void dprov_dual_task(dprov_req_t *); 1534 static void dprov_cipher_task(dprov_req_t *); 1535 static void dprov_cipher_mac_task(dprov_req_t *); 1536 static void dprov_random_task(dprov_req_t *); 1537 static void dprov_session_task(dprov_req_t *); 1538 static void dprov_object_task(dprov_req_t *); 1539 static void dprov_key_task(dprov_req_t *); 1540 static void dprov_mgmt_task(dprov_req_t *); 1541 1542 /* helper functions */ 1543 static int dprov_digest_submit_req(dprov_req_type_t, dprov_state_t *, 1544 crypto_req_handle_t, crypto_mechanism_t *, crypto_data_t *, crypto_key_t *, 1545 crypto_data_t *, crypto_ctx_t *, int); 1546 static int dprov_cipher_submit_req(dprov_req_type_t, dprov_state_t *, 1547 crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 1548 crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int); 1549 static int dprov_mac_submit_req(dprov_req_type_t, dprov_state_t *, 1550 crypto_req_handle_t, crypto_mechanism_t *, crypto_data_t *, 1551 crypto_key_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int); 1552 static int dprov_sign_submit_req(dprov_req_type_t, dprov_state_t *, 1553 crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *, 1554 crypto_data_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int); 1555 static int dprov_verify_submit_req(dprov_req_type_t, dprov_state_t *, 1556 crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *, 1557 crypto_data_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int); 1558 static int dprov_dual_submit_req(dprov_req_type_t, dprov_state_t *, 1559 crypto_req_handle_t, crypto_ctx_t *, crypto_ctx_t *, crypto_data_t *, 1560 crypto_data_t *); 1561 static int dprov_cipher_mac_submit_req(dprov_req_type_t, dprov_state_t *, 1562 crypto_req_handle_t, crypto_ctx_t *, crypto_session_id_t, 1563 crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *, crypto_key_t *, 1564 crypto_dual_data_t *, crypto_data_t *, crypto_data_t *, int); 1565 static int dprov_random_submit_req(dprov_req_type_t, dprov_state_t *, 1566 crypto_req_handle_t, uchar_t *, size_t, crypto_session_id_t, uint_t, 1567 uint32_t); 1568 static int dprov_session_submit_req(dprov_req_type_t, dprov_state_t *, 1569 crypto_req_handle_t, crypto_session_id_t *, crypto_session_id_t, 1570 crypto_user_type_t, char *, size_t); 1571 static int dprov_object_submit_req(dprov_req_type_t, dprov_state_t *, 1572 crypto_req_handle_t, crypto_session_id_t, crypto_object_id_t, 1573 crypto_object_attribute_t *, uint_t, crypto_object_id_t *, size_t *, 1574 void **, void *, uint_t, uint_t *, int); 1575 static int dprov_key_submit_req(dprov_req_type_t, dprov_state_t *, 1576 crypto_req_handle_t, crypto_session_id_t, crypto_mechanism_t *, 1577 crypto_object_attribute_t *, uint_t, crypto_object_id_t *, 1578 crypto_object_attribute_t *, uint_t, crypto_object_id_t *, 1579 crypto_key_t *, uchar_t *, size_t *, crypto_object_attribute_t *, 1580 uint_t, crypto_object_attribute_t *, uint_t); 1581 static int dprov_mgmt_submit_req(dprov_req_type_t, dprov_state_t *, 1582 crypto_req_handle_t, crypto_session_id_t, char *, size_t, char *, size_t, 1583 char *, crypto_provider_ext_info_t *); 1584 static int dprov_get_sw_prov(crypto_mechanism_t *, kcf_provider_desc_t **, 1585 crypto_mech_type_t *); 1586 1587 /* object management helper functions */ 1588 static void dprov_free_object(dprov_object_t *); 1589 static void dprov_release_session_objects(dprov_session_t *); 1590 static void dprov_adjust_attrs(crypto_object_attribute_t *, int); 1591 static boolean_t dprov_object_is_private(dprov_object_t *); 1592 static boolean_t dprov_object_is_token(dprov_object_t *); 1593 static int dprov_key_value_secret(dprov_state_t *, crypto_session_id_t, 1594 dprov_req_type_t, crypto_key_t *, crypto_key_t *); 1595 static int dprov_key_attr_asymmetric(dprov_state_t *, crypto_session_id_t, 1596 dprov_req_type_t, crypto_key_t *, crypto_key_t *); 1597 static int dprov_get_object_attr_boolean(dprov_object_t *, uint64_t, 1598 boolean_t *); 1599 static int dprov_get_object_attr_ulong(dprov_object_t *, uint64_t, ulong_t *); 1600 static int dprov_get_object_attr_array(dprov_object_t *, uint64_t, void **, 1601 size_t *); 1602 static int dprov_get_key_attr_ulong(crypto_key_t *, uint64_t, ulong_t *); 1603 static int dprov_get_key_attr_array(crypto_key_t *, uint64_t, void **, 1604 size_t *); 1605 static int dprov_create_object_from_template(dprov_state_t *, dprov_session_t *, 1606 crypto_object_attribute_t *, uint_t, crypto_object_id_t *, boolean_t, 1607 boolean_t); 1608 static int dprov_get_template_attr_scalar_common(crypto_object_attribute_t *, 1609 uint_t, uint64_t, void *, size_t); 1610 static int dprov_get_template_attr_boolean(crypto_object_attribute_t *, 1611 uint_t, uint64_t, boolean_t *); 1612 static int dprov_get_template_attr_ulong(crypto_object_attribute_t *, uint_t, 1613 uint64_t, ulong_t *); 1614 static int dprov_template_attr_present(crypto_object_attribute_t *, uint_t, 1615 uint64_t); 1616 static int dprov_get_template_attr_array(crypto_object_attribute_t *, uint_t, 1617 uint64_t, void **, size_t *); 1618 static int dprov_destroy_object(dprov_state_t *, dprov_session_t *, 1619 crypto_object_id_t); 1620 static int dprov_object_set_attr(dprov_session_t *, crypto_object_id_t, 1621 crypto_object_attribute_t *, uint_t, boolean_t); 1622 static int dprov_find_attr(crypto_object_attribute_t *, uint_t, uint64_t); 1623 static boolean_t dprov_attributes_match(dprov_object_t *, 1624 crypto_object_attribute_t *, uint_t); 1625 1626 /* retrieve the softc and instance number from a SPI crypto context */ 1627 #define DPROV_SOFTC_FROM_CTX(ctx, softc, instance) { \ 1628 (softc) = (dprov_state_t *)(ctx)->cc_provider; \ 1629 (instance) = ddi_get_instance((softc)->ds_dip); \ 1630 } 1631 1632 /* retrieve the softc and instance number from a taskq request */ 1633 #define DPROV_SOFTC_FROM_REQ(req, softc, instance) { \ 1634 (softc) = (req)->dr_softc; \ 1635 (instance) = ddi_get_instance((softc)->ds_dip); \ 1636 } 1637 1638 /* 1639 * The dprov private context most of the time contains a pointer to the 1640 * crypto_context_t that was allocated when calling a KCF function. 1641 * Dual cipher/mac operations however require the dprov driver 1642 * to maintain the contexts associated with the separate cipher 1643 * and mac operations. These two types of dprov contexts are 1644 * defined below. 1645 */ 1646 typedef enum dprov_ctx_type { 1647 DPROV_CTX_SINGLE, 1648 DPROV_CTX_DUAL 1649 } dprov_ctx_type_t; 1650 1651 /* 1652 * When the context refers to a single KCF context, the 1653 * cc_provider field of a crypto_ctx_t points to a structure of 1654 * type dprov_ctx_single. 1655 */ 1656 typedef struct dprov_ctx_single { 1657 dprov_ctx_type_t dc_type; 1658 crypto_context_t dc_ctx; 1659 boolean_t dc_svrfy_to_mac; 1660 } dprov_ctx_single_t; 1661 1662 /* 1663 * When the context is used for cipher/mac operations, it contains 1664 * pointers to to KCF contexts, one for the cipher operation, the 1665 * other for the mac operation. 1666 */ 1667 typedef struct dprov_ctx_dual { 1668 dprov_ctx_type_t cd_type; 1669 crypto_context_t cd_cipher_ctx; 1670 crypto_context_t cd_mac_ctx; 1671 } dprov_ctx_dual_t; 1672 1673 /* 1674 * Helper macros for context accessors. These macros return the 1675 * k-API context corresponding to the given SPI context for 1676 * single and dual cipher/mac operations. 1677 */ 1678 1679 #define DPROV_CTX_P(_ctx) \ 1680 ((dprov_ctx_single_t *)(_ctx)->cc_provider_private) 1681 1682 #define DPROV_CTX_SINGLE(_ctx) ((DPROV_CTX_P(_ctx))->dc_ctx) 1683 1684 #define DPROV_CTX_DUAL_CIPHER(_ctx) \ 1685 (((dprov_ctx_dual_t *)(_ctx)->cc_provider_private)->cd_cipher_ctx) 1686 1687 #define DPROV_CTX_DUAL_MAC(_ctx) \ 1688 (((dprov_ctx_dual_t *)(_ctx)->cc_provider_private)->cd_mac_ctx) 1689 1690 static int dprov_alloc_context(dprov_req_type_t, crypto_ctx_t *); 1691 1692 1693 1694 static void *statep; /* state pointer */ 1695 1696 /* 1697 * DDI entry points. 1698 */ 1699 int 1700 _init(void) 1701 { 1702 int error; 1703 1704 DPROV_DEBUG(D_INIT, ("dprov: in _init\n")); 1705 1706 if ((error = ddi_soft_state_init(&statep, sizeof (dprov_state_t), 1707 0)) != 0) 1708 return (error); 1709 1710 return (mod_install(&modlinkage)); 1711 } 1712 1713 int 1714 _fini(void) 1715 { 1716 int error; 1717 1718 DPROV_DEBUG(D_INIT, ("dprov: in _fini\n")); 1719 1720 if ((error = mod_remove(&modlinkage)) != 0) 1721 return (error); 1722 1723 ddi_soft_state_fini(&statep); 1724 1725 return (0); 1726 } 1727 1728 int 1729 _info(struct modinfo *modinfop) 1730 { 1731 DPROV_DEBUG(D_INIT, ("dprov: in _info\n")); 1732 1733 return (mod_info(&modlinkage, modinfop)); 1734 } 1735 1736 /* ARGSUSED */ 1737 static int 1738 dprov_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result) 1739 { 1740 int instance = getminor((dev_t)arg); 1741 dprov_state_t *softc; 1742 1743 DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_getinfo() for %d\n", 1744 instance)); 1745 1746 switch (cmd) { 1747 case DDI_INFO_DEVT2DEVINFO: 1748 softc = ddi_get_soft_state(statep, instance); 1749 *result = softc->ds_dip; 1750 return (DDI_SUCCESS); 1751 1752 case DDI_INFO_DEVT2INSTANCE: 1753 *result = (void *)(uintptr_t)instance; 1754 return (DDI_SUCCESS); 1755 } 1756 return (DDI_FAILURE); 1757 } 1758 1759 static int 1760 dprov_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1761 { 1762 int instance = ddi_get_instance(dip); 1763 dprov_state_t *softc; 1764 char devname[256]; 1765 int ret; 1766 1767 DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_attach() for %d\n", 1768 instance)); 1769 1770 if (cmd != DDI_ATTACH) { 1771 return (DDI_FAILURE); 1772 } 1773 1774 /* get new softc and initialize it */ 1775 if (ddi_soft_state_zalloc(statep, instance) != DDI_SUCCESS) 1776 return (DDI_FAILURE); 1777 1778 softc = ddi_get_soft_state(statep, instance); 1779 mutex_init(&softc->ds_lock, NULL, MUTEX_DRIVER, NULL); 1780 softc->ds_dip = dip; 1781 softc->ds_prov_handle = NULL; 1782 1783 /* create minor node */ 1784 (void) sprintf(devname, "dprov%d", instance); 1785 if (ddi_create_minor_node(dip, devname, S_IFCHR, instance, 1786 DDI_PSEUDO, 0) != DDI_SUCCESS) { 1787 cmn_err(CE_WARN, "attach: failed creating minor node"); 1788 mutex_destroy(&softc->ds_lock); 1789 ddi_soft_state_free(statep, instance); 1790 return (DDI_FAILURE); 1791 } 1792 1793 nostore_key_gen = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1794 DDI_PROP_DONTPASS, "nostore_key_gen", 0); 1795 if (nostore_key_gen != 0) { 1796 dprov_prov_info.pi_interface_version = CRYPTO_SPI_VERSION_3; 1797 dprov_crypto_ops.co_object_ops = NULL; 1798 dprov_crypto_ops.co_nostore_key_ops = &dprov_nostore_key_ops; 1799 } 1800 1801 dprov_max_digestsz = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1802 DDI_PROP_DONTPASS, "max_digest_sz", INT_MAX); 1803 if (dprov_max_digestsz != INT_MAX && dprov_max_digestsz != 0 && 1804 dprov_max_digestsz != DDI_PROP_NOT_FOUND) { 1805 dprov_no_multipart = B_TRUE; 1806 dprov_prov_info.pi_flags |= 1807 (CRYPTO_HASH_NO_UPDATE | CRYPTO_HMAC_NO_UPDATE); 1808 } 1809 1810 /* create taskq */ 1811 softc->ds_taskq = taskq_create(devname, 1, minclsyspri, 1812 crypto_taskq_minalloc, crypto_taskq_maxalloc, TASKQ_PREPOPULATE); 1813 1814 /* initialize table of sessions */ 1815 softc->ds_sessions = kmem_zalloc(DPROV_MIN_SESSIONS * 1816 sizeof (dprov_session_t *), KM_SLEEP); 1817 softc->ds_sessions_slots = DPROV_MIN_SESSIONS; 1818 softc->ds_sessions_count = 0; 1819 1820 /* initialized done by init_token entry point */ 1821 softc->ds_token_initialized = B_TRUE; 1822 1823 (void) memset(softc->ds_label, ' ', CRYPTO_EXT_SIZE_LABEL); 1824 bcopy("Dummy Pseudo HW Provider", softc->ds_label, 24); 1825 1826 bcopy("changeme", softc->ds_user_pin, 8); 1827 softc->ds_user_pin_len = 8; 1828 softc->ds_user_pin_set = B_TRUE; 1829 1830 /* register with the crypto framework */ 1831 dprov_prov_info.pi_provider_dev.pd_hw = dip; 1832 dprov_prov_info.pi_provider_handle = softc; 1833 1834 if (dprov_no_multipart) { /* Export only single part */ 1835 dprov_digest_ops.digest_update = NULL; 1836 dprov_digest_ops.digest_key = NULL; 1837 dprov_digest_ops.digest_final = NULL; 1838 dprov_object_ops.object_create = NULL; 1839 } 1840 1841 if ((ret = crypto_register_provider(&dprov_prov_info, 1842 &softc->ds_prov_handle)) != CRYPTO_SUCCESS) { 1843 cmn_err(CE_WARN, 1844 "dprov crypto_register_provider() failed (0x%x)", ret); 1845 taskq_destroy(softc->ds_taskq); 1846 kmem_free(softc->ds_sessions, softc->ds_sessions_slots * 1847 sizeof (dprov_session_t *)); 1848 mutex_destroy(&softc->ds_lock); 1849 ddi_soft_state_free(statep, instance); 1850 ddi_remove_minor_node(dip, NULL); 1851 return (DDI_FAILURE); 1852 } 1853 1854 /* 1855 * This call is for testing only; it is not required by the SPI. 1856 */ 1857 crypto_provider_notification(softc->ds_prov_handle, 1858 CRYPTO_PROVIDER_READY); 1859 1860 return (DDI_SUCCESS); 1861 } 1862 1863 static int 1864 dprov_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1865 { 1866 int instance = ddi_get_instance(dip); 1867 dprov_state_t *softc = ddi_get_soft_state(statep, instance); 1868 dprov_session_t *session; 1869 int i, ret; 1870 1871 DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_detach() for %d\n", 1872 instance)); 1873 1874 if (cmd != DDI_DETACH) 1875 return (DDI_FAILURE); 1876 1877 /* unregister from the crypto framework */ 1878 if (softc->ds_prov_handle != NULL) 1879 if ((ret = crypto_unregister_provider( 1880 softc->ds_prov_handle)) != CRYPTO_SUCCESS) { 1881 cmn_err(CE_WARN, "dprov_detach: " 1882 "crypto_unregister_provider() " 1883 "failed (0x%x)", ret); 1884 return (DDI_FAILURE); 1885 } 1886 1887 1888 taskq_destroy(softc->ds_taskq); 1889 1890 for (i = 0; i < softc->ds_sessions_slots; i++) { 1891 if ((session = softc->ds_sessions[i]) == NULL) 1892 continue; 1893 1894 dprov_release_session_objects(session); 1895 1896 kmem_free(session, sizeof (dprov_session_t)); 1897 softc->ds_sessions_count--; 1898 1899 } 1900 1901 kmem_free(softc->ds_sessions, softc->ds_sessions_slots * 1902 sizeof (dprov_session_t *)); 1903 /* free token objects */ 1904 for (i = 0; i < DPROV_MAX_OBJECTS; i++) 1905 if (softc->ds_objects[i] != NULL) 1906 dprov_free_object(softc->ds_objects[i]); 1907 1908 mutex_destroy(&softc->ds_lock); 1909 ddi_soft_state_free(statep, instance); 1910 1911 ddi_remove_minor_node(dip, NULL); 1912 1913 return (DDI_SUCCESS); 1914 } 1915 1916 /* 1917 * Control entry points. 1918 */ 1919 static void 1920 dprov_provider_status(crypto_provider_handle_t provider, uint_t *status) 1921 { 1922 _NOTE(ARGUNUSED(provider)) 1923 1924 *status = CRYPTO_PROVIDER_READY; 1925 } 1926 1927 /* 1928 * Digest entry points. 1929 */ 1930 1931 static int 1932 dprov_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 1933 crypto_req_handle_t req) 1934 { 1935 int error = CRYPTO_FAILED; 1936 dprov_state_t *softc; 1937 /* LINTED E_FUNC_SET_NOT_USED */ 1938 int instance; 1939 1940 /* extract softc and instance number from context */ 1941 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 1942 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_init: started\n", instance)); 1943 1944 /* check mechanism */ 1945 if (mechanism->cm_type != MD4_MECH_INFO_TYPE && 1946 mechanism->cm_type != MD5_MECH_INFO_TYPE && 1947 mechanism->cm_type != SHA1_MECH_INFO_TYPE && 1948 mechanism->cm_type != SHA256_MECH_INFO_TYPE && 1949 mechanism->cm_type != SHA384_MECH_INFO_TYPE && 1950 mechanism->cm_type != SHA512_MECH_INFO_TYPE) { 1951 cmn_err(CE_WARN, "dprov_digest_init: unexpected mech type " 1952 "0x%llx\n", (unsigned long long)mechanism->cm_type); 1953 return (CRYPTO_MECHANISM_INVALID); 1954 } 1955 1956 /* submit request to the taskq */ 1957 error = dprov_digest_submit_req(DPROV_REQ_DIGEST_INIT, softc, req, 1958 mechanism, NULL, NULL, NULL, ctx, KM_SLEEP); 1959 1960 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_init: done err = 0x%x\n", 1961 instance, error)); 1962 1963 return (error); 1964 } 1965 1966 static int 1967 dprov_digest(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *digest, 1968 crypto_req_handle_t req) 1969 { 1970 int error = CRYPTO_FAILED; 1971 dprov_state_t *softc; 1972 /* LINTED E_FUNC_SET_NOT_USED */ 1973 int instance; 1974 1975 if (dprov_no_multipart && data->cd_length > dprov_max_digestsz) 1976 return (CRYPTO_BUFFER_TOO_BIG); 1977 1978 /* extract softc and instance number from context */ 1979 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 1980 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest: started\n", instance)); 1981 1982 /* submit request to the taskq */ 1983 error = dprov_digest_submit_req(DPROV_REQ_DIGEST, softc, req, 1984 NULL, data, NULL, digest, ctx, KM_NOSLEEP); 1985 1986 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest: done, err = 0x%x\n", 1987 instance, error)); 1988 1989 return (error); 1990 } 1991 1992 static int 1993 dprov_digest_update(crypto_ctx_t *ctx, crypto_data_t *data, 1994 crypto_req_handle_t req) 1995 { 1996 int error = CRYPTO_FAILED; 1997 dprov_state_t *softc; 1998 /* LINTED E_FUNC_SET_NOT_USED */ 1999 int instance; 2000 2001 /* extract softc and instance number from context */ 2002 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2003 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_update: started\n", 2004 instance)); 2005 2006 /* submit request to the taskq */ 2007 error = dprov_digest_submit_req(DPROV_REQ_DIGEST_UPDATE, softc, 2008 req, NULL, data, NULL, NULL, ctx, KM_NOSLEEP); 2009 2010 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_update: done err = 0x0%x\n", 2011 instance, error)); 2012 2013 return (error); 2014 } 2015 2016 static int 2017 dprov_digest_key(crypto_ctx_t *ctx, crypto_key_t *key, crypto_req_handle_t req) 2018 { 2019 int error = CRYPTO_FAILED; 2020 dprov_state_t *softc; 2021 /* LINTED E_FUNC_SET_NOT_USED */ 2022 int instance; 2023 2024 /* extract softc and instance number from context */ 2025 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2026 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_key: started\n", instance)); 2027 2028 /* submit request to the taskq */ 2029 error = dprov_digest_submit_req(DPROV_REQ_DIGEST_KEY, softc, req, NULL, 2030 NULL, key, NULL, ctx, KM_NOSLEEP); 2031 2032 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_key: done err = 0x0%x\n", 2033 instance, error)); 2034 2035 return (error); 2036 } 2037 2038 static int 2039 dprov_digest_final(crypto_ctx_t *ctx, crypto_data_t *digest, 2040 crypto_req_handle_t req) 2041 { 2042 int error = CRYPTO_FAILED; 2043 dprov_state_t *softc; 2044 /* LINTED E_FUNC_SET_NOT_USED */ 2045 int instance; 2046 2047 /* extract softc and instance number from context */ 2048 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2049 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_final: started\n", instance)); 2050 2051 /* submit request to the taskq */ 2052 error = dprov_digest_submit_req(DPROV_REQ_DIGEST_FINAL, softc, req, 2053 NULL, NULL, NULL, digest, ctx, KM_NOSLEEP); 2054 2055 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_final: done err = 0x0%x\n", 2056 instance, error)); 2057 2058 return (error); 2059 } 2060 2061 /* ARGSUSED */ 2062 static int 2063 dprov_digest_atomic(crypto_provider_handle_t provider, 2064 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 2065 crypto_data_t *data, crypto_data_t *digest, 2066 crypto_req_handle_t req) 2067 { 2068 int error = CRYPTO_FAILED; 2069 dprov_state_t *softc = (dprov_state_t *)provider; 2070 /* LINTED E_FUNC_SET_NOT_USED */ 2071 int instance; 2072 2073 if (dprov_no_multipart && data->cd_length > dprov_max_digestsz) 2074 return (CRYPTO_BUFFER_TOO_BIG); 2075 2076 instance = ddi_get_instance(softc->ds_dip); 2077 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_atomic: started\n", 2078 instance)); 2079 2080 /* check mechanism */ 2081 if (mechanism->cm_type != MD4_MECH_INFO_TYPE && 2082 mechanism->cm_type != MD5_MECH_INFO_TYPE && 2083 mechanism->cm_type != SHA1_MECH_INFO_TYPE && 2084 mechanism->cm_type != SHA256_MECH_INFO_TYPE && 2085 mechanism->cm_type != SHA384_MECH_INFO_TYPE && 2086 mechanism->cm_type != SHA512_MECH_INFO_TYPE) { 2087 cmn_err(CE_WARN, "dprov_digest_atomic: unexpected mech type " 2088 "0x%llx\n", (unsigned long long)mechanism->cm_type); 2089 return (CRYPTO_MECHANISM_INVALID); 2090 } 2091 2092 /* submit request to the taskq */ 2093 error = dprov_digest_submit_req(DPROV_REQ_DIGEST_ATOMIC, softc, req, 2094 mechanism, data, NULL, digest, NULL, KM_SLEEP); 2095 2096 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_atomic: done err = 0x0%x\n", 2097 instance, error)); 2098 2099 return (error); 2100 } 2101 2102 /* 2103 * MAC entry points. 2104 */ 2105 2106 /* 2107 * Checks whether the specified mech_type is supported by mac 2108 * entry points. 2109 */ 2110 static boolean_t 2111 dprov_valid_mac_mech(crypto_mech_type_t mech_type) 2112 { 2113 return (mech_type == MD5_HMAC_MECH_INFO_TYPE || 2114 mech_type == MD5_HMAC_GEN_MECH_INFO_TYPE || 2115 mech_type == SHA1_HMAC_MECH_INFO_TYPE || 2116 mech_type == SHA1_HMAC_GEN_MECH_INFO_TYPE || 2117 mech_type == SHA256_HMAC_MECH_INFO_TYPE || 2118 mech_type == SHA256_HMAC_GEN_MECH_INFO_TYPE || 2119 mech_type == SHA384_HMAC_MECH_INFO_TYPE || 2120 mech_type == SHA384_HMAC_GEN_MECH_INFO_TYPE || 2121 mech_type == SHA512_HMAC_MECH_INFO_TYPE || 2122 mech_type == SHA512_HMAC_GEN_MECH_INFO_TYPE || 2123 mech_type == AES_GMAC_MECH_INFO_TYPE || 2124 mech_type == AES_CMAC_MECH_INFO_TYPE); 2125 } 2126 2127 static int 2128 dprov_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 2129 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 2130 crypto_req_handle_t req) 2131 { 2132 int error = CRYPTO_FAILED; 2133 dprov_state_t *softc; 2134 /* LINTED E_FUNC_SET_NOT_USED */ 2135 int instance; 2136 2137 /* extract softc and instance number from context */ 2138 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2139 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_init: started\n", instance)); 2140 2141 /* check mechanism */ 2142 if (!dprov_valid_mac_mech(mechanism->cm_type)) { 2143 cmn_err(CE_WARN, "dprov_mac_init: unexpected mech type " 2144 "0x%llx\n", (unsigned long long)mechanism->cm_type); 2145 return (CRYPTO_MECHANISM_INVALID); 2146 } 2147 2148 if (ctx_template != NULL) 2149 return (CRYPTO_ARGUMENTS_BAD); 2150 2151 /* submit request to the taskq */ 2152 error = dprov_mac_submit_req(DPROV_REQ_MAC_INIT, softc, req, 2153 mechanism, NULL, key, NULL, ctx, 0, KM_SLEEP); 2154 2155 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_init: done err = 0x%x\n", 2156 instance, error)); 2157 2158 return (error); 2159 } 2160 2161 static int 2162 dprov_mac(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *mac, 2163 crypto_req_handle_t req) 2164 { 2165 int error = CRYPTO_FAILED; 2166 dprov_state_t *softc; 2167 /* LINTED E_FUNC_SET_NOT_USED */ 2168 int instance; 2169 2170 /* extract softc and instance number from context */ 2171 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2172 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac: started\n", instance)); 2173 2174 /* submit request to the taskq */ 2175 error = dprov_mac_submit_req(DPROV_REQ_MAC, softc, req, 2176 NULL, data, NULL, mac, ctx, 0, KM_NOSLEEP); 2177 2178 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac: done, err = 0x%x\n", instance, 2179 error)); 2180 2181 return (error); 2182 } 2183 2184 static int 2185 dprov_mac_update(crypto_ctx_t *ctx, crypto_data_t *data, 2186 crypto_req_handle_t req) 2187 { 2188 int error = CRYPTO_FAILED; 2189 dprov_state_t *softc; 2190 /* LINTED E_FUNC_SET_NOT_USED */ 2191 int instance; 2192 2193 /* extract softc and instance number from context */ 2194 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2195 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_update: started\n", instance)); 2196 2197 /* submit request to the taskq */ 2198 error = dprov_mac_submit_req(DPROV_REQ_MAC_UPDATE, softc, 2199 req, NULL, data, NULL, NULL, ctx, 0, KM_NOSLEEP); 2200 2201 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_update: done err = 0x0%x\n", 2202 instance, error)); 2203 2204 return (error); 2205 } 2206 2207 static int 2208 dprov_mac_final(crypto_ctx_t *ctx, crypto_data_t *mac, crypto_req_handle_t req) 2209 { 2210 int error = CRYPTO_FAILED; 2211 dprov_state_t *softc; 2212 /* LINTED E_FUNC_SET_NOT_USED */ 2213 int instance; 2214 2215 /* extract softc and instance number from context */ 2216 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2217 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_final: started\n", instance)); 2218 2219 /* submit request to the taskq */ 2220 error = dprov_mac_submit_req(DPROV_REQ_MAC_FINAL, softc, req, 2221 NULL, NULL, NULL, mac, ctx, 0, KM_NOSLEEP); 2222 2223 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_final: done err = 0x0%x\n", 2224 instance, error)); 2225 2226 return (error); 2227 } 2228 2229 static int 2230 dprov_mac_atomic(crypto_provider_handle_t provider, 2231 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 2232 crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac, 2233 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 2234 { 2235 int error = CRYPTO_FAILED; 2236 dprov_state_t *softc = (dprov_state_t *)provider; 2237 /* LINTED E_FUNC_SET_NOT_USED */ 2238 int instance; 2239 2240 instance = ddi_get_instance(softc->ds_dip); 2241 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_atomic: started\n", instance)); 2242 2243 if (ctx_template != NULL) 2244 return (CRYPTO_ARGUMENTS_BAD); 2245 2246 /* check mechanism */ 2247 if (!dprov_valid_mac_mech(mechanism->cm_type)) { 2248 cmn_err(CE_WARN, "dprov_mac_atomic: unexpected mech type " 2249 "0x%llx\n", (unsigned long long)mechanism->cm_type); 2250 return (CRYPTO_MECHANISM_INVALID); 2251 } 2252 2253 /* submit request to the taskq */ 2254 error = dprov_mac_submit_req(DPROV_REQ_MAC_ATOMIC, softc, req, 2255 mechanism, data, key, mac, NULL, session_id, KM_SLEEP); 2256 2257 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_atomic: done err = 0x0%x\n", 2258 instance, error)); 2259 2260 return (error); 2261 } 2262 2263 static int 2264 dprov_mac_verify_atomic(crypto_provider_handle_t provider, 2265 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 2266 crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac, 2267 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 2268 { 2269 int error = CRYPTO_FAILED; 2270 dprov_state_t *softc = (dprov_state_t *)provider; 2271 /* LINTED E_FUNC_SET_NOT_USED */ 2272 int instance; 2273 2274 instance = ddi_get_instance(softc->ds_dip); 2275 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_verify_atomic: started\n", 2276 instance)); 2277 2278 if (ctx_template != NULL) 2279 return (CRYPTO_ARGUMENTS_BAD); 2280 2281 /* check mechanism */ 2282 if (!dprov_valid_mac_mech(mechanism->cm_type)) { 2283 cmn_err(CE_WARN, "dprov_mac_verify_atomic: unexpected mech " 2284 "type 0x%llx\n", (unsigned long long)mechanism->cm_type); 2285 return (CRYPTO_MECHANISM_INVALID); 2286 } 2287 2288 /* submit request to the taskq */ 2289 error = dprov_mac_submit_req(DPROV_REQ_MAC_VERIFY_ATOMIC, softc, req, 2290 mechanism, data, key, mac, NULL, session_id, KM_SLEEP); 2291 2292 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_verify_atomic: done err = 0x0%x\n", 2293 instance, error)); 2294 2295 return (error); 2296 } 2297 2298 /* 2299 * Cipher (encrypt/decrypt) entry points. 2300 */ 2301 2302 /* 2303 * Checks whether the specified mech_type is supported by cipher entry 2304 * points. 2305 */ 2306 static boolean_t 2307 dprov_valid_cipher_mech(crypto_mech_type_t mech_type) 2308 { 2309 return (mech_type == DES_CBC_MECH_INFO_TYPE || 2310 mech_type == DES3_CBC_MECH_INFO_TYPE || 2311 mech_type == DES_ECB_MECH_INFO_TYPE || 2312 mech_type == DES3_ECB_MECH_INFO_TYPE || 2313 mech_type == BLOWFISH_CBC_MECH_INFO_TYPE || 2314 mech_type == BLOWFISH_ECB_MECH_INFO_TYPE || 2315 mech_type == AES_CBC_MECH_INFO_TYPE || 2316 mech_type == AES_CMAC_MECH_INFO_TYPE || 2317 mech_type == AES_ECB_MECH_INFO_TYPE || 2318 mech_type == AES_CTR_MECH_INFO_TYPE || 2319 mech_type == AES_CCM_MECH_INFO_TYPE || 2320 mech_type == AES_GCM_MECH_INFO_TYPE || 2321 mech_type == AES_GMAC_MECH_INFO_TYPE || 2322 mech_type == RC4_MECH_INFO_TYPE || 2323 mech_type == RSA_PKCS_MECH_INFO_TYPE || 2324 mech_type == RSA_X_509_MECH_INFO_TYPE || 2325 mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE || 2326 mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE || 2327 mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE || 2328 mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE || 2329 mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE); 2330 } 2331 2332 static boolean_t 2333 is_publickey_mech(crypto_mech_type_t mech_type) 2334 { 2335 return (mech_type == RSA_PKCS_MECH_INFO_TYPE || 2336 mech_type == RSA_X_509_MECH_INFO_TYPE || 2337 mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE || 2338 mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE || 2339 mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE || 2340 mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE || 2341 mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE || 2342 mech_type == ECDSA_SHA1_MECH_INFO_TYPE || 2343 mech_type == ECDSA_MECH_INFO_TYPE); 2344 } 2345 2346 2347 /* ARGSUSED */ 2348 static int 2349 dprov_encrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 2350 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 2351 crypto_req_handle_t req) 2352 { 2353 int error = CRYPTO_FAILED; 2354 dprov_state_t *softc; 2355 /* LINTED E_FUNC_SET_NOT_USED */ 2356 int instance; 2357 2358 /* extract softc and instance number from context */ 2359 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2360 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_init: started\n", 2361 instance)); 2362 2363 /* check mechanism */ 2364 if (!dprov_valid_cipher_mech(mechanism->cm_type)) { 2365 cmn_err(CE_WARN, "dprov_encrypt_init: unexpected mech type " 2366 "0x%llx\n", (unsigned long long)mechanism->cm_type); 2367 return (CRYPTO_MECHANISM_INVALID); 2368 } 2369 2370 /* submit request to the taskq */ 2371 error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_INIT, softc, 2372 req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP); 2373 2374 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_init: done err = 0x0%x\n", 2375 instance, error)); 2376 2377 return (error); 2378 } 2379 2380 /* ARGSUSED */ 2381 static int 2382 dprov_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext, 2383 crypto_data_t *ciphertext, crypto_req_handle_t req) 2384 { 2385 int error = CRYPTO_FAILED; 2386 dprov_state_t *softc; 2387 /* LINTED E_FUNC_SET_NOT_USED */ 2388 int instance; 2389 2390 /* extract softc and instance number from context */ 2391 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2392 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt: started\n", instance)); 2393 2394 /* submit request to the taskq */ 2395 error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT, softc, 2396 req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP); 2397 2398 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt: done err = 0x0%x\n", 2399 instance, error)); 2400 2401 return (error); 2402 } 2403 2404 /* ARGSUSED */ 2405 static int 2406 dprov_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext, 2407 crypto_data_t *ciphertext, crypto_req_handle_t req) 2408 { 2409 int error = CRYPTO_FAILED; 2410 dprov_state_t *softc; 2411 /* LINTED E_FUNC_SET_NOT_USED */ 2412 int instance; 2413 2414 /* extract softc and instance number from context */ 2415 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2416 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_update: started\n", 2417 instance)); 2418 2419 /* submit request to the taskq */ 2420 error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_UPDATE, softc, 2421 req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP); 2422 2423 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_update: done err = 0x0%x\n", 2424 instance, error)); 2425 2426 return (error); 2427 } 2428 2429 /* ARGSUSED */ 2430 static int 2431 dprov_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *ciphertext, 2432 crypto_req_handle_t req) 2433 { 2434 int error = CRYPTO_FAILED; 2435 dprov_state_t *softc; 2436 /* LINTED E_FUNC_SET_NOT_USED */ 2437 int instance; 2438 2439 /* extract softc and instance number from context */ 2440 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2441 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_final: started\n", 2442 instance)); 2443 2444 /* submit request to the taskq */ 2445 error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_FINAL, softc, 2446 req, NULL, NULL, NULL, ciphertext, ctx, 0, KM_NOSLEEP); 2447 2448 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_final: done err = 0x0%x\n", 2449 instance, error)); 2450 2451 return (error); 2452 } 2453 2454 static int 2455 dprov_encrypt_atomic(crypto_provider_handle_t provider, 2456 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 2457 crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext, 2458 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 2459 { 2460 int error = CRYPTO_FAILED; 2461 dprov_state_t *softc = (dprov_state_t *)provider; 2462 /* LINTED E_FUNC_SET_NOT_USED */ 2463 int instance; 2464 2465 instance = ddi_get_instance(softc->ds_dip); 2466 DPROV_DEBUG(D_MAC, ("(%d) dprov_encrypt_atomic: started\n", instance)); 2467 2468 if (ctx_template != NULL) 2469 return (CRYPTO_ARGUMENTS_BAD); 2470 2471 /* check mechanism */ 2472 if (!dprov_valid_cipher_mech(mechanism->cm_type)) { 2473 cmn_err(CE_WARN, "dprov_encrypt_atomic: unexpected mech type " 2474 "0x%llx\n", (unsigned long long)mechanism->cm_type); 2475 return (CRYPTO_MECHANISM_INVALID); 2476 } 2477 2478 error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_ATOMIC, softc, 2479 req, mechanism, key, plaintext, ciphertext, NULL, session_id, 2480 KM_SLEEP); 2481 2482 DPROV_DEBUG(D_MAC, ("(%d) dprov_encrypt_atomic: done err = 0x0%x\n", 2483 instance, error)); 2484 2485 return (error); 2486 } 2487 2488 /* ARGSUSED */ 2489 static int 2490 dprov_decrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 2491 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 2492 crypto_req_handle_t req) 2493 { 2494 int error = CRYPTO_FAILED; 2495 dprov_state_t *softc; 2496 /* LINTED E_FUNC_SET_NOT_USED */ 2497 int instance; 2498 2499 /* extract softc and instance number from context */ 2500 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2501 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_init: started\n", 2502 instance)); 2503 2504 /* check mechanism */ 2505 if (!dprov_valid_cipher_mech(mechanism->cm_type)) { 2506 cmn_err(CE_WARN, "dprov_decrypt_init: unexpected mech type " 2507 "0x%llx\n", (unsigned long long)mechanism->cm_type); 2508 return (CRYPTO_MECHANISM_INVALID); 2509 } 2510 2511 /* submit request to the taskq */ 2512 error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_INIT, softc, 2513 req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP); 2514 2515 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_init: done err = 0x0%x\n", 2516 instance, error)); 2517 2518 return (error); 2519 } 2520 2521 /* ARGSUSED */ 2522 static int 2523 dprov_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext, 2524 crypto_data_t *plaintext, crypto_req_handle_t req) 2525 { 2526 int error = CRYPTO_FAILED; 2527 2528 dprov_state_t *softc; 2529 /* LINTED E_FUNC_SET_NOT_USED */ 2530 int instance; 2531 2532 /* extract softc and instance number from context */ 2533 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2534 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt: started\n", instance)); 2535 2536 /* submit request to the taskq */ 2537 error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT, softc, 2538 req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP); 2539 2540 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt: done err = 0x0%x\n", 2541 instance, error)); 2542 2543 return (error); 2544 } 2545 2546 /* ARGSUSED */ 2547 static int 2548 dprov_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext, 2549 crypto_data_t *plaintext, crypto_req_handle_t req) 2550 { 2551 int error = CRYPTO_FAILED; 2552 dprov_state_t *softc; 2553 /* LINTED E_FUNC_SET_NOT_USED */ 2554 int instance; 2555 2556 /* extract softc and instance number from context */ 2557 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2558 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_update: started\n", 2559 instance)); 2560 2561 /* submit request to the taskq */ 2562 error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_UPDATE, softc, 2563 req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP); 2564 2565 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_update: done err = 0x0%x\n", 2566 instance, error)); 2567 2568 return (error); 2569 } 2570 2571 /* ARGSUSED */ 2572 static int 2573 dprov_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *plaintext, 2574 crypto_req_handle_t req) 2575 { 2576 int error = CRYPTO_FAILED; 2577 dprov_state_t *softc; 2578 /* LINTED E_FUNC_SET_NOT_USED */ 2579 int instance; 2580 2581 /* extract softc and instance number from context */ 2582 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2583 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_final: started\n", 2584 instance)); 2585 2586 /* submit request to the taskq */ 2587 error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_FINAL, softc, 2588 req, NULL, NULL, plaintext, NULL, ctx, 0, KM_NOSLEEP); 2589 2590 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_final: done err = 0x0%x\n", 2591 instance, error)); 2592 2593 return (error); 2594 } 2595 2596 static int 2597 dprov_decrypt_atomic(crypto_provider_handle_t provider, 2598 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 2599 crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext, 2600 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 2601 { 2602 int error = CRYPTO_FAILED; 2603 dprov_state_t *softc = (dprov_state_t *)provider; 2604 /* LINTED E_FUNC_SET_NOT_USED */ 2605 int instance; 2606 2607 instance = ddi_get_instance(softc->ds_dip); 2608 DPROV_DEBUG(D_MAC, ("(%d) dprov_decrypt_atomic: started\n", instance)); 2609 2610 if (ctx_template != NULL) 2611 return (CRYPTO_ARGUMENTS_BAD); 2612 2613 /* check mechanism */ 2614 if (!dprov_valid_cipher_mech(mechanism->cm_type)) { 2615 cmn_err(CE_WARN, "dprov_atomic_init: unexpected mech type " 2616 "0x%llx\n", (unsigned long long)mechanism->cm_type); 2617 return (CRYPTO_MECHANISM_INVALID); 2618 } 2619 2620 error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_ATOMIC, softc, 2621 req, mechanism, key, plaintext, ciphertext, NULL, session_id, 2622 KM_SLEEP); 2623 2624 DPROV_DEBUG(D_MAC, ("(%d) dprov_decrypt_atomic: done err = 0x0%x\n", 2625 instance, error)); 2626 2627 return (error); 2628 } 2629 2630 /* 2631 * Sign entry points. 2632 */ 2633 2634 /* 2635 * Checks whether the specified mech_type is supported by sign/verify 2636 * entry points. 2637 */ 2638 static boolean_t 2639 dprov_valid_sign_verif_mech(crypto_mech_type_t mech_type) 2640 { 2641 return (mech_type == MD5_HMAC_MECH_INFO_TYPE || 2642 mech_type == MD5_HMAC_GEN_MECH_INFO_TYPE || 2643 mech_type == SHA1_HMAC_MECH_INFO_TYPE || 2644 mech_type == SHA1_HMAC_GEN_MECH_INFO_TYPE || 2645 mech_type == SHA256_HMAC_MECH_INFO_TYPE || 2646 mech_type == SHA256_HMAC_GEN_MECH_INFO_TYPE || 2647 mech_type == SHA384_HMAC_MECH_INFO_TYPE || 2648 mech_type == SHA384_HMAC_GEN_MECH_INFO_TYPE || 2649 mech_type == SHA512_HMAC_MECH_INFO_TYPE || 2650 mech_type == SHA512_HMAC_GEN_MECH_INFO_TYPE || 2651 mech_type == RSA_PKCS_MECH_INFO_TYPE || 2652 mech_type == RSA_X_509_MECH_INFO_TYPE || 2653 mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE || 2654 mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE || 2655 mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE || 2656 mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE || 2657 mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE || 2658 mech_type == ECDSA_SHA1_MECH_INFO_TYPE || 2659 mech_type == ECDSA_MECH_INFO_TYPE); 2660 } 2661 2662 static int 2663 dprov_sign_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 2664 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 2665 crypto_req_handle_t req) 2666 { 2667 int error = CRYPTO_FAILED; 2668 dprov_state_t *softc; 2669 /* LINTED E_FUNC_SET_NOT_USED */ 2670 int instance; 2671 2672 /* extract softc and instance number from context */ 2673 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2674 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_init: started\n", instance)); 2675 2676 /* check mechanism */ 2677 if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) { 2678 cmn_err(CE_WARN, "dprov_sign_init: unexpected mech type " 2679 "0x%llx\n", (unsigned long long)mechanism->cm_type); 2680 return (CRYPTO_MECHANISM_INVALID); 2681 } 2682 2683 if (ctx_template != NULL) 2684 return (CRYPTO_ARGUMENTS_BAD); 2685 2686 /* submit request to the taskq */ 2687 error = dprov_sign_submit_req(DPROV_REQ_SIGN_INIT, softc, req, 2688 mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP); 2689 2690 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_init: done err = 0x%x\n", 2691 instance, error)); 2692 2693 return (error); 2694 } 2695 2696 static int 2697 dprov_sign(crypto_ctx_t *ctx, crypto_data_t *data, 2698 crypto_data_t *signature, crypto_req_handle_t req) 2699 { 2700 int error = CRYPTO_FAILED; 2701 dprov_state_t *softc; 2702 /* LINTED E_FUNC_SET_NOT_USED */ 2703 int instance; 2704 2705 /* extract softc and instance number from context */ 2706 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2707 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign: started\n", instance)); 2708 2709 /* submit request to the taskq */ 2710 error = dprov_sign_submit_req(DPROV_REQ_SIGN, softc, req, 2711 NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP); 2712 2713 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign: done err = 0x%x\n", 2714 instance, error)); 2715 2716 return (error); 2717 } 2718 2719 static int 2720 dprov_sign_update(crypto_ctx_t *ctx, crypto_data_t *data, 2721 crypto_req_handle_t req) 2722 { 2723 int error = CRYPTO_FAILED; 2724 dprov_state_t *softc; 2725 /* LINTED E_FUNC_SET_NOT_USED */ 2726 int instance; 2727 2728 /* extract softc and instance number from context */ 2729 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2730 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_update: started\n", instance)); 2731 2732 /* submit request to the taskq */ 2733 error = dprov_sign_submit_req(DPROV_REQ_SIGN_UPDATE, softc, req, 2734 NULL, NULL, data, NULL, ctx, 0, KM_NOSLEEP); 2735 2736 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_update: done err = 0x%x\n", 2737 instance, error)); 2738 2739 return (error); 2740 } 2741 2742 static int 2743 dprov_sign_final(crypto_ctx_t *ctx, crypto_data_t *signature, 2744 crypto_req_handle_t req) 2745 { 2746 int error = CRYPTO_FAILED; 2747 dprov_state_t *softc; 2748 /* LINTED E_FUNC_SET_NOT_USED */ 2749 int instance; 2750 2751 /* extract softc and instance number from context */ 2752 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2753 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_final: started\n", instance)); 2754 2755 /* submit request to the taskq */ 2756 error = dprov_sign_submit_req(DPROV_REQ_SIGN_FINAL, softc, req, 2757 NULL, NULL, NULL, signature, ctx, 0, KM_NOSLEEP); 2758 2759 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_final: done err = 0x%x\n", 2760 instance, error)); 2761 2762 return (error); 2763 } 2764 2765 static int 2766 dprov_sign_atomic(crypto_provider_handle_t provider, 2767 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 2768 crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature, 2769 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 2770 { 2771 int error = CRYPTO_FAILED; 2772 dprov_state_t *softc = (dprov_state_t *)provider; 2773 /* LINTED E_FUNC_SET_NOT_USED */ 2774 int instance; 2775 2776 instance = ddi_get_instance(softc->ds_dip); 2777 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_atomic: started\n", instance)); 2778 2779 /* check mechanism */ 2780 if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) { 2781 cmn_err(CE_WARN, "dprov_sign_atomic: unexpected mech type " 2782 "0x%llx\n", (unsigned long long)mechanism->cm_type); 2783 return (CRYPTO_MECHANISM_INVALID); 2784 } 2785 2786 if (ctx_template != NULL) 2787 return (CRYPTO_ARGUMENTS_BAD); 2788 2789 /* submit request to the taskq */ 2790 error = dprov_sign_submit_req(DPROV_REQ_SIGN_ATOMIC, softc, req, 2791 mechanism, key, data, signature, NULL, session_id, KM_SLEEP); 2792 2793 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_atomic: done err = 0x%x\n", 2794 instance, error)); 2795 2796 return (error); 2797 } 2798 2799 static int 2800 dprov_sign_recover_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 2801 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 2802 crypto_req_handle_t req) 2803 { 2804 int error = CRYPTO_FAILED; 2805 dprov_state_t *softc; 2806 /* LINTED E_FUNC_SET_NOT_USED */ 2807 int instance; 2808 2809 /* extract softc and instance number from context */ 2810 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2811 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_init: started\n", 2812 instance)); 2813 2814 if (ctx_template != NULL) 2815 return (CRYPTO_ARGUMENTS_BAD); 2816 2817 /* submit request to the taskq */ 2818 error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER_INIT, softc, req, 2819 mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP); 2820 2821 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_init: done err = 0x%x\n", 2822 instance, error)); 2823 2824 return (error); 2825 } 2826 2827 static int 2828 dprov_sign_recover(crypto_ctx_t *ctx, crypto_data_t *data, 2829 crypto_data_t *signature, crypto_req_handle_t req) 2830 { 2831 int error = CRYPTO_FAILED; 2832 dprov_state_t *softc; 2833 /* LINTED E_FUNC_SET_NOT_USED */ 2834 int instance; 2835 2836 /* extract softc and instance number from context */ 2837 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2838 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover: started\n", instance)); 2839 2840 /* submit request to the taskq */ 2841 error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER, softc, req, 2842 NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP); 2843 2844 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover: done err = 0x%x\n", 2845 instance, error)); 2846 2847 return (error); 2848 } 2849 2850 static int 2851 dprov_sign_recover_atomic(crypto_provider_handle_t provider, 2852 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 2853 crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature, 2854 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 2855 { 2856 int error = CRYPTO_FAILED; 2857 dprov_state_t *softc = (dprov_state_t *)provider; 2858 /* LINTED E_FUNC_SET_NOT_USED */ 2859 int instance; 2860 2861 instance = ddi_get_instance(softc->ds_dip); 2862 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_atomic: started\n", 2863 instance)); 2864 2865 if (ctx_template != NULL) 2866 return (CRYPTO_ARGUMENTS_BAD); 2867 2868 /* submit request to the taskq */ 2869 error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER_ATOMIC, softc, req, 2870 mechanism, key, data, signature, NULL, session_id, KM_SLEEP); 2871 2872 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_atomic: done " 2873 "err = 0x%x\n", instance, error)); 2874 2875 return (error); 2876 } 2877 2878 /* 2879 * Verify entry points. 2880 */ 2881 2882 static int 2883 dprov_verify_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 2884 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 2885 crypto_req_handle_t req) 2886 { 2887 int error = CRYPTO_FAILED; 2888 dprov_state_t *softc; 2889 /* LINTED E_FUNC_SET_NOT_USED */ 2890 int instance; 2891 2892 /* extract softc and instance number from context */ 2893 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2894 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_init: started\n", instance)); 2895 2896 /* check mechanism */ 2897 if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) { 2898 cmn_err(CE_WARN, "dprov_verify_init: unexpected mech type " 2899 "0x%llx\n", (unsigned long long)mechanism->cm_type); 2900 return (CRYPTO_MECHANISM_INVALID); 2901 } 2902 2903 if (ctx_template != NULL) 2904 return (CRYPTO_ARGUMENTS_BAD); 2905 2906 error = dprov_verify_submit_req(DPROV_REQ_VERIFY_INIT, softc, req, 2907 mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP); 2908 2909 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_init: done err = 0x%x\n", 2910 instance, error)); 2911 2912 return (error); 2913 } 2914 2915 static int 2916 dprov_verify(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 2917 crypto_req_handle_t req) 2918 { 2919 int error = CRYPTO_FAILED; 2920 dprov_state_t *softc; 2921 /* LINTED E_FUNC_SET_NOT_USED */ 2922 int instance; 2923 2924 /* extract softc and instance number from context */ 2925 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2926 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify: started\n", instance)); 2927 2928 /* submit request to the taskq */ 2929 error = dprov_verify_submit_req(DPROV_REQ_VERIFY, softc, req, 2930 NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP); 2931 2932 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify: done err = 0x%x\n", 2933 instance, error)); 2934 2935 return (error); 2936 } 2937 2938 static int 2939 dprov_verify_update(crypto_ctx_t *ctx, crypto_data_t *data, 2940 crypto_req_handle_t req) 2941 { 2942 int error = CRYPTO_FAILED; 2943 dprov_state_t *softc; 2944 /* LINTED E_FUNC_SET_NOT_USED */ 2945 int instance; 2946 2947 /* extract softc and instance number from context */ 2948 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2949 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_update: started\n", 2950 instance)); 2951 2952 /* submit request to the taskq */ 2953 error = dprov_verify_submit_req(DPROV_REQ_VERIFY_UPDATE, softc, req, 2954 NULL, NULL, data, NULL, ctx, 0, KM_NOSLEEP); 2955 2956 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_update: done err = 0x%x\n", 2957 instance, error)); 2958 2959 return (error); 2960 } 2961 2962 static int 2963 dprov_verify_final(crypto_ctx_t *ctx, crypto_data_t *signature, 2964 crypto_req_handle_t req) 2965 { 2966 int error = CRYPTO_FAILED; 2967 dprov_state_t *softc; 2968 /* LINTED E_FUNC_SET_NOT_USED */ 2969 int instance; 2970 2971 /* extract softc and instance number from context */ 2972 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 2973 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_final: started\n", instance)); 2974 2975 /* submit request to the taskq */ 2976 error = dprov_verify_submit_req(DPROV_REQ_VERIFY_FINAL, softc, req, 2977 NULL, NULL, NULL, signature, ctx, 0, KM_NOSLEEP); 2978 2979 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_final: done err = 0x%x\n", 2980 instance, error)); 2981 2982 return (error); 2983 } 2984 2985 static int 2986 dprov_verify_atomic(crypto_provider_handle_t provider, 2987 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 2988 crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature, 2989 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 2990 { 2991 int error = CRYPTO_FAILED; 2992 dprov_state_t *softc = (dprov_state_t *)provider; 2993 /* LINTED E_FUNC_SET_NOT_USED */ 2994 int instance; 2995 2996 instance = ddi_get_instance(softc->ds_dip); 2997 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_atomic: started\n", 2998 instance)); 2999 3000 /* check mechanism */ 3001 if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) { 3002 cmn_err(CE_WARN, "dprov_verify_atomic: unexpected mech type " 3003 "0x%llx\n", (unsigned long long)mechanism->cm_type); 3004 return (CRYPTO_MECHANISM_INVALID); 3005 } 3006 3007 if (ctx_template != NULL) 3008 return (CRYPTO_ARGUMENTS_BAD); 3009 3010 /* submit request to the taskq */ 3011 error = dprov_verify_submit_req(DPROV_REQ_VERIFY_ATOMIC, softc, req, 3012 mechanism, key, data, signature, NULL, session_id, KM_SLEEP); 3013 3014 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_atomic: done err = 0x%x\n", 3015 instance, error)); 3016 3017 return (error); 3018 } 3019 3020 static int 3021 dprov_verify_recover_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 3022 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 3023 crypto_req_handle_t req) 3024 { 3025 int error = CRYPTO_FAILED; 3026 dprov_state_t *softc; 3027 /* LINTED E_FUNC_SET_NOT_USED */ 3028 int instance; 3029 3030 /* extract softc and instance number from context */ 3031 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 3032 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_init: started\n", 3033 instance)); 3034 3035 if (ctx_template != NULL) 3036 return (CRYPTO_ARGUMENTS_BAD); 3037 3038 /* submit request to the taskq */ 3039 error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER_INIT, softc, 3040 req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP); 3041 3042 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_init: done " 3043 "err = 0x%x\n", instance, error)); 3044 3045 return (error); 3046 } 3047 3048 static int 3049 dprov_verify_recover(crypto_ctx_t *ctx, crypto_data_t *signature, 3050 crypto_data_t *data, crypto_req_handle_t req) 3051 { 3052 int error = CRYPTO_FAILED; 3053 dprov_state_t *softc; 3054 /* LINTED E_FUNC_SET_NOT_USED */ 3055 int instance; 3056 3057 /* extract softc and instance number from context */ 3058 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 3059 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover: started\n", 3060 instance)); 3061 3062 /* submit request to the taskq */ 3063 error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER, softc, req, 3064 NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP); 3065 3066 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover: done err = 0x%x\n", 3067 instance, error)); 3068 3069 return (error); 3070 } 3071 3072 static int 3073 dprov_verify_recover_atomic(crypto_provider_handle_t provider, 3074 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 3075 crypto_key_t *key, crypto_data_t *signature, crypto_data_t *data, 3076 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 3077 { 3078 int error = CRYPTO_FAILED; 3079 dprov_state_t *softc = (dprov_state_t *)provider; 3080 /* LINTED E_FUNC_SET_NOT_USED */ 3081 int instance; 3082 3083 instance = ddi_get_instance(softc->ds_dip); 3084 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_atomic: started\n", 3085 instance)); 3086 3087 if (ctx_template != NULL) 3088 return (CRYPTO_ARGUMENTS_BAD); 3089 3090 /* submit request to the taskq */ 3091 error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER_ATOMIC, softc, 3092 req, mechanism, key, data, signature, NULL, session_id, KM_SLEEP); 3093 3094 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_atomic: done " 3095 "err = 0x%x\n", instance, error)); 3096 3097 return (error); 3098 } 3099 3100 /* 3101 * Dual operations entry points. 3102 */ 3103 3104 static int 3105 dprov_digest_encrypt_update(crypto_ctx_t *digest_ctx, 3106 crypto_ctx_t *encrypt_ctx, crypto_data_t *plaintext, 3107 crypto_data_t *ciphertext, crypto_req_handle_t req) 3108 { 3109 int error = CRYPTO_FAILED; 3110 dprov_state_t *softc; 3111 /* LINTED E_FUNC_SET_NOT_USED */ 3112 int instance; 3113 3114 /* extract softc and instance number from context */ 3115 DPROV_SOFTC_FROM_CTX(digest_ctx, softc, instance); 3116 DPROV_DEBUG(D_DUAL, ("(%d) dprov_digest_encrypt_update: started\n", 3117 instance)); 3118 3119 if (digest_ctx->cc_provider != encrypt_ctx->cc_provider) 3120 return (CRYPTO_INVALID_CONTEXT); 3121 3122 /* submit request to the taskq */ 3123 error = dprov_dual_submit_req(DPROV_REQ_DIGEST_ENCRYPT_UPDATE, 3124 softc, req, digest_ctx, encrypt_ctx, plaintext, ciphertext); 3125 3126 DPROV_DEBUG(D_DUAL, ("(%d) dprov_digest_encrypt_update: done " 3127 "err = 0x%x\n", instance, error)); 3128 3129 return (error); 3130 } 3131 3132 static int 3133 dprov_decrypt_digest_update(crypto_ctx_t *decrypt_ctx, crypto_ctx_t *digest_ctx, 3134 crypto_data_t *ciphertext, crypto_data_t *plaintext, 3135 crypto_req_handle_t req) 3136 { 3137 int error = CRYPTO_FAILED; 3138 dprov_state_t *softc; 3139 /* LINTED E_FUNC_SET_NOT_USED */ 3140 int instance; 3141 3142 /* extract softc and instance number from context */ 3143 DPROV_SOFTC_FROM_CTX(decrypt_ctx, softc, instance); 3144 DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_digest_update: started\n", 3145 instance)); 3146 3147 if (decrypt_ctx->cc_provider != digest_ctx->cc_provider) 3148 return (CRYPTO_INVALID_CONTEXT); 3149 3150 /* submit request to the taskq */ 3151 error = dprov_dual_submit_req(DPROV_REQ_DECRYPT_DIGEST_UPDATE, 3152 softc, req, digest_ctx, decrypt_ctx, plaintext, ciphertext); 3153 3154 DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_digest_update: done " 3155 "err = 0x%x\n", instance, error)); 3156 3157 return (error); 3158 } 3159 3160 static int 3161 dprov_sign_encrypt_update(crypto_ctx_t *sign_ctx, crypto_ctx_t *encrypt_ctx, 3162 crypto_data_t *plaintext, crypto_data_t *ciphertext, 3163 crypto_req_handle_t req) 3164 { 3165 int error = CRYPTO_FAILED; 3166 dprov_state_t *softc; 3167 /* LINTED E_FUNC_SET_NOT_USED */ 3168 int instance; 3169 3170 /* extract softc and instance number from context */ 3171 DPROV_SOFTC_FROM_CTX(sign_ctx, softc, instance); 3172 DPROV_DEBUG(D_DUAL, ("(%d) dprov_sign_encrypt_update: started\n", 3173 instance)); 3174 3175 if (sign_ctx->cc_provider != encrypt_ctx->cc_provider) 3176 return (CRYPTO_INVALID_CONTEXT); 3177 3178 /* submit request to the taskq */ 3179 error = dprov_dual_submit_req(DPROV_REQ_SIGN_ENCRYPT_UPDATE, 3180 softc, req, sign_ctx, encrypt_ctx, plaintext, ciphertext); 3181 3182 DPROV_DEBUG(D_DUAL, ("(%d) dprov_sign_encrypt_update: done " 3183 "err = 0x%x\n", instance, error)); 3184 3185 return (error); 3186 } 3187 3188 static int 3189 dprov_decrypt_verify_update(crypto_ctx_t *decrypt_ctx, crypto_ctx_t *verify_ctx, 3190 crypto_data_t *ciphertext, crypto_data_t *plaintext, 3191 crypto_req_handle_t req) 3192 { 3193 int error = CRYPTO_FAILED; 3194 dprov_state_t *softc; 3195 /* LINTED E_FUNC_SET_NOT_USED */ 3196 int instance; 3197 3198 /* extract softc and instance number from context */ 3199 DPROV_SOFTC_FROM_CTX(decrypt_ctx, softc, instance); 3200 DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_verify_update: started\n", 3201 instance)); 3202 3203 if (decrypt_ctx->cc_provider != verify_ctx->cc_provider) 3204 return (CRYPTO_INVALID_CONTEXT); 3205 3206 /* submit request to the taskq */ 3207 error = dprov_dual_submit_req(DPROV_REQ_DECRYPT_VERIFY_UPDATE, 3208 softc, req, verify_ctx, decrypt_ctx, plaintext, ciphertext); 3209 3210 DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_verify_update: done " 3211 "err = 0x%x\n", instance, error)); 3212 3213 return (error); 3214 } 3215 3216 /* 3217 * Dual cipher-mac entry points. 3218 */ 3219 3220 static int 3221 dprov_encrypt_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *encrypt_mech, 3222 crypto_key_t *encrypt_key, crypto_mechanism_t *mac_mech, 3223 crypto_key_t *mac_key, crypto_spi_ctx_template_t encr_ctx_template, 3224 crypto_spi_ctx_template_t mac_ctx_template, 3225 crypto_req_handle_t req) 3226 { 3227 int error = CRYPTO_FAILED; 3228 dprov_state_t *softc; 3229 /* LINTED E_FUNC_SET_NOT_USED */ 3230 int instance; 3231 3232 /* extract softc and instance number from context */ 3233 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 3234 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_init: started\n", 3235 instance)); 3236 3237 /* check mechanisms */ 3238 if (!dprov_valid_cipher_mech(encrypt_mech->cm_type)) { 3239 cmn_err(CE_WARN, "dprov_encrypt_mac_init: unexpected encrypt " 3240 "mech type 0x%llx\n", 3241 (unsigned long long)encrypt_mech->cm_type); 3242 return (CRYPTO_MECHANISM_INVALID); 3243 } 3244 if (!dprov_valid_mac_mech(mac_mech->cm_type)) { 3245 cmn_err(CE_WARN, "dprov_encrypt_mac_init: unexpected mac " 3246 "mech type 0x%llx\n", 3247 (unsigned long long)mac_mech->cm_type); 3248 return (CRYPTO_MECHANISM_INVALID); 3249 } 3250 3251 if (encr_ctx_template != NULL || mac_ctx_template != NULL) 3252 return (CRYPTO_ARGUMENTS_BAD); 3253 3254 /* submit request to the taskq */ 3255 error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_INIT, 3256 softc, req, ctx, 0, encrypt_mech, encrypt_key, mac_mech, mac_key, 3257 NULL, NULL, NULL, KM_SLEEP); 3258 3259 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_init: done " 3260 "err = 0x%x\n", instance, error)); 3261 3262 return (error); 3263 } 3264 3265 static int 3266 dprov_encrypt_mac(crypto_ctx_t *ctx, crypto_data_t *plaintext, 3267 crypto_dual_data_t *ciphertext, crypto_data_t *mac, crypto_req_handle_t req) 3268 { 3269 int error = CRYPTO_FAILED; 3270 dprov_state_t *softc; 3271 /* LINTED E_FUNC_SET_NOT_USED */ 3272 int instance; 3273 3274 /* extract softc and instance number from context */ 3275 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 3276 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac: started\n", 3277 instance)); 3278 3279 /* 3280 * submit request to the taskq 3281 * Careful! cihertext/plaintext order inversion 3282 */ 3283 error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC, 3284 softc, req, ctx, 0, NULL, NULL, NULL, NULL, 3285 ciphertext, plaintext, mac, KM_NOSLEEP); 3286 3287 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac: done " 3288 "err = 0x%x\n", instance, error)); 3289 3290 return (error); 3291 } 3292 3293 static int 3294 dprov_encrypt_mac_update(crypto_ctx_t *ctx, crypto_data_t *plaintext, 3295 crypto_dual_data_t *ciphertext, crypto_req_handle_t req) 3296 { 3297 int error = CRYPTO_FAILED; 3298 dprov_state_t *softc; 3299 /* LINTED E_FUNC_SET_NOT_USED */ 3300 int instance; 3301 3302 /* extract softc and instance number from context */ 3303 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 3304 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_update: started\n", 3305 instance)); 3306 3307 /* submit request to the taskq */ 3308 error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_UPDATE, 3309 softc, req, ctx, 0, NULL, NULL, NULL, NULL, 3310 ciphertext, plaintext, NULL, KM_NOSLEEP); 3311 3312 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_update: done " 3313 "err = 0x%x\n", instance, error)); 3314 3315 return (error); 3316 } 3317 3318 static int 3319 dprov_encrypt_mac_final(crypto_ctx_t *ctx, 3320 crypto_dual_data_t *ciphertext, crypto_data_t *mac, 3321 crypto_req_handle_t req) 3322 { 3323 int error = CRYPTO_FAILED; 3324 dprov_state_t *softc; 3325 /* LINTED E_FUNC_SET_NOT_USED */ 3326 int instance; 3327 3328 /* extract softc and instance number from context */ 3329 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 3330 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_final: started\n", 3331 instance)); 3332 3333 /* submit request to the taskq */ 3334 error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_FINAL, 3335 softc, req, ctx, 0, NULL, NULL, NULL, NULL, 3336 ciphertext, NULL, mac, KM_NOSLEEP); 3337 3338 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_final: done " 3339 "err = 0x%x\n", instance, error)); 3340 3341 return (error); 3342 } 3343 3344 static int 3345 dprov_encrypt_mac_atomic(crypto_provider_handle_t provider, 3346 crypto_session_id_t session_id, crypto_mechanism_t *encrypt_mech, 3347 crypto_key_t *encrypt_key, crypto_mechanism_t *mac_mech, 3348 crypto_key_t *mac_key, crypto_data_t *plaintext, 3349 crypto_dual_data_t *ciphertext, crypto_data_t *mac, 3350 crypto_spi_ctx_template_t encr_ctx_template, 3351 crypto_spi_ctx_template_t mac_ctx_template, 3352 crypto_req_handle_t req) 3353 { 3354 int error = CRYPTO_FAILED; 3355 dprov_state_t *softc = (dprov_state_t *)provider; 3356 /* LINTED E_FUNC_SET_NOT_USED */ 3357 int instance; 3358 3359 instance = ddi_get_instance(softc->ds_dip); 3360 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_atomic: started\n", 3361 instance)); 3362 3363 /* check mechanisms */ 3364 if (!dprov_valid_cipher_mech(encrypt_mech->cm_type)) { 3365 cmn_err(CE_WARN, "dprov_encrypt_mac_atomic: unexpected encrypt " 3366 "mech type 0x%llx\n", 3367 (unsigned long long)encrypt_mech->cm_type); 3368 return (CRYPTO_MECHANISM_INVALID); 3369 } 3370 if (!dprov_valid_mac_mech(mac_mech->cm_type)) { 3371 cmn_err(CE_WARN, "dprov_encrypt_mac_atomic: unexpected mac " 3372 "mech type 0x%llx\n", 3373 (unsigned long long)mac_mech->cm_type); 3374 return (CRYPTO_MECHANISM_INVALID); 3375 } 3376 3377 if (encr_ctx_template != NULL || mac_ctx_template != NULL) 3378 return (CRYPTO_ARGUMENTS_BAD); 3379 3380 /* submit request to the taskq */ 3381 error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_ATOMIC, 3382 softc, req, NULL, session_id, encrypt_mech, encrypt_key, mac_mech, 3383 mac_key, ciphertext, plaintext, mac, KM_SLEEP); 3384 3385 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_atomic: done " 3386 "err = 0x%x\n", instance, error)); 3387 3388 return (error); 3389 } 3390 3391 static int 3392 dprov_mac_decrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mac_mech, 3393 crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech, 3394 crypto_key_t *decrypt_key, crypto_spi_ctx_template_t mac_ctx_template, 3395 crypto_spi_ctx_template_t decr_ctx_template, 3396 crypto_req_handle_t req) 3397 { 3398 int error = CRYPTO_FAILED; 3399 dprov_state_t *softc; 3400 /* LINTED E_FUNC_SET_NOT_USED */ 3401 int instance; 3402 3403 /* extract softc and instance number from context */ 3404 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 3405 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_init: started\n", 3406 instance)); 3407 3408 /* check mechanisms */ 3409 if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) { 3410 cmn_err(CE_WARN, "dprov_mac_decrypt_init: unexpected decrypt " 3411 "mech type 0x%llx\n", 3412 (unsigned long long)decrypt_mech->cm_type); 3413 return (CRYPTO_MECHANISM_INVALID); 3414 } 3415 if (!dprov_valid_mac_mech(mac_mech->cm_type)) { 3416 cmn_err(CE_WARN, "dprov_mac_decrypt_init: unexpected mac " 3417 "mech type 0x%llx\n", 3418 (unsigned long long)mac_mech->cm_type); 3419 return (CRYPTO_MECHANISM_INVALID); 3420 } 3421 3422 if (decr_ctx_template != NULL || mac_ctx_template != NULL) 3423 return (CRYPTO_ARGUMENTS_BAD); 3424 3425 /* submit request to the taskq */ 3426 error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_INIT, 3427 softc, req, ctx, 0, decrypt_mech, decrypt_key, mac_mech, mac_key, 3428 NULL, NULL, NULL, KM_SLEEP); 3429 3430 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_init: done " 3431 "err = 0x%x\n", instance, error)); 3432 3433 return (error); 3434 } 3435 3436 static int 3437 dprov_mac_decrypt(crypto_ctx_t *ctx, crypto_dual_data_t *ciphertext, 3438 crypto_data_t *mac, crypto_data_t *plaintext, crypto_req_handle_t req) 3439 { 3440 int error = CRYPTO_FAILED; 3441 dprov_state_t *softc; 3442 /* LINTED E_FUNC_SET_NOT_USED */ 3443 int instance; 3444 3445 /* extract softc and instance number from context */ 3446 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 3447 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt: started\n", 3448 instance)); 3449 3450 /* submit request to the taskq */ 3451 error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT, 3452 softc, req, ctx, 0, NULL, NULL, NULL, NULL, 3453 ciphertext, plaintext, mac, KM_NOSLEEP); 3454 3455 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt: done " 3456 "err = 0x%x\n", instance, error)); 3457 3458 return (error); 3459 } 3460 3461 static int 3462 dprov_mac_decrypt_update(crypto_ctx_t *ctx, crypto_dual_data_t *ciphertext, 3463 crypto_data_t *plaintext, crypto_req_handle_t req) 3464 { 3465 int error = CRYPTO_FAILED; 3466 dprov_state_t *softc; 3467 /* LINTED E_FUNC_SET_NOT_USED */ 3468 int instance; 3469 3470 /* extract softc and instance number from context */ 3471 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 3472 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_update: started\n", 3473 instance)); 3474 3475 /* submit request to the taskq */ 3476 error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_UPDATE, 3477 softc, req, ctx, 0, NULL, NULL, NULL, NULL, 3478 ciphertext, plaintext, NULL, KM_NOSLEEP); 3479 3480 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_update: done " 3481 "err = 0x%x\n", instance, error)); 3482 3483 return (error); 3484 } 3485 3486 static int 3487 dprov_mac_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *mac, 3488 crypto_data_t *plaintext, crypto_req_handle_t req) 3489 { 3490 int error = CRYPTO_FAILED; 3491 dprov_state_t *softc; 3492 /* LINTED E_FUNC_SET_NOT_USED */ 3493 int instance; 3494 3495 /* extract softc and instance number from context */ 3496 DPROV_SOFTC_FROM_CTX(ctx, softc, instance); 3497 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_final: started\n", 3498 instance)); 3499 3500 /* submit request to the taskq */ 3501 error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_FINAL, 3502 softc, req, ctx, 0, NULL, NULL, NULL, NULL, 3503 NULL, plaintext, mac, KM_NOSLEEP); 3504 3505 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_final: done " 3506 "err = 0x%x\n", instance, error)); 3507 3508 return (error); 3509 } 3510 3511 static int 3512 dprov_mac_decrypt_atomic(crypto_provider_handle_t provider, 3513 crypto_session_id_t session_id, crypto_mechanism_t *mac_mech, 3514 crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech, 3515 crypto_key_t *decrypt_key, crypto_dual_data_t *ciphertext, 3516 crypto_data_t *mac, crypto_data_t *plaintext, 3517 crypto_spi_ctx_template_t mac_ctx_template, 3518 crypto_spi_ctx_template_t decr_ctx_template, 3519 crypto_req_handle_t req) 3520 { 3521 int error = CRYPTO_FAILED; 3522 dprov_state_t *softc = (dprov_state_t *)provider; 3523 /* LINTED E_FUNC_SET_NOT_USED */ 3524 int instance; 3525 3526 instance = ddi_get_instance(softc->ds_dip); 3527 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_atomic: started\n", 3528 instance)); 3529 3530 /* check mechanisms */ 3531 if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) { 3532 cmn_err(CE_WARN, "dprov_mac_decrypt_atomic: unexpected encrypt " 3533 "mech type 0x%llx\n", 3534 (unsigned long long)decrypt_mech->cm_type); 3535 return (CRYPTO_MECHANISM_INVALID); 3536 } 3537 if (!dprov_valid_mac_mech(mac_mech->cm_type)) { 3538 cmn_err(CE_WARN, "dprov_mac_decrypt_atomic: unexpected mac " 3539 "mech type 0x%llx\n", 3540 (unsigned long long)mac_mech->cm_type); 3541 return (CRYPTO_MECHANISM_INVALID); 3542 } 3543 3544 if (decr_ctx_template != NULL || mac_ctx_template != NULL) 3545 return (CRYPTO_ARGUMENTS_BAD); 3546 3547 /* submit request to the taskq */ 3548 error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_ATOMIC, 3549 softc, req, NULL, session_id, decrypt_mech, decrypt_key, mac_mech, 3550 mac_key, ciphertext, plaintext, mac, KM_SLEEP); 3551 3552 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_atomic: done " 3553 "err = 0x%x\n", instance, error)); 3554 3555 return (error); 3556 } 3557 3558 static int 3559 dprov_mac_verify_decrypt_atomic(crypto_provider_handle_t provider, 3560 crypto_session_id_t session_id, crypto_mechanism_t *mac_mech, 3561 crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech, 3562 crypto_key_t *decrypt_key, crypto_dual_data_t *ciphertext, 3563 crypto_data_t *mac, crypto_data_t *plaintext, 3564 crypto_spi_ctx_template_t mac_ctx_template, 3565 crypto_spi_ctx_template_t decr_ctx_template, 3566 crypto_req_handle_t req) 3567 { 3568 int error = CRYPTO_FAILED; 3569 dprov_state_t *softc = (dprov_state_t *)provider; 3570 /* LINTED E_FUNC_SET_NOT_USED */ 3571 int instance; 3572 3573 instance = ddi_get_instance(softc->ds_dip); 3574 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_verify_decrypt_atomic:" 3575 "started\n", instance)); 3576 3577 /* check mechanisms */ 3578 if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) { 3579 cmn_err(CE_WARN, "dprov_mac_verify_decrypt_atomic: " 3580 "unexpected encrypt mech type 0x%llx\n", 3581 (unsigned long long)decrypt_mech->cm_type); 3582 return (CRYPTO_MECHANISM_INVALID); 3583 } 3584 if (!dprov_valid_mac_mech(mac_mech->cm_type)) { 3585 cmn_err(CE_WARN, "dprov_mac_verify_decrypt_atomic: " 3586 "unexpected mac mech type 0x%llx\n", 3587 (unsigned long long)mac_mech->cm_type); 3588 return (CRYPTO_MECHANISM_INVALID); 3589 } 3590 3591 if (decr_ctx_template != NULL || mac_ctx_template != NULL) 3592 return (CRYPTO_ARGUMENTS_BAD); 3593 3594 /* submit request to the taskq */ 3595 error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC, 3596 softc, req, NULL, session_id, decrypt_mech, decrypt_key, mac_mech, 3597 mac_key, ciphertext, plaintext, mac, KM_SLEEP); 3598 3599 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_verify_decrypt_atomic: done " 3600 "err = 0x%x\n", instance, error)); 3601 3602 return (error); 3603 } 3604 3605 /* 3606 * Random number entry points. 3607 */ 3608 3609 static int 3610 dprov_seed_random(crypto_provider_handle_t provider, crypto_session_id_t sid, 3611 uchar_t *buf, size_t len, uint_t entropy_est, uint32_t flags, 3612 crypto_req_handle_t req) 3613 { 3614 int error = CRYPTO_FAILED; 3615 dprov_state_t *softc = (dprov_state_t *)provider; 3616 /* LINTED E_FUNC_SET_NOT_USED */ 3617 int instance; 3618 3619 instance = ddi_get_instance(softc->ds_dip); 3620 DPROV_DEBUG(D_RANDOM, ("(%d) dprov_seed_random: started\n", 3621 instance)); 3622 3623 error = dprov_random_submit_req(DPROV_REQ_RANDOM_SEED, softc, 3624 req, buf, len, sid, entropy_est, flags); 3625 3626 DPROV_DEBUG(D_RANDOM, ("(%d) dprov_seed_random: done err = 0x0%x\n", 3627 instance, error)); 3628 3629 return (error); 3630 } 3631 3632 static int 3633 dprov_generate_random(crypto_provider_handle_t provider, 3634 crypto_session_id_t sid, uchar_t *buf, size_t len, crypto_req_handle_t req) 3635 { 3636 int error = CRYPTO_FAILED; 3637 dprov_state_t *softc = (dprov_state_t *)provider; 3638 /* LINTED E_FUNC_SET_NOT_USED */ 3639 int instance; 3640 3641 instance = ddi_get_instance(softc->ds_dip); 3642 DPROV_DEBUG(D_RANDOM, ("(%d) dprov_generate_random: started\n", 3643 instance)); 3644 3645 error = dprov_random_submit_req(DPROV_REQ_RANDOM_GENERATE, softc, 3646 req, buf, len, sid, 0, 0); 3647 3648 DPROV_DEBUG(D_RANDOM, ("(%d) dprov_generate_random: done " 3649 "err = 0x0%x\n", instance, error)); 3650 3651 return (error); 3652 } 3653 3654 /* 3655 * Session Management entry points. 3656 */ 3657 3658 static int 3659 dprov_session_open(crypto_provider_handle_t provider, 3660 crypto_session_id_t *session_id, crypto_req_handle_t req) 3661 { 3662 int error = CRYPTO_FAILED; 3663 dprov_state_t *softc = (dprov_state_t *)provider; 3664 /* LINTED E_FUNC_SET_NOT_USED */ 3665 int instance; 3666 3667 instance = ddi_get_instance(softc->ds_dip); 3668 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_open: started\n", 3669 instance)); 3670 3671 error = dprov_session_submit_req(DPROV_REQ_SESSION_OPEN, softc, 3672 req, session_id, 0, 0, NULL, 0); 3673 3674 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_open: done err = 0x0%x\n", 3675 instance, error)); 3676 3677 return (error); 3678 } 3679 3680 static int 3681 dprov_session_close(crypto_provider_handle_t provider, 3682 crypto_session_id_t session_id, crypto_req_handle_t req) 3683 { 3684 int error = CRYPTO_FAILED; 3685 dprov_state_t *softc = (dprov_state_t *)provider; 3686 /* LINTED E_FUNC_SET_NOT_USED */ 3687 int instance; 3688 3689 instance = ddi_get_instance(softc->ds_dip); 3690 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_close: started\n", 3691 instance)); 3692 3693 error = dprov_session_submit_req(DPROV_REQ_SESSION_CLOSE, softc, 3694 req, 0, session_id, 0, NULL, 0); 3695 3696 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_close: done err = 0x0%x\n", 3697 instance, error)); 3698 3699 return (error); 3700 } 3701 3702 static int 3703 dprov_session_login(crypto_provider_handle_t provider, 3704 crypto_session_id_t session_id, crypto_user_type_t user_type, 3705 char *pin, size_t pin_len, crypto_req_handle_t req) 3706 { 3707 int error = CRYPTO_FAILED; 3708 dprov_state_t *softc = (dprov_state_t *)provider; 3709 /* LINTED E_FUNC_SET_NOT_USED */ 3710 int instance; 3711 3712 instance = ddi_get_instance(softc->ds_dip); 3713 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_login: started\n", 3714 instance)); 3715 3716 error = dprov_session_submit_req(DPROV_REQ_SESSION_LOGIN, softc, 3717 req, 0, session_id, user_type, pin, pin_len); 3718 3719 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_login: done err = 0x0%x\n", 3720 instance, error)); 3721 3722 return (error); 3723 } 3724 3725 static int 3726 dprov_session_logout(crypto_provider_handle_t provider, 3727 crypto_session_id_t session_id, crypto_req_handle_t req) 3728 { 3729 int error = CRYPTO_FAILED; 3730 dprov_state_t *softc = (dprov_state_t *)provider; 3731 /* LINTED E_FUNC_SET_NOT_USED */ 3732 int instance; 3733 3734 instance = ddi_get_instance(softc->ds_dip); 3735 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_logout: started\n", 3736 instance)); 3737 3738 error = dprov_session_submit_req(DPROV_REQ_SESSION_LOGOUT, softc, 3739 req, 0, session_id, 0, NULL, 0); 3740 3741 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_logout: done err = 0x0%x\n", 3742 instance, error)); 3743 3744 return (error); 3745 } 3746 3747 /* 3748 * Object management entry points. 3749 */ 3750 3751 static int 3752 dprov_object_create(crypto_provider_handle_t provider, 3753 crypto_session_id_t session_id, crypto_object_attribute_t *template, 3754 uint_t attribute_count, crypto_object_id_t *object, 3755 crypto_req_handle_t req) 3756 { 3757 int error = CRYPTO_FAILED; 3758 dprov_state_t *softc = (dprov_state_t *)provider; 3759 /* LINTED E_FUNC_SET_NOT_USED */ 3760 int instance; 3761 3762 instance = ddi_get_instance(softc->ds_dip); 3763 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_create: started\n", 3764 instance)); 3765 3766 /* submit request to the taskq */ 3767 error = dprov_object_submit_req(DPROV_REQ_OBJECT_CREATE, softc, req, 3768 session_id, 0, template, attribute_count, object, NULL, NULL, 3769 NULL, 0, NULL, KM_NOSLEEP); 3770 3771 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_create: done err = 0x0%x\n", 3772 instance, error)); 3773 3774 return (error); 3775 } 3776 3777 static int 3778 dprov_object_copy(crypto_provider_handle_t provider, 3779 crypto_session_id_t session_id, crypto_object_id_t object, 3780 crypto_object_attribute_t *template, uint_t attribute_count, 3781 crypto_object_id_t *new_object, crypto_req_handle_t req) 3782 { 3783 int error = CRYPTO_FAILED; 3784 dprov_state_t *softc = (dprov_state_t *)provider; 3785 /* LINTED E_FUNC_SET_NOT_USED */ 3786 int instance; 3787 3788 instance = ddi_get_instance(softc->ds_dip); 3789 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_copy: started\n", 3790 instance)); 3791 3792 /* submit request to the taskq */ 3793 error = dprov_object_submit_req(DPROV_REQ_OBJECT_COPY, softc, req, 3794 session_id, object, template, attribute_count, new_object, 3795 NULL, NULL, NULL, 0, NULL, KM_NOSLEEP); 3796 3797 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_copy: done err = 0x0%x\n", 3798 instance, error)); 3799 3800 return (error); 3801 } 3802 3803 static int 3804 dprov_object_destroy(crypto_provider_handle_t provider, 3805 crypto_session_id_t session_id, crypto_object_id_t object, 3806 crypto_req_handle_t req) 3807 { 3808 int error = CRYPTO_FAILED; 3809 dprov_state_t *softc = (dprov_state_t *)provider; 3810 /* LINTED E_FUNC_SET_NOT_USED */ 3811 int instance; 3812 3813 instance = ddi_get_instance(softc->ds_dip); 3814 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_destroy: started\n", 3815 instance)); 3816 3817 /* submit request to the taskq */ 3818 error = dprov_object_submit_req(DPROV_REQ_OBJECT_DESTROY, softc, req, 3819 session_id, object, NULL, 0, NULL, NULL, NULL, NULL, 0, NULL, 3820 KM_NOSLEEP); 3821 3822 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_destroy: done err = 0x0%x\n", 3823 instance, error)); 3824 3825 return (error); 3826 } 3827 3828 static int 3829 dprov_object_get_size(crypto_provider_handle_t provider, 3830 crypto_session_id_t session_id, crypto_object_id_t object, 3831 size_t *size, crypto_req_handle_t req) 3832 { 3833 int error = CRYPTO_FAILED; 3834 dprov_state_t *softc = (dprov_state_t *)provider; 3835 /* LINTED E_FUNC_SET_NOT_USED */ 3836 int instance; 3837 3838 instance = ddi_get_instance(softc->ds_dip); 3839 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_size: started\n", 3840 instance)); 3841 3842 /* submit request to the taskq */ 3843 error = dprov_object_submit_req(DPROV_REQ_OBJECT_GET_SIZE, softc, req, 3844 session_id, object, NULL, 0, NULL, size, NULL, NULL, 0, NULL, 3845 KM_NOSLEEP); 3846 3847 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_size: done err = 0x0%x\n", 3848 instance, error)); 3849 3850 return (error); 3851 } 3852 3853 static int 3854 dprov_object_get_attribute_value(crypto_provider_handle_t provider, 3855 crypto_session_id_t session_id, crypto_object_id_t object, 3856 crypto_object_attribute_t *template, uint_t attribute_count, 3857 crypto_req_handle_t req) 3858 { 3859 int error = CRYPTO_FAILED; 3860 dprov_state_t *softc = (dprov_state_t *)provider; 3861 /* LINTED E_FUNC_SET_NOT_USED */ 3862 int instance; 3863 3864 instance = ddi_get_instance(softc->ds_dip); 3865 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_attribute_value: " 3866 "started\n", instance)); 3867 3868 /* submit request to the taskq */ 3869 error = dprov_object_submit_req(DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE, 3870 softc, req, session_id, object, template, attribute_count, 3871 NULL, NULL, NULL, NULL, 0, NULL, KM_NOSLEEP); 3872 3873 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_attribute_value: " 3874 "done err = 0x0%x\n", instance, error)); 3875 3876 return (error); 3877 } 3878 3879 static int 3880 dprov_object_set_attribute_value(crypto_provider_handle_t provider, 3881 crypto_session_id_t session_id, crypto_object_id_t object, 3882 crypto_object_attribute_t *template, uint_t attribute_count, 3883 crypto_req_handle_t req) 3884 { 3885 int error = CRYPTO_FAILED; 3886 dprov_state_t *softc = (dprov_state_t *)provider; 3887 /* LINTED E_FUNC_SET_NOT_USED */ 3888 int instance; 3889 3890 instance = ddi_get_instance(softc->ds_dip); 3891 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_set_attribute_value: " 3892 "started\n", instance)); 3893 3894 /* submit request to the taskq */ 3895 error = dprov_object_submit_req(DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE, 3896 softc, req, session_id, object, template, attribute_count, 3897 NULL, NULL, NULL, NULL, 0, NULL, KM_NOSLEEP); 3898 3899 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_set_attribute_value: " 3900 "done err = 0x0%x\n", instance, error)); 3901 3902 return (error); 3903 } 3904 3905 static int 3906 dprov_object_find_init(crypto_provider_handle_t provider, 3907 crypto_session_id_t session_id, crypto_object_attribute_t *template, 3908 uint_t attribute_count, void **provider_private, 3909 crypto_req_handle_t req) 3910 { 3911 int error = CRYPTO_FAILED; 3912 dprov_state_t *softc = (dprov_state_t *)provider; 3913 /* LINTED E_FUNC_SET_NOT_USED */ 3914 int instance; 3915 3916 instance = ddi_get_instance(softc->ds_dip); 3917 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_init: started\n", 3918 instance)); 3919 3920 /* submit request to the taskq */ 3921 error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND_INIT, softc, req, 3922 session_id, 0, template, attribute_count, NULL, NULL, 3923 provider_private, NULL, 0, NULL, KM_SLEEP); 3924 3925 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_init: done " 3926 "err = 0x0%x\n", instance, error)); 3927 3928 return (error); 3929 } 3930 3931 static int 3932 dprov_object_find(crypto_provider_handle_t provider, void *provider_private, 3933 crypto_object_id_t *objects, uint_t max_object_count, 3934 uint_t *object_count, crypto_req_handle_t req) 3935 { 3936 int error = CRYPTO_FAILED; 3937 dprov_state_t *softc = (dprov_state_t *)provider; 3938 /* LINTED E_FUNC_SET_NOT_USED */ 3939 int instance; 3940 3941 instance = ddi_get_instance(softc->ds_dip); 3942 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find: started\n", 3943 instance)); 3944 3945 /* submit request to the taskq */ 3946 error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND, softc, req, 3947 0, 0, NULL, 0, objects, NULL, NULL, provider_private, 3948 max_object_count, object_count, KM_NOSLEEP); 3949 3950 3951 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find: done err = 0x0%x\n", 3952 instance, error)); 3953 3954 return (error); 3955 } 3956 3957 static int 3958 dprov_object_find_final(crypto_provider_handle_t provider, 3959 void *provider_private, crypto_req_handle_t req) 3960 { 3961 int error = CRYPTO_FAILED; 3962 dprov_state_t *softc = (dprov_state_t *)provider; 3963 /* LINTED E_FUNC_SET_NOT_USED */ 3964 int instance; 3965 3966 instance = ddi_get_instance(softc->ds_dip); 3967 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_final: started\n", 3968 instance)); 3969 3970 /* submit request to the taskq */ 3971 error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND_FINAL, softc, req, 3972 0, 0, NULL, 0, NULL, NULL, NULL, provider_private, 3973 0, NULL, KM_NOSLEEP); 3974 3975 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_final: done " 3976 "err = 0x0%x\n", instance, error)); 3977 3978 return (error); 3979 } 3980 3981 /* 3982 * Key management entry points. 3983 */ 3984 3985 static int 3986 dprov_key_generate(crypto_provider_handle_t provider, 3987 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 3988 crypto_object_attribute_t *template, uint_t attribute_count, 3989 crypto_object_id_t *object, crypto_req_handle_t req) 3990 { 3991 int error = CRYPTO_FAILED; 3992 dprov_state_t *softc = (dprov_state_t *)provider; 3993 /* LINTED E_FUNC_SET_NOT_USED */ 3994 int instance; 3995 3996 instance = ddi_get_instance(softc->ds_dip); 3997 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate: started\n", 3998 instance)); 3999 4000 /* submit request to the taskq */ 4001 error = dprov_key_submit_req(DPROV_REQ_KEY_GENERATE, softc, req, 4002 session_id, mechanism, template, attribute_count, object, NULL, 4003 0, NULL, NULL, NULL, 0, NULL, 0, NULL, 0); 4004 4005 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate: done err = 0x0%x\n", 4006 instance, error)); 4007 4008 return (error); 4009 } 4010 4011 static int 4012 dprov_key_generate_pair(crypto_provider_handle_t provider, 4013 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 4014 crypto_object_attribute_t *public_key_template, 4015 uint_t public_key_attribute_count, 4016 crypto_object_attribute_t *private_key_template, 4017 uint_t private_key_attribute_count, 4018 crypto_object_id_t *public_key, crypto_object_id_t *private_key, 4019 crypto_req_handle_t req) 4020 { 4021 int error = CRYPTO_FAILED; 4022 dprov_state_t *softc = (dprov_state_t *)provider; 4023 /* LINTED E_FUNC_SET_NOT_USED */ 4024 int instance; 4025 4026 instance = ddi_get_instance(softc->ds_dip); 4027 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate_pair: started\n", 4028 instance)); 4029 4030 /* submit request to the taskq */ 4031 error = dprov_key_submit_req(DPROV_REQ_KEY_GENERATE_PAIR, softc, req, 4032 session_id, mechanism, public_key_template, 4033 public_key_attribute_count, public_key, private_key_template, 4034 private_key_attribute_count, private_key, NULL, NULL, 0, NULL, 0, 4035 NULL, 0); 4036 4037 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate_pair: done err = 0x0%x\n", 4038 instance, error)); 4039 4040 return (error); 4041 } 4042 4043 static int 4044 dprov_key_wrap(crypto_provider_handle_t provider, 4045 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 4046 crypto_key_t *wrapping_key, crypto_object_id_t *key, 4047 uchar_t *wrapped_key, size_t *wrapped_key_len_ptr, crypto_req_handle_t req) 4048 { 4049 int error = CRYPTO_FAILED; 4050 dprov_state_t *softc = (dprov_state_t *)provider; 4051 /* LINTED E_FUNC_SET_NOT_USED */ 4052 int instance; 4053 4054 instance = ddi_get_instance(softc->ds_dip); 4055 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_wrap: started\n", 4056 instance)); 4057 4058 /* submit request to the taskq */ 4059 error = dprov_key_submit_req(DPROV_REQ_KEY_WRAP, softc, req, 4060 session_id, mechanism, NULL, 0, key, NULL, 4061 0, NULL, wrapping_key, wrapped_key, wrapped_key_len_ptr, 4062 NULL, 0, NULL, 0); 4063 4064 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_wrap: done err = 0x0%x\n", 4065 instance, error)); 4066 4067 return (error); 4068 } 4069 4070 static int 4071 dprov_key_unwrap(crypto_provider_handle_t provider, 4072 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 4073 crypto_key_t *unwrapping_key, uchar_t *wrapped_key, 4074 size_t *wrapped_key_len_ptr, crypto_object_attribute_t *template, 4075 uint_t attribute_count, crypto_object_id_t *key, crypto_req_handle_t req) 4076 { 4077 int error = CRYPTO_FAILED; 4078 dprov_state_t *softc = (dprov_state_t *)provider; 4079 /* LINTED E_FUNC_SET_NOT_USED */ 4080 int instance; 4081 4082 instance = ddi_get_instance(softc->ds_dip); 4083 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_unwrap: started\n", 4084 instance)); 4085 4086 /* submit request to the taskq */ 4087 error = dprov_key_submit_req(DPROV_REQ_KEY_UNWRAP, softc, req, 4088 session_id, mechanism, template, attribute_count, key, NULL, 4089 0, NULL, unwrapping_key, wrapped_key, wrapped_key_len_ptr, 4090 NULL, 0, NULL, 0); 4091 4092 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_unwrap: done err = 0x0%x\n", 4093 instance, error)); 4094 4095 return (error); 4096 } 4097 4098 static int 4099 dprov_key_derive(crypto_provider_handle_t provider, 4100 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 4101 crypto_key_t *base_key, crypto_object_attribute_t *template, 4102 uint_t attribute_count, crypto_object_id_t *key, crypto_req_handle_t req) 4103 { 4104 int error = CRYPTO_FAILED; 4105 dprov_state_t *softc = (dprov_state_t *)provider; 4106 /* LINTED E_FUNC_SET_NOT_USED */ 4107 int instance; 4108 4109 instance = ddi_get_instance(softc->ds_dip); 4110 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_derive: started\n", 4111 instance)); 4112 4113 /* submit request to the taskq */ 4114 error = dprov_key_submit_req(DPROV_REQ_KEY_DERIVE, softc, req, 4115 session_id, mechanism, template, attribute_count, key, NULL, 4116 0, NULL, base_key, NULL, 0, NULL, 0, NULL, 0); 4117 4118 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_derive: done err = 0x0%x\n", 4119 instance, error)); 4120 4121 return (error); 4122 } 4123 4124 /* 4125 * Provider management entry points. 4126 */ 4127 4128 static int 4129 dprov_ext_info(crypto_provider_handle_t provider, 4130 crypto_provider_ext_info_t *ext_info, crypto_req_handle_t req) 4131 { 4132 int error = CRYPTO_FAILED; 4133 dprov_state_t *softc = (dprov_state_t *)provider; 4134 /* LINTED E_FUNC_SET_NOT_USED */ 4135 int instance; 4136 4137 instance = ddi_get_instance(softc->ds_dip); 4138 DPROV_DEBUG(D_MGMT, ("(%d) dprov_ext_info: started\n", 4139 instance)); 4140 4141 error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_EXTINFO, softc, req, 4142 0, NULL, 0, NULL, 0, NULL, ext_info); 4143 4144 DPROV_DEBUG(D_MGMT, ("(%d) dprov_ext_info: done err = 0x0%x\n", 4145 instance, error)); 4146 4147 return (error); 4148 } 4149 4150 static int 4151 dprov_init_token(crypto_provider_handle_t provider, char *pin, size_t pin_len, 4152 char *label, crypto_req_handle_t req) 4153 { 4154 int error = CRYPTO_FAILED; 4155 dprov_state_t *softc = (dprov_state_t *)provider; 4156 /* LINTED E_FUNC_SET_NOT_USED */ 4157 int instance; 4158 4159 instance = ddi_get_instance(softc->ds_dip); 4160 DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_token: started\n", 4161 instance)); 4162 4163 error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_INITTOKEN, softc, req, 4164 0, pin, pin_len, NULL, 0, label, NULL); 4165 4166 DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_token: done err = 0x0%x\n", 4167 instance, error)); 4168 4169 return (error); 4170 } 4171 4172 static int 4173 dprov_init_pin(crypto_provider_handle_t provider, 4174 crypto_session_id_t session_id, char *pin, size_t pin_len, 4175 crypto_req_handle_t req) 4176 { 4177 int error = CRYPTO_FAILED; 4178 dprov_state_t *softc = (dprov_state_t *)provider; 4179 /* LINTED E_FUNC_SET_NOT_USED */ 4180 int instance; 4181 4182 instance = ddi_get_instance(softc->ds_dip); 4183 DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_pin: started\n", 4184 instance)); 4185 4186 error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_INITPIN, softc, req, 4187 session_id, pin, pin_len, NULL, 0, NULL, NULL); 4188 4189 DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_pin: done err = 0x0%x\n", 4190 instance, error)); 4191 4192 return (error); 4193 } 4194 4195 static int 4196 dprov_set_pin(crypto_provider_handle_t provider, crypto_session_id_t session_id, 4197 char *old_pin, size_t old_pin_len, char *new_pin, size_t new_pin_len, 4198 crypto_req_handle_t req) 4199 { 4200 int error = CRYPTO_FAILED; 4201 dprov_state_t *softc = (dprov_state_t *)provider; 4202 /* LINTED E_FUNC_SET_NOT_USED */ 4203 int instance; 4204 4205 instance = ddi_get_instance(softc->ds_dip); 4206 DPROV_DEBUG(D_MGMT, ("(%d) dprov_set_pin: started\n", 4207 instance)); 4208 4209 error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_SETPIN, softc, req, 4210 session_id, new_pin, new_pin_len, old_pin, old_pin_len, NULL, NULL); 4211 4212 DPROV_DEBUG(D_MGMT, ("(%d) dprov_set_pin: done err = 0x0%x\n", 4213 instance, error)); 4214 4215 return (error); 4216 } 4217 4218 4219 /* 4220 * Context management entry points. 4221 */ 4222 4223 /* 4224 * Allocate a dprov-private context based on the specified dprov request. 4225 * For dual cipher/mac requests, the allocated context will 4226 * contain a structure dprov_ctx_dual_t, for other request types, 4227 * it will contain a dprov_ctx_single. 4228 * Returns one of the CRYPTO_ status codes. 4229 */ 4230 static int 4231 dprov_alloc_context(dprov_req_type_t req_type, crypto_ctx_t *spi_ctx) 4232 { 4233 dprov_ctx_single_t *dprov_private; 4234 4235 switch (req_type) { 4236 case DPROV_REQ_ENCRYPT_MAC_INIT: 4237 case DPROV_REQ_MAC_DECRYPT_INIT: 4238 dprov_private = kmem_zalloc(sizeof (dprov_ctx_dual_t), 4239 KM_NOSLEEP); 4240 if (dprov_private == NULL) 4241 return (CRYPTO_HOST_MEMORY); 4242 dprov_private->dc_type = DPROV_CTX_DUAL; 4243 break; 4244 default: 4245 dprov_private = kmem_zalloc(sizeof (dprov_ctx_single_t), 4246 KM_NOSLEEP); 4247 if (dprov_private == NULL) 4248 return (CRYPTO_HOST_MEMORY); 4249 dprov_private->dc_type = DPROV_CTX_SINGLE; 4250 dprov_private->dc_svrfy_to_mac = B_FALSE; 4251 break; 4252 } 4253 4254 spi_ctx->cc_provider_private = (void *)dprov_private; 4255 4256 return (CRYPTO_SUCCESS); 4257 } 4258 4259 static int 4260 dprov_free_context(crypto_ctx_t *ctx) 4261 { 4262 if (ctx->cc_provider_private == NULL) 4263 return (CRYPTO_SUCCESS); 4264 4265 DPROV_DEBUG(D_CONTEXT, ("dprov_free_context\n")); 4266 4267 { 4268 /* 4269 * The dprov private context could contain either 4270 * a dprov_ctx_single_t or a dprov_ctx_dual_t. Free 4271 * the context based on its type. The k-API contexts 4272 * that were attached to the dprov private context 4273 * are freed by the framework. 4274 */ 4275 dprov_ctx_single_t *ctx_single = 4276 (dprov_ctx_single_t *)(ctx->cc_provider_private); 4277 4278 if (ctx_single->dc_type == DPROV_CTX_SINGLE) { 4279 crypto_context_t context = DPROV_CTX_SINGLE(ctx); 4280 4281 /* 4282 * This case happens for the crypto_cancel_ctx() case. 4283 * We have to cancel the SW provider context also. 4284 */ 4285 if (context != NULL) 4286 crypto_cancel_ctx(context); 4287 4288 kmem_free(ctx_single, sizeof (dprov_ctx_single_t)); 4289 } else { 4290 crypto_context_t cipher_context = 4291 DPROV_CTX_DUAL_CIPHER(ctx); 4292 crypto_context_t mac_context = DPROV_CTX_DUAL_MAC(ctx); 4293 4294 /* See comments above. */ 4295 if (cipher_context != NULL) 4296 crypto_cancel_ctx(cipher_context); 4297 if (mac_context != NULL) 4298 crypto_cancel_ctx(mac_context); 4299 4300 ASSERT(ctx_single->dc_type == DPROV_CTX_DUAL); 4301 kmem_free(ctx_single, sizeof (dprov_ctx_dual_t)); 4302 } 4303 ctx->cc_provider_private = NULL; 4304 } 4305 4306 return (CRYPTO_SUCCESS); 4307 } 4308 4309 /* 4310 * Resource control checks don't need to be done. Why? Because this routine 4311 * knows the size of the structure, and it can't be overridden by a user. 4312 * This is different from the crypto module, which has no knowledge of 4313 * specific mechanisms, and therefore has to trust specified size of the 4314 * parameter. This trust, or lack of trust, is why the size of the 4315 * parameter has to be charged against the project resource control. 4316 */ 4317 static int 4318 copyin_aes_ccm_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech, 4319 int *out_error, int mode) 4320 { 4321 STRUCT_DECL(crypto_mechanism, mech); 4322 STRUCT_DECL(CK_AES_CCM_PARAMS, params); 4323 CK_AES_CCM_PARAMS *aes_ccm_params; 4324 caddr_t pp; 4325 size_t param_len; 4326 int error = 0; 4327 int rv = 0; 4328 4329 STRUCT_INIT(mech, mode); 4330 STRUCT_INIT(params, mode); 4331 bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech)); 4332 pp = STRUCT_FGETP(mech, cm_param); 4333 param_len = STRUCT_FGET(mech, cm_param_len); 4334 4335 if (param_len != STRUCT_SIZE(params)) { 4336 rv = CRYPTO_ARGUMENTS_BAD; 4337 goto out; 4338 } 4339 4340 out_mech->cm_type = STRUCT_FGET(mech, cm_type); 4341 out_mech->cm_param = NULL; 4342 out_mech->cm_param_len = 0; 4343 if (pp != NULL) { 4344 size_t nonce_len, auth_data_len, total_param_len; 4345 4346 if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) { 4347 out_mech->cm_param = NULL; 4348 error = EFAULT; 4349 goto out; 4350 } 4351 4352 nonce_len = STRUCT_FGET(params, ulNonceSize); 4353 auth_data_len = STRUCT_FGET(params, ulAuthDataSize); 4354 4355 /* allocate param structure */ 4356 total_param_len = 4357 sizeof (CK_AES_CCM_PARAMS) + nonce_len + auth_data_len; 4358 aes_ccm_params = kmem_alloc(total_param_len, KM_NOSLEEP); 4359 if (aes_ccm_params == NULL) { 4360 rv = CRYPTO_HOST_MEMORY; 4361 goto out; 4362 } 4363 aes_ccm_params->ulMACSize = STRUCT_FGET(params, ulMACSize); 4364 aes_ccm_params->ulNonceSize = nonce_len; 4365 aes_ccm_params->ulAuthDataSize = auth_data_len; 4366 aes_ccm_params->ulDataSize 4367 = STRUCT_FGET(params, ulDataSize); 4368 aes_ccm_params->nonce 4369 = (uchar_t *)aes_ccm_params + sizeof (CK_AES_CCM_PARAMS); 4370 aes_ccm_params->authData 4371 = aes_ccm_params->nonce + nonce_len; 4372 4373 if (copyin((char *)STRUCT_FGETP(params, nonce), 4374 aes_ccm_params->nonce, nonce_len) != 0) { 4375 kmem_free(aes_ccm_params, total_param_len); 4376 out_mech->cm_param = NULL; 4377 error = EFAULT; 4378 goto out; 4379 } 4380 if (copyin((char *)STRUCT_FGETP(params, authData), 4381 aes_ccm_params->authData, auth_data_len) != 0) { 4382 kmem_free(aes_ccm_params, total_param_len); 4383 out_mech->cm_param = NULL; 4384 error = EFAULT; 4385 goto out; 4386 } 4387 out_mech->cm_param = (char *)aes_ccm_params; 4388 out_mech->cm_param_len = sizeof (CK_AES_CCM_PARAMS); 4389 } 4390 out: 4391 *out_error = error; 4392 return (rv); 4393 } 4394 4395 /* 4396 * Resource control checks don't need to be done. Why? Because this routine 4397 * knows the size of the structure, and it can't be overridden by a user. 4398 * This is different from the crypto module, which has no knowledge of 4399 * specific mechanisms, and therefore has to trust specified size of the 4400 * parameter. This trust, or lack of trust, is why the size of the 4401 * parameter has to be charged against the project resource control. 4402 */ 4403 static int 4404 copyin_aes_gcm_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech, 4405 int *out_error, int mode) 4406 { 4407 STRUCT_DECL(crypto_mechanism, mech); 4408 STRUCT_DECL(CK_AES_GCM_PARAMS, params); 4409 CK_AES_GCM_PARAMS *aes_gcm_params; 4410 caddr_t pp; 4411 size_t param_len; 4412 int error = 0; 4413 int rv = 0; 4414 4415 STRUCT_INIT(mech, mode); 4416 STRUCT_INIT(params, mode); 4417 bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech)); 4418 pp = STRUCT_FGETP(mech, cm_param); 4419 param_len = STRUCT_FGET(mech, cm_param_len); 4420 4421 if (param_len != STRUCT_SIZE(params)) { 4422 rv = CRYPTO_ARGUMENTS_BAD; 4423 goto out; 4424 } 4425 4426 out_mech->cm_type = STRUCT_FGET(mech, cm_type); 4427 out_mech->cm_param = NULL; 4428 out_mech->cm_param_len = 0; 4429 if (pp != NULL) { 4430 size_t nonce_len, auth_data_len, total_param_len; 4431 4432 if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) { 4433 out_mech->cm_param = NULL; 4434 error = EFAULT; 4435 goto out; 4436 } 4437 4438 nonce_len = STRUCT_FGET(params, ulIvLen); 4439 auth_data_len = STRUCT_FGET(params, ulAADLen); 4440 4441 /* allocate param structure */ 4442 total_param_len = 4443 sizeof (CK_AES_GCM_PARAMS) + nonce_len + auth_data_len; 4444 aes_gcm_params = kmem_alloc(total_param_len, KM_NOSLEEP); 4445 if (aes_gcm_params == NULL) { 4446 rv = CRYPTO_HOST_MEMORY; 4447 goto out; 4448 } 4449 aes_gcm_params->ulTagBits = STRUCT_FGET(params, ulTagBits); 4450 aes_gcm_params->ulIvLen = nonce_len; 4451 aes_gcm_params->ulAADLen = auth_data_len; 4452 aes_gcm_params->pIv 4453 = (uchar_t *)aes_gcm_params + sizeof (CK_AES_GCM_PARAMS); 4454 aes_gcm_params->pAAD = aes_gcm_params->pIv + nonce_len; 4455 4456 if (copyin((char *)STRUCT_FGETP(params, pIv), 4457 aes_gcm_params->pIv, nonce_len) != 0) { 4458 kmem_free(aes_gcm_params, total_param_len); 4459 out_mech->cm_param = NULL; 4460 error = EFAULT; 4461 goto out; 4462 } 4463 if (copyin((char *)STRUCT_FGETP(params, pAAD), 4464 aes_gcm_params->pAAD, auth_data_len) != 0) { 4465 kmem_free(aes_gcm_params, total_param_len); 4466 out_mech->cm_param = NULL; 4467 error = EFAULT; 4468 goto out; 4469 } 4470 out_mech->cm_param = (char *)aes_gcm_params; 4471 out_mech->cm_param_len = sizeof (CK_AES_GCM_PARAMS); 4472 } 4473 out: 4474 *out_error = error; 4475 return (rv); 4476 } 4477 4478 static int 4479 copyin_aes_gmac_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech, 4480 int *out_error, int mode) 4481 { 4482 STRUCT_DECL(crypto_mechanism, mech); 4483 STRUCT_DECL(CK_AES_GMAC_PARAMS, params); 4484 CK_AES_GMAC_PARAMS *aes_gmac_params; 4485 caddr_t pp; 4486 size_t param_len; 4487 int error = 0; 4488 int rv = 0; 4489 4490 STRUCT_INIT(mech, mode); 4491 STRUCT_INIT(params, mode); 4492 bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech)); 4493 pp = STRUCT_FGETP(mech, cm_param); 4494 param_len = STRUCT_FGET(mech, cm_param_len); 4495 4496 if (param_len != STRUCT_SIZE(params)) { 4497 rv = CRYPTO_ARGUMENTS_BAD; 4498 goto out; 4499 } 4500 4501 out_mech->cm_type = STRUCT_FGET(mech, cm_type); 4502 out_mech->cm_param = NULL; 4503 out_mech->cm_param_len = 0; 4504 if (pp != NULL) { 4505 size_t auth_data_len, total_param_len; 4506 4507 if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) { 4508 out_mech->cm_param = NULL; 4509 error = EFAULT; 4510 goto out; 4511 } 4512 4513 auth_data_len = STRUCT_FGET(params, ulAADLen); 4514 4515 /* allocate param structure */ 4516 total_param_len = sizeof (CK_AES_GMAC_PARAMS) + 4517 AES_GMAC_IV_LEN + auth_data_len; 4518 aes_gmac_params = kmem_alloc(total_param_len, KM_NOSLEEP); 4519 if (aes_gmac_params == NULL) { 4520 rv = CRYPTO_HOST_MEMORY; 4521 goto out; 4522 } 4523 aes_gmac_params->ulAADLen = auth_data_len; 4524 aes_gmac_params->pIv 4525 = (uchar_t *)aes_gmac_params + sizeof (CK_AES_GMAC_PARAMS); 4526 aes_gmac_params->pAAD = aes_gmac_params->pIv + AES_GMAC_IV_LEN; 4527 4528 if (copyin((char *)STRUCT_FGETP(params, pIv), 4529 aes_gmac_params->pIv, AES_GMAC_IV_LEN) != 0) { 4530 kmem_free(aes_gmac_params, total_param_len); 4531 out_mech->cm_param = NULL; 4532 error = EFAULT; 4533 goto out; 4534 } 4535 if (copyin((char *)STRUCT_FGETP(params, pAAD), 4536 aes_gmac_params->pAAD, auth_data_len) != 0) { 4537 kmem_free(aes_gmac_params, total_param_len); 4538 out_mech->cm_param = NULL; 4539 error = EFAULT; 4540 goto out; 4541 } 4542 out_mech->cm_param = (char *)aes_gmac_params; 4543 out_mech->cm_param_len = sizeof (CK_AES_GMAC_PARAMS); 4544 } 4545 out: 4546 *out_error = error; 4547 return (rv); 4548 } 4549 4550 /* 4551 * Resource control checks don't need to be done. Why? Because this routine 4552 * knows the size of the structure, and it can't be overridden by a user. 4553 * This is different from the crypto module, which has no knowledge of 4554 * specific mechanisms, and therefore has to trust specified size of the 4555 * parameter. This trust, or lack of trust, is why the size of the 4556 * parameter has to be charged against the project resource control. 4557 */ 4558 static int 4559 copyin_aes_ctr_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech, 4560 int *out_error, int mode) 4561 { 4562 STRUCT_DECL(crypto_mechanism, mech); 4563 STRUCT_DECL(CK_AES_CTR_PARAMS, params); 4564 CK_AES_CTR_PARAMS *aes_ctr_params; 4565 caddr_t pp; 4566 size_t param_len; 4567 int error = 0; 4568 int rv = 0; 4569 4570 STRUCT_INIT(mech, mode); 4571 STRUCT_INIT(params, mode); 4572 bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech)); 4573 pp = STRUCT_FGETP(mech, cm_param); 4574 param_len = STRUCT_FGET(mech, cm_param_len); 4575 4576 if (param_len != STRUCT_SIZE(params)) { 4577 rv = CRYPTO_ARGUMENTS_BAD; 4578 goto out; 4579 } 4580 4581 out_mech->cm_type = STRUCT_FGET(mech, cm_type); 4582 out_mech->cm_param = NULL; 4583 out_mech->cm_param_len = 0; 4584 if (pp != NULL) { 4585 if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) { 4586 out_mech->cm_param = NULL; 4587 error = EFAULT; 4588 goto out; 4589 } 4590 /* allocate param structure and counter block */ 4591 aes_ctr_params = kmem_alloc(sizeof (CK_AES_CTR_PARAMS), 4592 KM_NOSLEEP); 4593 if (aes_ctr_params == NULL) { 4594 rv = CRYPTO_HOST_MEMORY; 4595 goto out; 4596 } 4597 aes_ctr_params->ulCounterBits = STRUCT_FGET(params, 4598 ulCounterBits); 4599 bcopy(STRUCT_FGETP(params, cb), aes_ctr_params->cb, 16); 4600 out_mech->cm_param = (char *)aes_ctr_params; 4601 out_mech->cm_param_len = sizeof (CK_AES_CTR_PARAMS); 4602 } 4603 out: 4604 *out_error = error; 4605 return (rv); 4606 } 4607 4608 static int 4609 copyin_ecc_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech, 4610 int *out_error, int mode) 4611 { 4612 STRUCT_DECL(crypto_mechanism, mech); 4613 STRUCT_DECL(CK_ECDH1_DERIVE_PARAMS, params); 4614 CK_ECDH1_DERIVE_PARAMS *ecc_params; 4615 caddr_t pp; 4616 size_t param_len, shared_data_len, public_data_len; 4617 int error = 0; 4618 int rv = 0; 4619 4620 STRUCT_INIT(mech, mode); 4621 STRUCT_INIT(params, mode); 4622 bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech)); 4623 pp = STRUCT_FGETP(mech, cm_param); 4624 param_len = STRUCT_FGET(mech, cm_param_len); 4625 4626 if (param_len != STRUCT_SIZE(params)) { 4627 rv = CRYPTO_ARGUMENTS_BAD; 4628 goto out; 4629 } 4630 4631 out_mech->cm_type = STRUCT_FGET(mech, cm_type); 4632 out_mech->cm_param = NULL; 4633 out_mech->cm_param_len = 0; 4634 if (pp != NULL) { 4635 if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) { 4636 out_mech->cm_param = NULL; 4637 error = EFAULT; 4638 goto out; 4639 } 4640 shared_data_len = STRUCT_FGET(params, ulSharedDataLen); 4641 public_data_len = STRUCT_FGET(params, ulPublicDataLen); 4642 /* allocate param structure and buffers */ 4643 ecc_params = kmem_alloc(sizeof (CK_ECDH1_DERIVE_PARAMS) + 4644 roundup(shared_data_len, sizeof (caddr_t)) + 4645 roundup(public_data_len, sizeof (caddr_t)), KM_NOSLEEP); 4646 if (ecc_params == NULL) { 4647 rv = CRYPTO_HOST_MEMORY; 4648 goto out; 4649 } 4650 ecc_params->pSharedData = (uchar_t *)ecc_params + 4651 sizeof (CK_ECDH1_DERIVE_PARAMS); 4652 ecc_params->pPublicData = (uchar_t *)ecc_params->pSharedData + 4653 roundup(shared_data_len, sizeof (caddr_t)); 4654 if (copyin((char *)STRUCT_FGETP(params, pSharedData), 4655 ecc_params->pSharedData, shared_data_len) != 0) { 4656 kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) + 4657 roundup(shared_data_len, sizeof (caddr_t)) + 4658 roundup(public_data_len, sizeof (caddr_t))); 4659 out_mech->cm_param = NULL; 4660 error = EFAULT; 4661 goto out; 4662 } 4663 ecc_params->ulSharedDataLen = shared_data_len; 4664 4665 if (copyin((char *)STRUCT_FGETP(params, pPublicData), 4666 ecc_params->pPublicData, public_data_len) != 0) { 4667 kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) + 4668 roundup(shared_data_len, sizeof (caddr_t)) + 4669 roundup(public_data_len, sizeof (caddr_t))); 4670 out_mech->cm_param = NULL; 4671 error = EFAULT; 4672 goto out; 4673 } 4674 ecc_params->ulPublicDataLen = public_data_len; 4675 ecc_params->kdf = STRUCT_FGET(params, kdf); 4676 out_mech->cm_param = (char *)ecc_params; 4677 out_mech->cm_param_len = sizeof (CK_ECDH1_DERIVE_PARAMS); 4678 } 4679 out: 4680 *out_error = error; 4681 return (rv); 4682 } 4683 4684 /* ARGSUSED */ 4685 static int 4686 copyout_aes_ctr_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech, 4687 int *out_error, int mode) 4688 { 4689 STRUCT_DECL(crypto_mechanism, mech); 4690 STRUCT_DECL(CK_AES_CTR_PARAMS, params); 4691 caddr_t pp; 4692 size_t param_len; 4693 int error = 0; 4694 int rv = 0; 4695 4696 STRUCT_INIT(mech, mode); 4697 STRUCT_INIT(params, mode); 4698 bcopy(out_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech)); 4699 pp = STRUCT_FGETP(mech, cm_param); 4700 param_len = STRUCT_FGET(mech, cm_param_len); 4701 if (param_len != STRUCT_SIZE(params)) { 4702 rv = CRYPTO_ARGUMENTS_BAD; 4703 goto out; 4704 } 4705 4706 if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) { 4707 error = EFAULT; 4708 goto out; 4709 } 4710 4711 /* for testing, overwrite the iv with 16 X 'A' */ 4712 (void) memset(STRUCT_FGETP(params, cb), 'A', 16); 4713 if (copyout((char *)pp, STRUCT_BUF(params), param_len) != 0) { 4714 error = EFAULT; 4715 goto out; 4716 } 4717 out: 4718 *out_error = error; 4719 return (rv); 4720 } 4721 4722 /* ARGSUSED */ 4723 static int 4724 dprov_copyin_mechanism(crypto_provider_handle_t provider, 4725 crypto_mechanism_t *umech, crypto_mechanism_t *kmech, 4726 int *out_error, int mode) 4727 { 4728 STRUCT_DECL(crypto_mechanism, mech); 4729 size_t param_len, expected_param_len; 4730 caddr_t pp; 4731 char *param; 4732 int rv; 4733 int error = 0; 4734 4735 ASSERT(!servicing_interrupt()); 4736 4737 STRUCT_INIT(mech, mode); 4738 bcopy(umech, STRUCT_BUF(mech), STRUCT_SIZE(mech)); 4739 pp = STRUCT_FGETP(mech, cm_param); 4740 param_len = STRUCT_FGET(mech, cm_param_len); 4741 4742 kmech->cm_param = NULL; 4743 kmech->cm_param_len = 0; 4744 4745 switch (kmech->cm_type) { 4746 case DES_CBC_MECH_INFO_TYPE: 4747 case DES3_CBC_MECH_INFO_TYPE: 4748 expected_param_len = DES_BLOCK_LEN; 4749 break; 4750 4751 case BLOWFISH_CBC_MECH_INFO_TYPE: 4752 expected_param_len = BLOWFISH_BLOCK_LEN; 4753 break; 4754 4755 case AES_CBC_MECH_INFO_TYPE: 4756 expected_param_len = AES_BLOCK_LEN; 4757 break; 4758 4759 case AES_CTR_MECH_INFO_TYPE: 4760 case SHA1_KEY_DERIVATION_MECH_INFO_TYPE: /* for testing only */ 4761 rv = copyin_aes_ctr_mech(umech, kmech, &error, mode); 4762 goto out; 4763 4764 case ECDH1_DERIVE_MECH_INFO_TYPE: 4765 rv = copyin_ecc_mech(umech, kmech, &error, mode); 4766 goto out; 4767 4768 case AES_CCM_MECH_INFO_TYPE: 4769 rv = copyin_aes_ccm_mech(umech, kmech, &error, mode); 4770 goto out; 4771 4772 case AES_GCM_MECH_INFO_TYPE: 4773 rv = copyin_aes_gcm_mech(umech, kmech, &error, mode); 4774 goto out; 4775 4776 case AES_GMAC_MECH_INFO_TYPE: 4777 rv = copyin_aes_gmac_mech(umech, kmech, &error, mode); 4778 goto out; 4779 4780 case DH_PKCS_DERIVE_MECH_INFO_TYPE: 4781 expected_param_len = param_len; 4782 break; 4783 4784 default: 4785 /* nothing to do - mechanism has no parameters */ 4786 rv = CRYPTO_SUCCESS; 4787 goto out; 4788 } 4789 4790 if (param_len != expected_param_len) { 4791 rv = CRYPTO_MECHANISM_PARAM_INVALID; 4792 goto out; 4793 } 4794 if (pp == NULL) { 4795 rv = CRYPTO_MECHANISM_PARAM_INVALID; 4796 goto out; 4797 } 4798 if ((param = kmem_alloc(param_len, KM_NOSLEEP)) == NULL) { 4799 rv = CRYPTO_HOST_MEMORY; 4800 goto out; 4801 } 4802 if (copyin((char *)pp, param, param_len) != 0) { 4803 kmem_free(param, param_len); 4804 error = EFAULT; 4805 rv = CRYPTO_FAILED; 4806 goto out; 4807 } 4808 kmech->cm_param = (char *)param; 4809 kmech->cm_param_len = param_len; 4810 rv = CRYPTO_SUCCESS; 4811 out: 4812 *out_error = error; 4813 return (rv); 4814 } 4815 4816 /* ARGSUSED */ 4817 static int 4818 dprov_copyout_mechanism(crypto_provider_handle_t provider, 4819 crypto_mechanism_t *kmech, crypto_mechanism_t *umech, 4820 int *out_error, int mode) 4821 { 4822 ASSERT(!servicing_interrupt()); 4823 4824 switch (kmech->cm_type) { 4825 case AES_CTR_MECH_INFO_TYPE: 4826 case SHA1_KEY_DERIVATION_MECH_INFO_TYPE: /* for testing only */ 4827 return (copyout_aes_ctr_mech(kmech, umech, out_error, mode)); 4828 case ECDH1_DERIVE_MECH_INFO_TYPE: 4829 return (CRYPTO_SUCCESS); 4830 default: 4831 return (CRYPTO_MECHANISM_INVALID); 4832 } 4833 } 4834 4835 /* 4836 * Free mechanism parameter that was allocated by the provider. 4837 */ 4838 /* ARGSUSED */ 4839 static int 4840 dprov_free_mechanism(crypto_provider_handle_t provider, 4841 crypto_mechanism_t *mech) 4842 { 4843 size_t len; 4844 4845 if (mech->cm_param == NULL || mech->cm_param_len == 0) 4846 return (CRYPTO_SUCCESS); 4847 4848 switch (mech->cm_type) { 4849 case AES_CTR_MECH_INFO_TYPE: 4850 case SHA1_KEY_DERIVATION_MECH_INFO_TYPE: 4851 len = sizeof (CK_AES_CTR_PARAMS); 4852 break; 4853 case ECDH1_DERIVE_MECH_INFO_TYPE: { 4854 CK_ECDH1_DERIVE_PARAMS *ecc_params; 4855 4856 /* LINTED: pointer alignment */ 4857 ecc_params = (CK_ECDH1_DERIVE_PARAMS *)mech->cm_param; 4858 kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) + 4859 roundup(ecc_params->ulSharedDataLen, sizeof (caddr_t)) + 4860 roundup(ecc_params->ulPublicDataLen, sizeof (caddr_t))); 4861 return (CRYPTO_SUCCESS); 4862 } 4863 case AES_CCM_MECH_INFO_TYPE: { 4864 CK_AES_CCM_PARAMS *params; 4865 size_t total_param_len; 4866 4867 if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) { 4868 /* LINTED: pointer alignment */ 4869 params = (CK_AES_CCM_PARAMS *)mech->cm_param; 4870 total_param_len = mech->cm_param_len + 4871 params->ulNonceSize + params->ulAuthDataSize; 4872 kmem_free(params, total_param_len); 4873 mech->cm_param = NULL; 4874 mech->cm_param_len = 0; 4875 } 4876 return (CRYPTO_SUCCESS); 4877 } 4878 case AES_GMAC_MECH_INFO_TYPE: { 4879 CK_AES_GMAC_PARAMS *params; 4880 size_t total_param_len; 4881 4882 if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) { 4883 /* LINTED: pointer alignment */ 4884 params = (CK_AES_GMAC_PARAMS *)mech->cm_param; 4885 total_param_len = mech->cm_param_len + 4886 AES_GMAC_IV_LEN + params->ulAADLen; 4887 kmem_free(params, total_param_len); 4888 mech->cm_param = NULL; 4889 mech->cm_param_len = 0; 4890 } 4891 return (CRYPTO_SUCCESS); 4892 } 4893 case AES_GCM_MECH_INFO_TYPE: { 4894 CK_AES_GCM_PARAMS *params; 4895 size_t total_param_len; 4896 4897 if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) { 4898 /* LINTED: pointer alignment */ 4899 params = (CK_AES_GCM_PARAMS *)mech->cm_param; 4900 total_param_len = mech->cm_param_len + 4901 params->ulIvLen + params->ulAADLen; 4902 kmem_free(params, total_param_len); 4903 mech->cm_param = NULL; 4904 mech->cm_param_len = 0; 4905 } 4906 return (CRYPTO_SUCCESS); 4907 } 4908 4909 default: 4910 len = mech->cm_param_len; 4911 } 4912 kmem_free(mech->cm_param, len); 4913 return (CRYPTO_SUCCESS); 4914 } 4915 4916 /* 4917 * No (Key)Store Key management entry point. 4918 */ 4919 static int 4920 dprov_nostore_key_generate(crypto_provider_handle_t provider, 4921 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 4922 crypto_object_attribute_t *template, uint_t attribute_count, 4923 crypto_object_attribute_t *out_template, uint_t out_attribute_count, 4924 crypto_req_handle_t req) 4925 { 4926 int error = CRYPTO_FAILED; 4927 dprov_state_t *softc = (dprov_state_t *)provider; 4928 /* LINTED E_FUNC_SET_NOT_USED */ 4929 int instance; 4930 4931 instance = ddi_get_instance(softc->ds_dip); 4932 DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate: started\n", 4933 instance)); 4934 4935 /* submit request to the taskq */ 4936 error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_GENERATE, 4937 softc, req, session_id, mechanism, template, attribute_count, 4938 NULL, NULL, 0, NULL, NULL, NULL, 0, out_template, 4939 out_attribute_count, NULL, 0); 4940 4941 DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate: " 4942 "done err = 0x0%x\n", instance, error)); 4943 4944 return (error); 4945 } 4946 4947 static int 4948 dprov_nostore_key_generate_pair(crypto_provider_handle_t provider, 4949 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 4950 crypto_object_attribute_t *public_key_template, 4951 uint_t public_key_attribute_count, 4952 crypto_object_attribute_t *private_key_template, 4953 uint_t private_key_attribute_count, 4954 crypto_object_attribute_t *out_public_key_template, 4955 uint_t out_public_key_attribute_count, 4956 crypto_object_attribute_t *out_private_key_template, 4957 uint_t out_private_key_attribute_count, 4958 crypto_req_handle_t req) 4959 { 4960 int error = CRYPTO_FAILED; 4961 dprov_state_t *softc = (dprov_state_t *)provider; 4962 /* LINTED E_FUNC_SET_NOT_USED */ 4963 int instance; 4964 4965 instance = ddi_get_instance(softc->ds_dip); 4966 DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate_pair: started\n", 4967 instance)); 4968 4969 /* submit request to the taskq */ 4970 error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR, 4971 softc, req, session_id, mechanism, public_key_template, 4972 public_key_attribute_count, NULL, private_key_template, 4973 private_key_attribute_count, NULL, NULL, NULL, 0, 4974 out_public_key_template, out_public_key_attribute_count, 4975 out_private_key_template, out_private_key_attribute_count); 4976 4977 DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate_pair: " 4978 "done err = 0x0%x\n", instance, error)); 4979 4980 return (error); 4981 } 4982 4983 static int 4984 dprov_nostore_key_derive(crypto_provider_handle_t provider, 4985 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 4986 crypto_key_t *base_key, crypto_object_attribute_t *template, 4987 uint_t attribute_count, crypto_object_attribute_t *out_template, 4988 uint_t out_attribute_count, crypto_req_handle_t req) 4989 { 4990 int error = CRYPTO_FAILED; 4991 dprov_state_t *softc = (dprov_state_t *)provider; 4992 /* LINTED E_FUNC_SET_NOT_USED */ 4993 int instance; 4994 4995 instance = ddi_get_instance(softc->ds_dip); 4996 DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_derive: started\n", 4997 instance)); 4998 4999 /* submit request to the taskq */ 5000 error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_DERIVE, softc, req, 5001 session_id, mechanism, template, attribute_count, NULL, NULL, 5002 0, NULL, base_key, NULL, 0, out_template, out_attribute_count, 5003 NULL, 0); 5004 5005 DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_derive: " 5006 "done err = 0x0%x\n", instance, error)); 5007 5008 return (error); 5009 } 5010 5011 /* 5012 * Allocate a dprov taskq request and initialize the common fields. 5013 * Return NULL if the memory allocation failed. 5014 */ 5015 static dprov_req_t * 5016 dprov_alloc_req(dprov_req_type_t req_type, dprov_state_t *softc, 5017 crypto_req_handle_t kcf_req, int kmflag) 5018 { 5019 dprov_req_t *taskq_req; 5020 5021 if ((taskq_req = kmem_alloc(sizeof (dprov_req_t), kmflag)) == NULL) 5022 return (NULL); 5023 5024 taskq_req->dr_type = req_type; 5025 taskq_req->dr_softc = softc; 5026 taskq_req->dr_kcf_req = kcf_req; 5027 5028 return (taskq_req); 5029 } 5030 5031 /* 5032 * Dispatch a dprov request on the taskq associated with a softc. 5033 * Returns CRYPTO_HOST_MEMORY if the request cannot be queued, 5034 * CRYPTO_QUEUED on success. 5035 */ 5036 static int 5037 dprov_taskq_dispatch(dprov_state_t *softc, dprov_req_t *taskq_req, 5038 task_func_t *func, int kmflag) 5039 { 5040 if (taskq_dispatch(softc->ds_taskq, func, taskq_req, 5041 kmflag == KM_NOSLEEP ? TQ_NOSLEEP : TQ_SLEEP) == (taskqid_t)0) { 5042 kmem_free(taskq_req, sizeof (dprov_req_t)); 5043 return (CRYPTO_HOST_MEMORY); 5044 } else 5045 return (CRYPTO_QUEUED); 5046 } 5047 5048 /* 5049 * Helper function to submit digest operations to the taskq. 5050 * Returns one of the CRYPTO_ errors. 5051 */ 5052 static int 5053 dprov_digest_submit_req(dprov_req_type_t req_type, 5054 dprov_state_t *softc, crypto_req_handle_t req, 5055 crypto_mechanism_t *mechanism, crypto_data_t *data, crypto_key_t *key, 5056 crypto_data_t *digest, crypto_ctx_t *ctx, int kmflag) 5057 { 5058 dprov_req_t *taskq_req; 5059 5060 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL) 5061 return (CRYPTO_HOST_MEMORY); 5062 5063 taskq_req->dr_digest_req.dr_mechanism = mechanism; 5064 taskq_req->dr_digest_req.dr_ctx = ctx; 5065 taskq_req->dr_digest_req.dr_data = data; 5066 taskq_req->dr_digest_req.dr_key = key; 5067 taskq_req->dr_digest_req.dr_digest = digest; 5068 5069 return (dprov_taskq_dispatch(softc, taskq_req, 5070 (task_func_t *)dprov_digest_task, kmflag)); 5071 } 5072 5073 /* 5074 * Helper function to submit mac operations to the taskq. 5075 * Returns one of the CRYPTO_ errors. 5076 */ 5077 static int 5078 dprov_mac_submit_req(dprov_req_type_t req_type, 5079 dprov_state_t *softc, crypto_req_handle_t req, 5080 crypto_mechanism_t *mechanism, crypto_data_t *data, crypto_key_t *key, 5081 crypto_data_t *mac, crypto_ctx_t *ctx, crypto_session_id_t sid, int kmflag) 5082 { 5083 dprov_req_t *taskq_req; 5084 5085 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL) 5086 return (CRYPTO_HOST_MEMORY); 5087 5088 taskq_req->dr_mac_req.dr_mechanism = mechanism; 5089 taskq_req->dr_mac_req.dr_ctx = ctx; 5090 taskq_req->dr_mac_req.dr_data = data; 5091 taskq_req->dr_mac_req.dr_key = key; 5092 taskq_req->dr_mac_req.dr_mac = mac; 5093 taskq_req->dr_mac_req.dr_session_id = sid; 5094 5095 return (dprov_taskq_dispatch(softc, taskq_req, 5096 (task_func_t *)dprov_mac_task, kmflag)); 5097 } 5098 5099 /* 5100 * Helper function to submit sign operations to the taskq. 5101 * Returns one of the CRYPTO_ errors. 5102 */ 5103 static int 5104 dprov_sign_submit_req(dprov_req_type_t req_type, 5105 dprov_state_t *softc, crypto_req_handle_t req, 5106 crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data, 5107 crypto_data_t *signature, crypto_ctx_t *ctx, crypto_session_id_t sid, 5108 int kmflag) 5109 { 5110 dprov_req_t *taskq_req; 5111 5112 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL) 5113 return (CRYPTO_HOST_MEMORY); 5114 5115 taskq_req->dr_sign_req.sr_mechanism = mechanism; 5116 taskq_req->dr_sign_req.sr_ctx = ctx; 5117 taskq_req->dr_sign_req.sr_key = key; 5118 taskq_req->dr_sign_req.sr_data = data; 5119 taskq_req->dr_sign_req.sr_signature = signature; 5120 taskq_req->dr_sign_req.sr_session_id = sid; 5121 5122 return (dprov_taskq_dispatch(softc, taskq_req, 5123 (task_func_t *)dprov_sign_task, kmflag)); 5124 } 5125 5126 /* 5127 * Helper function to submit verify operations to the taskq. 5128 * Returns one of the CRYPTO_ errors. 5129 */ 5130 static int 5131 dprov_verify_submit_req(dprov_req_type_t req_type, 5132 dprov_state_t *softc, crypto_req_handle_t req, 5133 crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data, 5134 crypto_data_t *signature, crypto_ctx_t *ctx, crypto_session_id_t sid, 5135 int kmflag) 5136 { 5137 dprov_req_t *taskq_req; 5138 5139 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL) 5140 return (CRYPTO_HOST_MEMORY); 5141 5142 taskq_req->dr_verify_req.vr_mechanism = mechanism; 5143 taskq_req->dr_verify_req.vr_ctx = ctx; 5144 taskq_req->dr_verify_req.vr_key = key; 5145 taskq_req->dr_verify_req.vr_data = data; 5146 taskq_req->dr_verify_req.vr_signature = signature; 5147 taskq_req->dr_verify_req.vr_session_id = sid; 5148 5149 return (dprov_taskq_dispatch(softc, taskq_req, 5150 (task_func_t *)dprov_verify_task, kmflag)); 5151 } 5152 5153 /* 5154 * Helper function to submit dual operations to the taskq. 5155 * Returns one of the CRYPTO_ errors. 5156 */ 5157 static int 5158 dprov_dual_submit_req(dprov_req_type_t req_type, dprov_state_t *softc, 5159 crypto_req_handle_t req, crypto_ctx_t *signverify_ctx, 5160 crypto_ctx_t *cipher_ctx, crypto_data_t *plaintext, 5161 crypto_data_t *ciphertext) 5162 { 5163 dprov_req_t *taskq_req; 5164 5165 if ((taskq_req = dprov_alloc_req(req_type, softc, req, 5166 KM_NOSLEEP)) == NULL) 5167 return (CRYPTO_HOST_MEMORY); 5168 5169 taskq_req->dr_dual_req.dr_signverify_ctx = signverify_ctx; 5170 taskq_req->dr_dual_req.dr_cipher_ctx = cipher_ctx; 5171 taskq_req->dr_dual_req.dr_plaintext = plaintext; 5172 taskq_req->dr_dual_req.dr_ciphertext = ciphertext; 5173 5174 return (dprov_taskq_dispatch(softc, taskq_req, 5175 (task_func_t *)dprov_dual_task, KM_NOSLEEP)); 5176 } 5177 5178 /* 5179 * Helper function to submit dual cipher/mac operations to the taskq. 5180 * Returns one of the CRYPTO_ errors. 5181 */ 5182 static int 5183 dprov_cipher_mac_submit_req(dprov_req_type_t req_type, 5184 dprov_state_t *softc, crypto_req_handle_t req, crypto_ctx_t *ctx, 5185 crypto_session_id_t sid, crypto_mechanism_t *cipher_mech, 5186 crypto_key_t *cipher_key, crypto_mechanism_t *mac_mech, 5187 crypto_key_t *mac_key, crypto_dual_data_t *dual_data, 5188 crypto_data_t *data, crypto_data_t *mac, int kmflag) 5189 { 5190 dprov_req_t *taskq_req; 5191 5192 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL) 5193 return (CRYPTO_HOST_MEMORY); 5194 5195 taskq_req->dr_cipher_mac_req.mr_session_id = sid; 5196 taskq_req->dr_cipher_mac_req.mr_ctx = ctx; 5197 taskq_req->dr_cipher_mac_req.mr_cipher_mech = cipher_mech; 5198 taskq_req->dr_cipher_mac_req.mr_cipher_key = cipher_key; 5199 taskq_req->dr_cipher_mac_req.mr_mac_mech = mac_mech; 5200 taskq_req->dr_cipher_mac_req.mr_mac_key = mac_key; 5201 taskq_req->dr_cipher_mac_req.mr_dual_data = dual_data; 5202 taskq_req->dr_cipher_mac_req.mr_data = data; 5203 taskq_req->dr_cipher_mac_req.mr_mac = mac; 5204 5205 return (dprov_taskq_dispatch(softc, taskq_req, 5206 (task_func_t *)dprov_cipher_mac_task, kmflag)); 5207 } 5208 5209 /* 5210 * Helper function to submit cipher operations to the taskq. 5211 * Returns one of the CRYPTO_ errors. 5212 */ 5213 static int 5214 dprov_cipher_submit_req(dprov_req_type_t req_type, 5215 dprov_state_t *softc, crypto_req_handle_t req, 5216 crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *plaintext, 5217 crypto_data_t *ciphertext, crypto_ctx_t *ctx, crypto_session_id_t sid, 5218 int kmflag) 5219 { 5220 dprov_req_t *taskq_req; 5221 5222 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL) 5223 return (CRYPTO_HOST_MEMORY); 5224 5225 taskq_req->dr_cipher_req.dr_mechanism = mechanism; 5226 taskq_req->dr_cipher_req.dr_ctx = ctx; 5227 taskq_req->dr_cipher_req.dr_key = key; 5228 taskq_req->dr_cipher_req.dr_plaintext = plaintext; 5229 taskq_req->dr_cipher_req.dr_ciphertext = ciphertext; 5230 taskq_req->dr_cipher_req.dr_session_id = sid; 5231 5232 return (dprov_taskq_dispatch(softc, taskq_req, 5233 (task_func_t *)dprov_cipher_task, kmflag)); 5234 } 5235 5236 /* 5237 * Helper function to submit random number operations to the taskq. 5238 * Returns one of the CRYPTO_ errors. 5239 */ 5240 static int 5241 dprov_random_submit_req(dprov_req_type_t req_type, 5242 dprov_state_t *softc, crypto_req_handle_t req, uchar_t *buf, size_t len, 5243 crypto_session_id_t sid, uint_t entropy_est, uint32_t flags) 5244 { 5245 dprov_req_t *taskq_req; 5246 5247 if ((taskq_req = dprov_alloc_req(req_type, softc, req, 5248 KM_NOSLEEP)) == NULL) 5249 return (CRYPTO_HOST_MEMORY); 5250 5251 taskq_req->dr_random_req.rr_buf = buf; 5252 taskq_req->dr_random_req.rr_len = len; 5253 taskq_req->dr_random_req.rr_session_id = sid; 5254 taskq_req->dr_random_req.rr_entropy_est = entropy_est; 5255 taskq_req->dr_random_req.rr_flags = flags; 5256 5257 return (dprov_taskq_dispatch(softc, taskq_req, 5258 (task_func_t *)dprov_random_task, KM_NOSLEEP)); 5259 } 5260 5261 5262 /* 5263 * Helper function to submit session management operations to the taskq. 5264 * Returns one of the CRYPTO_ errors. 5265 */ 5266 static int 5267 dprov_session_submit_req(dprov_req_type_t req_type, 5268 dprov_state_t *softc, crypto_req_handle_t req, 5269 crypto_session_id_t *session_id_ptr, crypto_session_id_t session_id, 5270 crypto_user_type_t user_type, char *pin, size_t pin_len) 5271 { 5272 dprov_req_t *taskq_req; 5273 5274 if ((taskq_req = dprov_alloc_req(req_type, softc, req, 5275 KM_NOSLEEP)) == NULL) 5276 return (CRYPTO_HOST_MEMORY); 5277 5278 taskq_req->dr_session_req.sr_session_id_ptr = session_id_ptr; 5279 taskq_req->dr_session_req.sr_session_id = session_id; 5280 taskq_req->dr_session_req.sr_user_type = user_type; 5281 taskq_req->dr_session_req.sr_pin = pin; 5282 taskq_req->dr_session_req.sr_pin_len = pin_len; 5283 5284 return (dprov_taskq_dispatch(softc, taskq_req, 5285 (task_func_t *)dprov_session_task, KM_NOSLEEP)); 5286 } 5287 5288 /* 5289 * Helper function to submit object management operations to the taskq. 5290 * Returns one of the CRYPTO_ errors. 5291 */ 5292 static int 5293 dprov_object_submit_req(dprov_req_type_t req_type, 5294 dprov_state_t *softc, crypto_req_handle_t req, 5295 crypto_session_id_t session_id, crypto_object_id_t object_id, 5296 crypto_object_attribute_t *template, uint_t attribute_count, 5297 crypto_object_id_t *object_id_ptr, size_t *object_size, 5298 void **find_pp, void *find_p, uint_t max_object_count, 5299 uint_t *object_count_ptr, int kmflag) 5300 { 5301 dprov_req_t *taskq_req; 5302 5303 if ((taskq_req = dprov_alloc_req(req_type, softc, req, 5304 kmflag)) == NULL) 5305 return (CRYPTO_HOST_MEMORY); 5306 5307 taskq_req->dr_object_req.or_session_id = session_id; 5308 taskq_req->dr_object_req.or_object_id = object_id; 5309 taskq_req->dr_object_req.or_template = template; 5310 taskq_req->dr_object_req.or_attribute_count = attribute_count; 5311 taskq_req->dr_object_req.or_object_id_ptr = object_id_ptr; 5312 taskq_req->dr_object_req.or_object_size = object_size; 5313 taskq_req->dr_object_req.or_find_pp = find_pp; 5314 taskq_req->dr_object_req.or_find_p = find_p; 5315 taskq_req->dr_object_req.or_max_object_count = max_object_count; 5316 taskq_req->dr_object_req.or_object_count_ptr = object_count_ptr; 5317 5318 return (dprov_taskq_dispatch(softc, taskq_req, 5319 (task_func_t *)dprov_object_task, KM_NOSLEEP)); 5320 } 5321 5322 /* 5323 * Helper function to submit key management operations to the taskq. 5324 * Returns one of the CRYPTO_ errors. 5325 */ 5326 static int 5327 dprov_key_submit_req(dprov_req_type_t req_type, 5328 dprov_state_t *softc, crypto_req_handle_t req, 5329 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 5330 crypto_object_attribute_t *template, uint_t attribute_count, 5331 crypto_object_id_t *object_id_ptr, 5332 crypto_object_attribute_t *private_key_template, 5333 uint_t private_key_attribute_count, 5334 crypto_object_id_t *private_key_object_id_ptr, crypto_key_t *key, 5335 uchar_t *wrapped_key, size_t *wrapped_key_len_ptr, 5336 crypto_object_attribute_t *out_template1, uint_t out_attribute_count1, 5337 crypto_object_attribute_t *out_template2, uint_t out_attribute_count2) 5338 { 5339 dprov_req_t *taskq_req; 5340 5341 if ((taskq_req = dprov_alloc_req(req_type, softc, req, 5342 KM_NOSLEEP)) == NULL) 5343 return (CRYPTO_HOST_MEMORY); 5344 5345 taskq_req->dr_key_req.kr_session_id = session_id; 5346 taskq_req->dr_key_req.kr_mechanism = mechanism; 5347 taskq_req->dr_key_req.kr_template = template; 5348 taskq_req->dr_key_req.kr_attribute_count = attribute_count; 5349 taskq_req->dr_key_req.kr_object_id_ptr = object_id_ptr; 5350 taskq_req->dr_key_req.kr_private_key_template = private_key_template; 5351 taskq_req->dr_key_req.kr_private_key_attribute_count = 5352 private_key_attribute_count; 5353 taskq_req->dr_key_req.kr_private_key_object_id_ptr = 5354 private_key_object_id_ptr; 5355 taskq_req->dr_key_req.kr_key = key; 5356 taskq_req->dr_key_req.kr_wrapped_key = wrapped_key; 5357 taskq_req->dr_key_req.kr_wrapped_key_len_ptr = wrapped_key_len_ptr; 5358 taskq_req->dr_key_req.kr_out_template1 = out_template1; 5359 taskq_req->dr_key_req.kr_out_attribute_count1 = out_attribute_count1; 5360 taskq_req->dr_key_req.kr_out_template2 = out_template2; 5361 taskq_req->dr_key_req.kr_out_attribute_count2 = out_attribute_count2; 5362 5363 return (dprov_taskq_dispatch(softc, taskq_req, 5364 (task_func_t *)dprov_key_task, KM_NOSLEEP)); 5365 } 5366 5367 /* 5368 * Helper function to submit provider management operations to the taskq. 5369 * Returns one of the CRYPTO_ errors. 5370 */ 5371 static int 5372 dprov_mgmt_submit_req(dprov_req_type_t req_type, 5373 dprov_state_t *softc, crypto_req_handle_t req, 5374 crypto_session_id_t session_id, char *pin, size_t pin_len, 5375 char *old_pin, size_t old_pin_len, char *label, 5376 crypto_provider_ext_info_t *ext_info) 5377 { 5378 dprov_req_t *taskq_req; 5379 5380 if ((taskq_req = dprov_alloc_req(req_type, softc, req, 5381 KM_NOSLEEP)) == NULL) 5382 return (CRYPTO_HOST_MEMORY); 5383 5384 taskq_req->dr_mgmt_req.mr_session_id = session_id; 5385 taskq_req->dr_mgmt_req.mr_pin = pin; 5386 taskq_req->dr_mgmt_req.mr_pin_len = pin_len; 5387 taskq_req->dr_mgmt_req.mr_old_pin = old_pin; 5388 taskq_req->dr_mgmt_req.mr_old_pin_len = old_pin_len; 5389 taskq_req->dr_mgmt_req.mr_label = label; 5390 taskq_req->dr_mgmt_req.mr_ext_info = ext_info; 5391 5392 return (dprov_taskq_dispatch(softc, taskq_req, 5393 (task_func_t *)dprov_mgmt_task, KM_NOSLEEP)); 5394 } 5395 5396 /* 5397 * Helper function for taskq dispatcher routines. Notify the framework 5398 * that the operation corresponding to the specified request is done, 5399 * and pass it the error code. Finally, free the taskq_req. 5400 */ 5401 static void 5402 dprov_op_done(dprov_req_t *taskq_req, int error) 5403 { 5404 /* notify framework that request is completed */ 5405 crypto_op_notification(taskq_req->dr_kcf_req, error); 5406 5407 /* free taskq request structure */ 5408 kmem_free(taskq_req, sizeof (dprov_req_t)); 5409 } 5410 5411 /* 5412 * taskq dispatcher function for digest operations. 5413 */ 5414 static void 5415 dprov_digest_task(dprov_req_t *taskq_req) 5416 { 5417 kcf_provider_desc_t *pd; 5418 dprov_state_t *softc; 5419 /* LINTED E_FUNC_SET_NOT_USED */ 5420 int instance; 5421 int error = CRYPTO_NOT_SUPPORTED; 5422 crypto_ctx_t *ctx = taskq_req->dr_digest_req.dr_ctx; 5423 crypto_mechanism_t mech; 5424 5425 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 5426 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_task: started\n", instance)); 5427 5428 switch (taskq_req->dr_type) { 5429 5430 case DPROV_REQ_DIGEST_INIT: 5431 /* allocate a dprov-private context */ 5432 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) != 5433 CRYPTO_SUCCESS) 5434 break; 5435 5436 /* structure assignment */ 5437 mech = *taskq_req->dr_digest_req.dr_mechanism; 5438 5439 /* get the software provider for this mechanism */ 5440 if ((error = dprov_get_sw_prov( 5441 taskq_req->dr_digest_req.dr_mechanism, &pd, 5442 &mech.cm_type)) != CRYPTO_SUCCESS) 5443 break; 5444 5445 /* Use a session id of zero since we use a software provider */ 5446 error = crypto_digest_init_prov(pd, 0, &mech, 5447 &DPROV_CTX_SINGLE(ctx), NULL); 5448 5449 /* release provider reference */ 5450 KCF_PROV_REFRELE(pd); 5451 break; 5452 5453 case DPROV_REQ_DIGEST: 5454 error = crypto_digest_single(DPROV_CTX_SINGLE(ctx), 5455 taskq_req->dr_digest_req.dr_data, 5456 taskq_req->dr_digest_req.dr_digest, NULL); 5457 5458 if (error != CRYPTO_BUFFER_TOO_SMALL) { 5459 DPROV_CTX_SINGLE(ctx) = NULL; 5460 (void) dprov_free_context(ctx); 5461 } 5462 break; 5463 5464 case DPROV_REQ_DIGEST_UPDATE: 5465 error = crypto_digest_update(DPROV_CTX_SINGLE(ctx), 5466 taskq_req->dr_digest_req.dr_data, NULL); 5467 break; 5468 5469 case DPROV_REQ_DIGEST_KEY: { 5470 crypto_data_t data; 5471 crypto_key_t key; 5472 size_t len; 5473 5474 mutex_enter(&softc->ds_lock); 5475 error = dprov_key_value_secret(softc, ctx->cc_session, 5476 taskq_req->dr_type, taskq_req->dr_digest_req.dr_key, &key); 5477 mutex_exit(&softc->ds_lock); 5478 if (error != CRYPTO_SUCCESS) 5479 break; 5480 5481 /* key lengths are specified in bits */ 5482 len = CRYPTO_BITS2BYTES(key.ck_length); 5483 data.cd_format = CRYPTO_DATA_RAW; 5484 data.cd_offset = 0; 5485 data.cd_length = len; 5486 data.cd_raw.iov_base = key.ck_data; 5487 data.cd_raw.iov_len = len; 5488 error = crypto_digest_update(DPROV_CTX_SINGLE(ctx), 5489 &data, NULL); 5490 break; 5491 } 5492 5493 case DPROV_REQ_DIGEST_FINAL: 5494 error = crypto_digest_final(DPROV_CTX_SINGLE(ctx), 5495 taskq_req->dr_digest_req.dr_digest, NULL); 5496 if (error != CRYPTO_BUFFER_TOO_SMALL) { 5497 DPROV_CTX_SINGLE(ctx) = NULL; 5498 (void) dprov_free_context(ctx); 5499 } 5500 break; 5501 5502 case DPROV_REQ_DIGEST_ATOMIC: 5503 /* structure assignment */ 5504 mech = *taskq_req->dr_digest_req.dr_mechanism; 5505 5506 /* get the software provider for this mechanism */ 5507 if ((error = dprov_get_sw_prov( 5508 taskq_req->dr_digest_req.dr_mechanism, &pd, 5509 &mech.cm_type)) != CRYPTO_SUCCESS) 5510 break; 5511 5512 /* use a session id of zero since we use a software provider */ 5513 error = crypto_digest_prov(pd, 0, &mech, 5514 taskq_req->dr_digest_req.dr_data, 5515 taskq_req->dr_digest_req.dr_digest, NULL); 5516 5517 /* release provider reference */ 5518 KCF_PROV_REFRELE(pd); 5519 5520 break; 5521 } 5522 5523 dprov_op_done(taskq_req, error); 5524 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_task: end\n", instance)); 5525 } 5526 5527 /* 5528 * taskq dispatcher function for mac operations. 5529 */ 5530 static void 5531 dprov_mac_task(dprov_req_t *taskq_req) 5532 { 5533 kcf_provider_desc_t *pd; 5534 dprov_state_t *softc; 5535 /* LINTED E_FUNC_SET_NOT_USED */ 5536 int instance; 5537 int error = CRYPTO_NOT_SUPPORTED; 5538 crypto_ctx_t *ctx = taskq_req->dr_mac_req.dr_ctx; 5539 crypto_key_t key; 5540 crypto_mechanism_t mech; 5541 5542 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 5543 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: started\n", instance)); 5544 5545 switch (taskq_req->dr_type) { 5546 5547 case DPROV_REQ_MAC_INIT: 5548 /* allocate a dprov-private context */ 5549 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) != 5550 CRYPTO_SUCCESS) 5551 break; 5552 5553 /* get key value */ 5554 mutex_enter(&softc->ds_lock); 5555 error = dprov_key_value_secret(softc, ctx->cc_session, 5556 taskq_req->dr_type, taskq_req->dr_mac_req.dr_key, &key); 5557 mutex_exit(&softc->ds_lock); 5558 if (error != CRYPTO_SUCCESS) 5559 break; 5560 5561 /* structure assignment */ 5562 mech = *taskq_req->dr_mac_req.dr_mechanism; 5563 5564 /* get the software provider for this mechanism */ 5565 if ((error = dprov_get_sw_prov( 5566 taskq_req->dr_mac_req.dr_mechanism, &pd, 5567 &mech.cm_type)) != CRYPTO_SUCCESS) 5568 break; 5569 5570 /* Use a session id of zero since we use a software provider */ 5571 error = crypto_mac_init_prov(pd, 0, &mech, &key, NULL, 5572 &DPROV_CTX_SINGLE(ctx), NULL); 5573 5574 /* release provider reference */ 5575 KCF_PROV_REFRELE(pd); 5576 break; 5577 5578 case DPROV_REQ_MAC: 5579 error = crypto_mac_single(DPROV_CTX_SINGLE(ctx), 5580 taskq_req->dr_mac_req.dr_data, 5581 taskq_req->dr_mac_req.dr_mac, NULL); 5582 5583 if (error != CRYPTO_BUFFER_TOO_SMALL) { 5584 DPROV_CTX_SINGLE(ctx) = NULL; 5585 (void) dprov_free_context(ctx); 5586 } 5587 break; 5588 5589 case DPROV_REQ_MAC_UPDATE: 5590 error = crypto_mac_update(DPROV_CTX_SINGLE(ctx), 5591 taskq_req->dr_mac_req.dr_data, NULL); 5592 break; 5593 5594 case DPROV_REQ_MAC_FINAL: 5595 error = crypto_mac_final(DPROV_CTX_SINGLE(ctx), 5596 taskq_req->dr_mac_req.dr_mac, NULL); 5597 if (error != CRYPTO_BUFFER_TOO_SMALL) { 5598 DPROV_CTX_SINGLE(ctx) = NULL; 5599 (void) dprov_free_context(ctx); 5600 } 5601 break; 5602 5603 case DPROV_REQ_MAC_ATOMIC: 5604 case DPROV_REQ_MAC_VERIFY_ATOMIC: 5605 /* get key value */ 5606 mutex_enter(&softc->ds_lock); 5607 error = dprov_key_value_secret(softc, 5608 taskq_req->dr_mac_req.dr_session_id, 5609 taskq_req->dr_type, taskq_req->dr_mac_req.dr_key, &key); 5610 mutex_exit(&softc->ds_lock); 5611 if (error != CRYPTO_SUCCESS) 5612 break; 5613 5614 /* structure assignment */ 5615 mech = *taskq_req->dr_mac_req.dr_mechanism; 5616 5617 /* get the software provider for this mechanism */ 5618 if ((error = dprov_get_sw_prov( 5619 taskq_req->dr_mac_req.dr_mechanism, &pd, 5620 &mech.cm_type)) != CRYPTO_SUCCESS) 5621 break; 5622 5623 /* use a session id of zero since we use a software provider */ 5624 if (taskq_req->dr_type == DPROV_REQ_MAC_ATOMIC) 5625 error = crypto_mac_prov(pd, 0, &mech, 5626 taskq_req->dr_mac_req.dr_data, 5627 &key, NULL, taskq_req->dr_mac_req.dr_mac, NULL); 5628 else 5629 error = crypto_mac_verify_prov(pd, 0, &mech, 5630 taskq_req->dr_mac_req.dr_data, 5631 &key, NULL, taskq_req->dr_mac_req.dr_mac, NULL); 5632 5633 /* release provider reference */ 5634 KCF_PROV_REFRELE(pd); 5635 5636 break; 5637 } 5638 5639 dprov_op_done(taskq_req, error); 5640 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: end\n", instance)); 5641 } 5642 5643 /* 5644 * taskq dispatcher function for sign operations. 5645 */ 5646 static void 5647 dprov_sign_task(dprov_req_t *taskq_req) 5648 { 5649 kcf_provider_desc_t *pd; 5650 dprov_state_t *softc; 5651 /* LINTED E_FUNC_SET_NOT_USED */ 5652 int instance; 5653 int error = CRYPTO_NOT_SUPPORTED; 5654 crypto_ctx_t *ctx = taskq_req->dr_sign_req.sr_ctx; 5655 crypto_key_t key, *keyp; 5656 crypto_mechanism_t mech; 5657 5658 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 5659 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_task: started\n", instance)); 5660 5661 switch (taskq_req->dr_type) { 5662 5663 case DPROV_REQ_SIGN_INIT: 5664 case DPROV_REQ_SIGN_RECOVER_INIT: 5665 /* allocate a dprov-private context */ 5666 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) != 5667 CRYPTO_SUCCESS) 5668 break; 5669 5670 /* structure assignment */ 5671 mech = *taskq_req->dr_sign_req.sr_mechanism; 5672 if (dprov_valid_mac_mech(mech.cm_type)) { 5673 DPROV_CTX_P(ctx)->dc_svrfy_to_mac = B_TRUE; 5674 } 5675 5676 mutex_enter(&softc->ds_lock); 5677 if (is_publickey_mech(mech.cm_type)) { 5678 if ((error = dprov_key_attr_asymmetric(softc, 5679 ctx->cc_session, taskq_req->dr_type, 5680 taskq_req->dr_sign_req.sr_key, &key)) 5681 != CRYPTO_SUCCESS) { 5682 mutex_exit(&softc->ds_lock); 5683 break; 5684 } 5685 keyp = &key; 5686 } else { 5687 if ((error = dprov_key_value_secret(softc, 5688 ctx->cc_session, taskq_req->dr_type, 5689 taskq_req->dr_sign_req.sr_key, &key)) 5690 != CRYPTO_SUCCESS) { 5691 mutex_exit(&softc->ds_lock); 5692 break; 5693 } 5694 keyp = &key; 5695 } 5696 mutex_exit(&softc->ds_lock); 5697 5698 /* get the software provider for this mechanism */ 5699 if ((error = dprov_get_sw_prov( 5700 taskq_req->dr_sign_req.sr_mechanism, &pd, 5701 &mech.cm_type)) != CRYPTO_SUCCESS) 5702 break; 5703 5704 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) { 5705 error = crypto_mac_init_prov(pd, 0, &mech, keyp, NULL, 5706 &DPROV_CTX_SINGLE(ctx), NULL); 5707 5708 /* release provider reference */ 5709 KCF_PROV_REFRELE(pd); 5710 break; 5711 } 5712 5713 /* Use a session id of zero since we use a software provider */ 5714 if (taskq_req->dr_type == DPROV_REQ_SIGN_INIT) 5715 error = crypto_sign_init_prov(pd, 0, &mech, keyp, 5716 NULL, &DPROV_CTX_SINGLE(ctx), NULL); 5717 else 5718 error = crypto_sign_recover_init_prov(pd, 0, &mech, 5719 keyp, NULL, &DPROV_CTX_SINGLE(ctx), NULL); 5720 5721 /* release provider reference */ 5722 KCF_PROV_REFRELE(pd); 5723 5724 break; 5725 5726 case DPROV_REQ_SIGN: 5727 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) { 5728 /* Emulate using update and final */ 5729 error = crypto_mac_update(DPROV_CTX_SINGLE(ctx), 5730 taskq_req->dr_mac_req.dr_data, NULL); 5731 if (error == CRYPTO_SUCCESS) { 5732 error = crypto_mac_final(DPROV_CTX_SINGLE(ctx), 5733 taskq_req->dr_mac_req.dr_mac, NULL); 5734 } 5735 } else { 5736 error = crypto_sign_single(DPROV_CTX_SINGLE(ctx), 5737 taskq_req->dr_sign_req.sr_data, 5738 taskq_req->dr_sign_req.sr_signature, NULL); 5739 } 5740 5741 if (error != CRYPTO_BUFFER_TOO_SMALL) { 5742 DPROV_CTX_SINGLE(ctx) = NULL; 5743 (void) dprov_free_context(ctx); 5744 } 5745 break; 5746 5747 case DPROV_REQ_SIGN_UPDATE: 5748 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) { 5749 error = crypto_mac_update(DPROV_CTX_SINGLE(ctx), 5750 taskq_req->dr_mac_req.dr_data, NULL); 5751 } else { 5752 error = crypto_sign_update(DPROV_CTX_SINGLE(ctx), 5753 taskq_req->dr_sign_req.sr_data, NULL); 5754 } 5755 break; 5756 5757 case DPROV_REQ_SIGN_FINAL: 5758 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) { 5759 error = crypto_mac_final(DPROV_CTX_SINGLE(ctx), 5760 taskq_req->dr_mac_req.dr_mac, NULL); 5761 } else { 5762 error = crypto_sign_final(DPROV_CTX_SINGLE(ctx), 5763 taskq_req->dr_sign_req.sr_signature, NULL); 5764 } 5765 5766 if (error != CRYPTO_BUFFER_TOO_SMALL) { 5767 DPROV_CTX_SINGLE(ctx) = NULL; 5768 (void) dprov_free_context(ctx); 5769 } 5770 break; 5771 5772 case DPROV_REQ_SIGN_ATOMIC: 5773 case DPROV_REQ_SIGN_RECOVER_ATOMIC: 5774 /* structure assignment */ 5775 mech = *taskq_req->dr_sign_req.sr_mechanism; 5776 5777 mutex_enter(&softc->ds_lock); 5778 /* get key value for secret key algorithms */ 5779 if (is_publickey_mech(mech.cm_type)) { 5780 if ((error = dprov_key_attr_asymmetric(softc, 5781 taskq_req->dr_sign_req.sr_session_id, 5782 taskq_req->dr_type, 5783 taskq_req->dr_sign_req.sr_key, &key)) 5784 != CRYPTO_SUCCESS) { 5785 mutex_exit(&softc->ds_lock); 5786 break; 5787 } 5788 keyp = &key; 5789 } else { 5790 if ((error = dprov_key_value_secret(softc, 5791 taskq_req->dr_sign_req.sr_session_id, 5792 taskq_req->dr_type, 5793 taskq_req->dr_sign_req.sr_key, &key)) 5794 != CRYPTO_SUCCESS) { 5795 mutex_exit(&softc->ds_lock); 5796 break; 5797 } 5798 keyp = &key; 5799 } 5800 mutex_exit(&softc->ds_lock); 5801 5802 /* get the software provider for this mechanism */ 5803 if ((error = dprov_get_sw_prov( 5804 taskq_req->dr_sign_req.sr_mechanism, &pd, 5805 &mech.cm_type)) != CRYPTO_SUCCESS) 5806 break; 5807 5808 /* Use a session id of zero since we use a software provider */ 5809 if (taskq_req->dr_type == DPROV_REQ_SIGN_ATOMIC) 5810 error = crypto_sign_prov(pd, 0, &mech, keyp, 5811 taskq_req->dr_sign_req.sr_data, 5812 NULL, taskq_req->dr_sign_req.sr_signature, NULL); 5813 else 5814 error = crypto_sign_recover_prov(pd, 0, &mech, keyp, 5815 taskq_req->dr_sign_req.sr_data, 5816 NULL, taskq_req->dr_sign_req.sr_signature, NULL); 5817 5818 /* release provider reference */ 5819 KCF_PROV_REFRELE(pd); 5820 break; 5821 5822 case DPROV_REQ_SIGN_RECOVER: 5823 error = crypto_sign_recover_single(DPROV_CTX_SINGLE(ctx), 5824 taskq_req->dr_sign_req.sr_data, 5825 taskq_req->dr_sign_req.sr_signature, NULL); 5826 5827 if (error != CRYPTO_BUFFER_TOO_SMALL) { 5828 DPROV_CTX_SINGLE(ctx) = NULL; 5829 (void) dprov_free_context(ctx); 5830 } 5831 break; 5832 } 5833 5834 dprov_op_done(taskq_req, error); 5835 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_task: end\n", instance)); 5836 } 5837 5838 static int 5839 emulate_verify_with_mac(crypto_ctx_t *ctx, crypto_data_t *in_mac) 5840 { 5841 int error; 5842 crypto_data_t tmpd; 5843 crypto_data_t *out_mac; 5844 char digest[SHA512_DIGEST_LENGTH]; 5845 5846 bzero(&tmpd, sizeof (crypto_data_t)); 5847 tmpd.cd_format = CRYPTO_DATA_RAW; 5848 tmpd.cd_length = SHA512_DIGEST_LENGTH; 5849 tmpd.cd_raw.iov_base = digest; 5850 tmpd.cd_raw.iov_len = SHA512_DIGEST_LENGTH; 5851 out_mac = &tmpd; 5852 5853 error = crypto_mac_final(DPROV_CTX_SINGLE(ctx), out_mac, NULL); 5854 if (in_mac->cd_length != out_mac->cd_length || 5855 (bcmp(digest, (unsigned char *)in_mac->cd_raw.iov_base + 5856 in_mac->cd_offset, out_mac->cd_length) != 0)) { 5857 error = CRYPTO_INVALID_MAC; 5858 } 5859 5860 return (error); 5861 } 5862 5863 /* 5864 * taskq dispatcher function for verify operations. 5865 */ 5866 static void 5867 dprov_verify_task(dprov_req_t *taskq_req) 5868 { 5869 kcf_provider_desc_t *pd; 5870 dprov_state_t *softc; 5871 /* LINTED E_FUNC_SET_NOT_USED */ 5872 int instance; 5873 int error = CRYPTO_NOT_SUPPORTED; 5874 crypto_ctx_t *ctx = taskq_req->dr_verify_req.vr_ctx; 5875 crypto_key_t key, *keyp; 5876 crypto_mechanism_t mech; 5877 5878 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 5879 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_task: started\n", instance)); 5880 5881 switch (taskq_req->dr_type) { 5882 5883 case DPROV_REQ_VERIFY_INIT: 5884 case DPROV_REQ_VERIFY_RECOVER_INIT: 5885 /* allocate a dprov-private context */ 5886 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) != 5887 CRYPTO_SUCCESS) 5888 break; 5889 5890 /* structure assignment */ 5891 mech = *taskq_req->dr_verify_req.vr_mechanism; 5892 if (dprov_valid_mac_mech(mech.cm_type)) { 5893 DPROV_CTX_P(ctx)->dc_svrfy_to_mac = B_TRUE; 5894 } 5895 5896 mutex_enter(&softc->ds_lock); 5897 /* get key value for secret key algorithms */ 5898 if (is_publickey_mech(mech.cm_type)) { 5899 if ((error = dprov_key_attr_asymmetric(softc, 5900 ctx->cc_session, taskq_req->dr_type, 5901 taskq_req->dr_verify_req.vr_key, &key)) 5902 != CRYPTO_SUCCESS) { 5903 mutex_exit(&softc->ds_lock); 5904 break; 5905 } 5906 keyp = &key; 5907 } else { 5908 if ((error = dprov_key_value_secret(softc, 5909 ctx->cc_session, taskq_req->dr_type, 5910 taskq_req->dr_verify_req.vr_key, &key)) 5911 != CRYPTO_SUCCESS) { 5912 mutex_exit(&softc->ds_lock); 5913 break; 5914 } 5915 keyp = &key; 5916 } 5917 mutex_exit(&softc->ds_lock); 5918 5919 /* get the software provider for this mechanism */ 5920 if ((error = dprov_get_sw_prov( 5921 taskq_req->dr_verify_req.vr_mechanism, &pd, 5922 &mech.cm_type)) != CRYPTO_SUCCESS) 5923 break; 5924 5925 5926 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) { 5927 error = crypto_mac_init_prov(pd, 0, &mech, keyp, NULL, 5928 &DPROV_CTX_SINGLE(ctx), NULL); 5929 5930 /* release provider reference */ 5931 KCF_PROV_REFRELE(pd); 5932 break; 5933 } 5934 5935 /* Use a session id of zero since we use a software provider */ 5936 if (taskq_req->dr_type == DPROV_REQ_VERIFY_INIT) 5937 error = crypto_verify_init_prov(pd, 0, &mech, keyp, 5938 NULL, &DPROV_CTX_SINGLE(ctx), NULL); 5939 else 5940 error = crypto_verify_recover_init_prov(pd, 0, &mech, 5941 keyp, NULL, &DPROV_CTX_SINGLE(ctx), NULL); 5942 5943 /* release provider reference */ 5944 KCF_PROV_REFRELE(pd); 5945 5946 break; 5947 5948 case DPROV_REQ_VERIFY: 5949 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) { 5950 /* Emulate using update and final */ 5951 error = crypto_mac_update(DPROV_CTX_SINGLE(ctx), 5952 taskq_req->dr_mac_req.dr_data, NULL); 5953 if (error == CRYPTO_SUCCESS) { 5954 error = emulate_verify_with_mac(ctx, 5955 taskq_req->dr_mac_req.dr_mac); 5956 } 5957 } else { 5958 error = crypto_verify_single(DPROV_CTX_SINGLE(ctx), 5959 taskq_req->dr_verify_req.vr_data, 5960 taskq_req->dr_verify_req.vr_signature, NULL); 5961 } 5962 5963 ASSERT(error != CRYPTO_BUFFER_TOO_SMALL); 5964 DPROV_CTX_SINGLE(ctx) = NULL; 5965 (void) dprov_free_context(ctx); 5966 break; 5967 5968 case DPROV_REQ_VERIFY_UPDATE: 5969 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) { 5970 error = crypto_mac_update(DPROV_CTX_SINGLE(ctx), 5971 taskq_req->dr_mac_req.dr_data, NULL); 5972 } else { 5973 error = crypto_verify_update(DPROV_CTX_SINGLE(ctx), 5974 taskq_req->dr_verify_req.vr_data, NULL); 5975 } 5976 break; 5977 5978 case DPROV_REQ_VERIFY_FINAL: 5979 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) { 5980 error = emulate_verify_with_mac(ctx, 5981 taskq_req->dr_mac_req.dr_mac); 5982 } else { 5983 error = crypto_verify_final(DPROV_CTX_SINGLE(ctx), 5984 taskq_req->dr_verify_req.vr_signature, NULL); 5985 } 5986 5987 ASSERT(error != CRYPTO_BUFFER_TOO_SMALL); 5988 DPROV_CTX_SINGLE(ctx) = NULL; 5989 (void) dprov_free_context(ctx); 5990 break; 5991 5992 case DPROV_REQ_VERIFY_ATOMIC: 5993 case DPROV_REQ_VERIFY_RECOVER_ATOMIC: 5994 /* structure assignment */ 5995 mech = *taskq_req->dr_verify_req.vr_mechanism; 5996 5997 mutex_enter(&softc->ds_lock); 5998 /* get key value for secret key algorithms */ 5999 if (is_publickey_mech(mech.cm_type)) { 6000 if ((error = dprov_key_attr_asymmetric(softc, 6001 taskq_req->dr_verify_req.vr_session_id, 6002 taskq_req->dr_type, 6003 taskq_req->dr_verify_req.vr_key, &key)) 6004 != CRYPTO_SUCCESS) { 6005 mutex_exit(&softc->ds_lock); 6006 break; 6007 } 6008 keyp = &key; 6009 } else { 6010 if ((error = dprov_key_value_secret(softc, 6011 taskq_req->dr_verify_req.vr_session_id, 6012 taskq_req->dr_type, 6013 taskq_req->dr_verify_req.vr_key, &key)) 6014 != CRYPTO_SUCCESS) { 6015 mutex_exit(&softc->ds_lock); 6016 break; 6017 } 6018 keyp = &key; 6019 } 6020 mutex_exit(&softc->ds_lock); 6021 6022 /* get the software provider for this mechanism */ 6023 if ((error = dprov_get_sw_prov( 6024 taskq_req->dr_verify_req.vr_mechanism, &pd, 6025 &mech.cm_type)) != CRYPTO_SUCCESS) 6026 break; 6027 6028 /* Use a session id of zero since we use a software provider */ 6029 if (taskq_req->dr_type == DPROV_REQ_VERIFY_ATOMIC) 6030 error = crypto_verify_prov(pd, 0, &mech, keyp, 6031 taskq_req->dr_verify_req.vr_data, 6032 NULL, taskq_req->dr_verify_req.vr_signature, NULL); 6033 else 6034 /* 6035 * crypto_verify_recover_prov() has different argument 6036 * order than crypto_verify_prov(). 6037 */ 6038 error = crypto_verify_recover_prov(pd, 0, &mech, keyp, 6039 taskq_req->dr_verify_req.vr_signature, 6040 NULL, taskq_req->dr_verify_req.vr_data, NULL); 6041 6042 /* release provider reference */ 6043 KCF_PROV_REFRELE(pd); 6044 break; 6045 6046 case DPROV_REQ_VERIFY_RECOVER: 6047 /* 6048 * crypto_verify_recover_single() has different argument 6049 * order than crypto_verify_single(). 6050 */ 6051 error = crypto_verify_recover_single(DPROV_CTX_SINGLE(ctx), 6052 taskq_req->dr_verify_req.vr_signature, 6053 taskq_req->dr_verify_req.vr_data, NULL); 6054 6055 if (error != CRYPTO_BUFFER_TOO_SMALL) { 6056 DPROV_CTX_SINGLE(ctx) = NULL; 6057 (void) dprov_free_context(ctx); 6058 } 6059 break; 6060 } 6061 6062 dprov_op_done(taskq_req, error); 6063 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_task: end\n", instance)); 6064 } 6065 6066 /* 6067 * taskq dispatcher function for dual operations. 6068 */ 6069 static void 6070 dprov_dual_task(dprov_req_t *taskq_req) 6071 { 6072 dprov_state_t *softc; 6073 /* LINTED E_FUNC_SET_NOT_USED */ 6074 int instance; 6075 int error = CRYPTO_NOT_SUPPORTED; 6076 crypto_ctx_t *signverify_ctx = taskq_req->dr_dual_req.dr_signverify_ctx; 6077 crypto_ctx_t *cipher_ctx = taskq_req->dr_dual_req.dr_cipher_ctx; 6078 6079 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 6080 DPROV_DEBUG(D_DUAL, ("(%d) dprov_dual_task: started\n", instance)); 6081 6082 switch (taskq_req->dr_type) { 6083 6084 case DPROV_REQ_DIGEST_ENCRYPT_UPDATE: 6085 error = crypto_digest_encrypt_update( 6086 DPROV_CTX_SINGLE(signverify_ctx), 6087 DPROV_CTX_SINGLE(cipher_ctx), 6088 taskq_req->dr_dual_req.dr_plaintext, 6089 taskq_req->dr_dual_req.dr_ciphertext, NULL); 6090 break; 6091 6092 case DPROV_REQ_DECRYPT_DIGEST_UPDATE: 6093 error = crypto_decrypt_digest_update( 6094 DPROV_CTX_SINGLE(cipher_ctx), 6095 DPROV_CTX_SINGLE(signverify_ctx), 6096 taskq_req->dr_dual_req.dr_ciphertext, 6097 taskq_req->dr_dual_req.dr_plaintext, NULL); 6098 break; 6099 6100 case DPROV_REQ_SIGN_ENCRYPT_UPDATE: 6101 error = crypto_sign_encrypt_update( 6102 DPROV_CTX_SINGLE(signverify_ctx), 6103 DPROV_CTX_SINGLE(cipher_ctx), 6104 taskq_req->dr_dual_req.dr_plaintext, 6105 taskq_req->dr_dual_req.dr_ciphertext, NULL); 6106 break; 6107 6108 case DPROV_REQ_DECRYPT_VERIFY_UPDATE: 6109 error = crypto_decrypt_verify_update( 6110 DPROV_CTX_SINGLE(cipher_ctx), 6111 DPROV_CTX_SINGLE(signverify_ctx), 6112 taskq_req->dr_dual_req.dr_ciphertext, 6113 taskq_req->dr_dual_req.dr_plaintext, NULL); 6114 break; 6115 } 6116 6117 dprov_op_done(taskq_req, error); 6118 DPROV_DEBUG(D_DUAL, ("(%d) dprov_dual_task: end\n", instance)); 6119 } 6120 6121 /* 6122 * taskq dispatcher function for cipher operations. 6123 */ 6124 static void 6125 dprov_cipher_task(dprov_req_t *taskq_req) 6126 { 6127 kcf_provider_desc_t *pd; 6128 dprov_state_t *softc; 6129 /* LINTED E_FUNC_SET_NOT_USED */ 6130 int instance; 6131 int error = CRYPTO_NOT_SUPPORTED; 6132 crypto_ctx_t *ctx = taskq_req->dr_cipher_req.dr_ctx; 6133 crypto_key_t key, *keyp; 6134 crypto_mechanism_t mech; 6135 6136 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 6137 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_cipher_task: started\n", instance)); 6138 6139 switch (taskq_req->dr_type) { 6140 6141 case DPROV_REQ_ENCRYPT_INIT: 6142 case DPROV_REQ_DECRYPT_INIT: 6143 /* allocate a dprov-private context */ 6144 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) != 6145 CRYPTO_SUCCESS) 6146 break; 6147 6148 /* structure assignment */ 6149 mech = *taskq_req->dr_cipher_req.dr_mechanism; 6150 6151 mutex_enter(&softc->ds_lock); 6152 /* get key value for secret key algorithms */ 6153 if (is_publickey_mech(mech.cm_type)) { 6154 if ((error = dprov_key_attr_asymmetric(softc, 6155 ctx->cc_session, taskq_req->dr_type, 6156 taskq_req->dr_cipher_req.dr_key, &key)) 6157 != CRYPTO_SUCCESS) { 6158 mutex_exit(&softc->ds_lock); 6159 break; 6160 } 6161 keyp = &key; 6162 } else { 6163 if ((error = dprov_key_value_secret(softc, 6164 ctx->cc_session, taskq_req->dr_type, 6165 taskq_req->dr_cipher_req.dr_key, &key)) 6166 != CRYPTO_SUCCESS) { 6167 mutex_exit(&softc->ds_lock); 6168 break; 6169 } 6170 keyp = &key; 6171 } 6172 mutex_exit(&softc->ds_lock); 6173 6174 /* get the software provider for this mechanism */ 6175 if ((error = dprov_get_sw_prov( 6176 taskq_req->dr_cipher_req.dr_mechanism, &pd, 6177 &mech.cm_type)) != CRYPTO_SUCCESS) 6178 break; 6179 6180 /* Use a session id of zero since we use a software provider */ 6181 if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_INIT) 6182 error = crypto_encrypt_init_prov(pd, 0, &mech, keyp, 6183 NULL, &DPROV_CTX_SINGLE(ctx), NULL); 6184 else 6185 error = crypto_decrypt_init_prov(pd, 0, &mech, keyp, 6186 NULL, &DPROV_CTX_SINGLE(ctx), NULL); 6187 6188 if (ctx->cc_flags & CRYPTO_INIT_OPSTATE) { 6189 crypto_ctx_t *lctx = 6190 (crypto_ctx_t *)(DPROV_CTX_SINGLE(ctx)); 6191 6192 ctx->cc_opstate = lctx->cc_provider_private; 6193 ctx->cc_flags |= CRYPTO_USE_OPSTATE; 6194 } 6195 6196 /* release provider reference */ 6197 KCF_PROV_REFRELE(pd); 6198 break; 6199 6200 case DPROV_REQ_ENCRYPT: 6201 error = crypto_encrypt_single(DPROV_CTX_SINGLE(ctx), 6202 taskq_req->dr_cipher_req.dr_plaintext, 6203 taskq_req->dr_cipher_req.dr_ciphertext, NULL); 6204 6205 if (error != CRYPTO_BUFFER_TOO_SMALL) { 6206 DPROV_CTX_SINGLE(ctx) = NULL; 6207 (void) dprov_free_context(ctx); 6208 } 6209 break; 6210 6211 case DPROV_REQ_DECRYPT: 6212 error = crypto_decrypt_single(DPROV_CTX_SINGLE(ctx), 6213 taskq_req->dr_cipher_req.dr_ciphertext, 6214 taskq_req->dr_cipher_req.dr_plaintext, NULL); 6215 6216 if (error != CRYPTO_BUFFER_TOO_SMALL) { 6217 DPROV_CTX_SINGLE(ctx) = NULL; 6218 (void) dprov_free_context(ctx); 6219 } 6220 break; 6221 6222 case DPROV_REQ_ENCRYPT_UPDATE: 6223 ASSERT(!(ctx->cc_flags & CRYPTO_INIT_OPSTATE) || 6224 (ctx->cc_flags & CRYPTO_USE_OPSTATE)); 6225 error = crypto_encrypt_update(DPROV_CTX_SINGLE(ctx), 6226 taskq_req->dr_cipher_req.dr_plaintext, 6227 taskq_req->dr_cipher_req.dr_ciphertext, NULL); 6228 break; 6229 6230 case DPROV_REQ_DECRYPT_UPDATE: 6231 ASSERT(!(ctx->cc_flags & CRYPTO_INIT_OPSTATE) || 6232 (ctx->cc_flags & CRYPTO_USE_OPSTATE)); 6233 error = crypto_decrypt_update(DPROV_CTX_SINGLE(ctx), 6234 taskq_req->dr_cipher_req.dr_ciphertext, 6235 taskq_req->dr_cipher_req.dr_plaintext, NULL); 6236 break; 6237 6238 case DPROV_REQ_ENCRYPT_FINAL: 6239 error = crypto_encrypt_final(DPROV_CTX_SINGLE(ctx), 6240 taskq_req->dr_cipher_req.dr_ciphertext, NULL); 6241 if (error != CRYPTO_BUFFER_TOO_SMALL) { 6242 DPROV_CTX_SINGLE(ctx) = NULL; 6243 (void) dprov_free_context(ctx); 6244 } 6245 break; 6246 6247 case DPROV_REQ_DECRYPT_FINAL: 6248 error = crypto_decrypt_final(DPROV_CTX_SINGLE(ctx), 6249 taskq_req->dr_cipher_req.dr_plaintext, NULL); 6250 if (error != CRYPTO_BUFFER_TOO_SMALL) { 6251 DPROV_CTX_SINGLE(ctx) = NULL; 6252 (void) dprov_free_context(ctx); 6253 } 6254 break; 6255 6256 case DPROV_REQ_ENCRYPT_ATOMIC: 6257 case DPROV_REQ_DECRYPT_ATOMIC: 6258 /* structure assignment */ 6259 mech = *taskq_req->dr_cipher_req.dr_mechanism; 6260 6261 mutex_enter(&softc->ds_lock); 6262 /* get key value for secret key algorithms */ 6263 if (is_publickey_mech(mech.cm_type)) { 6264 if ((error = dprov_key_attr_asymmetric(softc, 6265 taskq_req->dr_cipher_req.dr_session_id, 6266 taskq_req->dr_type, 6267 taskq_req->dr_cipher_req.dr_key, 6268 &key)) != CRYPTO_SUCCESS) { 6269 mutex_exit(&softc->ds_lock); 6270 break; 6271 } 6272 keyp = &key; 6273 } else { 6274 if ((error = dprov_key_value_secret(softc, 6275 taskq_req->dr_cipher_req.dr_session_id, 6276 taskq_req->dr_type, taskq_req->dr_cipher_req.dr_key, 6277 &key)) 6278 != CRYPTO_SUCCESS) { 6279 mutex_exit(&softc->ds_lock); 6280 break; 6281 } 6282 keyp = &key; 6283 } 6284 mutex_exit(&softc->ds_lock); 6285 6286 /* get the software provider for this mechanism */ 6287 if ((error = dprov_get_sw_prov( 6288 taskq_req->dr_cipher_req.dr_mechanism, &pd, 6289 &mech.cm_type)) != CRYPTO_SUCCESS) 6290 break; 6291 6292 /* use a session id of zero since we use a software provider */ 6293 if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_ATOMIC) 6294 error = crypto_encrypt_prov(pd, 0, &mech, 6295 taskq_req->dr_cipher_req.dr_plaintext, 6296 keyp, NULL, 6297 taskq_req->dr_cipher_req.dr_ciphertext, NULL); 6298 else 6299 error = crypto_decrypt_prov(pd, 0, &mech, 6300 taskq_req->dr_cipher_req.dr_ciphertext, 6301 keyp, NULL, 6302 taskq_req->dr_cipher_req.dr_plaintext, NULL); 6303 6304 /* release provider reference */ 6305 KCF_PROV_REFRELE(pd); 6306 6307 break; 6308 } 6309 6310 dprov_op_done(taskq_req, error); 6311 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: end\n", instance)); 6312 } 6313 6314 /* 6315 * Helper function for the cipher/mac dual operation taskq dispatch 6316 * function. Initialize the cipher and mac key values and find the 6317 * providers that can process the request for the specified mechanisms. 6318 */ 6319 static int 6320 dprov_cipher_mac_key_pd(dprov_state_t *softc, crypto_session_id_t sid, 6321 dprov_req_t *taskq_req, crypto_key_t *cipher_key, crypto_key_t *mac_key, 6322 kcf_provider_desc_t **cipher_pd, kcf_provider_desc_t **mac_pd, 6323 crypto_mech_type_t *cipher_mech_type, crypto_mech_type_t *mac_mech_type) 6324 { 6325 int error; 6326 6327 /* get the cipher key value */ 6328 mutex_enter(&softc->ds_lock); 6329 error = dprov_key_value_secret(softc, sid, DPROV_REQ_ENCRYPT_ATOMIC, 6330 taskq_req->dr_cipher_mac_req.mr_cipher_key, cipher_key); 6331 if (error != CRYPTO_SUCCESS) { 6332 mutex_exit(&softc->ds_lock); 6333 return (error); 6334 } 6335 6336 /* get the mac key value */ 6337 error = dprov_key_value_secret(softc, sid, DPROV_REQ_MAC_ATOMIC, 6338 taskq_req->dr_cipher_mac_req.mr_mac_key, mac_key); 6339 mutex_exit(&softc->ds_lock); 6340 if (error != CRYPTO_SUCCESS) 6341 return (error); 6342 6343 /* get the SW provider to perform the cipher operation */ 6344 if ((error = dprov_get_sw_prov( 6345 taskq_req->dr_cipher_mac_req.mr_cipher_mech, cipher_pd, 6346 cipher_mech_type)) != CRYPTO_SUCCESS) 6347 return (error); 6348 6349 /* get the SW provider to perform the mac operation */ 6350 error = dprov_get_sw_prov(taskq_req->dr_cipher_mac_req.mr_mac_mech, 6351 mac_pd, mac_mech_type); 6352 6353 return (error); 6354 } 6355 6356 /* 6357 * taskq dispatcher function for cipher/mac dual operations. 6358 */ 6359 static void 6360 dprov_cipher_mac_task(dprov_req_t *taskq_req) 6361 { 6362 dprov_state_t *softc; 6363 /* LINTED E_FUNC_SET_NOT_USED */ 6364 int instance; 6365 int error = CRYPTO_NOT_SUPPORTED; 6366 crypto_ctx_t *ctx = taskq_req->dr_cipher_mac_req.mr_ctx; 6367 kcf_provider_desc_t *cipher_pd; 6368 kcf_provider_desc_t *mac_pd; 6369 crypto_key_t cipher_key; 6370 crypto_key_t mac_key; 6371 crypto_dual_data_t *dual_data = 6372 taskq_req->dr_cipher_mac_req.mr_dual_data; 6373 crypto_data_t cipher_data; 6374 crypto_data_t mac_data; 6375 crypto_mechanism_t cipher_mech, mac_mech; 6376 crypto_session_id_t session_id; 6377 6378 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 6379 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_cipher_mac_task: started\n", 6380 instance)); 6381 6382 switch (taskq_req->dr_type) { 6383 case DPROV_REQ_ENCRYPT_MAC_INIT: 6384 case DPROV_REQ_MAC_DECRYPT_INIT: 6385 /* structure assignment */ 6386 cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech; 6387 mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech; 6388 6389 /* get the keys values and providers to use for operations */ 6390 if ((error = dprov_cipher_mac_key_pd(softc, ctx->cc_session, 6391 taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd, 6392 &cipher_mech.cm_type, &mac_mech.cm_type)) != CRYPTO_SUCCESS) 6393 break; 6394 6395 /* allocate a dprov-private context */ 6396 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) != 6397 CRYPTO_SUCCESS) 6398 break; 6399 6400 if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_MAC_INIT) 6401 /* do the encryption initialization */ 6402 error = crypto_encrypt_init_prov(cipher_pd, 0, 6403 &cipher_mech, &cipher_key, NULL, 6404 &DPROV_CTX_DUAL_CIPHER(ctx), NULL); 6405 else 6406 /* do the decryption initialization */ 6407 error = crypto_decrypt_init_prov(cipher_pd, 0, 6408 &cipher_mech, &cipher_key, NULL, 6409 &DPROV_CTX_DUAL_CIPHER(ctx), NULL); 6410 if (error != CRYPTO_SUCCESS) 6411 break; 6412 6413 /* do the mac initialization */ 6414 if ((error = crypto_mac_init_prov(mac_pd, 0, 6415 &mac_mech, &mac_key, NULL, &DPROV_CTX_DUAL_MAC(ctx), 6416 NULL)) != CRYPTO_SUCCESS) 6417 break; 6418 6419 /* release references to providers */ 6420 KCF_PROV_REFRELE(cipher_pd); 6421 KCF_PROV_REFRELE(mac_pd); 6422 6423 break; 6424 6425 case DPROV_REQ_ENCRYPT_MAC: { 6426 size_t encrypted; 6427 boolean_t inplace; 6428 6429 crypto_data_t *plaintext_tmp, *ciphertext_tmp; 6430 6431 cipher_data = *((crypto_data_t *)dual_data); 6432 6433 /* do an encrypt update */ 6434 inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL); 6435 if (inplace) { 6436 plaintext_tmp = &cipher_data; 6437 ciphertext_tmp = NULL; 6438 } else { 6439 plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data; 6440 ciphertext_tmp = &cipher_data; 6441 } 6442 if ((error = crypto_encrypt_update(DPROV_CTX_DUAL_CIPHER(ctx), 6443 plaintext_tmp, ciphertext_tmp, NULL)) != CRYPTO_SUCCESS) 6444 break; 6445 6446 /* do an encrypt final */ 6447 encrypted = cipher_data.cd_length; 6448 6449 cipher_data.cd_offset += encrypted; 6450 cipher_data.cd_length = dual_data->dd_len1 - encrypted; 6451 6452 if ((error = crypto_encrypt_final(DPROV_CTX_DUAL_CIPHER(ctx), 6453 &cipher_data, NULL)) != CRYPTO_SUCCESS) 6454 break; 6455 6456 /* 6457 * Do a mac update on the resulting ciphertext, but with no 6458 * more bytes than specified by dual_data, and starting at 6459 * offset specified by dual_data. For in-place operations, 6460 * we use the length specified by the dual_data. 6461 */ 6462 mac_data = cipher_data; 6463 mac_data.cd_offset = dual_data->dd_offset2; 6464 mac_data.cd_length = dual_data->dd_len2; 6465 if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx), 6466 &mac_data, NULL)) != CRYPTO_SUCCESS) 6467 break; 6468 6469 /* do a mac final */ 6470 error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx), 6471 taskq_req->dr_cipher_mac_req.mr_mac, NULL); 6472 6473 /* Set the total size of the ciphertext, when successful */ 6474 if (error == CRYPTO_SUCCESS) 6475 dual_data->dd_len1 = encrypted + cipher_data.cd_length; 6476 6477 if (error != CRYPTO_BUFFER_TOO_SMALL) { 6478 DPROV_CTX_DUAL_CIPHER(ctx) = NULL; 6479 DPROV_CTX_DUAL_MAC(ctx) = NULL; 6480 (void) dprov_free_context(ctx); 6481 } 6482 break; 6483 } 6484 6485 case DPROV_REQ_ENCRYPT_MAC_UPDATE: { 6486 crypto_data_t *plaintext_tmp, *ciphertext_tmp; 6487 size_t encrypted; 6488 ssize_t maclen; 6489 boolean_t inplace; 6490 6491 cipher_data = *((crypto_data_t *)dual_data); 6492 6493 /* do an encrypt update */ 6494 inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL); 6495 if (inplace) { 6496 plaintext_tmp = &cipher_data; 6497 ciphertext_tmp = NULL; 6498 } else { 6499 plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data; 6500 ciphertext_tmp = &cipher_data; 6501 } 6502 if ((error = crypto_encrypt_update(DPROV_CTX_DUAL_CIPHER(ctx), 6503 plaintext_tmp, ciphertext_tmp, NULL)) != CRYPTO_SUCCESS) 6504 break; 6505 6506 encrypted = cipher_data.cd_length; 6507 6508 /* 6509 * Do a mac update on the resulting ciphertext, but with no 6510 * more bytes than specified by dual_data, and starting at 6511 * offset specified by dual_data. For in-place operations, 6512 * we use the length specified by the dual_data. 6513 * There is an edge case, when the encryption step produced 6514 * zero bytes in the ciphertext. Only the portion between 6515 * offset2 and offset1 is then thrown in the MAC mix. 6516 */ 6517 maclen = dual_data->dd_offset1 - dual_data->dd_offset2 + 6518 encrypted; 6519 if (maclen > 0) { 6520 mac_data = cipher_data; 6521 mac_data.cd_offset = dual_data->dd_offset2; 6522 mac_data.cd_length = min(dual_data->dd_len2, maclen); 6523 if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx), 6524 &mac_data, NULL)) != CRYPTO_SUCCESS) 6525 break; 6526 } 6527 /* Set the total size of the ciphertext, when successful */ 6528 if (error == CRYPTO_SUCCESS) 6529 dual_data->dd_len1 = encrypted; 6530 6531 break; 6532 } 6533 6534 case DPROV_REQ_ENCRYPT_MAC_FINAL: 6535 cipher_data = *((crypto_data_t *)dual_data); 6536 6537 /* do an encrypt final */ 6538 if ((error = crypto_encrypt_final(DPROV_CTX_DUAL_CIPHER(ctx), 6539 taskq_req->dr_cipher_mac_req.mr_data == NULL ? 6540 &cipher_data : taskq_req->dr_cipher_mac_req.mr_data, 6541 NULL)) != CRYPTO_SUCCESS) 6542 break; 6543 6544 /* 6545 * If ciphertext length is different from zero, do a mac 6546 * update on it. This does not apply to in-place since we 6547 * do not allow partial updates, hence no final residual. 6548 */ 6549 if (taskq_req->dr_cipher_mac_req.mr_data != NULL && 6550 taskq_req->dr_cipher_mac_req.mr_data->cd_length > 0) 6551 if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx), 6552 taskq_req->dr_cipher_mac_req.mr_data, NULL)) != 6553 CRYPTO_SUCCESS) 6554 break; 6555 6556 /* do a mac final */ 6557 error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx), 6558 taskq_req->dr_cipher_mac_req.mr_mac, NULL); 6559 6560 if (error != CRYPTO_BUFFER_TOO_SMALL) { 6561 DPROV_CTX_DUAL_CIPHER(ctx) = NULL; 6562 DPROV_CTX_DUAL_MAC(ctx) = NULL; 6563 (void) dprov_free_context(ctx); 6564 } 6565 break; 6566 6567 case DPROV_REQ_ENCRYPT_MAC_ATOMIC: { 6568 crypto_data_t *plaintext_tmp, *ciphertext_tmp; 6569 boolean_t inplace; 6570 6571 cipher_data = *((crypto_data_t *)dual_data); 6572 6573 /* do an encrypt atomic */ 6574 inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL); 6575 if (inplace) { 6576 plaintext_tmp = &cipher_data; 6577 ciphertext_tmp = NULL; 6578 } else { 6579 plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data; 6580 ciphertext_tmp = &cipher_data; 6581 } 6582 6583 /* structure assignment */ 6584 cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech; 6585 mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech; 6586 session_id = taskq_req->dr_cipher_mac_req.mr_session_id; 6587 6588 /* get the keys values and providers to use for operations */ 6589 if ((error = dprov_cipher_mac_key_pd(softc, session_id, 6590 taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd, 6591 &cipher_mech.cm_type, &mac_mech.cm_type)) != 6592 CRYPTO_SUCCESS) 6593 break; 6594 6595 /* do the atomic encrypt */ 6596 if ((error = crypto_encrypt_prov(cipher_pd, 0, 6597 &cipher_mech, plaintext_tmp, &cipher_key, NULL, 6598 ciphertext_tmp, NULL)) != CRYPTO_SUCCESS) 6599 break; 6600 6601 /* do the atomic mac */ 6602 mac_data = cipher_data; 6603 mac_data.cd_length = dual_data->dd_len2; 6604 mac_data.cd_offset = dual_data->dd_offset2; 6605 error = crypto_mac_prov(mac_pd, 0, &mac_mech, &mac_data, 6606 &mac_key, NULL, taskq_req->dr_cipher_mac_req.mr_mac, NULL); 6607 6608 dual_data->dd_len1 = cipher_data.cd_length; 6609 6610 break; 6611 } 6612 6613 case DPROV_REQ_MAC_DECRYPT: { 6614 uint_t decrypted; 6615 crypto_data_t plaintext_tmp; 6616 6617 cipher_data = *((crypto_data_t *)dual_data); 6618 6619 /* do a mac update and final on the ciphertext */ 6620 if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx), 6621 &mac_data, NULL)) != CRYPTO_SUCCESS) 6622 break; 6623 6624 /* do a mac final */ 6625 if ((error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx), 6626 taskq_req->dr_cipher_mac_req.mr_mac, NULL)) != 6627 CRYPTO_SUCCESS) 6628 break; 6629 6630 /* do an decrypt update */ 6631 cipher_data = mac_data; 6632 cipher_data.cd_length = dual_data->dd_len2; 6633 cipher_data.cd_offset = dual_data->dd_offset2; 6634 if (taskq_req->dr_cipher_mac_req.mr_data == NULL) 6635 /* in-place */ 6636 plaintext_tmp = cipher_data; 6637 else 6638 plaintext_tmp = *taskq_req->dr_cipher_mac_req.mr_data; 6639 6640 if ((error = crypto_decrypt_update(DPROV_CTX_DUAL_CIPHER(ctx), 6641 &cipher_data, taskq_req->dr_cipher_mac_req.mr_data, 6642 NULL)) != CRYPTO_SUCCESS) 6643 break; 6644 6645 /* do an decrypt final */ 6646 if (taskq_req->dr_cipher_mac_req.mr_data == NULL) 6647 /* in-place, everything must have been decrypted */ 6648 decrypted = cipher_data.cd_length; 6649 else 6650 decrypted = 6651 taskq_req->dr_cipher_mac_req.mr_data->cd_length; 6652 plaintext_tmp.cd_offset += decrypted; 6653 plaintext_tmp.cd_length -= decrypted; 6654 6655 error = crypto_decrypt_final(DPROV_CTX_DUAL_CIPHER(ctx), 6656 &plaintext_tmp, NULL); 6657 if (taskq_req->dr_cipher_mac_req.mr_data != NULL) 6658 taskq_req->dr_cipher_mac_req.mr_data->cd_length += 6659 plaintext_tmp.cd_length; 6660 6661 if (error != CRYPTO_BUFFER_TOO_SMALL) { 6662 DPROV_CTX_DUAL_MAC(ctx) = NULL; 6663 DPROV_CTX_DUAL_CIPHER(ctx) = NULL; 6664 (void) dprov_free_context(ctx); 6665 } 6666 break; 6667 } 6668 6669 case DPROV_REQ_MAC_DECRYPT_UPDATE: 6670 cipher_data = *((crypto_data_t *)dual_data); 6671 6672 /* do mac update */ 6673 if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx), 6674 &cipher_data, NULL)) != CRYPTO_SUCCESS) 6675 break; 6676 6677 /* do a decrypt update */ 6678 cipher_data.cd_length = dual_data->dd_len2; 6679 cipher_data.cd_offset = dual_data->dd_offset2; 6680 error = crypto_decrypt_update(DPROV_CTX_DUAL_CIPHER(ctx), 6681 &cipher_data, taskq_req->dr_cipher_mac_req.mr_data, NULL); 6682 6683 break; 6684 6685 case DPROV_REQ_MAC_DECRYPT_FINAL: 6686 /* do a mac final */ 6687 if ((error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx), 6688 taskq_req->dr_cipher_mac_req.mr_mac, NULL)) != 6689 CRYPTO_SUCCESS) 6690 break; 6691 6692 /* do a decrypt final */ 6693 error = crypto_decrypt_final(DPROV_CTX_DUAL_CIPHER(ctx), 6694 taskq_req->dr_cipher_mac_req.mr_data, NULL); 6695 6696 if (error != CRYPTO_BUFFER_TOO_SMALL) { 6697 DPROV_CTX_DUAL_MAC(ctx) = NULL; 6698 DPROV_CTX_DUAL_CIPHER(ctx) = NULL; 6699 (void) dprov_free_context(ctx); 6700 } 6701 break; 6702 6703 case DPROV_REQ_MAC_DECRYPT_ATOMIC: 6704 case DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC: 6705 cipher_data = *((crypto_data_t *)dual_data); 6706 6707 /* structure assignment */ 6708 cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech; 6709 mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech; 6710 session_id = taskq_req->dr_cipher_mac_req.mr_session_id; 6711 6712 /* get the keys values and providers to use for operations */ 6713 if ((error = dprov_cipher_mac_key_pd(softc, session_id, 6714 taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd, 6715 &cipher_mech.cm_type, &mac_mech.cm_type)) != CRYPTO_SUCCESS) 6716 break; 6717 6718 /* do the atomic mac */ 6719 if (taskq_req->dr_type == DPROV_REQ_MAC_DECRYPT_ATOMIC) 6720 error = crypto_mac_prov(mac_pd, 0, &mac_mech, 6721 &cipher_data, &mac_key, NULL, 6722 taskq_req->dr_cipher_mac_req.mr_mac, NULL); 6723 else 6724 /* DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC */ 6725 error = crypto_mac_verify_prov(mac_pd, 0, &mac_mech, 6726 &cipher_data, &mac_key, NULL, 6727 taskq_req->dr_cipher_mac_req.mr_mac, NULL); 6728 6729 if (error != CRYPTO_SUCCESS) 6730 break; 6731 6732 /* do the atomic decrypt */ 6733 cipher_data.cd_length = dual_data->dd_len2; 6734 cipher_data.cd_offset = dual_data->dd_offset2; 6735 error = crypto_decrypt_prov(cipher_pd, 0, &cipher_mech, 6736 &cipher_data, &cipher_key, NULL, 6737 taskq_req->dr_cipher_mac_req.mr_data, NULL); 6738 6739 break; 6740 } 6741 6742 dprov_op_done(taskq_req, error); 6743 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_cipher_mac_task: end\n", 6744 instance)); 6745 } 6746 6747 /* 6748 * taskq dispatcher function for random number generation. 6749 */ 6750 static void 6751 dprov_random_task(dprov_req_t *taskq_req) 6752 { 6753 dprov_state_t *softc; 6754 /* LINTED E_FUNC_SET_NOT_USED */ 6755 int instance; 6756 int error = CRYPTO_SUCCESS; 6757 6758 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 6759 DPROV_DEBUG(D_RANDOM, ("(%d) dprov_random_task: started\n", instance)); 6760 6761 mutex_enter(&softc->ds_lock); 6762 6763 switch (taskq_req->dr_type) { 6764 6765 DPROV_REQ_RANDOM_SEED: 6766 /* 6767 * Since we don't really generate random numbers 6768 * nothing to do. 6769 */ 6770 break; 6771 6772 case DPROV_REQ_RANDOM_GENERATE: { 6773 uint_t i; 6774 uchar_t c = 0; 6775 6776 /* 6777 * We don't generate random numbers so that the result 6778 * of the operation can be checked during testing. 6779 */ 6780 6781 for (i = 0; i < taskq_req->dr_random_req.rr_len; i++) 6782 taskq_req->dr_random_req.rr_buf[i] = c++; 6783 6784 break; 6785 } 6786 } 6787 6788 mutex_exit(&softc->ds_lock); 6789 dprov_op_done(taskq_req, error); 6790 DPROV_DEBUG(D_RANDOM, ("(%d) dprov_random_task: end\n", instance)); 6791 } 6792 6793 6794 /* 6795 * taskq dispatcher function for session management operations. 6796 */ 6797 static void 6798 dprov_session_task(dprov_req_t *taskq_req) 6799 { 6800 dprov_state_t *softc; 6801 /* LINTED E_FUNC_SET_NOT_USED */ 6802 int instance; 6803 int error = CRYPTO_NOT_SUPPORTED; 6804 crypto_session_id_t session_id = 6805 taskq_req->dr_session_req.sr_session_id; 6806 dprov_session_t *session; 6807 dprov_object_t *object; 6808 int i; 6809 6810 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 6811 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_task: started\n", 6812 instance)); 6813 6814 mutex_enter(&softc->ds_lock); 6815 6816 if (taskq_req->dr_type != DPROV_REQ_SESSION_OPEN) 6817 /* validate session id and get ptr to session */ 6818 if ((session = softc->ds_sessions[session_id]) == NULL) { 6819 mutex_exit(&softc->ds_lock); 6820 dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID); 6821 return; 6822 } 6823 6824 switch (taskq_req->dr_type) { 6825 6826 case DPROV_REQ_SESSION_OPEN: { 6827 dprov_session_t **new_sessions; 6828 6829 if (softc->ds_token_initialized == B_FALSE) { 6830 error = CRYPTO_OPERATION_NOT_INITIALIZED; 6831 break; 6832 } 6833 6834 /* search for available session slot */ 6835 for (i = 0; i < softc->ds_sessions_slots; i++) 6836 if (softc->ds_sessions[i] == NULL) 6837 break; 6838 6839 if (i == softc->ds_sessions_slots) { 6840 /* ran out of slots, grow sessions array */ 6841 new_sessions = kmem_zalloc( 6842 2 * softc->ds_sessions_slots * 6843 sizeof (dprov_session_t *), KM_NOSLEEP); 6844 if (new_sessions == NULL) { 6845 error = CRYPTO_SESSION_COUNT; 6846 break; 6847 } 6848 bcopy(softc->ds_sessions, new_sessions, 6849 softc->ds_sessions_slots * 6850 sizeof (dprov_session_t *)); 6851 kmem_free(softc->ds_sessions, softc->ds_sessions_slots * 6852 sizeof (dprov_session_t *)); 6853 softc->ds_sessions = new_sessions; 6854 softc->ds_sessions_slots *= 2; 6855 } 6856 6857 /* allocate and initialize new session */ 6858 softc->ds_sessions[i] = kmem_zalloc( 6859 sizeof (dprov_session_t), KM_NOSLEEP); 6860 if (softc->ds_sessions[i] == NULL) { 6861 error = CRYPTO_HOST_MEMORY; 6862 break; 6863 } 6864 softc->ds_sessions_count++; 6865 6866 /* initialize session state */ 6867 softc->ds_sessions[i]->ds_state = DPROV_SESSION_STATE_PUBLIC; 6868 6869 /* return new session id to caller */ 6870 *(taskq_req->dr_session_req.sr_session_id_ptr) = i; 6871 6872 error = CRYPTO_SUCCESS; 6873 break; 6874 } 6875 6876 case DPROV_REQ_SESSION_CLOSE: 6877 softc->ds_sessions[session_id] = NULL; 6878 6879 if (softc->ds_token_initialized == B_FALSE) { 6880 error = CRYPTO_OPERATION_NOT_INITIALIZED; 6881 break; 6882 } 6883 6884 dprov_release_session_objects(session); 6885 6886 /* free session state and corresponding slot */ 6887 kmem_free(session, sizeof (dprov_session_t)); 6888 softc->ds_sessions_count--; 6889 6890 error = CRYPTO_SUCCESS; 6891 break; 6892 6893 case DPROV_REQ_SESSION_LOGIN: { 6894 char *pin = taskq_req->dr_session_req.sr_pin; 6895 size_t pin_len = taskq_req->dr_session_req.sr_pin_len; 6896 crypto_user_type_t user_type = 6897 taskq_req->dr_session_req.sr_user_type; 6898 6899 /* check user type */ 6900 if (user_type != CRYPTO_SO && user_type != CRYPTO_USER) { 6901 error = CRYPTO_USER_TYPE_INVALID; 6902 break; 6903 } 6904 6905 /* check pin length */ 6906 if (pin_len > DPROV_MAX_PIN_LEN) { 6907 error = CRYPTO_PIN_LEN_RANGE; 6908 break; 6909 } 6910 6911 /* check pin */ 6912 if (pin == NULL) { 6913 error = CRYPTO_PIN_INVALID; 6914 break; 6915 } 6916 6917 /* validate PIN state */ 6918 if ((user_type == CRYPTO_SO) && !softc->ds_token_initialized || 6919 (user_type == CRYPTO_USER) && !softc->ds_user_pin_set) { 6920 error = CRYPTO_USER_PIN_NOT_INITIALIZED; 6921 break; 6922 } 6923 6924 if ((user_type == CRYPTO_SO && 6925 softc->ds_sessions[session_id]->ds_state == 6926 DPROV_SESSION_STATE_SO) || 6927 (user_type == CRYPTO_USER && 6928 softc->ds_sessions[session_id]->ds_state == 6929 DPROV_SESSION_STATE_USER)) { 6930 /* SO or user already logged in */ 6931 error = CRYPTO_USER_ALREADY_LOGGED_IN; 6932 break; 6933 } 6934 6935 if (softc->ds_sessions[session_id]->ds_state != 6936 DPROV_SESSION_STATE_PUBLIC) { 6937 /* another user already logged in */ 6938 error = CRYPTO_USER_ANOTHER_ALREADY_LOGGED_IN; 6939 break; 6940 } 6941 6942 /* everything's fine, update session */ 6943 softc->ds_sessions[session_id]->ds_state = 6944 user_type == CRYPTO_SO ? 6945 DPROV_SESSION_STATE_SO : DPROV_SESSION_STATE_USER; 6946 6947 error = CRYPTO_SUCCESS; 6948 break; 6949 } 6950 6951 case DPROV_REQ_SESSION_LOGOUT: 6952 /* fail if not logged in */ 6953 if (softc->ds_sessions[session_id]->ds_state == 6954 DPROV_SESSION_STATE_PUBLIC) { 6955 error = CRYPTO_USER_NOT_LOGGED_IN; 6956 break; 6957 } 6958 6959 /* 6960 * Destroy all private session objects. 6961 * Invalidate handles to all private objects. 6962 */ 6963 for (i = 0; i < DPROV_MAX_OBJECTS; i++) { 6964 object = softc->ds_sessions[session_id]->ds_objects[i]; 6965 if (object != NULL && dprov_object_is_private(object)) { 6966 if (!dprov_object_is_token(object)) 6967 /* It's a session object, free it */ 6968 DPROV_OBJECT_REFRELE(object); 6969 softc->ds_sessions[session_id]->ds_objects[i] = 6970 NULL; 6971 } 6972 } 6973 6974 /* update session state */ 6975 softc->ds_sessions[session_id]->ds_state = 6976 DPROV_SESSION_STATE_PUBLIC; 6977 6978 error = CRYPTO_SUCCESS; 6979 break; 6980 } 6981 6982 mutex_exit(&softc->ds_lock); 6983 dprov_op_done(taskq_req, error); 6984 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_task: end\n", instance)); 6985 } 6986 6987 /* return true if attribute is defined to be a PKCS#11 long */ 6988 static boolean_t 6989 fixed_size_attribute(crypto_attr_type_t type) 6990 { 6991 return (type == DPROV_CKA_CLASS || 6992 type == DPROV_CKA_CERTIFICATE_TYPE || 6993 type == DPROV_CKA_KEY_TYPE || 6994 type == DPROV_HW_FEATURE_TYPE); 6995 } 6996 6997 /* 6998 * Attributes defined to be a PKCS#11 long causes problems for dprov 6999 * because 32-bit applications set the size to 4 and 64-bit applications 7000 * set the size to 8. dprov always stores these fixed-size attributes 7001 * as uint32_t. 7002 */ 7003 static ssize_t 7004 attribute_size(crypto_attr_type_t type, ssize_t len) 7005 { 7006 if (fixed_size_attribute(type)) 7007 return (sizeof (uint32_t)); 7008 7009 return (len); 7010 } 7011 7012 /* 7013 * taskq dispatcher function for object management operations. 7014 */ 7015 static void 7016 dprov_object_task(dprov_req_t *taskq_req) 7017 { 7018 dprov_state_t *softc; 7019 /* LINTED E_FUNC_SET_NOT_USED */ 7020 int instance; 7021 int error = CRYPTO_NOT_SUPPORTED; 7022 crypto_object_id_t object_id = taskq_req->dr_object_req.or_object_id; 7023 crypto_session_id_t session_id = taskq_req->dr_object_req.or_session_id; 7024 crypto_object_attribute_t *template = 7025 taskq_req->dr_object_req.or_template; 7026 uint_t attr_count = taskq_req->dr_object_req.or_attribute_count; 7027 dprov_object_t *object; 7028 dprov_session_t *session; 7029 7030 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 7031 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_task: started\n", instance)); 7032 7033 mutex_enter(&softc->ds_lock); 7034 7035 /* validate session id and get ptr to session */ 7036 if ((session = softc->ds_sessions[session_id]) == NULL) { 7037 mutex_exit(&softc->ds_lock); 7038 dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID); 7039 return; 7040 } 7041 7042 switch (taskq_req->dr_type) { 7043 7044 case DPROV_REQ_OBJECT_CREATE: 7045 /* create the object from the specified template */ 7046 if ((error = dprov_create_object_from_template(softc, session, 7047 template, attr_count, 7048 taskq_req->dr_object_req.or_object_id_ptr, B_TRUE, 7049 B_FALSE)) != CRYPTO_SUCCESS) 7050 break; 7051 7052 break; 7053 7054 case DPROV_REQ_OBJECT_COPY: 7055 /* check object id */ 7056 if (object_id >= DPROV_MAX_OBJECTS || 7057 (object = session->ds_objects[object_id]) == NULL) { 7058 error = CRYPTO_OBJECT_HANDLE_INVALID; 7059 break; 7060 } 7061 7062 /* 7063 * Create a new object from the object passed as 7064 * argument. 7065 */ 7066 if ((error = dprov_create_object_from_template(softc, session, 7067 object->do_attr, DPROV_MAX_ATTR, 7068 taskq_req->dr_object_req.or_object_id_ptr, B_TRUE, 7069 B_FALSE)) != CRYPTO_SUCCESS) 7070 break; 7071 7072 /* 7073 * Add the attributes specified by the template to the 7074 * newly created object, replacing existing ones if needed. 7075 */ 7076 error = dprov_object_set_attr(session, 7077 *taskq_req->dr_object_req.or_object_id_ptr, 7078 taskq_req->dr_object_req.or_template, 7079 taskq_req->dr_object_req.or_attribute_count, B_TRUE); 7080 7081 break; 7082 7083 case DPROV_REQ_OBJECT_DESTROY: 7084 /* destroy the object */ 7085 error = dprov_destroy_object(softc, session, 7086 taskq_req->dr_object_req.or_object_id); 7087 7088 break; 7089 7090 case DPROV_REQ_OBJECT_GET_SIZE: 7091 /* get ptr to object */ 7092 if (object_id >= DPROV_MAX_OBJECTS || 7093 session->ds_objects[object_id] == NULL) { 7094 error = CRYPTO_OBJECT_HANDLE_INVALID; 7095 break; 7096 } 7097 7098 /* 7099 * The PKCS11 specification does not specifies what 7100 * the object size really is, here we just return 7101 * the number of possible attributes of the object. 7102 */ 7103 *taskq_req->dr_object_req.or_object_size = DPROV_MAX_ATTR; 7104 7105 error = CRYPTO_SUCCESS; 7106 break; 7107 7108 case DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE: { 7109 crypto_attr_type_t type; 7110 size_t olen, tlen; 7111 offset_t offset; 7112 int tmpl_idx; 7113 int object_idx; 7114 ulong_t class = DPROV_CKO_DATA; 7115 boolean_t extractable = B_TRUE; 7116 7117 error = CRYPTO_SUCCESS; 7118 7119 /* get ptr to object */ 7120 if (object_id >= DPROV_MAX_OBJECTS || 7121 (object = session->ds_objects[object_id]) == NULL) { 7122 error = CRYPTO_OBJECT_HANDLE_INVALID; 7123 break; 7124 } 7125 7126 (void) dprov_get_object_attr_boolean(object, 7127 DPROV_CKA_EXTRACTABLE, &extractable); 7128 7129 (void) dprov_get_object_attr_ulong(object, 7130 DPROV_CKA_CLASS, &class); 7131 7132 /* return the specified attributes, when possible */ 7133 for (tmpl_idx = 0; tmpl_idx < attr_count; tmpl_idx++) { 7134 /* 7135 * Attribute can't be revealed if the CKA_EXTRACTABLE 7136 * attribute is set to false. 7137 */ 7138 type = template[tmpl_idx].oa_type; 7139 if (!extractable && class == DPROV_CKO_SECRET_KEY) { 7140 if (type == DPROV_CKA_VALUE) { 7141 template[tmpl_idx].oa_value_len = -1; 7142 error = CRYPTO_ATTRIBUTE_SENSITIVE; 7143 continue; 7144 } 7145 } 7146 if (!extractable && class == DPROV_CKO_PRIVATE_KEY) { 7147 if (type == DPROV_CKA_PRIVATE_EXPONENT) { 7148 template[tmpl_idx].oa_value_len = -1; 7149 error = CRYPTO_ATTRIBUTE_SENSITIVE; 7150 continue; 7151 } 7152 } 7153 7154 object_idx = dprov_find_attr(object->do_attr, 7155 DPROV_MAX_ATTR, type); 7156 if (object_idx == -1) { 7157 /* attribute not found in object */ 7158 template[tmpl_idx].oa_value_len = -1; 7159 error = CRYPTO_ATTRIBUTE_TYPE_INVALID; 7160 continue; 7161 } 7162 7163 tlen = template[tmpl_idx].oa_value_len; 7164 olen = object->do_attr[object_idx].oa_value_len; 7165 /* return attribute length */ 7166 if (template[tmpl_idx].oa_value == NULL) { 7167 /* 7168 * The size of the attribute is set by the 7169 * library according to the data model of the 7170 * application, so don't overwrite it with 7171 * dprov's size. 7172 */ 7173 if (!fixed_size_attribute(type)) 7174 template[tmpl_idx].oa_value_len = olen; 7175 continue; 7176 } 7177 7178 if (tlen < olen) { 7179 template[tmpl_idx].oa_value_len = -1; 7180 error = CRYPTO_BUFFER_TOO_SMALL; 7181 continue; 7182 } 7183 7184 /* copy attribute value */ 7185 bzero(template[tmpl_idx].oa_value, tlen); 7186 7187 offset = 0; 7188 #ifdef _BIG_ENDIAN 7189 if (fixed_size_attribute(type)) { 7190 offset = tlen - olen; 7191 } 7192 #endif 7193 bcopy(object->do_attr[object_idx].oa_value, 7194 &template[tmpl_idx].oa_value[offset], olen); 7195 7196 /* don't update length for fixed-size attributes */ 7197 if (!fixed_size_attribute(type)) 7198 template[tmpl_idx].oa_value_len = olen; 7199 } 7200 7201 break; 7202 } 7203 7204 case DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE: 7205 /* 7206 * Add the attributes specified by the template to the 7207 * newly created object, replacing existing ones if needed. 7208 */ 7209 error = dprov_object_set_attr(session, 7210 taskq_req->dr_object_req.or_object_id, 7211 taskq_req->dr_object_req.or_template, 7212 taskq_req->dr_object_req.or_attribute_count, B_TRUE); 7213 7214 break; 7215 7216 case DPROV_REQ_OBJECT_FIND_INIT: { 7217 dprov_find_ctx_t *find_ctx; 7218 int so_idx; /* session object index */ 7219 int to_idx; /* token object index */ 7220 7221 error = CRYPTO_SUCCESS; 7222 /* allocate find context */ 7223 find_ctx = kmem_zalloc(sizeof (dprov_find_ctx_t), KM_SLEEP); 7224 *taskq_req->dr_object_req.or_find_pp = find_ctx; 7225 7226 /* first go through the existing session objects */ 7227 for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++) { 7228 if ((object = session->ds_objects[so_idx]) == NULL) 7229 continue; 7230 7231 /* setting count to zero means find all objects */ 7232 if (attr_count > 0) { 7233 if (!dprov_attributes_match(object, template, 7234 attr_count)) 7235 continue; 7236 } 7237 7238 /* session object attributes matches template */ 7239 find_ctx->fc_ids[find_ctx->fc_nids] = so_idx; 7240 find_ctx->fc_nids++; 7241 } 7242 7243 /* 7244 * Go through the token object. For each token object 7245 * that can be accessed: 7246 * If there was already an session object id assigned 7247 * to that token object, skip it, since it was returned 7248 * during the check of session objects, else, 7249 * assign a new object id for that token object and 7250 * add it to the array of matching objects. 7251 */ 7252 for (to_idx = 0; to_idx < DPROV_MAX_OBJECTS && 7253 error == CRYPTO_SUCCESS; to_idx++) { 7254 if ((object = softc->ds_objects[to_idx]) == NULL) 7255 continue; 7256 7257 /* setting count to zero means find all objects */ 7258 if (attr_count > 0) { 7259 if (!dprov_attributes_match(object, template, 7260 attr_count)) 7261 continue; 7262 } 7263 7264 /* if the the object has been destroyed, skip it */ 7265 if (object->do_destroyed) 7266 continue; 7267 7268 /* skip object if it cannot be accessed from session */ 7269 if (dprov_object_is_private(object) && 7270 session->ds_state != DPROV_SESSION_STATE_USER) 7271 continue; 7272 7273 /* 7274 * Is there already a session object id for this 7275 * token object? 7276 */ 7277 for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++) 7278 if (session->ds_objects[so_idx] != NULL && 7279 session->ds_objects[so_idx]->do_token_idx == 7280 to_idx) 7281 break; 7282 if (so_idx < DPROV_MAX_OBJECTS) 7283 /* object found in session table, skip it */ 7284 continue; 7285 7286 /* find free session slot for this object */ 7287 for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++) 7288 if (session->ds_objects[so_idx] == NULL) 7289 break; 7290 if (so_idx == DPROV_MAX_OBJECTS) { 7291 /* ran out of session objects slots */ 7292 kmem_free(find_ctx, sizeof (dprov_find_ctx_t)); 7293 error = CRYPTO_HOST_MEMORY; 7294 break; 7295 } 7296 7297 /* add object to session objects table */ 7298 session->ds_objects[so_idx] = object; 7299 DPROV_OBJECT_REFHOLD(object); 7300 7301 /* add object to list of objects to return */ 7302 find_ctx->fc_ids[find_ctx->fc_nids] = so_idx; 7303 find_ctx->fc_nids++; 7304 } 7305 7306 break; 7307 } 7308 7309 case DPROV_REQ_OBJECT_FIND: { 7310 crypto_object_id_t *object_ids = 7311 taskq_req->dr_object_req.or_object_id_ptr; 7312 uint_t max_object_count = 7313 taskq_req->dr_object_req.or_max_object_count; 7314 dprov_find_ctx_t *find_ctx = 7315 taskq_req->dr_object_req.or_find_p; 7316 uint_t ret_oid_idx; 7317 7318 /* return the desired number of object ids */ 7319 for (ret_oid_idx = 0; ret_oid_idx < max_object_count && 7320 find_ctx->fc_next < find_ctx->fc_nids; ret_oid_idx++) 7321 object_ids[ret_oid_idx] = 7322 find_ctx->fc_ids[find_ctx->fc_next++]; 7323 7324 *taskq_req->dr_object_req.or_object_count_ptr = ret_oid_idx; 7325 7326 error = CRYPTO_SUCCESS; 7327 break; 7328 } 7329 7330 case DPROV_REQ_OBJECT_FIND_FINAL: 7331 kmem_free(taskq_req->dr_object_req.or_find_p, 7332 sizeof (dprov_find_ctx_t)); 7333 7334 error = CRYPTO_SUCCESS; 7335 break; 7336 } 7337 7338 mutex_exit(&softc->ds_lock); 7339 dprov_op_done(taskq_req, error); 7340 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_task: end\n", instance)); 7341 } 7342 7343 /* 7344 * Copy attribute values into a template. RSA values are precomputed. 7345 */ 7346 static int 7347 nostore_copy_attribute(crypto_object_attribute_t *template, uint_t count, 7348 uint64_t attr_type) 7349 { 7350 void *value, *dprov_attribute_value; 7351 size_t dprov_attribute_size; 7352 size_t value_len = 0; 7353 int error; 7354 7355 switch (attr_type) { 7356 case DPROV_CKA_VALUE: 7357 dprov_attribute_size = sizeof (dh_value); 7358 dprov_attribute_value = dh_value; 7359 break; 7360 7361 case DPROV_CKA_MODULUS: 7362 dprov_attribute_size = sizeof (modulus); 7363 dprov_attribute_value = modulus; 7364 break; 7365 7366 case DPROV_CKA_PUBLIC_EXPONENT: 7367 dprov_attribute_size = sizeof (public_exponent); 7368 dprov_attribute_value = public_exponent; 7369 break; 7370 7371 case DPROV_CKA_PRIVATE_EXPONENT: 7372 dprov_attribute_size = sizeof (private_exponent); 7373 dprov_attribute_value = private_exponent; 7374 break; 7375 7376 default: 7377 return (CRYPTO_ATTRIBUTE_TYPE_INVALID); 7378 } 7379 7380 error = dprov_get_template_attr_array(template, count, attr_type, 7381 &value, &value_len); 7382 if (error != CRYPTO_SUCCESS) 7383 return (error); 7384 7385 if (value_len < dprov_attribute_size) 7386 return (CRYPTO_BUFFER_TOO_SMALL); 7387 7388 /* 7389 * The updated template will be returned to libpkcs11. 7390 */ 7391 bcopy(dprov_attribute_value, value, dprov_attribute_size); 7392 7393 return (CRYPTO_SUCCESS); 7394 } 7395 7396 static void 7397 fill_dh(void *value, size_t len) 7398 { 7399 int i = 0; 7400 char *p = value; 7401 while (i < len) { 7402 p[i++] = 'D'; 7403 if (i >= len) 7404 break; 7405 p[i++] = 'H'; 7406 } 7407 } 7408 7409 /* 7410 * taskq dispatcher function for key management operations. 7411 */ 7412 static void 7413 dprov_key_task(dprov_req_t *taskq_req) 7414 { 7415 dprov_state_t *softc; 7416 /* LINTED E_FUNC_SET_NOT_USED */ 7417 int instance; 7418 int error = CRYPTO_NOT_SUPPORTED; 7419 kcf_provider_desc_t *pd; 7420 crypto_session_id_t session_id = taskq_req->dr_key_req.kr_session_id; 7421 dprov_session_t *session; 7422 7423 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 7424 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_task: started\n", instance)); 7425 7426 mutex_enter(&softc->ds_lock); 7427 7428 /* validate session id and get ptr to session */ 7429 if ((session = softc->ds_sessions[session_id]) == NULL) { 7430 mutex_exit(&softc->ds_lock); 7431 dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID); 7432 return; 7433 } 7434 7435 switch (taskq_req->dr_type) { 7436 case DPROV_REQ_KEY_GENERATE: { 7437 crypto_mechanism_t *mechp; 7438 crypto_object_id_t *object_id_ptr; 7439 crypto_object_attribute_t *template; 7440 crypto_object_attribute_t attribute; 7441 uint_t attribute_count; 7442 ulong_t key_type = ~0UL, class = ~0UL; 7443 ulong_t value_len; 7444 size_t key_len = 0; 7445 7446 error = CRYPTO_SUCCESS; 7447 7448 template = taskq_req->dr_key_req.kr_template; 7449 attribute_count = taskq_req->dr_key_req.kr_attribute_count; 7450 object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr; 7451 mechp = taskq_req->dr_key_req.kr_mechanism; 7452 7453 /* optional */ 7454 (void) dprov_get_template_attr_ulong(template, attribute_count, 7455 DPROV_CKA_CLASS, &class); 7456 7457 /* optional */ 7458 (void) dprov_get_template_attr_ulong(template, attribute_count, 7459 DPROV_CKA_KEY_TYPE, &key_type); 7460 7461 if (class != ~0UL && class != DPROV_CKO_SECRET_KEY) { 7462 error = CRYPTO_TEMPLATE_INCONSISTENT; 7463 break; 7464 } 7465 7466 switch (mechp->cm_type) { 7467 case DES_KEY_GEN_MECH_INFO_TYPE: 7468 if (key_type != ~0UL && key_type != DPROV_CKK_DES) { 7469 error = CRYPTO_TEMPLATE_INCONSISTENT; 7470 break; 7471 } 7472 key_len = DES_KEY_LEN; 7473 key_type = DPROV_CKK_DES; 7474 break; 7475 7476 case DES3_KEY_GEN_MECH_INFO_TYPE: 7477 if (key_type != ~0UL && key_type != DPROV_CKK_DES3) { 7478 error = CRYPTO_TEMPLATE_INCONSISTENT; 7479 break; 7480 } 7481 key_len = DES3_KEY_LEN; 7482 key_type = DPROV_CKK_DES3; 7483 break; 7484 7485 case AES_KEY_GEN_MECH_INFO_TYPE: 7486 if (key_type != ~0UL && key_type != DPROV_CKK_AES) { 7487 error = CRYPTO_TEMPLATE_INCONSISTENT; 7488 break; 7489 } 7490 if (dprov_get_template_attr_ulong(template, 7491 attribute_count, DPROV_CKA_VALUE_LEN, 7492 &value_len) != CRYPTO_SUCCESS) { 7493 error = CRYPTO_TEMPLATE_INCOMPLETE; 7494 break; 7495 } 7496 if (value_len >= AES_MAX_KEY_LEN) { 7497 error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 7498 break; 7499 } 7500 key_len = value_len; 7501 key_type = DPROV_CKK_AES; 7502 break; 7503 7504 case BLOWFISH_KEY_GEN_MECH_INFO_TYPE: 7505 if (key_type != ~0UL && 7506 key_type != DPROV_CKK_BLOWFISH) { 7507 error = CRYPTO_TEMPLATE_INCONSISTENT; 7508 break; 7509 } 7510 if (dprov_get_template_attr_ulong(template, 7511 attribute_count, DPROV_CKA_VALUE_LEN, 7512 &value_len) != CRYPTO_SUCCESS) { 7513 error = CRYPTO_TEMPLATE_INCOMPLETE; 7514 break; 7515 } 7516 if (value_len >= BLOWFISH_MAX_KEY_LEN) { 7517 error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 7518 break; 7519 } 7520 key_len = value_len; 7521 key_type = DPROV_CKK_BLOWFISH; 7522 break; 7523 7524 case RC4_KEY_GEN_MECH_INFO_TYPE: 7525 if (key_type != ~0UL && key_type != DPROV_CKK_RC4) { 7526 error = CRYPTO_TEMPLATE_INCONSISTENT; 7527 break; 7528 } 7529 if (dprov_get_template_attr_ulong(template, 7530 attribute_count, DPROV_CKA_VALUE_LEN, 7531 &value_len) != CRYPTO_SUCCESS) { 7532 error = CRYPTO_TEMPLATE_INCOMPLETE; 7533 break; 7534 } 7535 if (value_len >= 7536 CRYPTO_BITS2BYTES(ARCFOUR_MAX_KEY_BITS)) { 7537 error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 7538 break; 7539 } 7540 key_len = value_len; 7541 key_type = DPROV_CKK_RC4; 7542 break; 7543 7544 default: 7545 error = CRYPTO_MECHANISM_INVALID; 7546 } 7547 7548 if (error != CRYPTO_SUCCESS) 7549 break; 7550 7551 error = dprov_create_object_from_template(softc, session, 7552 template, attribute_count, object_id_ptr, B_FALSE, B_TRUE); 7553 7554 if (error != CRYPTO_SUCCESS) 7555 break; 7556 7557 /* make sure class is set */ 7558 attribute.oa_type = DPROV_CKA_CLASS; 7559 attribute.oa_value = (char *)&class; 7560 attribute.oa_value_len = sizeof (ulong_t); 7561 error = dprov_object_set_attr(session, *object_id_ptr, 7562 &attribute, 1, B_FALSE); 7563 7564 if (error != CRYPTO_SUCCESS) { 7565 goto destroy_object; 7566 } 7567 7568 /* make sure key_type is set */ 7569 attribute.oa_type = DPROV_CKA_KEY_TYPE; 7570 attribute.oa_value = (char *)&key_type; 7571 attribute.oa_value_len = sizeof (ulong_t); 7572 error = dprov_object_set_attr(session, *object_id_ptr, 7573 &attribute, 1, B_FALSE); 7574 7575 if (error != CRYPTO_SUCCESS) { 7576 goto destroy_object; 7577 } 7578 7579 attribute.oa_type = DPROV_CKA_VALUE; 7580 attribute.oa_value = kmem_alloc(key_len, KM_SLEEP); 7581 attribute.oa_value_len = key_len; 7582 7583 if (random_get_pseudo_bytes((uchar_t *)attribute.oa_value, 7584 key_len) != 0) { 7585 bzero(attribute.oa_value, key_len); 7586 kmem_free(attribute.oa_value, key_len); 7587 goto destroy_object; 7588 } 7589 error = dprov_object_set_attr(session, *object_id_ptr, 7590 &attribute, 1, B_FALSE); 7591 7592 bzero(attribute.oa_value, key_len); 7593 kmem_free(attribute.oa_value, key_len); 7594 7595 if (error != CRYPTO_SUCCESS) { 7596 goto destroy_object; 7597 } 7598 break; 7599 7600 destroy_object: 7601 (void) dprov_destroy_object(softc, session, *object_id_ptr); 7602 break; 7603 } 7604 7605 case DPROV_REQ_KEY_GENERATE_PAIR: { 7606 crypto_mechanism_t *mechp; 7607 crypto_object_id_t *pub_object_id_ptr; 7608 crypto_object_id_t *pri_object_id_ptr; 7609 crypto_object_attribute_t *pub_template; 7610 crypto_object_attribute_t *pri_template; 7611 crypto_object_attribute_t attribute; 7612 uint_t pub_attribute_count; 7613 uint_t pri_attribute_count; 7614 ulong_t pub_key_type = ~0UL, pub_class = ~0UL; 7615 ulong_t pri_key_type = ~0UL, pri_class = ~0UL; 7616 7617 pub_template = taskq_req->dr_key_req.kr_template; 7618 pub_attribute_count = taskq_req->dr_key_req.kr_attribute_count; 7619 pub_object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr; 7620 pri_template = taskq_req->dr_key_req.kr_private_key_template; 7621 pri_attribute_count = 7622 taskq_req->dr_key_req.kr_private_key_attribute_count; 7623 pri_object_id_ptr = 7624 taskq_req->dr_key_req.kr_private_key_object_id_ptr; 7625 mechp = taskq_req->dr_key_req.kr_mechanism; 7626 7627 error = CRYPTO_SUCCESS; 7628 7629 /* optional */ 7630 (void) dprov_get_template_attr_ulong(pub_template, 7631 pub_attribute_count, DPROV_CKA_CLASS, &pub_class); 7632 7633 /* optional */ 7634 (void) dprov_get_template_attr_ulong(pri_template, 7635 pri_attribute_count, DPROV_CKA_CLASS, &pri_class); 7636 7637 /* optional */ 7638 (void) dprov_get_template_attr_ulong(pub_template, 7639 pub_attribute_count, DPROV_CKA_KEY_TYPE, &pub_key_type); 7640 7641 /* optional */ 7642 (void) dprov_get_template_attr_ulong(pri_template, 7643 pri_attribute_count, DPROV_CKA_KEY_TYPE, &pri_key_type); 7644 7645 if (pub_class != ~0UL && pub_class != DPROV_CKO_PUBLIC_KEY) { 7646 error = CRYPTO_TEMPLATE_INCONSISTENT; 7647 break; 7648 } 7649 7650 if (pri_class != ~0UL && pri_class != DPROV_CKO_PRIVATE_KEY) { 7651 error = CRYPTO_TEMPLATE_INCONSISTENT; 7652 break; 7653 } 7654 7655 switch (mechp->cm_type) { 7656 case RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE: 7657 if (pub_key_type != ~0UL && 7658 pub_key_type != DPROV_CKK_RSA) { 7659 error = CRYPTO_TEMPLATE_INCONSISTENT; 7660 break; 7661 } 7662 pub_key_type = DPROV_CKK_RSA; 7663 7664 if (pri_key_type != ~0UL && 7665 pri_key_type != DPROV_CKK_RSA) { 7666 error = CRYPTO_TEMPLATE_INCONSISTENT; 7667 break; 7668 } 7669 pri_key_type = DPROV_CKK_RSA; 7670 7671 if (pub_class != ~0UL && 7672 pub_class != DPROV_CKO_PUBLIC_KEY) { 7673 error = CRYPTO_TEMPLATE_INCONSISTENT; 7674 break; 7675 } 7676 pub_class = DPROV_CKO_PUBLIC_KEY; 7677 7678 if (pri_class != ~0UL && 7679 pri_class != DPROV_CKO_PRIVATE_KEY) { 7680 error = CRYPTO_TEMPLATE_INCONSISTENT; 7681 break; 7682 } 7683 pri_class = DPROV_CKO_PRIVATE_KEY; 7684 break; 7685 7686 default: 7687 error = CRYPTO_MECHANISM_INVALID; 7688 } 7689 7690 if (error != CRYPTO_SUCCESS) 7691 break; 7692 7693 error = dprov_create_object_from_template(softc, session, 7694 pub_template, pub_attribute_count, pub_object_id_ptr, 7695 B_FALSE, B_TRUE); 7696 7697 if (error != CRYPTO_SUCCESS) 7698 break; 7699 7700 /* make sure class is set */ 7701 attribute.oa_type = DPROV_CKA_CLASS; 7702 attribute.oa_value = (char *)&pub_class; 7703 attribute.oa_value_len = sizeof (ulong_t); 7704 error = dprov_object_set_attr(session, *pub_object_id_ptr, 7705 &attribute, 1, B_FALSE); 7706 7707 if (error != CRYPTO_SUCCESS) { 7708 goto destroy_public_object; 7709 } 7710 7711 /* make sure key_type is set */ 7712 attribute.oa_type = DPROV_CKA_KEY_TYPE; 7713 attribute.oa_value = (char *)&pub_key_type; 7714 attribute.oa_value_len = sizeof (ulong_t); 7715 error = dprov_object_set_attr(session, *pub_object_id_ptr, 7716 &attribute, 1, B_FALSE); 7717 7718 if (error != CRYPTO_SUCCESS) { 7719 goto destroy_public_object; 7720 } 7721 7722 attribute.oa_type = DPROV_CKA_MODULUS; 7723 attribute.oa_value = (char *)modulus; 7724 attribute.oa_value_len = sizeof (modulus); 7725 error = dprov_object_set_attr(session, *pub_object_id_ptr, 7726 &attribute, 1, B_FALSE); 7727 7728 if (error != CRYPTO_SUCCESS) { 7729 goto destroy_public_object; 7730 } 7731 7732 attribute.oa_type = DPROV_CKA_PUBLIC_EXPONENT; 7733 attribute.oa_value = public_exponent; 7734 attribute.oa_value_len = sizeof (public_exponent); 7735 error = dprov_object_set_attr(session, *pub_object_id_ptr, 7736 &attribute, 1, B_FALSE); 7737 7738 if (error != CRYPTO_SUCCESS) { 7739 goto destroy_public_object; 7740 } 7741 7742 error = dprov_create_object_from_template(softc, session, 7743 pri_template, pri_attribute_count, pri_object_id_ptr, 7744 B_FALSE, B_TRUE); 7745 7746 if (error != CRYPTO_SUCCESS) 7747 break; 7748 7749 /* make sure class is set */ 7750 attribute.oa_type = DPROV_CKA_CLASS; 7751 attribute.oa_value = (char *)&pri_class; 7752 attribute.oa_value_len = sizeof (ulong_t); 7753 error = dprov_object_set_attr(session, *pri_object_id_ptr, 7754 &attribute, 1, B_FALSE); 7755 7756 if (error != CRYPTO_SUCCESS) { 7757 goto destroy_private_object; 7758 } 7759 7760 /* make sure key_type is set */ 7761 attribute.oa_type = DPROV_CKA_KEY_TYPE; 7762 attribute.oa_value = (char *)&pri_key_type; 7763 attribute.oa_value_len = sizeof (ulong_t); 7764 error = dprov_object_set_attr(session, *pri_object_id_ptr, 7765 &attribute, 1, B_FALSE); 7766 7767 if (error != CRYPTO_SUCCESS) { 7768 goto destroy_private_object; 7769 } 7770 7771 attribute.oa_type = DPROV_CKA_MODULUS; 7772 attribute.oa_value = (char *)modulus; 7773 attribute.oa_value_len = sizeof (modulus); 7774 error = dprov_object_set_attr(session, *pri_object_id_ptr, 7775 &attribute, 1, B_FALSE); 7776 7777 if (error != CRYPTO_SUCCESS) { 7778 goto destroy_private_object; 7779 } 7780 7781 attribute.oa_type = DPROV_CKA_PRIVATE_EXPONENT; 7782 attribute.oa_value = (char *)private_exponent; 7783 attribute.oa_value_len = sizeof (private_exponent); 7784 error = dprov_object_set_attr(session, *pri_object_id_ptr, 7785 &attribute, 1, B_FALSE); 7786 7787 if (error != CRYPTO_SUCCESS) { 7788 goto destroy_private_object; 7789 } 7790 break; 7791 7792 destroy_private_object: 7793 (void) dprov_destroy_object(softc, session, 7794 *pri_object_id_ptr); 7795 destroy_public_object: 7796 (void) dprov_destroy_object(softc, session, 7797 *pub_object_id_ptr); 7798 7799 break; 7800 } 7801 7802 case DPROV_REQ_KEY_WRAP: { 7803 crypto_mechanism_t mech, *mechp; 7804 crypto_key_t key, *keyp; 7805 crypto_object_id_t object_id; 7806 ulong_t class = DPROV_CKO_DATA; 7807 boolean_t extractable = B_TRUE; 7808 dprov_object_t *object; 7809 int object_idx; 7810 char *plaintext_key; 7811 size_t plaintext_key_len; 7812 crypto_data_t plaintext; 7813 crypto_data_t ciphertext; 7814 size_t *lenp; 7815 7816 mechp = taskq_req->dr_key_req.kr_mechanism; 7817 /* structure assignment */ 7818 mech = *mechp; 7819 7820 /* get wrapping key value */ 7821 if (is_publickey_mech(mech.cm_type)) { 7822 if ((error = dprov_key_attr_asymmetric(softc, 7823 session_id, taskq_req->dr_type, 7824 taskq_req->dr_key_req.kr_key, 7825 &key)) != CRYPTO_SUCCESS) 7826 break; 7827 keyp = &key; 7828 } else { 7829 if ((error = dprov_key_value_secret(softc, 7830 session_id, taskq_req->dr_type, 7831 taskq_req->dr_key_req.kr_key, 7832 &key)) != CRYPTO_SUCCESS) 7833 break; 7834 keyp = &key; 7835 } 7836 7837 /* get the software provider for this mechanism */ 7838 if ((error = dprov_get_sw_prov(mechp, &pd, 7839 &mech.cm_type)) != CRYPTO_SUCCESS) 7840 break; 7841 7842 object_id = *taskq_req->dr_key_req.kr_object_id_ptr; 7843 if (object_id >= DPROV_MAX_OBJECTS) { 7844 error = CRYPTO_KEY_HANDLE_INVALID; 7845 break; 7846 } 7847 7848 /* get ptr to object */ 7849 if ((object = session->ds_objects[object_id]) == NULL) { 7850 error = CRYPTO_OBJECT_HANDLE_INVALID; 7851 break; 7852 } 7853 7854 (void) dprov_get_object_attr_boolean(object, 7855 DPROV_CKA_EXTRACTABLE, &extractable); 7856 7857 if (!extractable) { 7858 error = CRYPTO_ATTRIBUTE_SENSITIVE; 7859 break; 7860 } 7861 7862 (void) dprov_get_object_attr_ulong(object, 7863 DPROV_CKA_CLASS, &class); 7864 7865 switch (class) { 7866 case DPROV_CKO_SECRET_KEY: 7867 object_idx = dprov_find_attr(object->do_attr, 7868 DPROV_MAX_ATTR, DPROV_CKA_VALUE); 7869 if (object_idx == -1) { 7870 error = CRYPTO_ATTRIBUTE_TYPE_INVALID; 7871 break; 7872 } 7873 break; 7874 7875 case DPROV_CKO_PRIVATE_KEY: 7876 /* 7877 * PKCS#11 says that ASN.1 should be used to encode 7878 * specific attributes before encrypting the blob. 7879 * We only encrypt the private exponent for the 7880 * purpose of testing. 7881 */ 7882 object_idx = dprov_find_attr(object->do_attr, 7883 DPROV_MAX_ATTR, DPROV_CKA_PRIVATE_EXPONENT); 7884 if (object_idx == -1) { 7885 error = CRYPTO_ATTRIBUTE_TYPE_INVALID; 7886 break; 7887 } 7888 break; 7889 default: 7890 error = CRYPTO_KEY_NOT_WRAPPABLE; 7891 break; 7892 } 7893 if (error != CRYPTO_SUCCESS) 7894 break; 7895 7896 plaintext_key = object->do_attr[object_idx].oa_value; 7897 plaintext_key_len = object->do_attr[object_idx].oa_value_len; 7898 lenp = taskq_req->dr_key_req.kr_wrapped_key_len_ptr; 7899 7900 /* session id is 0 for software provider */ 7901 plaintext.cd_format = CRYPTO_DATA_RAW; 7902 plaintext.cd_offset = 0; 7903 plaintext.cd_length = plaintext_key_len; 7904 plaintext.cd_raw.iov_base = plaintext_key; 7905 plaintext.cd_raw.iov_len = plaintext_key_len; 7906 plaintext.cd_miscdata = NULL; 7907 7908 ciphertext.cd_format = CRYPTO_DATA_RAW; 7909 ciphertext.cd_offset = 0; 7910 ciphertext.cd_length = *lenp; 7911 ciphertext.cd_raw.iov_base = 7912 (char *)taskq_req->dr_key_req.kr_wrapped_key; 7913 ciphertext.cd_raw.iov_len = ciphertext.cd_length; 7914 ciphertext.cd_miscdata = NULL; 7915 7916 error = crypto_encrypt_prov(pd, 0, &mech, &plaintext, keyp, 7917 NULL, &ciphertext, NULL); 7918 7919 KCF_PROV_REFRELE(pd); 7920 if (error == CRYPTO_SUCCESS || 7921 error == CRYPTO_BUFFER_TOO_SMALL) { 7922 *lenp = ciphertext.cd_length; 7923 } 7924 break; 7925 } 7926 7927 case DPROV_REQ_KEY_UNWRAP: { 7928 crypto_mechanism_t mech, *mechp; 7929 crypto_key_t key, *keyp; 7930 crypto_object_id_t *object_id_ptr; 7931 ulong_t class = DPROV_CKO_DATA; 7932 uchar_t *wrapped_key; 7933 char *plaintext_buf; 7934 size_t wrapped_key_len; 7935 crypto_data_t plaintext; 7936 crypto_data_t ciphertext; 7937 crypto_object_attribute_t unwrapped_key; 7938 crypto_object_attribute_t *template; 7939 uint_t attribute_count; 7940 7941 template = taskq_req->dr_key_req.kr_template; 7942 attribute_count = taskq_req->dr_key_req.kr_attribute_count; 7943 object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr; 7944 7945 /* all objects must have an object class attribute */ 7946 if (dprov_get_template_attr_ulong(template, attribute_count, 7947 DPROV_CKA_CLASS, &class) != CRYPTO_SUCCESS) { 7948 error = CRYPTO_TEMPLATE_INCOMPLETE; 7949 break; 7950 } 7951 7952 mechp = taskq_req->dr_key_req.kr_mechanism; 7953 /* structure assignment */ 7954 mech = *mechp; 7955 7956 /* get unwrapping key value */ 7957 if (is_publickey_mech(mech.cm_type)) { 7958 if ((error = dprov_key_attr_asymmetric(softc, 7959 session_id, taskq_req->dr_type, 7960 taskq_req->dr_key_req.kr_key, 7961 &key)) != CRYPTO_SUCCESS) 7962 break; 7963 keyp = &key; 7964 } else { 7965 if ((error = dprov_key_value_secret(softc, 7966 session_id, taskq_req->dr_type, 7967 taskq_req->dr_key_req.kr_key, 7968 &key)) != CRYPTO_SUCCESS) 7969 break; 7970 keyp = &key; 7971 } 7972 7973 /* get the software provider for this mechanism */ 7974 if ((error = dprov_get_sw_prov(mechp, &pd, 7975 &mech.cm_type)) != CRYPTO_SUCCESS) 7976 break; 7977 7978 wrapped_key = taskq_req->dr_key_req.kr_wrapped_key; 7979 wrapped_key_len = *taskq_req->dr_key_req.kr_wrapped_key_len_ptr; 7980 ciphertext.cd_format = CRYPTO_DATA_RAW; 7981 ciphertext.cd_offset = 0; 7982 ciphertext.cd_length = wrapped_key_len; 7983 ciphertext.cd_raw.iov_base = (char *)wrapped_key; 7984 ciphertext.cd_raw.iov_len = wrapped_key_len; 7985 ciphertext.cd_miscdata = NULL; 7986 7987 /* 7988 * Plaintext length is less than or equal to 7989 * the length of the ciphertext. 7990 */ 7991 plaintext_buf = kmem_alloc(wrapped_key_len, KM_SLEEP); 7992 plaintext.cd_format = CRYPTO_DATA_RAW; 7993 plaintext.cd_offset = 0; 7994 plaintext.cd_length = wrapped_key_len; 7995 plaintext.cd_raw.iov_base = plaintext_buf; 7996 plaintext.cd_raw.iov_len = wrapped_key_len; 7997 plaintext.cd_miscdata = NULL; 7998 7999 error = crypto_decrypt_prov(pd, 0, &mech, &ciphertext, keyp, 8000 NULL, &plaintext, NULL); 8001 8002 KCF_PROV_REFRELE(pd); 8003 8004 if (error != CRYPTO_SUCCESS) 8005 goto free_unwrapped_key; 8006 8007 error = dprov_create_object_from_template(softc, session, 8008 template, attribute_count, object_id_ptr, B_FALSE, B_FALSE); 8009 8010 if (error != CRYPTO_SUCCESS) 8011 goto free_unwrapped_key; 8012 8013 switch (class) { 8014 case DPROV_CKO_SECRET_KEY: 8015 unwrapped_key.oa_type = DPROV_CKA_VALUE; 8016 unwrapped_key.oa_value_len = plaintext.cd_length; 8017 unwrapped_key.oa_value = plaintext_buf; 8018 break; 8019 case DPROV_CKO_PRIVATE_KEY: 8020 /* 8021 * PKCS#11 says that ASN.1 should be used to encode 8022 * specific attributes before encrypting the blob. 8023 * We only encrypt the private exponent for the 8024 * purpose of testing. 8025 */ 8026 unwrapped_key.oa_type = DPROV_CKA_PRIVATE_EXPONENT; 8027 unwrapped_key.oa_value_len = plaintext.cd_length; 8028 unwrapped_key.oa_value = plaintext_buf; 8029 break; 8030 default: 8031 error = CRYPTO_TEMPLATE_INCONSISTENT; 8032 goto free_unwrapped_key; 8033 } 8034 8035 if ((error = dprov_object_set_attr(session, *object_id_ptr, 8036 &unwrapped_key, 1, B_FALSE)) == CRYPTO_SUCCESS) 8037 break; /* don't free the unwrapped key */ 8038 8039 /* failure */ 8040 (void) dprov_destroy_object(softc, session, *object_id_ptr); 8041 break; 8042 8043 free_unwrapped_key: 8044 bzero(plaintext_buf, wrapped_key_len); 8045 kmem_free(plaintext_buf, wrapped_key_len); 8046 break; 8047 } 8048 8049 case DPROV_REQ_KEY_DERIVE: { 8050 crypto_mechanism_t digest_mech, *mechp; 8051 crypto_key_t key, *base_keyp; 8052 crypto_object_id_t *object_id_ptr; 8053 crypto_data_t data; 8054 crypto_data_t digest; 8055 size_t hash_size; 8056 char *digest_buf; 8057 crypto_object_attribute_t derived_key; 8058 crypto_object_attribute_t *template; 8059 uint_t attribute_count; 8060 ulong_t key_type; 8061 void *value; 8062 size_t value_len = 0; 8063 8064 error = CRYPTO_SUCCESS; 8065 8066 template = taskq_req->dr_key_req.kr_template; 8067 attribute_count = taskq_req->dr_key_req.kr_attribute_count; 8068 object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr; 8069 8070 /* required */ 8071 if (dprov_get_template_attr_ulong(template, attribute_count, 8072 DPROV_CKA_KEY_TYPE, &key_type) != CRYPTO_SUCCESS) { 8073 error = CRYPTO_TEMPLATE_INCOMPLETE; 8074 break; 8075 } 8076 8077 mechp = taskq_req->dr_key_req.kr_mechanism; 8078 /* structure assignment */ 8079 digest_mech = *mechp; 8080 8081 switch (digest_mech.cm_type) { 8082 case SHA1_KEY_DERIVATION_MECH_INFO_TYPE: 8083 hash_size = SHA1_DIGEST_LEN; 8084 digest_mech.cm_type = SHA1_MECH_INFO_TYPE; 8085 break; 8086 8087 case SHA256_KEY_DERIVATION_MECH_INFO_TYPE: 8088 hash_size = SHA256_DIGEST_LENGTH; 8089 digest_mech.cm_type = SHA256_MECH_INFO_TYPE; 8090 break; 8091 8092 case SHA384_KEY_DERIVATION_MECH_INFO_TYPE: 8093 hash_size = SHA384_DIGEST_LENGTH; 8094 digest_mech.cm_type = SHA384_MECH_INFO_TYPE; 8095 break; 8096 8097 case SHA512_KEY_DERIVATION_MECH_INFO_TYPE: 8098 hash_size = SHA512_DIGEST_LENGTH; 8099 digest_mech.cm_type = SHA512_MECH_INFO_TYPE; 8100 break; 8101 8102 case MD5_KEY_DERIVATION_MECH_INFO_TYPE: 8103 hash_size = MD5_DIGEST_LEN; 8104 digest_mech.cm_type = MD5_MECH_INFO_TYPE; 8105 break; 8106 8107 default: 8108 error = CRYPTO_MECHANISM_INVALID; 8109 } 8110 8111 if (error != CRYPTO_SUCCESS) 8112 break; 8113 8114 /* CKA_VALUE is optional */ 8115 (void) dprov_get_template_attr_array(template, attribute_count, 8116 DPROV_CKA_VALUE, &value, &value_len); 8117 8118 /* check for inconsistent value length */ 8119 switch (key_type) { 8120 case DPROV_CKK_GENERIC_SECRET: 8121 if (value_len > 0) { 8122 if (value_len > hash_size) 8123 error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 8124 } else { 8125 value_len = hash_size; 8126 } 8127 break; 8128 8129 case DPROV_CKK_RC4: 8130 case DPROV_CKK_AES: 8131 if (value_len == 0 || 8132 value_len > hash_size) { 8133 error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 8134 } 8135 break; 8136 8137 case DPROV_CKK_DES: 8138 if (value_len > 0 && 8139 value_len != DES_KEY_LEN) { 8140 error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 8141 } 8142 value_len = DES_KEY_LEN; 8143 break; 8144 8145 case DPROV_CKK_DES3: 8146 if (value_len > 0 && 8147 value_len != DES3_KEY_LEN) { 8148 error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 8149 } 8150 value_len = DES3_KEY_LEN; 8151 break; 8152 8153 default: 8154 error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 8155 break; 8156 } 8157 8158 if (error != CRYPTO_SUCCESS) 8159 break; 8160 8161 /* get the software provider for this mechanism */ 8162 if ((error = dprov_get_sw_prov(&digest_mech, &pd, 8163 &digest_mech.cm_type)) != CRYPTO_SUCCESS) 8164 break; 8165 8166 /* get the base key */ 8167 error = dprov_key_value_secret(softc, session_id, 8168 taskq_req->dr_type, taskq_req->dr_key_req.kr_key, &key); 8169 if (error != CRYPTO_SUCCESS) 8170 break; 8171 8172 base_keyp = &key; 8173 8174 data.cd_format = CRYPTO_DATA_RAW; 8175 data.cd_offset = 0; 8176 data.cd_length = CRYPTO_BITS2BYTES(base_keyp->ck_length); 8177 data.cd_raw.iov_base = base_keyp->ck_data; 8178 data.cd_raw.iov_len = data.cd_length; 8179 8180 digest_buf = kmem_alloc(hash_size, KM_SLEEP); 8181 digest.cd_format = CRYPTO_DATA_RAW; 8182 digest.cd_offset = 0; 8183 digest.cd_length = hash_size; 8184 digest.cd_raw.iov_base = digest_buf; 8185 digest.cd_raw.iov_len = hash_size; 8186 8187 error = crypto_digest_prov(pd, 0, &digest_mech, &data, 8188 &digest, NULL); 8189 8190 KCF_PROV_REFRELE(pd); 8191 8192 if (error != CRYPTO_SUCCESS) 8193 goto free_derived_key; 8194 8195 error = dprov_create_object_from_template(softc, session, 8196 template, attribute_count, object_id_ptr, B_FALSE, B_FALSE); 8197 8198 if (error != CRYPTO_SUCCESS) 8199 goto free_derived_key; 8200 8201 derived_key.oa_type = DPROV_CKA_VALUE; 8202 derived_key.oa_value = digest_buf; 8203 derived_key.oa_value_len = value_len; 8204 8205 error = dprov_object_set_attr(session, *object_id_ptr, 8206 &derived_key, 1, B_FALSE); 8207 8208 if (error != CRYPTO_SUCCESS) { 8209 (void) dprov_destroy_object(softc, session, 8210 *object_id_ptr); 8211 } 8212 8213 free_derived_key: 8214 bzero(digest_buf, hash_size); 8215 kmem_free(digest_buf, hash_size); 8216 break; 8217 } 8218 8219 case DPROV_REQ_NOSTORE_KEY_GENERATE: { 8220 crypto_object_attribute_t *out_template; 8221 uint_t out_attribute_count; 8222 void *value; 8223 size_t value_len = 0; 8224 8225 out_template = taskq_req->dr_key_req.kr_out_template1; 8226 out_attribute_count = 8227 taskq_req->dr_key_req.kr_out_attribute_count1; 8228 8229 error = dprov_get_template_attr_array(out_template, 8230 out_attribute_count, DPROV_CKA_VALUE, &value, &value_len); 8231 if (error != CRYPTO_SUCCESS) 8232 break; 8233 8234 /* fill the entire array with pattern */ 8235 { 8236 int i = 0; 8237 char *p = value; 8238 while (i < value_len) { 8239 p[i++] = 'A'; 8240 if (i >= value_len) 8241 break; 8242 p[i++] = 'B'; 8243 if (i >= value_len) 8244 break; 8245 p[i++] = 'C'; 8246 } 8247 } 8248 8249 error = CRYPTO_SUCCESS; 8250 break; 8251 } 8252 8253 case DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR: { 8254 crypto_mechanism_t *mechp; 8255 crypto_object_attribute_t *pub_template; 8256 crypto_object_attribute_t *pri_template; 8257 uint_t pub_attribute_count; 8258 uint_t pri_attribute_count; 8259 crypto_object_attribute_t *out_pub_template; 8260 crypto_object_attribute_t *out_pri_template; 8261 uint_t out_pub_attribute_count; 8262 uint_t out_pri_attribute_count; 8263 8264 mechp = taskq_req->dr_key_req.kr_mechanism; 8265 pub_template = taskq_req->dr_key_req.kr_template; 8266 pub_attribute_count = taskq_req->dr_key_req.kr_attribute_count; 8267 pri_template = taskq_req->dr_key_req.kr_private_key_template; 8268 pri_attribute_count = 8269 taskq_req->dr_key_req.kr_private_key_attribute_count; 8270 out_pub_template = taskq_req->dr_key_req.kr_out_template1; 8271 out_pub_attribute_count = 8272 taskq_req->dr_key_req.kr_out_attribute_count1; 8273 out_pri_template = taskq_req->dr_key_req.kr_out_template2; 8274 out_pri_attribute_count = 8275 taskq_req->dr_key_req.kr_out_attribute_count2; 8276 8277 switch (mechp->cm_type) { 8278 case RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE: 8279 error = nostore_copy_attribute(out_pub_template, 8280 out_pub_attribute_count, DPROV_CKA_MODULUS); 8281 if (error != CRYPTO_SUCCESS) 8282 break; 8283 8284 error = nostore_copy_attribute(out_pub_template, 8285 out_pub_attribute_count, DPROV_CKA_PUBLIC_EXPONENT); 8286 if (error == CRYPTO_ARGUMENTS_BAD) { 8287 size_t tmp_len = 0; 8288 void *tmp; 8289 8290 /* public exponent must be here */ 8291 error = dprov_get_template_attr_array( 8292 pub_template, pub_attribute_count, 8293 DPROV_CKA_PUBLIC_EXPONENT, &tmp, &tmp_len); 8294 if (error != CRYPTO_SUCCESS) 8295 break; 8296 } 8297 error = nostore_copy_attribute(out_pri_template, 8298 out_pri_attribute_count, DPROV_CKA_MODULUS); 8299 if (error != CRYPTO_SUCCESS) 8300 break; 8301 8302 error = nostore_copy_attribute(out_pri_template, 8303 out_pri_attribute_count, 8304 DPROV_CKA_PRIVATE_EXPONENT); 8305 break; 8306 8307 case DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE: 8308 /* 8309 * There is no software provider for DH mechanism; 8310 * Just return pre-defined values. 8311 */ 8312 error = nostore_copy_attribute(out_pub_template, 8313 out_pub_attribute_count, DPROV_CKA_VALUE); 8314 error = nostore_copy_attribute(out_pri_template, 8315 out_pri_attribute_count, DPROV_CKA_VALUE); 8316 break; 8317 8318 case EC_KEY_PAIR_GEN_MECH_INFO_TYPE: { 8319 crypto_mechanism_t mech, *mechp; 8320 kcf_req_params_t params; 8321 crypto_object_attribute_t *pub_template; 8322 uint_t pub_attribute_count; 8323 crypto_object_attribute_t *out_pub_template; 8324 crypto_object_attribute_t *out_pri_template; 8325 uint_t out_pub_attribute_count; 8326 uint_t out_pri_attribute_count; 8327 8328 mechp = taskq_req->dr_key_req.kr_mechanism; 8329 pub_template = taskq_req->dr_key_req.kr_template; 8330 pub_attribute_count = 8331 taskq_req->dr_key_req.kr_attribute_count; 8332 out_pub_template = 8333 taskq_req->dr_key_req.kr_out_template1; 8334 out_pub_attribute_count = 8335 taskq_req->dr_key_req.kr_out_attribute_count1; 8336 out_pri_template = 8337 taskq_req->dr_key_req.kr_out_template2; 8338 out_pri_attribute_count = 8339 taskq_req->dr_key_req.kr_out_attribute_count2; 8340 8341 /* get the software provider for this mechanism */ 8342 mech = *mechp; 8343 if ((error = dprov_get_sw_prov(mechp, &pd, 8344 &mech.cm_type)) != CRYPTO_SUCCESS) 8345 break; 8346 /* 8347 * Turn 32-bit values into 64-bit values for certain 8348 * attributes like CKA_CLASS. 8349 */ 8350 dprov_adjust_attrs(pub_template, pub_attribute_count); 8351 dprov_adjust_attrs(pri_template, pri_attribute_count); 8352 8353 /* bypass the kernel API for now */ 8354 KCF_WRAP_NOSTORE_KEY_OPS_PARAMS(¶ms, 8355 KCF_OP_KEY_GENERATE_PAIR, 8356 0, /* session 0 for sw provider */ 8357 &mech, pub_template, pub_attribute_count, 8358 pri_template, pri_attribute_count, NULL, 8359 out_pub_template, out_pub_attribute_count, 8360 out_pri_template, out_pri_attribute_count); 8361 8362 error = kcf_submit_request(pd, NULL, NULL, ¶ms, 8363 B_FALSE); 8364 8365 KCF_PROV_REFRELE(pd); 8366 break; 8367 } 8368 default: 8369 error = CRYPTO_MECHANISM_INVALID; 8370 } 8371 break; 8372 } 8373 8374 case DPROV_REQ_NOSTORE_KEY_DERIVE: { 8375 crypto_mechanism_t *mechp; 8376 crypto_object_attribute_t *in_template, *out_template; 8377 crypto_key_t *base_key; 8378 uint_t in_attribute_count, out_attribute_count; 8379 ulong_t key_type; 8380 void *value; 8381 size_t value_len = 0; 8382 size_t value_len_value = 0; 8383 8384 in_template = taskq_req->dr_key_req.kr_template; 8385 out_template = taskq_req->dr_key_req.kr_out_template1; 8386 in_attribute_count = taskq_req->dr_key_req.kr_attribute_count; 8387 out_attribute_count = 8388 taskq_req->dr_key_req.kr_out_attribute_count1; 8389 mechp = taskq_req->dr_key_req.kr_mechanism; 8390 base_key = taskq_req->dr_key_req.kr_key; 8391 8392 /* 8393 * CKA_VALUE must be present so the derived key can 8394 * be returned by value. 8395 */ 8396 if (dprov_get_template_attr_array(out_template, 8397 out_attribute_count, DPROV_CKA_VALUE, &value, 8398 &value_len) != CRYPTO_SUCCESS) { 8399 error = CRYPTO_TEMPLATE_INCOMPLETE; 8400 break; 8401 } 8402 8403 if (dprov_get_template_attr_ulong(in_template, 8404 in_attribute_count, DPROV_CKA_KEY_TYPE, 8405 &key_type) != CRYPTO_SUCCESS) { 8406 error = CRYPTO_TEMPLATE_INCOMPLETE; 8407 break; 8408 } 8409 switch (mechp->cm_type) { 8410 case DH_PKCS_DERIVE_MECH_INFO_TYPE: { 8411 size_t tmp_len = 0; 8412 void *tmp; 8413 8414 if (base_key->ck_format != CRYPTO_KEY_ATTR_LIST) { 8415 error = CRYPTO_ARGUMENTS_BAD; 8416 break; 8417 } 8418 8419 if ((dprov_get_template_attr_array(base_key->ck_attrs, 8420 base_key->ck_count, DPROV_CKA_BASE, &tmp, 8421 &tmp_len) != CRYPTO_SUCCESS) || 8422 (dprov_get_template_attr_array(base_key->ck_attrs, 8423 base_key->ck_count, DPROV_CKA_PRIME, &tmp, 8424 &tmp_len) != CRYPTO_SUCCESS) || 8425 (dprov_get_template_attr_array(base_key->ck_attrs, 8426 base_key->ck_count, DPROV_CKA_VALUE, &tmp, 8427 &tmp_len) != CRYPTO_SUCCESS)) { 8428 error = CRYPTO_TEMPLATE_INCOMPLETE; 8429 break; 8430 } 8431 8432 /* 8433 * CKA_VALUE is added to the derived key template by 8434 * the library. 8435 */ 8436 error = CRYPTO_SUCCESS; 8437 switch (key_type) { 8438 case DPROV_CKK_AES: 8439 if (dprov_get_template_attr_ulong(in_template, 8440 in_attribute_count, DPROV_CKA_VALUE_LEN, 8441 &value_len_value) != CRYPTO_SUCCESS) { 8442 error = CRYPTO_TEMPLATE_INCOMPLETE; 8443 break; 8444 } 8445 if (value_len != value_len_value) { 8446 error = CRYPTO_TEMPLATE_INCONSISTENT; 8447 break; 8448 } 8449 break; 8450 default: 8451 error = CRYPTO_MECHANISM_INVALID; 8452 } 8453 if (error == CRYPTO_SUCCESS) 8454 fill_dh(value, value_len); 8455 break; 8456 } 8457 case ECDH1_DERIVE_MECH_INFO_TYPE: { 8458 crypto_mechanism_t mech; 8459 kcf_req_params_t params; 8460 8461 /* get the software provider for this mechanism */ 8462 mech = *mechp; 8463 if ((error = dprov_get_sw_prov(mechp, &pd, 8464 &mech.cm_type)) != CRYPTO_SUCCESS) 8465 break; 8466 8467 /* 8468 * Turn 32-bit values into 64-bit values for certain 8469 * attributes like CKA_VALUE_LEN. 8470 */ 8471 dprov_adjust_attrs(in_template, in_attribute_count); 8472 8473 /* bypass the kernel API for now */ 8474 KCF_WRAP_NOSTORE_KEY_OPS_PARAMS(¶ms, 8475 KCF_OP_KEY_DERIVE, 8476 0, /* session 0 for sw provider */ 8477 &mech, in_template, in_attribute_count, 8478 NULL, 0, base_key, 8479 out_template, out_attribute_count, 8480 NULL, 0); 8481 8482 error = kcf_submit_request(pd, NULL, NULL, ¶ms, 8483 B_FALSE); 8484 8485 KCF_PROV_REFRELE(pd); 8486 break; 8487 } 8488 8489 default: 8490 error = CRYPTO_MECHANISM_INVALID; 8491 } 8492 break; 8493 default: 8494 error = CRYPTO_MECHANISM_INVALID; 8495 } 8496 } /* end case */ 8497 8498 mutex_exit(&softc->ds_lock); 8499 dprov_op_done(taskq_req, error); 8500 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_task: end\n", instance)); 8501 } 8502 8503 /* 8504 * taskq dispatcher function for provider management operations. 8505 */ 8506 static void 8507 dprov_mgmt_task(dprov_req_t *taskq_req) 8508 { 8509 dprov_state_t *softc; 8510 /* LINTED E_FUNC_SET_NOT_USED */ 8511 int instance; 8512 int error = CRYPTO_NOT_SUPPORTED; 8513 8514 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 8515 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_mgmt_task: started\n", instance)); 8516 8517 mutex_enter(&softc->ds_lock); 8518 8519 switch (taskq_req->dr_type) { 8520 case DPROV_REQ_MGMT_EXTINFO: { 8521 crypto_provider_ext_info_t *ext_info = 8522 taskq_req->dr_mgmt_req.mr_ext_info; 8523 8524 (void) memset(ext_info->ei_label, ' ', CRYPTO_EXT_SIZE_LABEL); 8525 if (!softc->ds_token_initialized) { 8526 bcopy("(not initialized)", ext_info->ei_label, 8527 strlen("(not initialized)")); 8528 } else { 8529 bcopy(softc->ds_label, ext_info->ei_label, 8530 CRYPTO_EXT_SIZE_LABEL); 8531 } 8532 8533 bcopy(DPROV_MANUFACTURER, ext_info->ei_manufacturerID, 8534 CRYPTO_EXT_SIZE_MANUF); 8535 bcopy(DPROV_MODEL, ext_info->ei_model, CRYPTO_EXT_SIZE_MODEL); 8536 8537 (void) snprintf((char *)ext_info->ei_serial_number, 16, "%d%s", 8538 instance, DPROV_ALLSPACES); 8539 /* PKCS#11 blank padding */ 8540 ext_info->ei_serial_number[15] = ' '; 8541 ext_info->ei_max_session_count = CRYPTO_EFFECTIVELY_INFINITE; 8542 ext_info->ei_max_pin_len = (ulong_t)DPROV_MAX_PIN_LEN; 8543 ext_info->ei_min_pin_len = 1; 8544 ext_info->ei_total_public_memory = CRYPTO_EFFECTIVELY_INFINITE; 8545 ext_info->ei_free_public_memory = CRYPTO_EFFECTIVELY_INFINITE; 8546 ext_info->ei_total_private_memory = CRYPTO_EFFECTIVELY_INFINITE; 8547 ext_info->ei_free_private_memory = CRYPTO_EFFECTIVELY_INFINITE; 8548 ext_info->ei_hardware_version.cv_major = 1; 8549 ext_info->ei_hardware_version.cv_minor = 0; 8550 ext_info->ei_firmware_version.cv_major = 1; 8551 ext_info->ei_firmware_version.cv_minor = 0; 8552 8553 ext_info->ei_flags = CRYPTO_EXTF_RNG | 8554 CRYPTO_EXTF_LOGIN_REQUIRED | 8555 CRYPTO_EXTF_DUAL_CRYPTO_OPERATIONS; 8556 if (softc->ds_user_pin_set) 8557 ext_info->ei_flags |= CRYPTO_EXTF_USER_PIN_INITIALIZED; 8558 if (softc->ds_token_initialized) 8559 ext_info->ei_flags |= CRYPTO_EXTF_TOKEN_INITIALIZED; 8560 8561 ext_info->ei_hash_max_input_len = dprov_max_digestsz; 8562 ext_info->ei_hmac_max_input_len = dprov_max_digestsz; 8563 error = CRYPTO_SUCCESS; 8564 break; 8565 } 8566 case DPROV_REQ_MGMT_INITTOKEN: { 8567 char *pin = taskq_req->dr_mgmt_req.mr_pin; 8568 size_t pin_len = taskq_req->dr_mgmt_req.mr_pin_len; 8569 char *label = taskq_req->dr_mgmt_req.mr_label; 8570 8571 /* cannot initialize token when a session is open */ 8572 if (softc->ds_sessions_count > 0) { 8573 error = CRYPTO_SESSION_EXISTS; 8574 break; 8575 } 8576 8577 /* check PIN length */ 8578 if (pin_len > DPROV_MAX_PIN_LEN) { 8579 error = CRYPTO_PIN_LEN_RANGE; 8580 break; 8581 } 8582 8583 /* check PIN */ 8584 if (pin == NULL) { 8585 error = CRYPTO_PIN_INVALID; 8586 break; 8587 } 8588 8589 /* 8590 * If the token has already been initialized, need 8591 * to validate supplied PIN. 8592 */ 8593 if (softc->ds_token_initialized && 8594 (softc->ds_so_pin_len != pin_len || 8595 strncmp(softc->ds_so_pin, pin, pin_len) != 0)) { 8596 /* invalid SO PIN */ 8597 error = CRYPTO_PIN_INCORRECT; 8598 break; 8599 } 8600 8601 /* set label */ 8602 bcopy(label, softc->ds_label, CRYPTO_EXT_SIZE_LABEL); 8603 8604 /* set new SO PIN, update state */ 8605 bcopy(pin, softc->ds_so_pin, pin_len); 8606 softc->ds_so_pin_len = pin_len; 8607 softc->ds_token_initialized = B_TRUE; 8608 softc->ds_user_pin_set = B_FALSE; 8609 8610 error = CRYPTO_SUCCESS; 8611 break; 8612 } 8613 case DPROV_REQ_MGMT_INITPIN: { 8614 char *pin = taskq_req->dr_mgmt_req.mr_pin; 8615 size_t pin_len = taskq_req->dr_mgmt_req.mr_pin_len; 8616 crypto_session_id_t session_id = 8617 taskq_req->dr_mgmt_req.mr_session_id; 8618 8619 /* check session id */ 8620 if (softc->ds_sessions[session_id] == NULL) { 8621 error = CRYPTO_SESSION_HANDLE_INVALID; 8622 break; 8623 } 8624 8625 /* fail if not logged in as SO */ 8626 if (softc->ds_sessions[session_id]->ds_state != 8627 DPROV_SESSION_STATE_SO) { 8628 error = CRYPTO_USER_NOT_LOGGED_IN; 8629 break; 8630 } 8631 8632 /* check PIN length */ 8633 if (pin_len > DPROV_MAX_PIN_LEN) { 8634 error = CRYPTO_PIN_LEN_RANGE; 8635 break; 8636 } 8637 8638 /* check PIN */ 8639 if (pin == NULL) { 8640 error = CRYPTO_PIN_INVALID; 8641 break; 8642 } 8643 8644 /* set new normal user PIN */ 8645 bcopy(pin, softc->ds_user_pin, pin_len); 8646 softc->ds_user_pin_len = pin_len; 8647 softc->ds_user_pin_set = B_TRUE; 8648 8649 error = CRYPTO_SUCCESS; 8650 break; 8651 } 8652 case DPROV_REQ_MGMT_SETPIN: { 8653 char *new_pin = taskq_req->dr_mgmt_req.mr_pin; 8654 size_t new_pin_len = taskq_req->dr_mgmt_req.mr_pin_len; 8655 char *old_pin = taskq_req->dr_mgmt_req.mr_old_pin; 8656 size_t old_pin_len = taskq_req->dr_mgmt_req.mr_old_pin_len; 8657 crypto_session_id_t session_id = 8658 taskq_req->dr_mgmt_req.mr_session_id; 8659 8660 /* check session id */ 8661 if (softc->ds_sessions[session_id] == NULL) { 8662 error = CRYPTO_SESSION_HANDLE_INVALID; 8663 break; 8664 } 8665 8666 /* check PIN length */ 8667 if (old_pin_len > DPROV_MAX_PIN_LEN || 8668 new_pin_len > DPROV_MAX_PIN_LEN) { 8669 error = CRYPTO_PIN_LEN_RANGE; 8670 break; 8671 } 8672 8673 /* check PIN */ 8674 if (old_pin == NULL || new_pin == NULL) { 8675 error = CRYPTO_PIN_INVALID; 8676 break; 8677 } 8678 8679 /* check user PIN state */ 8680 if (!softc->ds_user_pin_set) { 8681 error = CRYPTO_USER_PIN_NOT_INITIALIZED; 8682 break; 8683 } 8684 8685 /* 8686 * If the token has already been initialized, need 8687 * to validate supplied PIN. 8688 */ 8689 if (softc->ds_user_pin_len != old_pin_len || 8690 strncmp(softc->ds_user_pin, old_pin, old_pin_len) != 0) { 8691 /* invalid SO PIN */ 8692 error = CRYPTO_PIN_INCORRECT; 8693 break; 8694 } 8695 8696 /* set new PIN */ 8697 bcopy(new_pin, softc->ds_user_pin, new_pin_len); 8698 softc->ds_user_pin_len = new_pin_len; 8699 8700 error = CRYPTO_SUCCESS; 8701 break; 8702 } 8703 } 8704 8705 mutex_exit(&softc->ds_lock); 8706 dprov_op_done(taskq_req, error); 8707 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_mgmt_task: end\n", instance)); 8708 } 8709 8710 /* 8711 * Returns in the location pointed to by pd a pointer to the descriptor 8712 * for the software provider for the specified mechanism. 8713 * The provider descriptor is returned held. Returns one of the CRYPTO_ 8714 * error codes on failure, CRYPTO_SUCCESS on success. 8715 */ 8716 static int 8717 dprov_get_sw_prov(crypto_mechanism_t *mech, kcf_provider_desc_t **pd, 8718 crypto_mech_type_t *provider_mech_type) 8719 { 8720 crypto_mech_type_t kcf_mech_type = CRYPTO_MECH_INVALID; 8721 int i, rv; 8722 8723 /* lookup the KCF mech type associated with our mech type */ 8724 for (i = 0; i < sizeof (dprov_mech_info_tab)/ 8725 sizeof (crypto_mech_info_t); i++) { 8726 if (mech->cm_type == dprov_mech_info_tab[i].cm_mech_number) { 8727 kcf_mech_type = crypto_mech2id_common( 8728 dprov_mech_info_tab[i].cm_mech_name, B_TRUE); 8729 } 8730 } 8731 8732 rv = kcf_get_sw_prov(kcf_mech_type, pd, NULL, B_TRUE); 8733 if (rv == CRYPTO_SUCCESS) 8734 *provider_mech_type = kcf_mech_type; 8735 8736 return (rv); 8737 } 8738 8739 /* 8740 * Object management helper functions. 8741 */ 8742 8743 /* 8744 * Given a crypto_key_t, return whether the key can be used or not 8745 * for the specified request. The attributes used here are defined 8746 * in table 42 of the PKCS#11 spec (Common secret key attributes). 8747 */ 8748 static int 8749 dprov_key_can_use(dprov_object_t *object, dprov_req_type_t req_type) 8750 { 8751 boolean_t ret = 0; 8752 int rv = CRYPTO_SUCCESS; 8753 8754 /* check if object is allowed for specified operation */ 8755 switch (req_type) { 8756 case DPROV_REQ_ENCRYPT_INIT: 8757 case DPROV_REQ_ENCRYPT_ATOMIC: 8758 rv = dprov_get_object_attr_boolean(object, 8759 DPROV_CKA_ENCRYPT, &ret); 8760 break; 8761 case DPROV_REQ_DECRYPT_INIT: 8762 case DPROV_REQ_DECRYPT_ATOMIC: 8763 rv = dprov_get_object_attr_boolean(object, 8764 DPROV_CKA_DECRYPT, &ret); 8765 break; 8766 case DPROV_REQ_SIGN_INIT: 8767 case DPROV_REQ_SIGN_ATOMIC: 8768 case DPROV_REQ_MAC_INIT: 8769 case DPROV_REQ_MAC_ATOMIC: 8770 case DPROV_REQ_MAC_VERIFY_ATOMIC: 8771 rv = dprov_get_object_attr_boolean(object, 8772 DPROV_CKA_SIGN, &ret); 8773 break; 8774 case DPROV_REQ_SIGN_RECOVER_INIT: 8775 case DPROV_REQ_SIGN_RECOVER_ATOMIC: 8776 rv = dprov_get_object_attr_boolean(object, 8777 DPROV_CKA_SIGN_RECOVER, &ret); 8778 break; 8779 case DPROV_REQ_VERIFY_INIT: 8780 case DPROV_REQ_VERIFY_ATOMIC: 8781 rv = dprov_get_object_attr_boolean(object, 8782 DPROV_CKA_VERIFY, &ret); 8783 break; 8784 case DPROV_REQ_VERIFY_RECOVER_INIT: 8785 case DPROV_REQ_VERIFY_RECOVER_ATOMIC: 8786 rv = dprov_get_object_attr_boolean(object, 8787 DPROV_CKA_VERIFY_RECOVER, &ret); 8788 break; 8789 case DPROV_REQ_KEY_WRAP: 8790 rv = dprov_get_object_attr_boolean(object, 8791 DPROV_CKA_WRAP, &ret); 8792 break; 8793 case DPROV_REQ_KEY_UNWRAP: 8794 rv = dprov_get_object_attr_boolean(object, 8795 DPROV_CKA_UNWRAP, &ret); 8796 break; 8797 case DPROV_REQ_DIGEST_KEY: 8798 /* 8799 * There is no attribute to check for; therefore, 8800 * any secret key can be used. 8801 */ 8802 ret = B_TRUE; 8803 rv = CRYPTO_SUCCESS; 8804 break; 8805 case DPROV_REQ_KEY_DERIVE: 8806 rv = dprov_get_object_attr_boolean(object, 8807 DPROV_CKA_DERIVE, &ret); 8808 break; 8809 } 8810 8811 if (rv != CRYPTO_SUCCESS || !ret) 8812 return (CRYPTO_KEY_FUNCTION_NOT_PERMITTED); 8813 8814 return (CRYPTO_SUCCESS); 8815 } 8816 8817 /* 8818 * Given a crypto_key_t corresponding to a secret key (i.e. for 8819 * use with symmetric crypto algorithms) specified in raw format, by 8820 * attribute, or by reference, initialize the ck_data and ck_length 8821 * fields of the ret_key argument so that they specify the key value 8822 * and length. 8823 * 8824 * For a key by value, this function uess the ck_data and ck_length, 8825 * for a key by reference, it looks up the corresponding object and 8826 * returns the appropriate attribute. For a key by attribute, it returns 8827 * the appropriate attribute. The attributes used are CKA_VALUE to retrieve 8828 * the value of the key, and CKA_VALUE_LEN to retrieve its length in bytes. 8829 */ 8830 static int 8831 dprov_key_value_secret(dprov_state_t *softc, crypto_session_id_t session_id, 8832 dprov_req_type_t req_type, crypto_key_t *key, crypto_key_t *ret_key) 8833 { 8834 ulong_t key_type; 8835 int ret = CRYPTO_SUCCESS; 8836 8837 ret_key->ck_format = CRYPTO_KEY_RAW; 8838 8839 switch (key->ck_format) { 8840 8841 case CRYPTO_KEY_RAW: 8842 ret_key->ck_data = key->ck_data; 8843 ret_key->ck_length = key->ck_length; 8844 break; 8845 8846 case CRYPTO_KEY_ATTR_LIST: { 8847 void *value; 8848 size_t len, value_len; 8849 8850 if ((ret = dprov_get_key_attr_ulong(key, DPROV_CKA_KEY_TYPE, 8851 &key_type)) != CRYPTO_SUCCESS) 8852 break; 8853 8854 if ((ret = dprov_get_key_attr_array(key, DPROV_CKA_VALUE, 8855 &value, &len)) != CRYPTO_SUCCESS) 8856 break; 8857 8858 /* 8859 * The length of the array is expressed in bytes. 8860 * Convert to bits now since that's how keys are measured. 8861 */ 8862 len = CRYPTO_BYTES2BITS(len); 8863 8864 /* optional */ 8865 if ((dprov_get_key_attr_ulong(key, DPROV_CKA_VALUE_LEN, 8866 &value_len)) == CRYPTO_SUCCESS) { 8867 len = value_len; 8868 } 8869 8870 ret_key->ck_data = value; 8871 ret_key->ck_length = (uint_t)len; 8872 8873 break; 8874 } 8875 8876 case CRYPTO_KEY_REFERENCE: { 8877 dprov_object_t *object; 8878 void *value; 8879 size_t len, value_len; 8880 8881 /* check session id */ 8882 if (softc->ds_sessions[session_id] == NULL) { 8883 ret = CRYPTO_SESSION_HANDLE_INVALID; 8884 break; 8885 } 8886 8887 if (key->ck_obj_id >= DPROV_MAX_OBJECTS) { 8888 ret = CRYPTO_KEY_HANDLE_INVALID; 8889 goto bail; 8890 } 8891 8892 /* check if object id specified by key is valid */ 8893 object = softc->ds_sessions[session_id]-> 8894 ds_objects[key->ck_obj_id]; 8895 if (object == NULL) { 8896 ret = CRYPTO_KEY_HANDLE_INVALID; 8897 goto bail; 8898 } 8899 8900 /* check if object can be used for operation */ 8901 if ((ret = dprov_key_can_use(object, req_type)) != 8902 CRYPTO_SUCCESS) 8903 goto bail; 8904 8905 if ((ret = dprov_get_object_attr_ulong(object, 8906 DPROV_CKA_KEY_TYPE, &key_type)) != CRYPTO_SUCCESS) 8907 goto bail; 8908 8909 if ((ret = dprov_get_object_attr_array(object, 8910 DPROV_CKA_VALUE, &value, &len)) != CRYPTO_SUCCESS) 8911 goto bail; 8912 8913 /* optional */ 8914 if ((dprov_get_object_attr_ulong(object, DPROV_CKA_VALUE_LEN, 8915 &value_len)) == CRYPTO_SUCCESS) { 8916 len = value_len; 8917 } 8918 8919 /* 8920 * The length of attributes are in bytes. 8921 * Convert to bits now since that's how keys are measured. 8922 */ 8923 len = CRYPTO_BYTES2BITS(len); 8924 8925 ret_key->ck_data = value; 8926 ret_key->ck_length = (uint_t)len; 8927 bail: 8928 break; 8929 } 8930 8931 default: 8932 ret = CRYPTO_ARGUMENTS_BAD; 8933 break; 8934 } 8935 8936 return (ret); 8937 } 8938 8939 /* 8940 * Get the attribute list for the specified asymmetric key. 8941 */ 8942 static int 8943 dprov_key_attr_asymmetric(dprov_state_t *softc, crypto_session_id_t session_id, 8944 dprov_req_type_t req_type, crypto_key_t *key, crypto_key_t *ret_key) 8945 { 8946 int ret = CRYPTO_SUCCESS; 8947 8948 ret_key->ck_format = CRYPTO_KEY_ATTR_LIST; 8949 8950 switch (key->ck_format) { 8951 8952 case CRYPTO_KEY_ATTR_LIST: 8953 ret_key->ck_attrs = key->ck_attrs; 8954 ret_key->ck_count = key->ck_count; 8955 break; 8956 8957 case CRYPTO_KEY_REFERENCE: { 8958 dprov_object_t *object; 8959 8960 /* check session id */ 8961 if (softc->ds_sessions[session_id] == NULL) { 8962 ret = CRYPTO_SESSION_HANDLE_INVALID; 8963 break; 8964 } 8965 8966 /* check if object id specified by key is valid */ 8967 object = softc->ds_sessions[session_id]-> 8968 ds_objects[key->ck_obj_id]; 8969 if (object == NULL) { 8970 ret = CRYPTO_KEY_HANDLE_INVALID; 8971 break; 8972 } 8973 8974 /* check if object can be used for operation */ 8975 if ((ret = dprov_key_can_use(object, req_type)) != 8976 CRYPTO_SUCCESS) 8977 break; 8978 8979 ret_key->ck_attrs = object->do_attr; 8980 ret_key->ck_count = DPROV_MAX_ATTR; 8981 break; 8982 } 8983 8984 default: 8985 ret = CRYPTO_ARGUMENTS_BAD; 8986 } 8987 8988 return (ret); 8989 } 8990 8991 /* 8992 * Return the index of an attribute of specified type found in 8993 * the specified array of attributes. If the attribute cannot 8994 * found, return -1. 8995 */ 8996 static int 8997 dprov_find_attr(crypto_object_attribute_t *attr, uint_t nattr, 8998 uint64_t attr_type) 8999 { 9000 int i; 9001 9002 for (i = 0; i < nattr; i++) 9003 if (attr[i].oa_value != NULL && 9004 attr[i].oa_type == attr_type) 9005 return (i); 9006 9007 return (-1); 9008 } 9009 9010 /* 9011 * Given the given object template and session, return whether 9012 * an object can be created from that template according to the 9013 * following rules: 9014 * - private objects can be created only by a logged-in user 9015 */ 9016 static int 9017 dprov_template_can_create(dprov_session_t *session, 9018 crypto_object_attribute_t *template, uint_t nattr, 9019 boolean_t check_for_secret) 9020 { 9021 boolean_t is_private = B_FALSE; 9022 ulong_t key_type, class; 9023 int error; 9024 9025 /* check CKA_PRIVATE attribute value */ 9026 error = dprov_get_template_attr_boolean(template, nattr, 9027 DPROV_CKA_PRIVATE, &is_private); 9028 if (error == CRYPTO_SUCCESS && is_private) { 9029 /* it's a private object */ 9030 if (session->ds_state != DPROV_SESSION_STATE_USER) { 9031 /* 9032 * Cannot create private object with SO or public 9033 * sessions. 9034 */ 9035 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 9036 } 9037 } 9038 9039 /* all objects must have an object class attribute */ 9040 if (dprov_get_template_attr_ulong(template, nattr, DPROV_CKA_CLASS, 9041 &class) != CRYPTO_SUCCESS) { 9042 return (CRYPTO_TEMPLATE_INCOMPLETE); 9043 } 9044 9045 /* key objects must have a key type attribute */ 9046 if (class == DPROV_CKO_SECRET_KEY || 9047 class == DPROV_CKO_PUBLIC_KEY || 9048 class == DPROV_CKO_PRIVATE_KEY) { 9049 if (!dprov_template_attr_present(template, nattr, 9050 DPROV_CKA_KEY_TYPE)) { 9051 return (CRYPTO_TEMPLATE_INCOMPLETE); 9052 } 9053 } 9054 9055 /* check for RSA public key attributes that must be present */ 9056 if (class == DPROV_CKO_PUBLIC_KEY) { 9057 if (dprov_get_template_attr_ulong(template, nattr, 9058 DPROV_CKA_KEY_TYPE, &key_type) == CRYPTO_SUCCESS) { 9059 if (key_type == DPROV_CKK_RSA) { 9060 if (!dprov_template_attr_present(template, 9061 nattr, DPROV_CKA_MODULUS) || 9062 !dprov_template_attr_present(template, 9063 nattr, DPROV_CKA_PUBLIC_EXPONENT)) { 9064 return (CRYPTO_TEMPLATE_INCOMPLETE); 9065 } 9066 9067 /* these attributes should not be present */ 9068 if (dprov_template_attr_present(template, nattr, 9069 DPROV_CKA_MODULUS_BITS)) { 9070 return (CRYPTO_TEMPLATE_INCONSISTENT); 9071 } 9072 } 9073 } 9074 } 9075 9076 /* check for RSA private key attributes that must be present */ 9077 if (class == DPROV_CKO_PRIVATE_KEY) { 9078 if (dprov_get_template_attr_ulong(template, nattr, 9079 DPROV_CKA_KEY_TYPE, &key_type) == CRYPTO_SUCCESS) { 9080 if (key_type == DPROV_CKK_RSA) { 9081 if (!dprov_template_attr_present(template, 9082 nattr, DPROV_CKA_MODULUS)) 9083 return (CRYPTO_TEMPLATE_INCOMPLETE); 9084 9085 if (check_for_secret) { 9086 if (!dprov_template_attr_present( 9087 template, nattr, 9088 DPROV_CKA_PRIVATE_EXPONENT)) 9089 return ( 9090 CRYPTO_TEMPLATE_INCOMPLETE); 9091 } 9092 } 9093 } 9094 } 9095 9096 /* check for secret key attributes that must be present */ 9097 if (class == DPROV_CKO_SECRET_KEY) { 9098 if (check_for_secret) { 9099 if (!dprov_template_attr_present(template, nattr, 9100 DPROV_CKA_VALUE)) { 9101 return (CRYPTO_TEMPLATE_INCOMPLETE); 9102 } 9103 } 9104 9105 /* these attributes should not be present */ 9106 if (dprov_template_attr_present(template, nattr, 9107 DPROV_CKA_VALUE_LEN)) { 9108 return (CRYPTO_TEMPLATE_INCONSISTENT); 9109 } 9110 } 9111 9112 return (CRYPTO_SUCCESS); 9113 } 9114 9115 /* 9116 * Create an object from the specified template. Checks whether the 9117 * object can be created according to its attributes and the state 9118 * of the session. The new session object id is returned. If the 9119 * object is a token object, it is added to the per-instance object 9120 * table as well. 9121 */ 9122 static int 9123 dprov_create_object_from_template(dprov_state_t *softc, 9124 dprov_session_t *session, crypto_object_attribute_t *template, 9125 uint_t nattr, crypto_object_id_t *object_id, boolean_t check_for_secret, 9126 boolean_t force) 9127 { 9128 dprov_object_t *object; 9129 boolean_t is_token = B_FALSE; 9130 boolean_t extractable_attribute_present = B_FALSE; 9131 boolean_t sensitive_attribute_present = B_FALSE; 9132 boolean_t private_attribute_present = B_FALSE; 9133 boolean_t token_attribute_present = B_FALSE; 9134 uint_t i; 9135 int error; 9136 uint_t attr; 9137 uint_t oattr; 9138 crypto_attr_type_t type; 9139 size_t old_len, new_len; 9140 offset_t offset; 9141 9142 if (nattr > DPROV_MAX_ATTR) 9143 return (CRYPTO_HOST_MEMORY); 9144 9145 if (!force) { 9146 /* verify that object can be created */ 9147 if ((error = dprov_template_can_create(session, template, 9148 nattr, check_for_secret)) != CRYPTO_SUCCESS) 9149 return (error); 9150 } 9151 9152 /* allocate new object */ 9153 object = kmem_zalloc(sizeof (dprov_object_t), KM_SLEEP); 9154 if (object == NULL) 9155 return (CRYPTO_HOST_MEMORY); 9156 9157 /* is it a token object? */ 9158 /* check CKA_TOKEN attribute value */ 9159 error = dprov_get_template_attr_boolean(template, nattr, 9160 DPROV_CKA_TOKEN, &is_token); 9161 if (error == CRYPTO_SUCCESS && is_token) { 9162 /* token object, add it to the per-instance object table */ 9163 for (i = 0; i < DPROV_MAX_OBJECTS; i++) 9164 if (softc->ds_objects[i] == NULL) 9165 break; 9166 if (i == DPROV_MAX_OBJECTS) 9167 /* no free slot */ 9168 return (CRYPTO_HOST_MEMORY); 9169 softc->ds_objects[i] = object; 9170 object->do_token_idx = i; 9171 DPROV_OBJECT_REFHOLD(object); 9172 } 9173 9174 /* add object to session object table */ 9175 for (i = 0; i < DPROV_MAX_OBJECTS; i++) 9176 if (session->ds_objects[i] == NULL) 9177 break; 9178 if (i == DPROV_MAX_OBJECTS) { 9179 /* no more session object slots */ 9180 DPROV_OBJECT_REFRELE(object); 9181 return (CRYPTO_HOST_MEMORY); 9182 } 9183 session->ds_objects[i] = object; 9184 DPROV_OBJECT_REFHOLD(object); 9185 *object_id = i; 9186 9187 /* initialize object from template */ 9188 for (attr = 0, oattr = 0; attr < nattr; attr++) { 9189 if (template[attr].oa_value == NULL) 9190 continue; 9191 type = template[attr].oa_type; 9192 old_len = template[attr].oa_value_len; 9193 new_len = attribute_size(type, old_len); 9194 9195 if (type == DPROV_CKA_EXTRACTABLE) { 9196 extractable_attribute_present = B_TRUE; 9197 } else if (type == DPROV_CKA_PRIVATE) { 9198 private_attribute_present = B_TRUE; 9199 } else if (type == DPROV_CKA_TOKEN) { 9200 token_attribute_present = B_TRUE; 9201 } 9202 object->do_attr[oattr].oa_type = type; 9203 object->do_attr[oattr].oa_value_len = new_len; 9204 9205 object->do_attr[oattr].oa_value = kmem_zalloc(new_len, 9206 KM_SLEEP); 9207 9208 offset = 0; 9209 #ifdef _BIG_ENDIAN 9210 if (fixed_size_attribute(type)) { 9211 offset = old_len - new_len; 9212 } 9213 #endif 9214 bcopy(&template[attr].oa_value[offset], 9215 object->do_attr[oattr].oa_value, new_len); 9216 oattr++; 9217 } 9218 9219 /* add boolean attributes that must be present */ 9220 if (extractable_attribute_present == B_FALSE) { 9221 object->do_attr[oattr].oa_type = DPROV_CKA_EXTRACTABLE; 9222 object->do_attr[oattr].oa_value_len = 1; 9223 object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP); 9224 object->do_attr[oattr].oa_value[0] = B_TRUE; 9225 oattr++; 9226 } 9227 9228 if (private_attribute_present == B_FALSE) { 9229 object->do_attr[oattr].oa_type = DPROV_CKA_PRIVATE; 9230 object->do_attr[oattr].oa_value_len = 1; 9231 object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP); 9232 object->do_attr[oattr].oa_value[0] = B_FALSE; 9233 oattr++; 9234 } 9235 9236 if (token_attribute_present == B_FALSE) { 9237 object->do_attr[oattr].oa_type = DPROV_CKA_TOKEN; 9238 object->do_attr[oattr].oa_value_len = 1; 9239 object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP); 9240 object->do_attr[oattr].oa_value[0] = B_FALSE; 9241 oattr++; 9242 } 9243 9244 if (sensitive_attribute_present == B_FALSE) { 9245 object->do_attr[oattr].oa_type = DPROV_CKA_SENSITIVE; 9246 object->do_attr[oattr].oa_value_len = 1; 9247 object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP); 9248 object->do_attr[oattr].oa_value[0] = B_FALSE; 9249 oattr++; 9250 } 9251 return (CRYPTO_SUCCESS); 9252 } 9253 9254 /* 9255 * Checks whether or not the object matches the specified attributes. 9256 * 9257 * PKCS#11 attributes which are longs are stored in uint32_t containers 9258 * so they can be matched by both 32 and 64-bit applications. 9259 */ 9260 static boolean_t 9261 dprov_attributes_match(dprov_object_t *object, 9262 crypto_object_attribute_t *template, uint_t nattr) 9263 { 9264 crypto_attr_type_t type; 9265 size_t tlen, olen, diff; 9266 int ta_idx; /* template attribute index */ 9267 int oa_idx; /* object attribute index */ 9268 9269 for (ta_idx = 0; ta_idx < nattr; ta_idx++) { 9270 /* no value for template attribute */ 9271 if (template[ta_idx].oa_value == NULL) 9272 continue; 9273 9274 /* find attribute in object */ 9275 type = template[ta_idx].oa_type; 9276 oa_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR, type); 9277 9278 if (oa_idx == -1) 9279 /* attribute not found in object */ 9280 return (B_FALSE); 9281 9282 tlen = template[ta_idx].oa_value_len; 9283 olen = object->do_attr[oa_idx].oa_value_len; 9284 if (tlen < olen) 9285 return (B_FALSE); 9286 9287 diff = 0; 9288 #ifdef _BIG_ENDIAN 9289 /* application may think attribute is 8 bytes */ 9290 if (fixed_size_attribute(type)) 9291 diff = tlen - olen; 9292 #endif 9293 9294 if (bcmp(&template[ta_idx].oa_value[diff], 9295 object->do_attr[oa_idx].oa_value, olen) != 0) 9296 /* value mismatch */ 9297 return (B_FALSE); 9298 } 9299 9300 return (B_TRUE); 9301 } 9302 9303 /* 9304 * Destroy the object specified by its session and object id. 9305 */ 9306 static int 9307 dprov_destroy_object(dprov_state_t *softc, dprov_session_t *session, 9308 crypto_object_id_t object_id) 9309 { 9310 dprov_object_t *object; 9311 9312 if ((object = session->ds_objects[object_id]) == NULL) 9313 return (CRYPTO_OBJECT_HANDLE_INVALID); 9314 9315 /* remove from session table */ 9316 session->ds_objects[object_id] = NULL; 9317 9318 if (dprov_object_is_token(object)) { 9319 if (!object->do_destroyed) { 9320 object->do_destroyed = B_TRUE; 9321 /* remove from per-instance token table */ 9322 softc->ds_objects[object->do_token_idx] = NULL; 9323 DPROV_OBJECT_REFRELE(object); 9324 } else { 9325 DPROV_DEBUG(D_OBJECT, ("dprov_destroy_object: " 9326 "object %p already destroyed\n", (void *)object)); 9327 } 9328 } 9329 9330 DPROV_OBJECT_REFRELE(object); 9331 return (CRYPTO_SUCCESS); 9332 } 9333 9334 static int 9335 dprov_object_can_modify(dprov_object_t *object, 9336 crypto_object_attribute_t *template, uint_t nattr) 9337 { 9338 ulong_t object_class; 9339 9340 /* all objects should have an object class attribute */ 9341 if (dprov_get_object_attr_ulong(object, DPROV_CKA_CLASS, 9342 &object_class) != CRYPTO_SUCCESS) { 9343 return (CRYPTO_SUCCESS); 9344 } 9345 9346 if (object_class == DPROV_CKO_SECRET_KEY || 9347 object_class == DPROV_CKO_PUBLIC_KEY || 9348 object_class == DPROV_CKO_PRIVATE_KEY) { 9349 if (dprov_template_attr_present(template, nattr, 9350 DPROV_CKA_CLASS) || 9351 dprov_template_attr_present(template, nattr, 9352 DPROV_CKA_KEY_TYPE)) 9353 return (CRYPTO_TEMPLATE_INCONSISTENT); 9354 } 9355 9356 switch (object_class) { 9357 case DPROV_CKO_SECRET_KEY: 9358 if (dprov_template_attr_present(template, nattr, 9359 DPROV_CKA_VALUE)) 9360 return (CRYPTO_TEMPLATE_INCONSISTENT); 9361 break; 9362 9363 case DPROV_CKO_PUBLIC_KEY: 9364 if (dprov_template_attr_present(template, nattr, 9365 DPROV_CKA_MODULUS) || 9366 dprov_template_attr_present(template, nattr, 9367 DPROV_CKA_PUBLIC_EXPONENT)) 9368 return (CRYPTO_TEMPLATE_INCONSISTENT); 9369 break; 9370 9371 case DPROV_CKO_PRIVATE_KEY: 9372 if (dprov_template_attr_present(template, nattr, 9373 DPROV_CKA_MODULUS) || 9374 dprov_template_attr_present(template, nattr, 9375 DPROV_CKA_PRIVATE_EXPONENT)) 9376 return (CRYPTO_TEMPLATE_INCONSISTENT); 9377 break; 9378 9379 default: 9380 return (CRYPTO_SUCCESS); 9381 } 9382 9383 return (CRYPTO_SUCCESS); 9384 } 9385 9386 /* 9387 * Set the attributes specified by the template in the specified object, 9388 * replacing existing ones if needed. 9389 */ 9390 static int 9391 dprov_object_set_attr(dprov_session_t *session, crypto_object_id_t object_id, 9392 crypto_object_attribute_t *template, uint_t nattr, 9393 boolean_t check_attributes) 9394 { 9395 crypto_attr_type_t type; 9396 dprov_object_t *object; 9397 size_t old_len, new_len; 9398 uint_t i, j; 9399 int error; 9400 9401 if ((object = session->ds_objects[object_id]) == NULL) 9402 return (CRYPTO_OBJECT_HANDLE_INVALID); 9403 9404 if (check_attributes) { 9405 /* verify that attributes in the template can be modified */ 9406 if ((error = dprov_object_can_modify(object, template, nattr)) 9407 != CRYPTO_SUCCESS) 9408 return (error); 9409 } 9410 9411 /* go through the attributes specified in the template */ 9412 for (i = 0; i < nattr; i++) { 9413 if (template[i].oa_value == NULL) 9414 continue; 9415 9416 /* find attribute in object */ 9417 type = template[i].oa_type; 9418 j = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR, type); 9419 9420 if (j != -1) { 9421 /* attribute already exists, free old value */ 9422 kmem_free(object->do_attr[j].oa_value, 9423 object->do_attr[j].oa_value_len); 9424 } else { 9425 /* attribute does not exist, create it */ 9426 for (j = 0; j < DPROV_MAX_ATTR; j++) 9427 if (object->do_attr[j].oa_value == NULL) 9428 break; 9429 if (j == DPROV_MAX_ATTR) 9430 /* ran out of attribute slots */ 9431 return (CRYPTO_HOST_MEMORY); 9432 } 9433 9434 old_len = template[i].oa_value_len; 9435 new_len = attribute_size(type, old_len); 9436 9437 /* set object attribute value */ 9438 object->do_attr[j].oa_value = kmem_alloc(new_len, KM_SLEEP); 9439 bcopy(&template[i].oa_value[old_len - new_len], 9440 object->do_attr[j].oa_value, new_len); 9441 object->do_attr[j].oa_value_len = new_len; 9442 9443 /* and the type */ 9444 object->do_attr[j].oa_type = type; 9445 } 9446 9447 return (CRYPTO_SUCCESS); 9448 } 9449 9450 9451 /* 9452 * Free the specified object. 9453 */ 9454 static void 9455 dprov_free_object(dprov_object_t *object) 9456 { 9457 int i; 9458 9459 /* free the object attributes values */ 9460 for (i = 0; i < DPROV_MAX_ATTR; i++) 9461 if (object->do_attr[i].oa_value != NULL) 9462 kmem_free(object->do_attr[i].oa_value, 9463 object->do_attr[i].oa_value_len); 9464 9465 /* free the object */ 9466 kmem_free(object, sizeof (dprov_object_t)); 9467 } 9468 9469 /* 9470 * Checks whether the specified object is a private or public object. 9471 */ 9472 static boolean_t 9473 dprov_object_is_private(dprov_object_t *object) 9474 { 9475 boolean_t ret; 9476 int err; 9477 9478 err = dprov_get_object_attr_boolean(object, DPROV_CKA_PRIVATE, &ret); 9479 9480 if (err != CRYPTO_SUCCESS) 9481 /* by default, CKA_PRIVATE is false */ 9482 ret = B_FALSE; 9483 9484 return (ret); 9485 } 9486 9487 /* 9488 * Checks whether the specified object is a token or session object. 9489 */ 9490 static boolean_t 9491 dprov_object_is_token(dprov_object_t *object) 9492 { 9493 boolean_t ret; 9494 int err; 9495 9496 err = dprov_get_object_attr_boolean(object, DPROV_CKA_TOKEN, &ret); 9497 9498 if (err != CRYPTO_SUCCESS) 9499 /* by default, CKA_TOKEN is false */ 9500 ret = B_FALSE; 9501 9502 return (ret); 9503 } 9504 9505 /* 9506 * Common function used by the dprov_get_object_attr_*() family of 9507 * functions. Returns the value of the specified attribute of specified 9508 * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID 9509 * if the length of the attribute does not match the specified length, 9510 * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found. 9511 */ 9512 static int 9513 dprov_get_object_attr_scalar_common(dprov_object_t *object, uint64_t attr_type, 9514 void *value, size_t value_len) 9515 { 9516 int attr_idx; 9517 size_t oa_value_len; 9518 size_t offset = 0; 9519 9520 if ((attr_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR, 9521 attr_type)) == -1) 9522 return (CRYPTO_ARGUMENTS_BAD); 9523 9524 oa_value_len = object->do_attr[attr_idx].oa_value_len; 9525 if (oa_value_len != value_len) { 9526 /* 9527 * For some attributes, it's okay to copy the value 9528 * into a larger container, e.g. copy an unsigned 9529 * 32-bit integer into a 64-bit container. 9530 */ 9531 if (attr_type == DPROV_CKA_VALUE_LEN || 9532 attr_type == DPROV_CKA_KEY_TYPE || 9533 attr_type == DPROV_CKA_CLASS) { 9534 if (oa_value_len < value_len) { 9535 #ifdef _BIG_ENDIAN 9536 offset = value_len - oa_value_len; 9537 #endif 9538 bzero(value, value_len); 9539 goto do_copy; 9540 } 9541 } 9542 /* incorrect attribute value length */ 9543 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 9544 } 9545 9546 do_copy: 9547 bcopy(object->do_attr[attr_idx].oa_value, (uchar_t *)value + offset, 9548 oa_value_len); 9549 9550 return (CRYPTO_SUCCESS); 9551 } 9552 9553 /* 9554 * Get the value of the a boolean attribute from the specified object. 9555 */ 9556 static int 9557 dprov_get_object_attr_boolean(dprov_object_t *object, uint64_t attr_type, 9558 boolean_t *attr_value) 9559 { 9560 uchar_t val; 9561 int ret; 9562 9563 /* PKCS#11 defines a boolean as one byte */ 9564 ret = dprov_get_object_attr_scalar_common(object, attr_type, &val, 1); 9565 if (ret == CRYPTO_SUCCESS) { 9566 *attr_value = (val == '\0') ? B_FALSE : B_TRUE; 9567 } 9568 return (ret); 9569 } 9570 9571 /* 9572 * Get the value of a ulong_t attribute from the specified object. 9573 */ 9574 static int 9575 dprov_get_object_attr_ulong(dprov_object_t *object, uint64_t attr_type, 9576 ulong_t *attr_value) 9577 { 9578 return (dprov_get_object_attr_scalar_common(object, attr_type, 9579 attr_value, sizeof (ulong_t))); 9580 } 9581 9582 /* 9583 * Find the specified byte array attribute of specified type in 9584 * the specified object. Returns CRYPTO_SUCCESS 9585 * on success or CRYPTO_ARGUMENTS_BAD if the specified 9586 * attribute cannot be found. 9587 */ 9588 static int 9589 dprov_get_object_attr_array(dprov_object_t *object, uint64_t attr_type, 9590 void **array, size_t *len) 9591 { 9592 int attr_idx; 9593 9594 if ((attr_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR, 9595 attr_type)) == -1) 9596 return (CRYPTO_ARGUMENTS_BAD); 9597 9598 *array = object->do_attr[attr_idx].oa_value; 9599 *len = object->do_attr[attr_idx].oa_value_len; 9600 9601 return (CRYPTO_SUCCESS); 9602 } 9603 9604 /* 9605 * Common function used by the dprov_get_template_attr_*() family of 9606 * functions. Returns the value of the specified attribute of specified 9607 * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID 9608 * if the length of the attribute does not match the specified length, 9609 * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found. 9610 */ 9611 static int 9612 dprov_get_template_attr_scalar_common(crypto_object_attribute_t *template, 9613 uint_t nattr, uint64_t attr_type, void *value, size_t value_len) 9614 { 9615 size_t oa_value_len; 9616 size_t offset = 0; 9617 int attr_idx; 9618 9619 if ((attr_idx = dprov_find_attr(template, nattr, attr_type)) == -1) 9620 return (CRYPTO_ARGUMENTS_BAD); 9621 9622 oa_value_len = template[attr_idx].oa_value_len; 9623 if (oa_value_len != value_len) { 9624 /* 9625 * For some attributes, it's okay to copy the value 9626 * into a larger container, e.g. copy an unsigned 9627 * 32-bit integer into a 64-bit container. 9628 */ 9629 if (attr_type == DPROV_CKA_VALUE_LEN || 9630 attr_type == DPROV_CKA_KEY_TYPE || 9631 attr_type == DPROV_CKA_CLASS) { 9632 if (oa_value_len < value_len) { 9633 #ifdef _BIG_ENDIAN 9634 offset = value_len - oa_value_len; 9635 #endif 9636 bzero(value, value_len); 9637 goto do_copy; 9638 } 9639 } 9640 /* incorrect attribute value length */ 9641 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 9642 } 9643 9644 do_copy: 9645 bcopy(template[attr_idx].oa_value, (uchar_t *)value + offset, 9646 oa_value_len); 9647 9648 return (CRYPTO_SUCCESS); 9649 } 9650 9651 /* 9652 * Get the value of the a boolean attribute from the specified template 9653 */ 9654 static int 9655 dprov_get_template_attr_boolean(crypto_object_attribute_t *template, 9656 uint_t nattr, uint64_t attr_type, boolean_t *attr_value) 9657 { 9658 uchar_t val; 9659 int ret; 9660 9661 /* PKCS#11 defines a boolean as one byte */ 9662 ret = dprov_get_template_attr_scalar_common(template, nattr, 9663 attr_type, &val, 1); 9664 if (ret == CRYPTO_SUCCESS) { 9665 *attr_value = (val == '\0') ? B_FALSE : B_TRUE; 9666 } 9667 return (ret); 9668 } 9669 9670 /* 9671 * Get the value of a ulong_t attribute from the specified template. 9672 */ 9673 static int 9674 dprov_get_template_attr_ulong(crypto_object_attribute_t *template, 9675 uint_t nattr, uint64_t attr_type, ulong_t *attr_value) 9676 { 9677 return (dprov_get_template_attr_scalar_common(template, nattr, 9678 attr_type, attr_value, sizeof (ulong_t))); 9679 } 9680 9681 static int 9682 dprov_template_attr_present(crypto_object_attribute_t *template, 9683 uint_t nattr, uint64_t attr_type) 9684 { 9685 return (dprov_find_attr(template, nattr, 9686 attr_type) == -1 ? B_FALSE : B_TRUE); 9687 } 9688 9689 /* 9690 * Find the specified byte array attribute of specified type in 9691 * the specified template. Returns CRYPTO_SUCCESS on success or 9692 * CRYPTO_ARGUMENTS_BAD if the specified attribute cannot be found. 9693 */ 9694 static int 9695 dprov_get_template_attr_array(crypto_object_attribute_t *template, 9696 uint_t nattr, uint64_t attr_type, void **array, size_t *len) 9697 { 9698 int attr_idx; 9699 9700 if ((attr_idx = dprov_find_attr(template, nattr, attr_type)) == -1) 9701 return (CRYPTO_ARGUMENTS_BAD); 9702 9703 *array = template[attr_idx].oa_value; 9704 *len = template[attr_idx].oa_value_len; 9705 9706 return (CRYPTO_SUCCESS); 9707 } 9708 9709 /* 9710 * Common function used by the dprov_get_key_attr_*() family of 9711 * functions. Returns the value of the specified attribute of specified 9712 * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID 9713 * if the length of the attribute does not match the specified length, 9714 * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found. 9715 */ 9716 static int 9717 dprov_get_key_attr_scalar_common(crypto_key_t *key, uint64_t attr_type, 9718 void *value, size_t value_len) 9719 { 9720 int attr_idx; 9721 9722 ASSERT(key->ck_format == CRYPTO_KEY_ATTR_LIST); 9723 9724 if ((attr_idx = dprov_find_attr(key->ck_attrs, key->ck_count, 9725 attr_type)) == -1) 9726 return (CRYPTO_ARGUMENTS_BAD); 9727 9728 if (key->ck_attrs[attr_idx].oa_value_len != value_len) 9729 /* incorrect attribute value length */ 9730 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 9731 9732 bcopy(key->ck_attrs[attr_idx].oa_value, value, value_len); 9733 9734 return (CRYPTO_SUCCESS); 9735 } 9736 9737 /* 9738 * Get the value of a ulong_t attribute from the specified key. 9739 */ 9740 static int 9741 dprov_get_key_attr_ulong(crypto_key_t *key, uint64_t attr_type, 9742 ulong_t *attr_value) 9743 { 9744 return (dprov_get_key_attr_scalar_common(key, attr_type, 9745 attr_value, sizeof (ulong_t))); 9746 } 9747 9748 /* 9749 * Find the specified byte array attribute of specified type in 9750 * the specified key by attributes. Returns CRYPTO_SUCCESS 9751 * on success or CRYPTO_ARGUMENTS_BAD if the specified 9752 * attribute cannot be found. 9753 */ 9754 static int 9755 dprov_get_key_attr_array(crypto_key_t *key, uint64_t attr_type, 9756 void **array, size_t *len) 9757 { 9758 int attr_idx; 9759 9760 ASSERT(key->ck_format == CRYPTO_KEY_ATTR_LIST); 9761 9762 if ((attr_idx = dprov_find_attr(key->ck_attrs, key->ck_count, 9763 attr_type)) == -1) 9764 return (CRYPTO_ARGUMENTS_BAD); 9765 9766 *array = key->ck_attrs[attr_idx].oa_value; 9767 *len = key->ck_attrs[attr_idx].oa_value_len; 9768 9769 return (CRYPTO_SUCCESS); 9770 } 9771 9772 static void 9773 dprov_release_session_objects(dprov_session_t *session) 9774 { 9775 dprov_object_t *object; 9776 int i; 9777 9778 for (i = 0; i < DPROV_MAX_OBJECTS; i++) { 9779 object = session->ds_objects[i]; 9780 if (object != NULL) { 9781 DPROV_OBJECT_REFRELE(object); 9782 } 9783 } 9784 } 9785 9786 /* 9787 * Adjust an attribute list by turning 32-bit values into 64-bit values 9788 * for certain attributes like CKA_CLASS. Assumes that at least 8 bytes 9789 * of storage have been allocated for all attributes. 9790 */ 9791 static void 9792 dprov_adjust_attrs(crypto_object_attribute_t *in, int in_count) 9793 { 9794 int i; 9795 size_t offset = 0; 9796 ulong_t tmp = 0; 9797 9798 for (i = 0; i < in_count; i++) { 9799 /* 9800 * For some attributes, it's okay to copy the value 9801 * into a larger container, e.g. copy an unsigned 9802 * 32-bit integer into a 64-bit container. 9803 */ 9804 if (in[i].oa_type == CKA_VALUE_LEN || 9805 in[i].oa_type == CKA_KEY_TYPE || 9806 in[i].oa_type == CKA_CLASS) { 9807 if (in[i].oa_value_len < sizeof (ulong_t)) { 9808 #ifdef _BIG_ENDIAN 9809 offset = sizeof (ulong_t) - in[i].oa_value_len; 9810 #endif 9811 bcopy(in[i].oa_value, (uchar_t *)&tmp + offset, 9812 in[i].oa_value_len); 9813 bcopy(&tmp, in[i].oa_value, sizeof (ulong_t)); 9814 in[i].oa_value_len = sizeof (ulong_t); 9815 } 9816 } 9817 } 9818 } 9819