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