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