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