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