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