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