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