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