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