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