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