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