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