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