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