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