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 AES_ECB_MECH_INFO_TYPE: 4216 case BLOWFISH_ECB_MECH_INFO_TYPE: 4217 case DES_ECB_MECH_INFO_TYPE: 4218 case DES3_ECB_MECH_INFO_TYPE: 4219 rv = CRYPTO_SUCCESS; 4220 goto out; 4221 4222 case DES_CBC_MECH_INFO_TYPE: 4223 case DES3_CBC_MECH_INFO_TYPE: 4224 expected_param_len = DES_BLOCK_LEN; 4225 break; 4226 4227 case BLOWFISH_CBC_MECH_INFO_TYPE: 4228 expected_param_len = BLOWFISH_BLOCK_LEN; 4229 break; 4230 4231 case AES_CBC_MECH_INFO_TYPE: 4232 expected_param_len = AES_BLOCK_LEN; 4233 break; 4234 4235 case AES_CTR_MECH_INFO_TYPE: 4236 case SHA1_KEY_DERIVATION_MECH_INFO_TYPE: /* for testing only */ 4237 rv = copyin_aes_ctr_mech(umech, kmech, &error, mode); 4238 goto out; 4239 4240 case RC4_MECH_INFO_TYPE: 4241 case RSA_PKCS_MECH_INFO_TYPE: 4242 case RSA_X_509_MECH_INFO_TYPE: 4243 case MD5_RSA_PKCS_MECH_INFO_TYPE: 4244 case SHA1_RSA_PKCS_MECH_INFO_TYPE: 4245 case SHA256_RSA_PKCS_MECH_INFO_TYPE: 4246 case SHA384_RSA_PKCS_MECH_INFO_TYPE: 4247 case SHA512_RSA_PKCS_MECH_INFO_TYPE: 4248 rv = CRYPTO_SUCCESS; 4249 goto out; 4250 4251 default: 4252 rv = CRYPTO_MECHANISM_INVALID; 4253 goto out; 4254 } 4255 4256 if (param_len != expected_param_len) { 4257 rv = CRYPTO_MECHANISM_PARAM_INVALID; 4258 goto out; 4259 } 4260 if (pp == NULL) { 4261 rv = CRYPTO_MECHANISM_PARAM_INVALID; 4262 goto out; 4263 } 4264 if ((param = kmem_alloc(param_len, KM_NOSLEEP)) == NULL) { 4265 rv = CRYPTO_HOST_MEMORY; 4266 goto out; 4267 } 4268 if (copyin((char *)pp, param, param_len) != 0) { 4269 kmem_free(param, param_len); 4270 error = EFAULT; 4271 rv = CRYPTO_FAILED; 4272 goto out; 4273 } 4274 kmech->cm_param = (char *)param; 4275 kmech->cm_param_len = param_len; 4276 rv = CRYPTO_SUCCESS; 4277 out: 4278 *out_error = error; 4279 return (rv); 4280 } 4281 4282 /* ARGSUSED */ 4283 static int 4284 dprov_copyout_mechanism(crypto_provider_handle_t provider, 4285 crypto_mechanism_t *kmech, crypto_mechanism_t *umech, 4286 int *out_error, int mode) 4287 { 4288 ASSERT(!servicing_interrupt()); 4289 4290 switch (kmech->cm_type) { 4291 case AES_CTR_MECH_INFO_TYPE: 4292 case SHA1_KEY_DERIVATION_MECH_INFO_TYPE: /* for testing only */ 4293 return (copyout_aes_ctr_mech(kmech, umech, out_error, mode)); 4294 default: 4295 return (CRYPTO_MECHANISM_INVALID); 4296 } 4297 } 4298 4299 /* 4300 * Free mechanism parameter that was allocated by the provider. 4301 */ 4302 /* ARGSUSED */ 4303 static int 4304 dprov_free_mechanism(crypto_provider_handle_t provider, 4305 crypto_mechanism_t *mech) 4306 { 4307 size_t len; 4308 4309 if (mech->cm_param == NULL || mech->cm_param_len == 0) 4310 return (CRYPTO_SUCCESS); 4311 4312 if (mech->cm_type == AES_CTR_MECH_INFO_TYPE || 4313 mech->cm_type == SHA1_KEY_DERIVATION_MECH_INFO_TYPE) { 4314 len = sizeof (CK_AES_CTR_PARAMS) + 16; 4315 } else { 4316 len = mech->cm_param_len; 4317 } 4318 kmem_free(mech->cm_param, len); 4319 return (CRYPTO_SUCCESS); 4320 } 4321 4322 /* 4323 * Allocate a dprov taskq request and initialize the common fields. 4324 * Return NULL if the memory allocation failed. 4325 */ 4326 static dprov_req_t * 4327 dprov_alloc_req(dprov_req_type_t req_type, dprov_state_t *softc, 4328 crypto_req_handle_t kcf_req, int kmflag) 4329 { 4330 dprov_req_t *taskq_req; 4331 4332 if ((taskq_req = kmem_alloc(sizeof (dprov_req_t), kmflag)) == NULL) 4333 return (NULL); 4334 4335 taskq_req->dr_type = req_type; 4336 taskq_req->dr_softc = softc; 4337 taskq_req->dr_kcf_req = kcf_req; 4338 4339 return (taskq_req); 4340 } 4341 4342 /* 4343 * Dispatch a dprov request on the taskq associated with a softc. 4344 * Returns CRYPTO_HOST_MEMORY if the request cannot be queued, 4345 * CRYPTO_QUEUED on success. 4346 */ 4347 static int 4348 dprov_taskq_dispatch(dprov_state_t *softc, dprov_req_t *taskq_req, 4349 task_func_t *func, int kmflag) 4350 { 4351 if (taskq_dispatch(softc->ds_taskq, func, taskq_req, 4352 kmflag == KM_NOSLEEP ? TQ_NOSLEEP : TQ_SLEEP) == (taskqid_t)0) { 4353 kmem_free(taskq_req, sizeof (dprov_req_t)); 4354 return (CRYPTO_HOST_MEMORY); 4355 } else 4356 return (CRYPTO_QUEUED); 4357 } 4358 4359 /* 4360 * Helper function to submit digest operations to the taskq. 4361 * Returns one of the CRYPTO_ errors. 4362 */ 4363 static int 4364 dprov_digest_submit_req(dprov_req_type_t req_type, 4365 dprov_state_t *softc, crypto_req_handle_t req, 4366 crypto_mechanism_t *mechanism, crypto_data_t *data, crypto_key_t *key, 4367 crypto_data_t *digest, crypto_ctx_t *ctx, int kmflag) 4368 { 4369 dprov_req_t *taskq_req; 4370 4371 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL) 4372 return (CRYPTO_HOST_MEMORY); 4373 4374 taskq_req->dr_digest_req.dr_mechanism = mechanism; 4375 taskq_req->dr_digest_req.dr_ctx = ctx; 4376 taskq_req->dr_digest_req.dr_data = data; 4377 taskq_req->dr_digest_req.dr_key = key; 4378 taskq_req->dr_digest_req.dr_digest = digest; 4379 4380 return (dprov_taskq_dispatch(softc, taskq_req, 4381 (task_func_t *)dprov_digest_task, kmflag)); 4382 } 4383 4384 /* 4385 * Helper function to submit mac operations to the taskq. 4386 * Returns one of the CRYPTO_ errors. 4387 */ 4388 static int 4389 dprov_mac_submit_req(dprov_req_type_t req_type, 4390 dprov_state_t *softc, crypto_req_handle_t req, 4391 crypto_mechanism_t *mechanism, crypto_data_t *data, crypto_key_t *key, 4392 crypto_data_t *mac, crypto_ctx_t *ctx, crypto_session_id_t sid, int kmflag) 4393 { 4394 dprov_req_t *taskq_req; 4395 4396 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL) 4397 return (CRYPTO_HOST_MEMORY); 4398 4399 taskq_req->dr_mac_req.dr_mechanism = mechanism; 4400 taskq_req->dr_mac_req.dr_ctx = ctx; 4401 taskq_req->dr_mac_req.dr_data = data; 4402 taskq_req->dr_mac_req.dr_key = key; 4403 taskq_req->dr_mac_req.dr_mac = mac; 4404 taskq_req->dr_mac_req.dr_session_id = sid; 4405 4406 return (dprov_taskq_dispatch(softc, taskq_req, 4407 (task_func_t *)dprov_mac_task, kmflag)); 4408 } 4409 4410 /* 4411 * Helper function to submit sign operations to the taskq. 4412 * Returns one of the CRYPTO_ errors. 4413 */ 4414 static int 4415 dprov_sign_submit_req(dprov_req_type_t req_type, 4416 dprov_state_t *softc, crypto_req_handle_t req, 4417 crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data, 4418 crypto_data_t *signature, crypto_ctx_t *ctx, crypto_session_id_t sid, 4419 int kmflag) 4420 { 4421 dprov_req_t *taskq_req; 4422 4423 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL) 4424 return (CRYPTO_HOST_MEMORY); 4425 4426 taskq_req->dr_sign_req.sr_mechanism = mechanism; 4427 taskq_req->dr_sign_req.sr_ctx = ctx; 4428 taskq_req->dr_sign_req.sr_key = key; 4429 taskq_req->dr_sign_req.sr_data = data; 4430 taskq_req->dr_sign_req.sr_signature = signature; 4431 taskq_req->dr_sign_req.sr_session_id = sid; 4432 4433 return (dprov_taskq_dispatch(softc, taskq_req, 4434 (task_func_t *)dprov_sign_task, kmflag)); 4435 } 4436 4437 /* 4438 * Helper function to submit verify operations to the taskq. 4439 * Returns one of the CRYPTO_ errors. 4440 */ 4441 static int 4442 dprov_verify_submit_req(dprov_req_type_t req_type, 4443 dprov_state_t *softc, crypto_req_handle_t req, 4444 crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data, 4445 crypto_data_t *signature, crypto_ctx_t *ctx, crypto_session_id_t sid, 4446 int kmflag) 4447 { 4448 dprov_req_t *taskq_req; 4449 4450 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL) 4451 return (CRYPTO_HOST_MEMORY); 4452 4453 taskq_req->dr_verify_req.vr_mechanism = mechanism; 4454 taskq_req->dr_verify_req.vr_ctx = ctx; 4455 taskq_req->dr_verify_req.vr_key = key; 4456 taskq_req->dr_verify_req.vr_data = data; 4457 taskq_req->dr_verify_req.vr_signature = signature; 4458 taskq_req->dr_verify_req.vr_session_id = sid; 4459 4460 return (dprov_taskq_dispatch(softc, taskq_req, 4461 (task_func_t *)dprov_verify_task, kmflag)); 4462 } 4463 4464 /* 4465 * Helper function to submit dual operations to the taskq. 4466 * Returns one of the CRYPTO_ errors. 4467 */ 4468 static int 4469 dprov_dual_submit_req(dprov_req_type_t req_type, dprov_state_t *softc, 4470 crypto_req_handle_t req, crypto_ctx_t *signverify_ctx, 4471 crypto_ctx_t *cipher_ctx, crypto_data_t *plaintext, 4472 crypto_data_t *ciphertext) 4473 { 4474 dprov_req_t *taskq_req; 4475 4476 if ((taskq_req = dprov_alloc_req(req_type, softc, req, 4477 KM_NOSLEEP)) == NULL) 4478 return (CRYPTO_HOST_MEMORY); 4479 4480 taskq_req->dr_dual_req.dr_signverify_ctx = signverify_ctx; 4481 taskq_req->dr_dual_req.dr_cipher_ctx = cipher_ctx; 4482 taskq_req->dr_dual_req.dr_plaintext = plaintext; 4483 taskq_req->dr_dual_req.dr_ciphertext = ciphertext; 4484 4485 return (dprov_taskq_dispatch(softc, taskq_req, 4486 (task_func_t *)dprov_dual_task, KM_NOSLEEP)); 4487 } 4488 4489 /* 4490 * Helper function to submit dual cipher/mac operations to the taskq. 4491 * Returns one of the CRYPTO_ errors. 4492 */ 4493 static int 4494 dprov_cipher_mac_submit_req(dprov_req_type_t req_type, 4495 dprov_state_t *softc, crypto_req_handle_t req, crypto_ctx_t *ctx, 4496 crypto_session_id_t sid, crypto_mechanism_t *cipher_mech, 4497 crypto_key_t *cipher_key, crypto_mechanism_t *mac_mech, 4498 crypto_key_t *mac_key, crypto_dual_data_t *dual_data, 4499 crypto_data_t *data, crypto_data_t *mac, int kmflag) 4500 { 4501 dprov_req_t *taskq_req; 4502 4503 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL) 4504 return (CRYPTO_HOST_MEMORY); 4505 4506 taskq_req->dr_cipher_mac_req.mr_session_id = sid; 4507 taskq_req->dr_cipher_mac_req.mr_ctx = ctx; 4508 taskq_req->dr_cipher_mac_req.mr_cipher_mech = cipher_mech; 4509 taskq_req->dr_cipher_mac_req.mr_cipher_key = cipher_key; 4510 taskq_req->dr_cipher_mac_req.mr_mac_mech = mac_mech; 4511 taskq_req->dr_cipher_mac_req.mr_mac_key = mac_key; 4512 taskq_req->dr_cipher_mac_req.mr_dual_data = dual_data; 4513 taskq_req->dr_cipher_mac_req.mr_data = data; 4514 taskq_req->dr_cipher_mac_req.mr_mac = mac; 4515 4516 return (dprov_taskq_dispatch(softc, taskq_req, 4517 (task_func_t *)dprov_cipher_mac_task, kmflag)); 4518 } 4519 4520 /* 4521 * Helper function to submit cipher operations to the taskq. 4522 * Returns one of the CRYPTO_ errors. 4523 */ 4524 static int 4525 dprov_cipher_submit_req(dprov_req_type_t req_type, 4526 dprov_state_t *softc, crypto_req_handle_t req, 4527 crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *plaintext, 4528 crypto_data_t *ciphertext, crypto_ctx_t *ctx, crypto_session_id_t sid, 4529 int kmflag) 4530 { 4531 dprov_req_t *taskq_req; 4532 4533 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL) 4534 return (CRYPTO_HOST_MEMORY); 4535 4536 taskq_req->dr_cipher_req.dr_mechanism = mechanism; 4537 taskq_req->dr_cipher_req.dr_ctx = ctx; 4538 taskq_req->dr_cipher_req.dr_key = key; 4539 taskq_req->dr_cipher_req.dr_plaintext = plaintext; 4540 taskq_req->dr_cipher_req.dr_ciphertext = ciphertext; 4541 taskq_req->dr_cipher_req.dr_session_id = sid; 4542 4543 return (dprov_taskq_dispatch(softc, taskq_req, 4544 (task_func_t *)dprov_cipher_task, kmflag)); 4545 } 4546 4547 /* 4548 * Helper function to submit random number operations to the taskq. 4549 * Returns one of the CRYPTO_ errors. 4550 */ 4551 static int 4552 dprov_random_submit_req(dprov_req_type_t req_type, 4553 dprov_state_t *softc, crypto_req_handle_t req, uchar_t *buf, size_t len, 4554 crypto_session_id_t sid, uint_t entropy_est, uint32_t flags) 4555 { 4556 dprov_req_t *taskq_req; 4557 4558 if ((taskq_req = dprov_alloc_req(req_type, softc, req, 4559 KM_NOSLEEP)) == NULL) 4560 return (CRYPTO_HOST_MEMORY); 4561 4562 taskq_req->dr_random_req.rr_buf = buf; 4563 taskq_req->dr_random_req.rr_len = len; 4564 taskq_req->dr_random_req.rr_session_id = sid; 4565 taskq_req->dr_random_req.rr_entropy_est = entropy_est; 4566 taskq_req->dr_random_req.rr_flags = flags; 4567 4568 return (dprov_taskq_dispatch(softc, taskq_req, 4569 (task_func_t *)dprov_random_task, KM_NOSLEEP)); 4570 } 4571 4572 4573 /* 4574 * Helper function to submit session management operations to the taskq. 4575 * Returns one of the CRYPTO_ errors. 4576 */ 4577 static int 4578 dprov_session_submit_req(dprov_req_type_t req_type, 4579 dprov_state_t *softc, crypto_req_handle_t req, 4580 crypto_session_id_t *session_id_ptr, crypto_session_id_t session_id, 4581 crypto_user_type_t user_type, char *pin, size_t pin_len) 4582 { 4583 dprov_req_t *taskq_req; 4584 4585 if ((taskq_req = dprov_alloc_req(req_type, softc, req, 4586 KM_NOSLEEP)) == NULL) 4587 return (CRYPTO_HOST_MEMORY); 4588 4589 taskq_req->dr_session_req.sr_session_id_ptr = session_id_ptr; 4590 taskq_req->dr_session_req.sr_session_id = session_id; 4591 taskq_req->dr_session_req.sr_user_type = user_type; 4592 taskq_req->dr_session_req.sr_pin = pin; 4593 taskq_req->dr_session_req.sr_pin_len = pin_len; 4594 4595 return (dprov_taskq_dispatch(softc, taskq_req, 4596 (task_func_t *)dprov_session_task, KM_NOSLEEP)); 4597 } 4598 4599 /* 4600 * Helper function to submit object management operations to the taskq. 4601 * Returns one of the CRYPTO_ errors. 4602 */ 4603 static int 4604 dprov_object_submit_req(dprov_req_type_t req_type, 4605 dprov_state_t *softc, crypto_req_handle_t req, 4606 crypto_session_id_t session_id, crypto_object_id_t object_id, 4607 crypto_object_attribute_t *template, uint_t attribute_count, 4608 crypto_object_id_t *object_id_ptr, size_t *object_size, 4609 void **find_pp, void *find_p, uint_t max_object_count, 4610 uint_t *object_count_ptr, int kmflag) 4611 { 4612 dprov_req_t *taskq_req; 4613 4614 if ((taskq_req = dprov_alloc_req(req_type, softc, req, 4615 kmflag)) == NULL) 4616 return (CRYPTO_HOST_MEMORY); 4617 4618 taskq_req->dr_object_req.or_session_id = session_id; 4619 taskq_req->dr_object_req.or_object_id = object_id; 4620 taskq_req->dr_object_req.or_template = template; 4621 taskq_req->dr_object_req.or_attribute_count = attribute_count; 4622 taskq_req->dr_object_req.or_object_id_ptr = object_id_ptr; 4623 taskq_req->dr_object_req.or_object_size = object_size; 4624 taskq_req->dr_object_req.or_find_pp = find_pp; 4625 taskq_req->dr_object_req.or_find_p = find_p; 4626 taskq_req->dr_object_req.or_max_object_count = max_object_count; 4627 taskq_req->dr_object_req.or_object_count_ptr = object_count_ptr; 4628 4629 return (dprov_taskq_dispatch(softc, taskq_req, 4630 (task_func_t *)dprov_object_task, KM_NOSLEEP)); 4631 } 4632 4633 /* 4634 * Helper function to submit key management operations to the taskq. 4635 * Returns one of the CRYPTO_ errors. 4636 */ 4637 static int 4638 dprov_key_submit_req(dprov_req_type_t req_type, 4639 dprov_state_t *softc, crypto_req_handle_t req, 4640 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 4641 crypto_object_attribute_t *template, uint_t attribute_count, 4642 crypto_object_id_t *object_id_ptr, 4643 crypto_object_attribute_t *private_key_template, 4644 uint_t private_key_attribute_count, 4645 crypto_object_id_t *private_key_object_id_ptr, crypto_key_t *key, 4646 uchar_t *wrapped_key, size_t *wrapped_key_len_ptr) 4647 { 4648 dprov_req_t *taskq_req; 4649 4650 if ((taskq_req = dprov_alloc_req(req_type, softc, req, 4651 KM_NOSLEEP)) == NULL) 4652 return (CRYPTO_HOST_MEMORY); 4653 4654 taskq_req->dr_key_req.kr_session_id = session_id; 4655 taskq_req->dr_key_req.kr_mechanism = mechanism; 4656 taskq_req->dr_key_req.kr_template = template; 4657 taskq_req->dr_key_req.kr_attribute_count = attribute_count; 4658 taskq_req->dr_key_req.kr_object_id_ptr = object_id_ptr; 4659 taskq_req->dr_key_req.kr_private_key_template = private_key_template; 4660 taskq_req->dr_key_req.kr_private_key_attribute_count = 4661 private_key_attribute_count; 4662 taskq_req->dr_key_req.kr_private_key_object_id_ptr = 4663 private_key_object_id_ptr; 4664 taskq_req->dr_key_req.kr_key = key; 4665 taskq_req->dr_key_req.kr_wrapped_key = wrapped_key; 4666 taskq_req->dr_key_req.kr_wrapped_key_len_ptr = wrapped_key_len_ptr; 4667 4668 return (dprov_taskq_dispatch(softc, taskq_req, 4669 (task_func_t *)dprov_key_task, KM_NOSLEEP)); 4670 } 4671 4672 /* 4673 * Helper function to submit provider management operations to the taskq. 4674 * Returns one of the CRYPTO_ errors. 4675 */ 4676 static int 4677 dprov_mgmt_submit_req(dprov_req_type_t req_type, 4678 dprov_state_t *softc, crypto_req_handle_t req, 4679 crypto_session_id_t session_id, char *pin, size_t pin_len, 4680 char *old_pin, size_t old_pin_len, char *label, 4681 crypto_provider_ext_info_t *ext_info) 4682 { 4683 dprov_req_t *taskq_req; 4684 4685 if ((taskq_req = dprov_alloc_req(req_type, softc, req, 4686 KM_NOSLEEP)) == NULL) 4687 return (CRYPTO_HOST_MEMORY); 4688 4689 taskq_req->dr_mgmt_req.mr_session_id = session_id; 4690 taskq_req->dr_mgmt_req.mr_pin = pin; 4691 taskq_req->dr_mgmt_req.mr_pin_len = pin_len; 4692 taskq_req->dr_mgmt_req.mr_old_pin = old_pin; 4693 taskq_req->dr_mgmt_req.mr_old_pin_len = old_pin_len; 4694 taskq_req->dr_mgmt_req.mr_label = label; 4695 taskq_req->dr_mgmt_req.mr_ext_info = ext_info; 4696 4697 return (dprov_taskq_dispatch(softc, taskq_req, 4698 (task_func_t *)dprov_mgmt_task, KM_NOSLEEP)); 4699 } 4700 4701 /* 4702 * Helper function for taskq dispatcher routines. Notify the framework 4703 * that the operation corresponding to the specified request is done, 4704 * and pass it the error code. Finally, free the taskq_req. 4705 */ 4706 static void 4707 dprov_op_done(dprov_req_t *taskq_req, int error) 4708 { 4709 /* notify framework that request is completed */ 4710 crypto_op_notification(taskq_req->dr_kcf_req, error); 4711 4712 /* free taskq request structure */ 4713 kmem_free(taskq_req, sizeof (dprov_req_t)); 4714 } 4715 4716 /* 4717 * taskq dispatcher function for digest operations. 4718 */ 4719 static void 4720 dprov_digest_task(dprov_req_t *taskq_req) 4721 { 4722 kcf_provider_desc_t *pd; 4723 dprov_state_t *softc; 4724 /* LINTED E_FUNC_SET_NOT_USED */ 4725 int instance; 4726 int error = CRYPTO_NOT_SUPPORTED; 4727 crypto_ctx_t *ctx = taskq_req->dr_digest_req.dr_ctx; 4728 crypto_mechanism_t mech; 4729 4730 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 4731 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_task: started\n", instance)); 4732 4733 switch (taskq_req->dr_type) { 4734 4735 case DPROV_REQ_DIGEST_INIT: 4736 /* allocate a dprov-private context */ 4737 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) != 4738 CRYPTO_SUCCESS) 4739 break; 4740 4741 /* structure assignment */ 4742 mech = *taskq_req->dr_digest_req.dr_mechanism; 4743 4744 /* get the software provider for this mechanism */ 4745 if ((error = dprov_get_sw_prov( 4746 taskq_req->dr_digest_req.dr_mechanism, &pd, 4747 &mech.cm_type)) != CRYPTO_SUCCESS) 4748 break; 4749 4750 /* Use a session id of zero since we use a software provider */ 4751 error = crypto_digest_init_prov(pd, 0, &mech, 4752 &DPROV_CTX_SINGLE(ctx), NULL); 4753 4754 /* release provider reference */ 4755 KCF_PROV_REFRELE(pd); 4756 break; 4757 4758 case DPROV_REQ_DIGEST: 4759 error = crypto_digest_single(DPROV_CTX_SINGLE(ctx), 4760 taskq_req->dr_digest_req.dr_data, 4761 taskq_req->dr_digest_req.dr_digest, NULL); 4762 4763 if (error != CRYPTO_BUFFER_TOO_SMALL) { 4764 DPROV_CTX_SINGLE(ctx) = NULL; 4765 (void) dprov_free_context(ctx); 4766 } 4767 break; 4768 4769 case DPROV_REQ_DIGEST_UPDATE: 4770 error = crypto_digest_update(DPROV_CTX_SINGLE(ctx), 4771 taskq_req->dr_digest_req.dr_data, NULL); 4772 break; 4773 4774 case DPROV_REQ_DIGEST_KEY: { 4775 crypto_data_t data; 4776 crypto_key_t key; 4777 size_t len; 4778 4779 mutex_enter(&softc->ds_lock); 4780 error = dprov_key_value_secret(softc, ctx->cc_session, 4781 taskq_req->dr_type, taskq_req->dr_digest_req.dr_key, &key); 4782 mutex_exit(&softc->ds_lock); 4783 if (error != CRYPTO_SUCCESS) 4784 break; 4785 4786 /* key lengths are specified in bits */ 4787 len = CRYPTO_BITS2BYTES(key.ck_length); 4788 data.cd_format = CRYPTO_DATA_RAW; 4789 data.cd_offset = 0; 4790 data.cd_length = len; 4791 data.cd_raw.iov_base = key.ck_data; 4792 data.cd_raw.iov_len = len; 4793 error = crypto_digest_update(DPROV_CTX_SINGLE(ctx), 4794 &data, NULL); 4795 break; 4796 } 4797 4798 case DPROV_REQ_DIGEST_FINAL: 4799 error = crypto_digest_final(DPROV_CTX_SINGLE(ctx), 4800 taskq_req->dr_digest_req.dr_digest, NULL); 4801 if (error != CRYPTO_BUFFER_TOO_SMALL) { 4802 DPROV_CTX_SINGLE(ctx) = NULL; 4803 (void) dprov_free_context(ctx); 4804 } 4805 break; 4806 4807 case DPROV_REQ_DIGEST_ATOMIC: 4808 /* structure assignment */ 4809 mech = *taskq_req->dr_digest_req.dr_mechanism; 4810 4811 /* get the software provider for this mechanism */ 4812 if ((error = dprov_get_sw_prov( 4813 taskq_req->dr_digest_req.dr_mechanism, &pd, 4814 &mech.cm_type)) != CRYPTO_SUCCESS) 4815 break; 4816 4817 /* use a session id of zero since we use a software provider */ 4818 error = crypto_digest_prov(pd, 0, &mech, 4819 taskq_req->dr_digest_req.dr_data, 4820 taskq_req->dr_digest_req.dr_digest, NULL); 4821 4822 /* release provider reference */ 4823 KCF_PROV_REFRELE(pd); 4824 4825 break; 4826 } 4827 4828 dprov_op_done(taskq_req, error); 4829 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_task: end\n", instance)); 4830 } 4831 4832 /* 4833 * taskq dispatcher function for mac operations. 4834 */ 4835 static void 4836 dprov_mac_task(dprov_req_t *taskq_req) 4837 { 4838 kcf_provider_desc_t *pd; 4839 dprov_state_t *softc; 4840 /* LINTED E_FUNC_SET_NOT_USED */ 4841 int instance; 4842 int error = CRYPTO_NOT_SUPPORTED; 4843 crypto_ctx_t *ctx = taskq_req->dr_mac_req.dr_ctx; 4844 crypto_key_t key; 4845 crypto_mechanism_t mech; 4846 4847 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 4848 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: started\n", instance)); 4849 4850 switch (taskq_req->dr_type) { 4851 4852 case DPROV_REQ_MAC_INIT: 4853 /* allocate a dprov-private context */ 4854 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) != 4855 CRYPTO_SUCCESS) 4856 break; 4857 4858 /* get key value */ 4859 mutex_enter(&softc->ds_lock); 4860 error = dprov_key_value_secret(softc, ctx->cc_session, 4861 taskq_req->dr_type, taskq_req->dr_mac_req.dr_key, &key); 4862 mutex_exit(&softc->ds_lock); 4863 if (error != CRYPTO_SUCCESS) 4864 break; 4865 4866 /* structure assignment */ 4867 mech = *taskq_req->dr_mac_req.dr_mechanism; 4868 4869 /* get the software provider for this mechanism */ 4870 if ((error = dprov_get_sw_prov( 4871 taskq_req->dr_mac_req.dr_mechanism, &pd, 4872 &mech.cm_type)) != CRYPTO_SUCCESS) 4873 break; 4874 4875 /* Use a session id of zero since we use a software provider */ 4876 error = crypto_mac_init_prov(pd, 0, &mech, &key, NULL, 4877 &DPROV_CTX_SINGLE(ctx), NULL); 4878 4879 /* release provider reference */ 4880 KCF_PROV_REFRELE(pd); 4881 break; 4882 4883 case DPROV_REQ_MAC: 4884 error = crypto_mac_single(DPROV_CTX_SINGLE(ctx), 4885 taskq_req->dr_mac_req.dr_data, 4886 taskq_req->dr_mac_req.dr_mac, NULL); 4887 4888 if (error != CRYPTO_BUFFER_TOO_SMALL) { 4889 DPROV_CTX_SINGLE(ctx) = NULL; 4890 (void) dprov_free_context(ctx); 4891 } 4892 break; 4893 4894 case DPROV_REQ_MAC_UPDATE: 4895 error = crypto_mac_update(DPROV_CTX_SINGLE(ctx), 4896 taskq_req->dr_mac_req.dr_data, NULL); 4897 break; 4898 4899 case DPROV_REQ_MAC_FINAL: 4900 error = crypto_mac_final(DPROV_CTX_SINGLE(ctx), 4901 taskq_req->dr_mac_req.dr_mac, NULL); 4902 if (error != CRYPTO_BUFFER_TOO_SMALL) { 4903 DPROV_CTX_SINGLE(ctx) = NULL; 4904 (void) dprov_free_context(ctx); 4905 } 4906 break; 4907 4908 case DPROV_REQ_MAC_ATOMIC: 4909 case DPROV_REQ_MAC_VERIFY_ATOMIC: 4910 /* get key value */ 4911 mutex_enter(&softc->ds_lock); 4912 error = dprov_key_value_secret(softc, 4913 taskq_req->dr_mac_req.dr_session_id, 4914 taskq_req->dr_type, taskq_req->dr_mac_req.dr_key, &key); 4915 mutex_exit(&softc->ds_lock); 4916 if (error != CRYPTO_SUCCESS) 4917 break; 4918 4919 /* structure assignment */ 4920 mech = *taskq_req->dr_mac_req.dr_mechanism; 4921 4922 /* get the software provider for this mechanism */ 4923 if ((error = dprov_get_sw_prov( 4924 taskq_req->dr_mac_req.dr_mechanism, &pd, 4925 &mech.cm_type)) != CRYPTO_SUCCESS) 4926 break; 4927 4928 /* use a session id of zero since we use a software provider */ 4929 if (taskq_req->dr_type == DPROV_REQ_MAC_ATOMIC) 4930 error = crypto_mac_prov(pd, 0, &mech, 4931 taskq_req->dr_mac_req.dr_data, 4932 &key, NULL, taskq_req->dr_mac_req.dr_mac, NULL); 4933 else 4934 error = crypto_mac_verify_prov(pd, 0, &mech, 4935 taskq_req->dr_mac_req.dr_data, 4936 &key, NULL, taskq_req->dr_mac_req.dr_mac, NULL); 4937 4938 /* release provider reference */ 4939 KCF_PROV_REFRELE(pd); 4940 4941 break; 4942 } 4943 4944 dprov_op_done(taskq_req, error); 4945 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: end\n", instance)); 4946 } 4947 4948 /* 4949 * taskq dispatcher function for sign operations. 4950 */ 4951 static void 4952 dprov_sign_task(dprov_req_t *taskq_req) 4953 { 4954 kcf_provider_desc_t *pd; 4955 dprov_state_t *softc; 4956 /* LINTED E_FUNC_SET_NOT_USED */ 4957 int instance; 4958 int error = CRYPTO_NOT_SUPPORTED; 4959 crypto_ctx_t *ctx = taskq_req->dr_mac_req.dr_ctx; 4960 crypto_key_t key, *keyp; 4961 crypto_mechanism_t mech; 4962 4963 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 4964 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_task: started\n", instance)); 4965 4966 switch (taskq_req->dr_type) { 4967 4968 case DPROV_REQ_SIGN_INIT: 4969 case DPROV_REQ_SIGN_RECOVER_INIT: 4970 /* allocate a dprov-private context */ 4971 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) != 4972 CRYPTO_SUCCESS) 4973 break; 4974 4975 /* structure assignment */ 4976 mech = *taskq_req->dr_sign_req.sr_mechanism; 4977 4978 mutex_enter(&softc->ds_lock); 4979 /* get key value for secret key algorithms */ 4980 if (is_publickey_mech(mech.cm_type)) { 4981 if ((error = dprov_key_attr_asymmetric(softc, 4982 ctx->cc_session, taskq_req->dr_type, 4983 taskq_req->dr_sign_req.sr_key, &key)) 4984 != CRYPTO_SUCCESS) { 4985 mutex_exit(&softc->ds_lock); 4986 break; 4987 } 4988 keyp = &key; 4989 } else { 4990 if ((error = dprov_key_value_secret(softc, 4991 ctx->cc_session, taskq_req->dr_type, 4992 taskq_req->dr_sign_req.sr_key, &key)) 4993 != CRYPTO_SUCCESS) { 4994 mutex_exit(&softc->ds_lock); 4995 break; 4996 } 4997 keyp = &key; 4998 } 4999 mutex_exit(&softc->ds_lock); 5000 5001 /* get the software provider for this mechanism */ 5002 if ((error = dprov_get_sw_prov( 5003 taskq_req->dr_sign_req.sr_mechanism, &pd, 5004 &mech.cm_type)) != CRYPTO_SUCCESS) 5005 break; 5006 5007 /* Use a session id of zero since we use a software provider */ 5008 if (taskq_req->dr_type == DPROV_REQ_SIGN_INIT) 5009 error = crypto_sign_init_prov(pd, 0, &mech, keyp, 5010 NULL, &DPROV_CTX_SINGLE(ctx), NULL); 5011 else 5012 error = crypto_sign_recover_init_prov(pd, 0, &mech, 5013 keyp, NULL, &DPROV_CTX_SINGLE(ctx), NULL); 5014 5015 /* release provider reference */ 5016 KCF_PROV_REFRELE(pd); 5017 5018 break; 5019 5020 case DPROV_REQ_SIGN: 5021 error = crypto_sign_single(DPROV_CTX_SINGLE(ctx), 5022 taskq_req->dr_sign_req.sr_data, 5023 taskq_req->dr_sign_req.sr_signature, NULL); 5024 5025 if (error != CRYPTO_BUFFER_TOO_SMALL) { 5026 DPROV_CTX_SINGLE(ctx) = NULL; 5027 (void) dprov_free_context(ctx); 5028 } 5029 break; 5030 5031 case DPROV_REQ_SIGN_UPDATE: 5032 error = crypto_sign_update(DPROV_CTX_SINGLE(ctx), 5033 taskq_req->dr_sign_req.sr_data, NULL); 5034 break; 5035 5036 case DPROV_REQ_SIGN_FINAL: 5037 error = crypto_sign_final(DPROV_CTX_SINGLE(ctx), 5038 taskq_req->dr_sign_req.sr_signature, NULL); 5039 5040 if (error != CRYPTO_BUFFER_TOO_SMALL) { 5041 DPROV_CTX_SINGLE(ctx) = NULL; 5042 (void) dprov_free_context(ctx); 5043 } 5044 break; 5045 5046 case DPROV_REQ_SIGN_ATOMIC: 5047 case DPROV_REQ_SIGN_RECOVER_ATOMIC: 5048 /* structure assignment */ 5049 mech = *taskq_req->dr_sign_req.sr_mechanism; 5050 5051 mutex_enter(&softc->ds_lock); 5052 /* get key value for secret key algorithms */ 5053 if (is_publickey_mech(mech.cm_type)) { 5054 if ((error = dprov_key_attr_asymmetric(softc, 5055 taskq_req->dr_sign_req.sr_session_id, 5056 taskq_req->dr_type, 5057 taskq_req->dr_sign_req.sr_key, &key)) 5058 != CRYPTO_SUCCESS) { 5059 mutex_exit(&softc->ds_lock); 5060 break; 5061 } 5062 keyp = &key; 5063 } else { 5064 if ((error = dprov_key_value_secret(softc, 5065 taskq_req->dr_sign_req.sr_session_id, 5066 taskq_req->dr_type, 5067 taskq_req->dr_sign_req.sr_key, &key)) 5068 != CRYPTO_SUCCESS) { 5069 mutex_exit(&softc->ds_lock); 5070 break; 5071 } 5072 keyp = &key; 5073 } 5074 mutex_exit(&softc->ds_lock); 5075 5076 /* get the software provider for this mechanism */ 5077 if ((error = dprov_get_sw_prov( 5078 taskq_req->dr_sign_req.sr_mechanism, &pd, 5079 &mech.cm_type)) != CRYPTO_SUCCESS) 5080 break; 5081 5082 /* Use a session id of zero since we use a software provider */ 5083 if (taskq_req->dr_type == DPROV_REQ_SIGN_ATOMIC) 5084 error = crypto_sign_prov(pd, 0, &mech, keyp, 5085 taskq_req->dr_sign_req.sr_data, 5086 NULL, taskq_req->dr_sign_req.sr_signature, NULL); 5087 else 5088 error = crypto_sign_recover_prov(pd, 0, &mech, keyp, 5089 taskq_req->dr_sign_req.sr_data, 5090 NULL, taskq_req->dr_sign_req.sr_signature, NULL); 5091 5092 /* release provider reference */ 5093 KCF_PROV_REFRELE(pd); 5094 break; 5095 5096 case DPROV_REQ_SIGN_RECOVER: 5097 error = crypto_sign_recover_single(DPROV_CTX_SINGLE(ctx), 5098 taskq_req->dr_sign_req.sr_data, 5099 taskq_req->dr_sign_req.sr_signature, NULL); 5100 5101 if (error != CRYPTO_BUFFER_TOO_SMALL) { 5102 DPROV_CTX_SINGLE(ctx) = NULL; 5103 (void) dprov_free_context(ctx); 5104 } 5105 break; 5106 } 5107 5108 dprov_op_done(taskq_req, error); 5109 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_task: end\n", instance)); 5110 } 5111 5112 /* 5113 * taskq dispatcher function for verify operations. 5114 */ 5115 static void 5116 dprov_verify_task(dprov_req_t *taskq_req) 5117 { 5118 kcf_provider_desc_t *pd; 5119 dprov_state_t *softc; 5120 /* LINTED E_FUNC_SET_NOT_USED */ 5121 int instance; 5122 int error = CRYPTO_NOT_SUPPORTED; 5123 crypto_ctx_t *ctx = taskq_req->dr_verify_req.vr_ctx; 5124 crypto_key_t key, *keyp; 5125 crypto_mechanism_t mech; 5126 5127 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 5128 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_task: started\n", instance)); 5129 5130 switch (taskq_req->dr_type) { 5131 5132 case DPROV_REQ_VERIFY_INIT: 5133 case DPROV_REQ_VERIFY_RECOVER_INIT: 5134 /* allocate a dprov-private context */ 5135 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) != 5136 CRYPTO_SUCCESS) 5137 break; 5138 5139 /* structure assignment */ 5140 mech = *taskq_req->dr_verify_req.vr_mechanism; 5141 5142 mutex_enter(&softc->ds_lock); 5143 /* get key value for secret key algorithms */ 5144 if (is_publickey_mech(mech.cm_type)) { 5145 if ((error = dprov_key_attr_asymmetric(softc, 5146 ctx->cc_session, taskq_req->dr_type, 5147 taskq_req->dr_verify_req.vr_key, &key)) 5148 != CRYPTO_SUCCESS) { 5149 mutex_exit(&softc->ds_lock); 5150 break; 5151 } 5152 keyp = &key; 5153 } else { 5154 if ((error = dprov_key_value_secret(softc, 5155 ctx->cc_session, taskq_req->dr_type, 5156 taskq_req->dr_verify_req.vr_key, &key)) 5157 != CRYPTO_SUCCESS) { 5158 mutex_exit(&softc->ds_lock); 5159 break; 5160 } 5161 keyp = &key; 5162 } 5163 mutex_exit(&softc->ds_lock); 5164 5165 /* get the software provider for this mechanism */ 5166 if ((error = dprov_get_sw_prov( 5167 taskq_req->dr_verify_req.vr_mechanism, &pd, 5168 &mech.cm_type)) != CRYPTO_SUCCESS) 5169 break; 5170 5171 /* Use a session id of zero since we use a software provider */ 5172 if (taskq_req->dr_type == DPROV_REQ_VERIFY_INIT) 5173 error = crypto_verify_init_prov(pd, 0, &mech, keyp, 5174 NULL, &DPROV_CTX_SINGLE(ctx), NULL); 5175 else 5176 error = crypto_verify_recover_init_prov(pd, 0, &mech, 5177 keyp, NULL, &DPROV_CTX_SINGLE(ctx), NULL); 5178 5179 /* release provider reference */ 5180 KCF_PROV_REFRELE(pd); 5181 5182 break; 5183 5184 case DPROV_REQ_VERIFY: 5185 error = crypto_verify_single(DPROV_CTX_SINGLE(ctx), 5186 taskq_req->dr_verify_req.vr_data, 5187 taskq_req->dr_verify_req.vr_signature, NULL); 5188 5189 ASSERT(error != CRYPTO_BUFFER_TOO_SMALL); 5190 DPROV_CTX_SINGLE(ctx) = NULL; 5191 (void) dprov_free_context(ctx); 5192 break; 5193 5194 case DPROV_REQ_VERIFY_UPDATE: 5195 error = crypto_verify_update(DPROV_CTX_SINGLE(ctx), 5196 taskq_req->dr_verify_req.vr_data, NULL); 5197 break; 5198 5199 case DPROV_REQ_VERIFY_FINAL: 5200 error = crypto_verify_final(DPROV_CTX_SINGLE(ctx), 5201 taskq_req->dr_verify_req.vr_signature, NULL); 5202 5203 ASSERT(error != CRYPTO_BUFFER_TOO_SMALL); 5204 DPROV_CTX_SINGLE(ctx) = NULL; 5205 (void) dprov_free_context(ctx); 5206 break; 5207 5208 case DPROV_REQ_VERIFY_ATOMIC: 5209 case DPROV_REQ_VERIFY_RECOVER_ATOMIC: 5210 /* structure assignment */ 5211 mech = *taskq_req->dr_verify_req.vr_mechanism; 5212 5213 mutex_enter(&softc->ds_lock); 5214 /* get key value for secret key algorithms */ 5215 if (is_publickey_mech(mech.cm_type)) { 5216 if ((error = dprov_key_attr_asymmetric(softc, 5217 taskq_req->dr_verify_req.vr_session_id, 5218 taskq_req->dr_type, 5219 taskq_req->dr_verify_req.vr_key, &key)) 5220 != CRYPTO_SUCCESS) { 5221 mutex_exit(&softc->ds_lock); 5222 break; 5223 } 5224 keyp = &key; 5225 } else { 5226 if ((error = dprov_key_value_secret(softc, 5227 taskq_req->dr_verify_req.vr_session_id, 5228 taskq_req->dr_type, 5229 taskq_req->dr_verify_req.vr_key, &key)) 5230 != CRYPTO_SUCCESS) { 5231 mutex_exit(&softc->ds_lock); 5232 break; 5233 } 5234 keyp = &key; 5235 } 5236 mutex_exit(&softc->ds_lock); 5237 5238 /* get the software provider for this mechanism */ 5239 if ((error = dprov_get_sw_prov( 5240 taskq_req->dr_verify_req.vr_mechanism, &pd, 5241 &mech.cm_type)) != CRYPTO_SUCCESS) 5242 break; 5243 5244 /* Use a session id of zero since we use a software provider */ 5245 if (taskq_req->dr_type == DPROV_REQ_VERIFY_ATOMIC) 5246 error = crypto_verify_prov(pd, 0, &mech, keyp, 5247 taskq_req->dr_verify_req.vr_data, 5248 NULL, taskq_req->dr_verify_req.vr_signature, NULL); 5249 else 5250 /* 5251 * crypto_verify_recover_prov() has different argument 5252 * order than crypto_verify_prov(). 5253 */ 5254 error = crypto_verify_recover_prov(pd, 0, &mech, keyp, 5255 taskq_req->dr_verify_req.vr_signature, 5256 NULL, taskq_req->dr_verify_req.vr_data, NULL); 5257 5258 /* release provider reference */ 5259 KCF_PROV_REFRELE(pd); 5260 break; 5261 5262 case DPROV_REQ_VERIFY_RECOVER: 5263 /* 5264 * crypto_verify_recover_single() has different argument 5265 * order than crypto_verify_single(). 5266 */ 5267 error = crypto_verify_recover_single(DPROV_CTX_SINGLE(ctx), 5268 taskq_req->dr_verify_req.vr_signature, 5269 taskq_req->dr_verify_req.vr_data, NULL); 5270 5271 if (error != CRYPTO_BUFFER_TOO_SMALL) { 5272 DPROV_CTX_SINGLE(ctx) = NULL; 5273 (void) dprov_free_context(ctx); 5274 } 5275 break; 5276 } 5277 5278 dprov_op_done(taskq_req, error); 5279 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_task: end\n", instance)); 5280 } 5281 5282 /* 5283 * taskq dispatcher function for dual operations. 5284 */ 5285 static void 5286 dprov_dual_task(dprov_req_t *taskq_req) 5287 { 5288 dprov_state_t *softc; 5289 /* LINTED E_FUNC_SET_NOT_USED */ 5290 int instance; 5291 int error = CRYPTO_NOT_SUPPORTED; 5292 crypto_ctx_t *signverify_ctx = taskq_req->dr_dual_req.dr_signverify_ctx; 5293 crypto_ctx_t *cipher_ctx = taskq_req->dr_dual_req.dr_cipher_ctx; 5294 5295 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 5296 DPROV_DEBUG(D_DUAL, ("(%d) dprov_dual_task: started\n", instance)); 5297 5298 switch (taskq_req->dr_type) { 5299 5300 case DPROV_REQ_DIGEST_ENCRYPT_UPDATE: 5301 error = crypto_digest_encrypt_update( 5302 DPROV_CTX_SINGLE(signverify_ctx), 5303 DPROV_CTX_SINGLE(cipher_ctx), 5304 taskq_req->dr_dual_req.dr_plaintext, 5305 taskq_req->dr_dual_req.dr_ciphertext, NULL); 5306 break; 5307 5308 case DPROV_REQ_DECRYPT_DIGEST_UPDATE: 5309 error = crypto_decrypt_digest_update( 5310 DPROV_CTX_SINGLE(cipher_ctx), 5311 DPROV_CTX_SINGLE(signverify_ctx), 5312 taskq_req->dr_dual_req.dr_ciphertext, 5313 taskq_req->dr_dual_req.dr_plaintext, NULL); 5314 break; 5315 5316 case DPROV_REQ_SIGN_ENCRYPT_UPDATE: 5317 error = crypto_sign_encrypt_update( 5318 DPROV_CTX_SINGLE(signverify_ctx), 5319 DPROV_CTX_SINGLE(cipher_ctx), 5320 taskq_req->dr_dual_req.dr_plaintext, 5321 taskq_req->dr_dual_req.dr_ciphertext, NULL); 5322 break; 5323 5324 case DPROV_REQ_DECRYPT_VERIFY_UPDATE: 5325 error = crypto_decrypt_verify_update( 5326 DPROV_CTX_SINGLE(cipher_ctx), 5327 DPROV_CTX_SINGLE(signverify_ctx), 5328 taskq_req->dr_dual_req.dr_ciphertext, 5329 taskq_req->dr_dual_req.dr_plaintext, NULL); 5330 break; 5331 } 5332 5333 dprov_op_done(taskq_req, error); 5334 DPROV_DEBUG(D_DUAL, ("(%d) dprov_dual_task: end\n", instance)); 5335 } 5336 5337 /* 5338 * taskq dispatcher function for cipher operations. 5339 */ 5340 static void 5341 dprov_cipher_task(dprov_req_t *taskq_req) 5342 { 5343 kcf_provider_desc_t *pd; 5344 dprov_state_t *softc; 5345 /* LINTED E_FUNC_SET_NOT_USED */ 5346 int instance; 5347 int error = CRYPTO_NOT_SUPPORTED; 5348 crypto_ctx_t *ctx = taskq_req->dr_cipher_req.dr_ctx; 5349 crypto_key_t key, *keyp; 5350 crypto_mechanism_t mech; 5351 5352 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 5353 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_cipher_task: started\n", instance)); 5354 5355 switch (taskq_req->dr_type) { 5356 5357 case DPROV_REQ_ENCRYPT_INIT: 5358 case DPROV_REQ_DECRYPT_INIT: 5359 /* allocate a dprov-private context */ 5360 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) != 5361 CRYPTO_SUCCESS) 5362 break; 5363 5364 /* structure assignment */ 5365 mech = *taskq_req->dr_cipher_req.dr_mechanism; 5366 5367 mutex_enter(&softc->ds_lock); 5368 /* get key value for secret key algorithms */ 5369 if (is_publickey_mech(mech.cm_type)) { 5370 if ((error = dprov_key_attr_asymmetric(softc, 5371 ctx->cc_session, taskq_req->dr_type, 5372 taskq_req->dr_cipher_req.dr_key, &key)) 5373 != CRYPTO_SUCCESS) { 5374 mutex_exit(&softc->ds_lock); 5375 break; 5376 } 5377 keyp = &key; 5378 } else { 5379 if ((error = dprov_key_value_secret(softc, 5380 ctx->cc_session, taskq_req->dr_type, 5381 taskq_req->dr_cipher_req.dr_key, &key)) 5382 != CRYPTO_SUCCESS) { 5383 mutex_exit(&softc->ds_lock); 5384 break; 5385 } 5386 keyp = &key; 5387 } 5388 mutex_exit(&softc->ds_lock); 5389 5390 /* get the software provider for this mechanism */ 5391 if ((error = dprov_get_sw_prov( 5392 taskq_req->dr_cipher_req.dr_mechanism, &pd, 5393 &mech.cm_type)) != CRYPTO_SUCCESS) 5394 break; 5395 5396 /* Use a session id of zero since we use a software provider */ 5397 if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_INIT) 5398 error = crypto_encrypt_init_prov(pd, 0, &mech, keyp, 5399 NULL, &DPROV_CTX_SINGLE(ctx), NULL); 5400 else 5401 error = crypto_decrypt_init_prov(pd, 0, &mech, keyp, 5402 NULL, &DPROV_CTX_SINGLE(ctx), NULL); 5403 5404 /* release provider reference */ 5405 KCF_PROV_REFRELE(pd); 5406 break; 5407 5408 case DPROV_REQ_ENCRYPT: 5409 error = crypto_encrypt_single(DPROV_CTX_SINGLE(ctx), 5410 taskq_req->dr_cipher_req.dr_plaintext, 5411 taskq_req->dr_cipher_req.dr_ciphertext, NULL); 5412 5413 if (error != CRYPTO_BUFFER_TOO_SMALL) { 5414 DPROV_CTX_SINGLE(ctx) = NULL; 5415 (void) dprov_free_context(ctx); 5416 } 5417 break; 5418 5419 case DPROV_REQ_DECRYPT: 5420 error = crypto_decrypt_single(DPROV_CTX_SINGLE(ctx), 5421 taskq_req->dr_cipher_req.dr_ciphertext, 5422 taskq_req->dr_cipher_req.dr_plaintext, NULL); 5423 5424 if (error != CRYPTO_BUFFER_TOO_SMALL) { 5425 DPROV_CTX_SINGLE(ctx) = NULL; 5426 (void) dprov_free_context(ctx); 5427 } 5428 break; 5429 5430 case DPROV_REQ_ENCRYPT_UPDATE: 5431 error = crypto_encrypt_update(DPROV_CTX_SINGLE(ctx), 5432 taskq_req->dr_cipher_req.dr_plaintext, 5433 taskq_req->dr_cipher_req.dr_ciphertext, NULL); 5434 break; 5435 5436 case DPROV_REQ_DECRYPT_UPDATE: 5437 error = crypto_decrypt_update(DPROV_CTX_SINGLE(ctx), 5438 taskq_req->dr_cipher_req.dr_ciphertext, 5439 taskq_req->dr_cipher_req.dr_plaintext, NULL); 5440 break; 5441 5442 case DPROV_REQ_ENCRYPT_FINAL: 5443 error = crypto_encrypt_final(DPROV_CTX_SINGLE(ctx), 5444 taskq_req->dr_cipher_req.dr_ciphertext, NULL); 5445 if (error != CRYPTO_BUFFER_TOO_SMALL) { 5446 DPROV_CTX_SINGLE(ctx) = NULL; 5447 (void) dprov_free_context(ctx); 5448 } 5449 break; 5450 5451 case DPROV_REQ_DECRYPT_FINAL: 5452 error = crypto_decrypt_final(DPROV_CTX_SINGLE(ctx), 5453 taskq_req->dr_cipher_req.dr_plaintext, NULL); 5454 if (error != CRYPTO_BUFFER_TOO_SMALL) { 5455 DPROV_CTX_SINGLE(ctx) = NULL; 5456 (void) dprov_free_context(ctx); 5457 } 5458 break; 5459 5460 case DPROV_REQ_ENCRYPT_ATOMIC: 5461 case DPROV_REQ_DECRYPT_ATOMIC: 5462 /* structure assignment */ 5463 mech = *taskq_req->dr_cipher_req.dr_mechanism; 5464 5465 mutex_enter(&softc->ds_lock); 5466 /* get key value for secret key algorithms */ 5467 if (is_publickey_mech(mech.cm_type)) { 5468 if ((error = dprov_key_attr_asymmetric(softc, 5469 taskq_req->dr_cipher_req.dr_session_id, 5470 taskq_req->dr_type, 5471 taskq_req->dr_cipher_req.dr_key, 5472 &key)) != CRYPTO_SUCCESS) { 5473 mutex_exit(&softc->ds_lock); 5474 break; 5475 } 5476 keyp = &key; 5477 } else { 5478 if ((error = dprov_key_value_secret(softc, 5479 taskq_req->dr_cipher_req.dr_session_id, 5480 taskq_req->dr_type, taskq_req->dr_cipher_req.dr_key, 5481 &key)) 5482 != CRYPTO_SUCCESS) { 5483 mutex_exit(&softc->ds_lock); 5484 break; 5485 } 5486 keyp = &key; 5487 } 5488 mutex_exit(&softc->ds_lock); 5489 5490 /* get the software provider for this mechanism */ 5491 if ((error = dprov_get_sw_prov( 5492 taskq_req->dr_cipher_req.dr_mechanism, &pd, 5493 &mech.cm_type)) != CRYPTO_SUCCESS) 5494 break; 5495 5496 /* use a session id of zero since we use a software provider */ 5497 if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_ATOMIC) 5498 error = crypto_encrypt_prov(pd, 0, &mech, 5499 taskq_req->dr_cipher_req.dr_plaintext, 5500 keyp, NULL, 5501 taskq_req->dr_cipher_req.dr_ciphertext, NULL); 5502 else 5503 error = crypto_decrypt_prov(pd, 0, &mech, 5504 taskq_req->dr_cipher_req.dr_ciphertext, 5505 keyp, NULL, 5506 taskq_req->dr_cipher_req.dr_plaintext, NULL); 5507 5508 /* release provider reference */ 5509 KCF_PROV_REFRELE(pd); 5510 5511 break; 5512 } 5513 5514 dprov_op_done(taskq_req, error); 5515 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: end\n", instance)); 5516 } 5517 5518 /* 5519 * Helper function for the cipher/mac dual operation taskq dispatch 5520 * function. Initialize the cipher and mac key values and find the 5521 * providers that can process the request for the specified mechanisms. 5522 */ 5523 static int 5524 dprov_cipher_mac_key_pd(dprov_state_t *softc, crypto_session_id_t sid, 5525 dprov_req_t *taskq_req, crypto_key_t *cipher_key, crypto_key_t *mac_key, 5526 kcf_provider_desc_t **cipher_pd, kcf_provider_desc_t **mac_pd, 5527 crypto_mech_type_t *cipher_mech_type, crypto_mech_type_t *mac_mech_type) 5528 { 5529 int error; 5530 5531 /* get the cipher key value */ 5532 mutex_enter(&softc->ds_lock); 5533 error = dprov_key_value_secret(softc, sid, DPROV_REQ_ENCRYPT_ATOMIC, 5534 taskq_req->dr_cipher_mac_req.mr_cipher_key, cipher_key); 5535 if (error != CRYPTO_SUCCESS) { 5536 mutex_exit(&softc->ds_lock); 5537 return (error); 5538 } 5539 5540 /* get the mac key value */ 5541 error = dprov_key_value_secret(softc, sid, DPROV_REQ_MAC_ATOMIC, 5542 taskq_req->dr_cipher_mac_req.mr_mac_key, mac_key); 5543 mutex_exit(&softc->ds_lock); 5544 if (error != CRYPTO_SUCCESS) 5545 return (error); 5546 5547 /* get the SW provider to perform the cipher operation */ 5548 if ((error = dprov_get_sw_prov( 5549 taskq_req->dr_cipher_mac_req.mr_cipher_mech, cipher_pd, 5550 cipher_mech_type)) != CRYPTO_SUCCESS) 5551 return (error); 5552 5553 /* get the SW provider to perform the mac operation */ 5554 error = dprov_get_sw_prov(taskq_req->dr_cipher_mac_req.mr_mac_mech, 5555 mac_pd, mac_mech_type); 5556 5557 return (error); 5558 } 5559 5560 /* 5561 * taskq dispatcher function for cipher/mac dual operations. 5562 */ 5563 static void 5564 dprov_cipher_mac_task(dprov_req_t *taskq_req) 5565 { 5566 dprov_state_t *softc; 5567 /* LINTED E_FUNC_SET_NOT_USED */ 5568 int instance; 5569 int error = CRYPTO_NOT_SUPPORTED; 5570 crypto_ctx_t *ctx = taskq_req->dr_cipher_mac_req.mr_ctx; 5571 kcf_provider_desc_t *cipher_pd; 5572 kcf_provider_desc_t *mac_pd; 5573 crypto_key_t cipher_key; 5574 crypto_key_t mac_key; 5575 crypto_dual_data_t *dual_data = 5576 taskq_req->dr_cipher_mac_req.mr_dual_data; 5577 crypto_data_t cipher_data; 5578 crypto_data_t mac_data; 5579 crypto_mechanism_t cipher_mech, mac_mech; 5580 crypto_session_id_t session_id; 5581 5582 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 5583 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_cipher_mac_task: started\n", 5584 instance)); 5585 5586 switch (taskq_req->dr_type) { 5587 case DPROV_REQ_ENCRYPT_MAC_INIT: 5588 case DPROV_REQ_MAC_DECRYPT_INIT: 5589 /* structure assignment */ 5590 cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech; 5591 mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech; 5592 5593 /* get the keys values and providers to use for operations */ 5594 if ((error = dprov_cipher_mac_key_pd(softc, ctx->cc_session, 5595 taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd, 5596 &cipher_mech.cm_type, &mac_mech.cm_type)) != CRYPTO_SUCCESS) 5597 break; 5598 5599 /* allocate a dprov-private context */ 5600 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) != 5601 CRYPTO_SUCCESS) 5602 break; 5603 5604 if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_MAC_INIT) 5605 /* do the encryption initialization */ 5606 error = crypto_encrypt_init_prov(cipher_pd, 0, 5607 &cipher_mech, &cipher_key, NULL, 5608 &DPROV_CTX_DUAL_CIPHER(ctx), NULL); 5609 else 5610 /* do the decryption initialization */ 5611 error = crypto_decrypt_init_prov(cipher_pd, 0, 5612 &cipher_mech, &cipher_key, NULL, 5613 &DPROV_CTX_DUAL_CIPHER(ctx), NULL); 5614 if (error != CRYPTO_SUCCESS) 5615 break; 5616 5617 /* do the mac initialization */ 5618 if ((error = crypto_mac_init_prov(mac_pd, 0, 5619 &mac_mech, &mac_key, NULL, &DPROV_CTX_DUAL_MAC(ctx), 5620 NULL)) != CRYPTO_SUCCESS) 5621 break; 5622 5623 /* release references to providers */ 5624 KCF_PROV_REFRELE(cipher_pd); 5625 KCF_PROV_REFRELE(mac_pd); 5626 5627 break; 5628 5629 case DPROV_REQ_ENCRYPT_MAC: { 5630 size_t encrypted; 5631 boolean_t inplace; 5632 5633 crypto_data_t *plaintext_tmp, *ciphertext_tmp; 5634 5635 cipher_data = *((crypto_data_t *)dual_data); 5636 5637 /* do an encrypt update */ 5638 inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL); 5639 if (inplace) { 5640 plaintext_tmp = &cipher_data; 5641 ciphertext_tmp = NULL; 5642 } else { 5643 plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data; 5644 ciphertext_tmp = &cipher_data; 5645 } 5646 if ((error = crypto_encrypt_update(DPROV_CTX_DUAL_CIPHER(ctx), 5647 plaintext_tmp, ciphertext_tmp, NULL)) != CRYPTO_SUCCESS) 5648 break; 5649 5650 /* do an encrypt final */ 5651 encrypted = cipher_data.cd_length; 5652 5653 cipher_data.cd_offset += encrypted; 5654 cipher_data.cd_length = dual_data->dd_len1 - encrypted; 5655 5656 if ((error = crypto_encrypt_final(DPROV_CTX_DUAL_CIPHER(ctx), 5657 &cipher_data, NULL)) != CRYPTO_SUCCESS) 5658 break; 5659 5660 /* 5661 * Do a mac update on the resulting ciphertext, but with no 5662 * more bytes than specified by dual_data, and starting at 5663 * offset specified by dual_data. For in-place operations, 5664 * we use the length specified by the dual_data. 5665 */ 5666 mac_data = cipher_data; 5667 mac_data.cd_offset = dual_data->dd_offset2; 5668 mac_data.cd_length = dual_data->dd_len2; 5669 if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx), 5670 &mac_data, NULL)) != CRYPTO_SUCCESS) 5671 break; 5672 5673 /* do a mac final */ 5674 error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx), 5675 taskq_req->dr_cipher_mac_req.mr_mac, NULL); 5676 5677 /* Set the total size of the ciphertext, when successful */ 5678 if (error == CRYPTO_SUCCESS) 5679 dual_data->dd_len1 = encrypted + cipher_data.cd_length; 5680 5681 if (error != CRYPTO_BUFFER_TOO_SMALL) { 5682 DPROV_CTX_DUAL_CIPHER(ctx) = NULL; 5683 DPROV_CTX_DUAL_MAC(ctx) = NULL; 5684 (void) dprov_free_context(ctx); 5685 } 5686 break; 5687 } 5688 5689 case DPROV_REQ_ENCRYPT_MAC_UPDATE: { 5690 crypto_data_t *plaintext_tmp, *ciphertext_tmp; 5691 size_t encrypted; 5692 ssize_t maclen; 5693 boolean_t inplace; 5694 5695 cipher_data = *((crypto_data_t *)dual_data); 5696 5697 /* do an encrypt update */ 5698 inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL); 5699 if (inplace) { 5700 plaintext_tmp = &cipher_data; 5701 ciphertext_tmp = NULL; 5702 } else { 5703 plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data; 5704 ciphertext_tmp = &cipher_data; 5705 } 5706 if ((error = crypto_encrypt_update(DPROV_CTX_DUAL_CIPHER(ctx), 5707 plaintext_tmp, ciphertext_tmp, NULL)) != CRYPTO_SUCCESS) 5708 break; 5709 5710 encrypted = cipher_data.cd_length; 5711 5712 /* 5713 * Do a mac update on the resulting ciphertext, but with no 5714 * more bytes than specified by dual_data, and starting at 5715 * offset specified by dual_data. For in-place operations, 5716 * we use the length specified by the dual_data. 5717 * There is an edge case, when the encryption step produced 5718 * zero bytes in the ciphertext. Only the portion between 5719 * offset2 and offset1 is then thrown in the MAC mix. 5720 */ 5721 maclen = dual_data->dd_offset1 - dual_data->dd_offset2 + 5722 encrypted; 5723 if (maclen > 0) { 5724 mac_data = cipher_data; 5725 mac_data.cd_offset = dual_data->dd_offset2; 5726 mac_data.cd_length = min(dual_data->dd_len2, maclen); 5727 if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx), 5728 &mac_data, NULL)) != CRYPTO_SUCCESS) 5729 break; 5730 } 5731 /* Set the total size of the ciphertext, when successful */ 5732 if (error == CRYPTO_SUCCESS) 5733 dual_data->dd_len1 = encrypted; 5734 5735 break; 5736 } 5737 5738 case DPROV_REQ_ENCRYPT_MAC_FINAL: 5739 cipher_data = *((crypto_data_t *)dual_data); 5740 5741 /* do an encrypt final */ 5742 if ((error = crypto_encrypt_final(DPROV_CTX_DUAL_CIPHER(ctx), 5743 taskq_req->dr_cipher_mac_req.mr_data == NULL ? 5744 &cipher_data : taskq_req->dr_cipher_mac_req.mr_data, 5745 NULL)) != CRYPTO_SUCCESS) 5746 break; 5747 5748 /* 5749 * If ciphertext length is different from zero, do a mac 5750 * update on it. This does not apply to in-place since we 5751 * do not allow partial updates, hence no final residual. 5752 */ 5753 if (taskq_req->dr_cipher_mac_req.mr_data != NULL && 5754 taskq_req->dr_cipher_mac_req.mr_data->cd_length > 0) 5755 if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx), 5756 taskq_req->dr_cipher_mac_req.mr_data, NULL)) != 5757 CRYPTO_SUCCESS) 5758 break; 5759 5760 /* do a mac final */ 5761 error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx), 5762 taskq_req->dr_cipher_mac_req.mr_mac, NULL); 5763 5764 if (error != CRYPTO_BUFFER_TOO_SMALL) { 5765 DPROV_CTX_DUAL_CIPHER(ctx) = NULL; 5766 DPROV_CTX_DUAL_MAC(ctx) = NULL; 5767 (void) dprov_free_context(ctx); 5768 } 5769 break; 5770 5771 case DPROV_REQ_ENCRYPT_MAC_ATOMIC: { 5772 crypto_data_t *plaintext_tmp, *ciphertext_tmp; 5773 boolean_t inplace; 5774 5775 cipher_data = *((crypto_data_t *)dual_data); 5776 5777 /* do an encrypt atomic */ 5778 inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL); 5779 if (inplace) { 5780 plaintext_tmp = &cipher_data; 5781 ciphertext_tmp = NULL; 5782 } else { 5783 plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data; 5784 ciphertext_tmp = &cipher_data; 5785 } 5786 5787 /* structure assignment */ 5788 cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech; 5789 mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech; 5790 session_id = taskq_req->dr_cipher_mac_req.mr_session_id; 5791 5792 /* get the keys values and providers to use for operations */ 5793 if ((error = dprov_cipher_mac_key_pd(softc, session_id, 5794 taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd, 5795 &cipher_mech.cm_type, &mac_mech.cm_type)) != 5796 CRYPTO_SUCCESS) 5797 break; 5798 5799 /* do the atomic encrypt */ 5800 if ((error = crypto_encrypt_prov(cipher_pd, 0, 5801 &cipher_mech, plaintext_tmp, &cipher_key, NULL, 5802 ciphertext_tmp, NULL)) != CRYPTO_SUCCESS) 5803 break; 5804 5805 /* do the atomic mac */ 5806 mac_data = cipher_data; 5807 mac_data.cd_length = dual_data->dd_len2; 5808 mac_data.cd_offset = dual_data->dd_offset2; 5809 error = crypto_mac_prov(mac_pd, 0, &mac_mech, &mac_data, 5810 &mac_key, NULL, taskq_req->dr_cipher_mac_req.mr_mac, NULL); 5811 5812 dual_data->dd_len1 = cipher_data.cd_length; 5813 5814 break; 5815 } 5816 5817 case DPROV_REQ_MAC_DECRYPT: { 5818 uint_t decrypted; 5819 crypto_data_t plaintext_tmp; 5820 5821 cipher_data = *((crypto_data_t *)dual_data); 5822 5823 /* do a mac update and final on the ciphertext */ 5824 if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx), 5825 &mac_data, NULL)) != CRYPTO_SUCCESS) 5826 break; 5827 5828 /* do a mac final */ 5829 if ((error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx), 5830 taskq_req->dr_cipher_mac_req.mr_mac, NULL)) != 5831 CRYPTO_SUCCESS) 5832 break; 5833 5834 /* do an decrypt update */ 5835 cipher_data = mac_data; 5836 cipher_data.cd_length = dual_data->dd_len2; 5837 cipher_data.cd_offset = dual_data->dd_offset2; 5838 if (taskq_req->dr_cipher_mac_req.mr_data == NULL) 5839 /* in-place */ 5840 plaintext_tmp = cipher_data; 5841 else 5842 plaintext_tmp = *taskq_req->dr_cipher_mac_req.mr_data; 5843 5844 if ((error = crypto_decrypt_update(DPROV_CTX_DUAL_CIPHER(ctx), 5845 &cipher_data, taskq_req->dr_cipher_mac_req.mr_data, 5846 NULL)) != CRYPTO_SUCCESS) 5847 break; 5848 5849 /* do an decrypt final */ 5850 if (taskq_req->dr_cipher_mac_req.mr_data == NULL) 5851 /* in-place, everything must have been decrypted */ 5852 decrypted = cipher_data.cd_length; 5853 else 5854 decrypted = 5855 taskq_req->dr_cipher_mac_req.mr_data->cd_length; 5856 plaintext_tmp.cd_offset += decrypted; 5857 plaintext_tmp.cd_length -= decrypted; 5858 5859 error = crypto_decrypt_final(DPROV_CTX_DUAL_CIPHER(ctx), 5860 &plaintext_tmp, NULL); 5861 if (taskq_req->dr_cipher_mac_req.mr_data != NULL) 5862 taskq_req->dr_cipher_mac_req.mr_data->cd_length += 5863 plaintext_tmp.cd_length; 5864 5865 if (error != CRYPTO_BUFFER_TOO_SMALL) { 5866 DPROV_CTX_DUAL_MAC(ctx) = NULL; 5867 DPROV_CTX_DUAL_CIPHER(ctx) = NULL; 5868 (void) dprov_free_context(ctx); 5869 } 5870 break; 5871 } 5872 5873 case DPROV_REQ_MAC_DECRYPT_UPDATE: 5874 cipher_data = *((crypto_data_t *)dual_data); 5875 5876 /* do mac update */ 5877 if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx), 5878 &cipher_data, NULL)) != CRYPTO_SUCCESS) 5879 break; 5880 5881 /* do a decrypt update */ 5882 cipher_data.cd_length = dual_data->dd_len2; 5883 cipher_data.cd_offset = dual_data->dd_offset2; 5884 error = crypto_decrypt_update(DPROV_CTX_DUAL_CIPHER(ctx), 5885 &cipher_data, taskq_req->dr_cipher_mac_req.mr_data, NULL); 5886 5887 break; 5888 5889 case DPROV_REQ_MAC_DECRYPT_FINAL: 5890 /* do a mac final */ 5891 if ((error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx), 5892 taskq_req->dr_cipher_mac_req.mr_mac, NULL)) != 5893 CRYPTO_SUCCESS) 5894 break; 5895 5896 /* do a decrypt final */ 5897 error = crypto_decrypt_final(DPROV_CTX_DUAL_CIPHER(ctx), 5898 taskq_req->dr_cipher_mac_req.mr_data, NULL); 5899 5900 if (error != CRYPTO_BUFFER_TOO_SMALL) { 5901 DPROV_CTX_DUAL_MAC(ctx) = NULL; 5902 DPROV_CTX_DUAL_CIPHER(ctx) = NULL; 5903 (void) dprov_free_context(ctx); 5904 } 5905 break; 5906 5907 case DPROV_REQ_MAC_DECRYPT_ATOMIC: 5908 case DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC: 5909 cipher_data = *((crypto_data_t *)dual_data); 5910 5911 /* structure assignment */ 5912 cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech; 5913 mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech; 5914 session_id = taskq_req->dr_cipher_mac_req.mr_session_id; 5915 5916 /* get the keys values and providers to use for operations */ 5917 if ((error = dprov_cipher_mac_key_pd(softc, session_id, 5918 taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd, 5919 &cipher_mech.cm_type, &mac_mech.cm_type)) != CRYPTO_SUCCESS) 5920 break; 5921 5922 /* do the atomic mac */ 5923 if (taskq_req->dr_type == DPROV_REQ_MAC_DECRYPT_ATOMIC) 5924 error = crypto_mac_prov(mac_pd, 0, &mac_mech, 5925 &cipher_data, &mac_key, NULL, 5926 taskq_req->dr_cipher_mac_req.mr_mac, NULL); 5927 else 5928 /* DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC */ 5929 error = crypto_mac_verify_prov(mac_pd, 0, &mac_mech, 5930 &cipher_data, &mac_key, NULL, 5931 taskq_req->dr_cipher_mac_req.mr_mac, NULL); 5932 5933 if (error != CRYPTO_SUCCESS) 5934 break; 5935 5936 /* do the atomic decrypt */ 5937 cipher_data.cd_length = dual_data->dd_len2; 5938 cipher_data.cd_offset = dual_data->dd_offset2; 5939 error = crypto_decrypt_prov(cipher_pd, 0, &cipher_mech, 5940 &cipher_data, &cipher_key, NULL, 5941 taskq_req->dr_cipher_mac_req.mr_data, NULL); 5942 5943 break; 5944 } 5945 5946 dprov_op_done(taskq_req, error); 5947 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_cipher_mac_task: end\n", 5948 instance)); 5949 } 5950 5951 /* 5952 * taskq dispatcher function for random number generation. 5953 */ 5954 static void 5955 dprov_random_task(dprov_req_t *taskq_req) 5956 { 5957 dprov_state_t *softc; 5958 /* LINTED E_FUNC_SET_NOT_USED */ 5959 int instance; 5960 int error = CRYPTO_SUCCESS; 5961 5962 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 5963 DPROV_DEBUG(D_RANDOM, ("(%d) dprov_random_task: started\n", instance)); 5964 5965 mutex_enter(&softc->ds_lock); 5966 5967 switch (taskq_req->dr_type) { 5968 5969 DPROV_REQ_RANDOM_SEED: 5970 /* 5971 * Since we don't really generate random numbers 5972 * nothing to do. 5973 */ 5974 break; 5975 5976 case DPROV_REQ_RANDOM_GENERATE: { 5977 uint_t i; 5978 uchar_t c = 0; 5979 5980 /* 5981 * We don't generate random numbers so that the result 5982 * of the operation can be checked during testing. 5983 */ 5984 5985 for (i = 0; i < taskq_req->dr_random_req.rr_len; i++) 5986 taskq_req->dr_random_req.rr_buf[i] = c++; 5987 5988 break; 5989 } 5990 } 5991 5992 mutex_exit(&softc->ds_lock); 5993 dprov_op_done(taskq_req, error); 5994 DPROV_DEBUG(D_RANDOM, ("(%d) dprov_random_task: end\n", instance)); 5995 } 5996 5997 5998 /* 5999 * taskq dispatcher function for session management operations. 6000 */ 6001 static void 6002 dprov_session_task(dprov_req_t *taskq_req) 6003 { 6004 dprov_state_t *softc; 6005 /* LINTED E_FUNC_SET_NOT_USED */ 6006 int instance; 6007 int error = CRYPTO_NOT_SUPPORTED; 6008 crypto_session_id_t session_id = 6009 taskq_req->dr_session_req.sr_session_id; 6010 dprov_session_t *session; 6011 dprov_object_t *object; 6012 int i; 6013 6014 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 6015 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_task: started\n", 6016 instance)); 6017 6018 mutex_enter(&softc->ds_lock); 6019 6020 if (taskq_req->dr_type != DPROV_REQ_SESSION_OPEN) 6021 /* validate session id and get ptr to session */ 6022 if ((session = softc->ds_sessions[session_id]) == NULL) { 6023 mutex_exit(&softc->ds_lock); 6024 dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID); 6025 return; 6026 } 6027 6028 switch (taskq_req->dr_type) { 6029 6030 case DPROV_REQ_SESSION_OPEN: { 6031 dprov_session_t **new_sessions; 6032 6033 if (softc->ds_token_initialized == B_FALSE) { 6034 error = CRYPTO_OPERATION_NOT_INITIALIZED; 6035 break; 6036 } 6037 6038 /* search for available session slot */ 6039 for (i = 0; i < softc->ds_sessions_slots; i++) 6040 if (softc->ds_sessions[i] == NULL) 6041 break; 6042 6043 if (i == softc->ds_sessions_slots) { 6044 /* ran out of slots, grow sessions array */ 6045 new_sessions = kmem_zalloc(2 * softc->ds_sessions_slots, 6046 KM_NOSLEEP); 6047 if (new_sessions == NULL) { 6048 error = CRYPTO_SESSION_COUNT; 6049 break; 6050 } 6051 bcopy(softc->ds_sessions, new_sessions, 6052 softc->ds_sessions_slots); 6053 kmem_free(softc->ds_sessions, softc->ds_sessions_slots * 6054 sizeof (dprov_session_t *)); 6055 softc->ds_sessions = new_sessions; 6056 softc->ds_sessions_slots *= 2; 6057 } 6058 6059 /* allocate and initialize new session */ 6060 softc->ds_sessions[i] = kmem_zalloc( 6061 sizeof (dprov_session_t), KM_NOSLEEP); 6062 if (softc->ds_sessions[i] == NULL) { 6063 error = CRYPTO_HOST_MEMORY; 6064 break; 6065 } 6066 softc->ds_sessions_count++; 6067 6068 /* initialize session state */ 6069 softc->ds_sessions[i]->ds_state = DPROV_SESSION_STATE_PUBLIC; 6070 6071 /* return new session id to caller */ 6072 *(taskq_req->dr_session_req.sr_session_id_ptr) = i; 6073 6074 error = CRYPTO_SUCCESS; 6075 break; 6076 } 6077 6078 case DPROV_REQ_SESSION_CLOSE: 6079 softc->ds_sessions[session_id] = NULL; 6080 6081 if (softc->ds_token_initialized == B_FALSE) { 6082 error = CRYPTO_OPERATION_NOT_INITIALIZED; 6083 break; 6084 } 6085 6086 dprov_release_session_objects(session); 6087 6088 /* free session state and corresponding slot */ 6089 kmem_free(session, sizeof (dprov_session_t)); 6090 softc->ds_sessions_count--; 6091 6092 error = CRYPTO_SUCCESS; 6093 break; 6094 6095 case DPROV_REQ_SESSION_LOGIN: { 6096 char *pin = taskq_req->dr_session_req.sr_pin; 6097 size_t pin_len = taskq_req->dr_session_req.sr_pin_len; 6098 crypto_user_type_t user_type = 6099 taskq_req->dr_session_req.sr_user_type; 6100 6101 /* check user type */ 6102 if (user_type != CRYPTO_SO && user_type != CRYPTO_USER) { 6103 error = CRYPTO_USER_TYPE_INVALID; 6104 break; 6105 } 6106 6107 /* check pin length */ 6108 if (pin_len > DPROV_MAX_PIN_LEN) { 6109 error = CRYPTO_PIN_LEN_RANGE; 6110 break; 6111 } 6112 6113 /* check pin */ 6114 if (pin == NULL) { 6115 error = CRYPTO_PIN_INVALID; 6116 break; 6117 } 6118 6119 /* validate PIN state */ 6120 if ((user_type == CRYPTO_SO) && !softc->ds_token_initialized || 6121 (user_type == CRYPTO_USER) && !softc->ds_user_pin_set) { 6122 error = CRYPTO_USER_PIN_NOT_INITIALIZED; 6123 break; 6124 } 6125 6126 if ((user_type == CRYPTO_SO && 6127 softc->ds_sessions[session_id]->ds_state == 6128 DPROV_SESSION_STATE_SO) || 6129 (user_type == CRYPTO_USER && 6130 softc->ds_sessions[session_id]->ds_state == 6131 DPROV_SESSION_STATE_USER)) { 6132 /* SO or user already logged in */ 6133 error = CRYPTO_USER_ALREADY_LOGGED_IN; 6134 break; 6135 } 6136 6137 if (softc->ds_sessions[session_id]->ds_state != 6138 DPROV_SESSION_STATE_PUBLIC) { 6139 /* another user already logged in */ 6140 error = CRYPTO_USER_ANOTHER_ALREADY_LOGGED_IN; 6141 break; 6142 } 6143 6144 /* everything's fine, update session */ 6145 softc->ds_sessions[session_id]->ds_state = 6146 user_type == CRYPTO_SO ? 6147 DPROV_SESSION_STATE_SO : DPROV_SESSION_STATE_USER; 6148 6149 error = CRYPTO_SUCCESS; 6150 break; 6151 } 6152 6153 case DPROV_REQ_SESSION_LOGOUT: 6154 /* fail if not logged in */ 6155 if (softc->ds_sessions[session_id]->ds_state == 6156 DPROV_SESSION_STATE_PUBLIC) { 6157 error = CRYPTO_USER_NOT_LOGGED_IN; 6158 break; 6159 } 6160 6161 /* 6162 * Destroy all private session objects. 6163 * Invalidate handles to all private objects. 6164 */ 6165 for (i = 0; i < DPROV_MAX_OBJECTS; i++) { 6166 object = softc->ds_sessions[session_id]->ds_objects[i]; 6167 if (object != NULL && dprov_object_is_private(object)) { 6168 if (!dprov_object_is_token(object)) 6169 /* It's a session object, free it */ 6170 DPROV_OBJECT_REFRELE(object); 6171 softc->ds_sessions[session_id]->ds_objects[i] = 6172 NULL; 6173 } 6174 } 6175 6176 /* update session state */ 6177 softc->ds_sessions[session_id]->ds_state = 6178 DPROV_SESSION_STATE_PUBLIC; 6179 6180 error = CRYPTO_SUCCESS; 6181 break; 6182 } 6183 6184 mutex_exit(&softc->ds_lock); 6185 dprov_op_done(taskq_req, error); 6186 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_task: end\n", instance)); 6187 } 6188 6189 /* return true if attribute is defined to be a PKCS#11 long */ 6190 static boolean_t 6191 fixed_size_attribute(crypto_attr_type_t type) 6192 { 6193 return (type == DPROV_CKA_CLASS || 6194 type == DPROV_CKA_CERTIFICATE_TYPE || 6195 type == DPROV_CKA_KEY_TYPE || 6196 type == DPROV_HW_FEATURE_TYPE); 6197 } 6198 6199 /* 6200 * Attributes defined to be a PKCS#11 long causes problems for dprov 6201 * because 32-bit applications set the size to 4 and 64-bit applications 6202 * set the size to 8. dprov always stores these fixed-size attributes 6203 * as uint32_t. 6204 */ 6205 static ssize_t 6206 attribute_size(crypto_attr_type_t type, ssize_t len) 6207 { 6208 if (fixed_size_attribute(type)) 6209 return (sizeof (uint32_t)); 6210 6211 return (len); 6212 } 6213 6214 /* 6215 * taskq dispatcher function for object management operations. 6216 */ 6217 static void 6218 dprov_object_task(dprov_req_t *taskq_req) 6219 { 6220 dprov_state_t *softc; 6221 /* LINTED E_FUNC_SET_NOT_USED */ 6222 int instance; 6223 int error = CRYPTO_NOT_SUPPORTED; 6224 crypto_object_id_t object_id = taskq_req->dr_object_req.or_object_id; 6225 crypto_session_id_t session_id = taskq_req->dr_object_req.or_session_id; 6226 crypto_object_attribute_t *template = 6227 taskq_req->dr_object_req.or_template; 6228 uint_t attr_count = taskq_req->dr_object_req.or_attribute_count; 6229 dprov_object_t *object; 6230 dprov_session_t *session; 6231 6232 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 6233 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_task: started\n", instance)); 6234 6235 mutex_enter(&softc->ds_lock); 6236 6237 /* validate session id and get ptr to session */ 6238 if ((session = softc->ds_sessions[session_id]) == NULL) { 6239 mutex_exit(&softc->ds_lock); 6240 dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID); 6241 return; 6242 } 6243 6244 switch (taskq_req->dr_type) { 6245 6246 case DPROV_REQ_OBJECT_CREATE: 6247 /* create the object from the specified template */ 6248 if ((error = dprov_create_object_from_template(softc, session, 6249 template, attr_count, 6250 taskq_req->dr_object_req.or_object_id_ptr, B_TRUE, 6251 B_FALSE)) != CRYPTO_SUCCESS) 6252 break; 6253 6254 break; 6255 6256 case DPROV_REQ_OBJECT_COPY: 6257 /* check object id */ 6258 if (object_id >= DPROV_MAX_OBJECTS || 6259 (object = session->ds_objects[object_id]) == NULL) { 6260 error = CRYPTO_OBJECT_HANDLE_INVALID; 6261 break; 6262 } 6263 6264 /* 6265 * Create a new object from the object passed as 6266 * argument. 6267 */ 6268 if ((error = dprov_create_object_from_template(softc, session, 6269 object->do_attr, DPROV_MAX_ATTR, 6270 taskq_req->dr_object_req.or_object_id_ptr, B_TRUE, 6271 B_FALSE)) != CRYPTO_SUCCESS) 6272 break; 6273 6274 /* 6275 * Add the attributes specified by the template to the 6276 * newly created object, replacing existing ones if needed. 6277 */ 6278 error = dprov_object_set_attr(session, 6279 *taskq_req->dr_object_req.or_object_id_ptr, 6280 taskq_req->dr_object_req.or_template, 6281 taskq_req->dr_object_req.or_attribute_count, B_TRUE); 6282 6283 break; 6284 6285 case DPROV_REQ_OBJECT_DESTROY: 6286 /* destroy the object */ 6287 error = dprov_destroy_object(softc, session, 6288 taskq_req->dr_object_req.or_object_id); 6289 6290 break; 6291 6292 case DPROV_REQ_OBJECT_GET_SIZE: 6293 /* get ptr to object */ 6294 if (object_id >= DPROV_MAX_OBJECTS || 6295 session->ds_objects[object_id] == NULL) { 6296 error = CRYPTO_OBJECT_HANDLE_INVALID; 6297 break; 6298 } 6299 6300 /* 6301 * The PKCS11 specification does not specifies what 6302 * the object size really is, here we just return 6303 * the number of possible attributes of the object. 6304 */ 6305 *taskq_req->dr_object_req.or_object_size = DPROV_MAX_ATTR; 6306 6307 error = CRYPTO_SUCCESS; 6308 break; 6309 6310 case DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE: { 6311 crypto_attr_type_t type; 6312 size_t olen, tlen; 6313 offset_t offset; 6314 int tmpl_idx; 6315 int object_idx; 6316 ulong_t class = DPROV_CKO_DATA; 6317 boolean_t extractable = B_TRUE; 6318 6319 error = CRYPTO_SUCCESS; 6320 6321 /* get ptr to object */ 6322 if (object_id >= DPROV_MAX_OBJECTS || 6323 (object = session->ds_objects[object_id]) == NULL) { 6324 error = CRYPTO_OBJECT_HANDLE_INVALID; 6325 break; 6326 } 6327 6328 (void) dprov_get_object_attr_boolean(object, 6329 DPROV_CKA_EXTRACTABLE, &extractable); 6330 6331 (void) dprov_get_object_attr_ulong(object, 6332 DPROV_CKA_CLASS, &class); 6333 6334 /* return the specified attributes, when possible */ 6335 for (tmpl_idx = 0; tmpl_idx < attr_count; tmpl_idx++) { 6336 /* 6337 * Attribute can't be revealed if the CKA_EXTRACTABLE 6338 * attribute is set to false. 6339 */ 6340 type = template[tmpl_idx].oa_type; 6341 if (!extractable && class == DPROV_CKO_SECRET_KEY) { 6342 if (type == DPROV_CKA_VALUE) { 6343 template[tmpl_idx].oa_value_len = -1; 6344 error = CRYPTO_ATTRIBUTE_SENSITIVE; 6345 continue; 6346 } 6347 } 6348 if (!extractable && class == DPROV_CKO_PRIVATE_KEY) { 6349 if (type == DPROV_CKA_PRIVATE_EXPONENT) { 6350 template[tmpl_idx].oa_value_len = -1; 6351 error = CRYPTO_ATTRIBUTE_SENSITIVE; 6352 continue; 6353 } 6354 } 6355 6356 object_idx = dprov_find_attr(object->do_attr, 6357 DPROV_MAX_ATTR, type); 6358 if (object_idx == -1) { 6359 /* attribute not found in object */ 6360 template[tmpl_idx].oa_value_len = -1; 6361 error = CRYPTO_ATTRIBUTE_TYPE_INVALID; 6362 continue; 6363 } 6364 6365 tlen = template[tmpl_idx].oa_value_len; 6366 olen = object->do_attr[object_idx].oa_value_len; 6367 /* return attribute length */ 6368 if (template[tmpl_idx].oa_value == NULL) { 6369 /* 6370 * The size of the attribute is set by the 6371 * library according to the data model of the 6372 * application, so don't overwrite it with 6373 * dprov's size. 6374 */ 6375 if (!fixed_size_attribute(type)) 6376 template[tmpl_idx].oa_value_len = olen; 6377 continue; 6378 } 6379 6380 if (tlen < olen) { 6381 template[tmpl_idx].oa_value_len = -1; 6382 error = CRYPTO_BUFFER_TOO_SMALL; 6383 continue; 6384 } 6385 6386 /* copy attribute value */ 6387 bzero(template[tmpl_idx].oa_value, tlen); 6388 6389 offset = 0; 6390 #ifdef _BIG_ENDIAN 6391 if (fixed_size_attribute(type)) { 6392 offset = tlen - olen; 6393 } 6394 #endif 6395 bcopy(object->do_attr[object_idx].oa_value, 6396 &template[tmpl_idx].oa_value[offset], olen); 6397 6398 /* don't update length for fixed-size attributes */ 6399 if (!fixed_size_attribute(type)) 6400 template[tmpl_idx].oa_value_len = olen; 6401 } 6402 6403 break; 6404 } 6405 6406 case DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE: 6407 /* 6408 * Add the attributes specified by the template to the 6409 * newly created object, replacing existing ones if needed. 6410 */ 6411 error = dprov_object_set_attr(session, 6412 taskq_req->dr_object_req.or_object_id, 6413 taskq_req->dr_object_req.or_template, 6414 taskq_req->dr_object_req.or_attribute_count, B_TRUE); 6415 6416 break; 6417 6418 case DPROV_REQ_OBJECT_FIND_INIT: { 6419 dprov_find_ctx_t *find_ctx; 6420 int so_idx; /* session object index */ 6421 int to_idx; /* token object index */ 6422 6423 error = CRYPTO_SUCCESS; 6424 /* allocate find context */ 6425 find_ctx = kmem_zalloc(sizeof (dprov_find_ctx_t), KM_SLEEP); 6426 *taskq_req->dr_object_req.or_find_pp = find_ctx; 6427 6428 /* first go through the existing session objects */ 6429 for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++) { 6430 if ((object = session->ds_objects[so_idx]) == NULL) 6431 continue; 6432 6433 /* setting count to zero means find all objects */ 6434 if (attr_count > 0) { 6435 if (!dprov_attributes_match(object, template, 6436 attr_count)) 6437 continue; 6438 } 6439 6440 /* session object attributes matches template */ 6441 find_ctx->fc_ids[find_ctx->fc_nids] = so_idx; 6442 find_ctx->fc_nids++; 6443 } 6444 6445 /* 6446 * Go through the token object. For each token object 6447 * that can be accessed: 6448 * If there was already an session object id assigned 6449 * to that token object, skip it, since it was returned 6450 * during the check of session objects, else, 6451 * assign a new object id for that token object and 6452 * add it to the array of matching objects. 6453 */ 6454 for (to_idx = 0; to_idx < DPROV_MAX_OBJECTS && 6455 error == CRYPTO_SUCCESS; to_idx++) { 6456 if ((object = softc->ds_objects[to_idx]) == NULL) 6457 continue; 6458 6459 /* setting count to zero means find all objects */ 6460 if (attr_count > 0) { 6461 if (!dprov_attributes_match(object, template, 6462 attr_count)) 6463 continue; 6464 } 6465 6466 /* if the the object has been destroyed, skip it */ 6467 if (object->do_destroyed) 6468 continue; 6469 6470 /* skip object if it cannot be accessed from session */ 6471 if (dprov_object_is_private(object) && 6472 session->ds_state != DPROV_SESSION_STATE_USER) 6473 continue; 6474 6475 /* 6476 * Is there already a session object id for this 6477 * token object? 6478 */ 6479 for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++) 6480 if (session->ds_objects[so_idx] != NULL && 6481 session->ds_objects[so_idx]->do_token_idx == 6482 to_idx) 6483 break; 6484 if (so_idx < DPROV_MAX_OBJECTS) 6485 /* object found in session table, skip it */ 6486 continue; 6487 6488 /* find free session slot for this object */ 6489 for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++) 6490 if (session->ds_objects[so_idx] == NULL) 6491 break; 6492 if (so_idx == DPROV_MAX_OBJECTS) { 6493 /* ran out of session objects slots */ 6494 kmem_free(find_ctx, sizeof (dprov_find_ctx_t)); 6495 error = CRYPTO_HOST_MEMORY; 6496 break; 6497 } 6498 6499 /* add object to session objects table */ 6500 session->ds_objects[so_idx] = object; 6501 DPROV_OBJECT_REFHOLD(object); 6502 6503 /* add object to list of objects to return */ 6504 find_ctx->fc_ids[find_ctx->fc_nids] = so_idx; 6505 find_ctx->fc_nids++; 6506 } 6507 6508 break; 6509 } 6510 6511 case DPROV_REQ_OBJECT_FIND: { 6512 crypto_object_id_t *object_ids = 6513 taskq_req->dr_object_req.or_object_id_ptr; 6514 uint_t max_object_count = 6515 taskq_req->dr_object_req.or_max_object_count; 6516 dprov_find_ctx_t *find_ctx = 6517 taskq_req->dr_object_req.or_find_p; 6518 uint_t ret_oid_idx; 6519 6520 /* return the desired number of object ids */ 6521 for (ret_oid_idx = 0; ret_oid_idx < max_object_count && 6522 find_ctx->fc_next < find_ctx->fc_nids; ret_oid_idx++) 6523 object_ids[ret_oid_idx] = 6524 find_ctx->fc_ids[find_ctx->fc_next++]; 6525 6526 *taskq_req->dr_object_req.or_object_count_ptr = ret_oid_idx; 6527 6528 error = CRYPTO_SUCCESS; 6529 break; 6530 } 6531 6532 case DPROV_REQ_OBJECT_FIND_FINAL: 6533 kmem_free(taskq_req->dr_object_req.or_find_p, 6534 sizeof (dprov_find_ctx_t)); 6535 6536 error = CRYPTO_SUCCESS; 6537 break; 6538 } 6539 6540 mutex_exit(&softc->ds_lock); 6541 dprov_op_done(taskq_req, error); 6542 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_task: end\n", instance)); 6543 } 6544 6545 /* 6546 * taskq dispatcher function for key management operations. 6547 */ 6548 static void 6549 dprov_key_task(dprov_req_t *taskq_req) 6550 { 6551 dprov_state_t *softc; 6552 /* LINTED E_FUNC_SET_NOT_USED */ 6553 int instance; 6554 int error = CRYPTO_NOT_SUPPORTED; 6555 kcf_provider_desc_t *pd; 6556 crypto_session_id_t session_id = taskq_req->dr_key_req.kr_session_id; 6557 dprov_session_t *session; 6558 6559 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 6560 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_task: started\n", instance)); 6561 6562 mutex_enter(&softc->ds_lock); 6563 6564 /* validate session id and get ptr to session */ 6565 if ((session = softc->ds_sessions[session_id]) == NULL) { 6566 mutex_exit(&softc->ds_lock); 6567 dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID); 6568 return; 6569 } 6570 6571 switch (taskq_req->dr_type) { 6572 case DPROV_REQ_KEY_GENERATE: { 6573 crypto_mechanism_t *mechp; 6574 crypto_object_id_t *object_id_ptr; 6575 crypto_object_attribute_t *template; 6576 crypto_object_attribute_t attribute; 6577 uint_t attribute_count; 6578 ulong_t key_type = ~0UL, class = ~0UL; 6579 ulong_t value_len; 6580 size_t key_len = 0; 6581 6582 error = CRYPTO_SUCCESS; 6583 6584 template = taskq_req->dr_key_req.kr_template; 6585 attribute_count = taskq_req->dr_key_req.kr_attribute_count; 6586 object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr; 6587 mechp = taskq_req->dr_key_req.kr_mechanism; 6588 6589 /* optional */ 6590 (void) dprov_get_template_attr_ulong(template, attribute_count, 6591 DPROV_CKA_CLASS, &class); 6592 6593 /* optional */ 6594 (void) dprov_get_template_attr_ulong(template, attribute_count, 6595 DPROV_CKA_KEY_TYPE, &key_type); 6596 6597 if (class != ~0UL && class != DPROV_CKO_SECRET_KEY) { 6598 error = CRYPTO_TEMPLATE_INCONSISTENT; 6599 break; 6600 } 6601 6602 switch (mechp->cm_type) { 6603 case DES_KEY_GEN_MECH_INFO_TYPE: 6604 if (key_type != ~0UL && key_type != DPROV_CKK_DES) { 6605 error = CRYPTO_TEMPLATE_INCONSISTENT; 6606 break; 6607 } 6608 key_len = DES_KEY_LEN; 6609 key_type = DPROV_CKK_DES; 6610 break; 6611 6612 case DES3_KEY_GEN_MECH_INFO_TYPE: 6613 if (key_type != ~0UL && key_type != DPROV_CKK_DES3) { 6614 error = CRYPTO_TEMPLATE_INCONSISTENT; 6615 break; 6616 } 6617 key_len = DES3_KEY_LEN; 6618 key_type = DPROV_CKK_DES3; 6619 break; 6620 6621 case AES_KEY_GEN_MECH_INFO_TYPE: 6622 if (key_type != ~0UL && key_type != DPROV_CKK_AES) { 6623 error = CRYPTO_TEMPLATE_INCONSISTENT; 6624 break; 6625 } 6626 if (dprov_get_template_attr_ulong(template, 6627 attribute_count, DPROV_CKA_VALUE_LEN, 6628 &value_len) != CRYPTO_SUCCESS) { 6629 error = CRYPTO_TEMPLATE_INCOMPLETE; 6630 break; 6631 } 6632 if (value_len >= AES_MAX_KEY_LEN) { 6633 error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 6634 break; 6635 } 6636 key_len = value_len; 6637 key_type = DPROV_CKK_AES; 6638 break; 6639 6640 case BLOWFISH_KEY_GEN_MECH_INFO_TYPE: 6641 if (key_type != ~0UL && 6642 key_type != DPROV_CKK_BLOWFISH) { 6643 error = CRYPTO_TEMPLATE_INCONSISTENT; 6644 break; 6645 } 6646 if (dprov_get_template_attr_ulong(template, 6647 attribute_count, DPROV_CKA_VALUE_LEN, 6648 &value_len) != CRYPTO_SUCCESS) { 6649 error = CRYPTO_TEMPLATE_INCOMPLETE; 6650 break; 6651 } 6652 if (value_len >= BLOWFISH_MAX_KEY_LEN) { 6653 error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 6654 break; 6655 } 6656 key_len = value_len; 6657 key_type = DPROV_CKK_BLOWFISH; 6658 break; 6659 6660 case RC4_KEY_GEN_MECH_INFO_TYPE: 6661 if (key_type != ~0UL && key_type != DPROV_CKK_RC4) { 6662 error = CRYPTO_TEMPLATE_INCONSISTENT; 6663 break; 6664 } 6665 if (dprov_get_template_attr_ulong(template, 6666 attribute_count, DPROV_CKA_VALUE_LEN, 6667 &value_len) != CRYPTO_SUCCESS) { 6668 error = CRYPTO_TEMPLATE_INCOMPLETE; 6669 break; 6670 } 6671 if (value_len >= 6672 CRYPTO_BITS2BYTES(ARCFOUR_MAX_KEY_BITS)) { 6673 error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 6674 break; 6675 } 6676 key_len = value_len; 6677 key_type = DPROV_CKK_RC4; 6678 break; 6679 6680 default: 6681 error = CRYPTO_MECHANISM_INVALID; 6682 } 6683 6684 if (error != CRYPTO_SUCCESS) 6685 break; 6686 6687 error = dprov_create_object_from_template(softc, session, 6688 template, attribute_count, object_id_ptr, B_FALSE, B_TRUE); 6689 6690 if (error != CRYPTO_SUCCESS) 6691 break; 6692 6693 /* make sure class is set */ 6694 attribute.oa_type = DPROV_CKA_CLASS; 6695 attribute.oa_value = (char *)&class; 6696 attribute.oa_value_len = sizeof (ulong_t); 6697 error = dprov_object_set_attr(session, *object_id_ptr, 6698 &attribute, 1, B_FALSE); 6699 6700 if (error != CRYPTO_SUCCESS) { 6701 goto destroy_object; 6702 } 6703 6704 /* make sure key_type is set */ 6705 attribute.oa_type = DPROV_CKA_KEY_TYPE; 6706 attribute.oa_value = (char *)&key_type; 6707 attribute.oa_value_len = sizeof (ulong_t); 6708 error = dprov_object_set_attr(session, *object_id_ptr, 6709 &attribute, 1, B_FALSE); 6710 6711 if (error != CRYPTO_SUCCESS) { 6712 goto destroy_object; 6713 } 6714 6715 attribute.oa_type = DPROV_CKA_VALUE; 6716 attribute.oa_value = kmem_alloc(key_len, KM_SLEEP); 6717 attribute.oa_value_len = key_len; 6718 6719 if (random_get_pseudo_bytes((uchar_t *)attribute.oa_value, 6720 key_len) != 0) { 6721 bzero(attribute.oa_value, key_len); 6722 kmem_free(attribute.oa_value, key_len); 6723 goto destroy_object; 6724 } 6725 error = dprov_object_set_attr(session, *object_id_ptr, 6726 &attribute, 1, B_FALSE); 6727 6728 bzero(attribute.oa_value, key_len); 6729 kmem_free(attribute.oa_value, key_len); 6730 6731 if (error != CRYPTO_SUCCESS) { 6732 goto destroy_object; 6733 } 6734 break; 6735 6736 destroy_object: 6737 (void) dprov_destroy_object(softc, session, *object_id_ptr); 6738 break; 6739 } 6740 6741 case DPROV_REQ_KEY_GENERATE_PAIR: { 6742 crypto_mechanism_t *mechp; 6743 crypto_object_id_t *pub_object_id_ptr; 6744 crypto_object_id_t *pri_object_id_ptr; 6745 crypto_object_attribute_t *pub_template; 6746 crypto_object_attribute_t *pri_template; 6747 crypto_object_attribute_t attribute; 6748 uint_t pub_attribute_count; 6749 uint_t pri_attribute_count; 6750 ulong_t pub_key_type = ~0UL, pub_class = ~0UL; 6751 ulong_t pri_key_type = ~0UL, pri_class = ~0UL; 6752 char public_exponent[3] = { 6753 0x01, 0x00, 0x01 6754 }; 6755 static uchar_t private_exponent[128] = { 6756 0x4a, 0xef, 0xb9, 0x30, 0xa1, 0x44, 0x0a, 0xe0, 6757 0x30, 0xdd, 0xd3, 0x57, 0xc2, 0xb6, 0x6a, 0xba, 6758 0x5f, 0x81, 0xb0, 0x72, 0x55, 0x5b, 0x5b, 0xf3, 6759 0x07, 0xd2, 0x5f, 0x15, 0x87, 0xc0, 0x78, 0x7d, 6760 0x4f, 0x95, 0x09, 0x59, 0xd2, 0x9a, 0x95, 0xc3, 6761 0xcc, 0xdc, 0xf1, 0xa4, 0x60, 0x76, 0xd7, 0xa7, 6762 0xf8, 0x01, 0x13, 0xf8, 0x54, 0xd4, 0xf8, 0x2f, 6763 0xcf, 0x0c, 0x8b, 0x6e, 0xee, 0x34, 0x53, 0x19, 6764 0x14, 0xa6, 0x15, 0x14, 0xaf, 0xb2, 0x28, 0xa1, 6765 0x78, 0x1b, 0x2d, 0x9b, 0x28, 0x52, 0x14, 0xfa, 6766 0x72, 0x2b, 0x81, 0x11, 0xd0, 0x59, 0xde, 0xc6, 6767 0x52, 0x90, 0xa4, 0xae, 0xc9, 0xf1, 0x97, 0xd4, 6768 0x57, 0xbc, 0xe3, 0x90, 0x30, 0xc7, 0xff, 0xe8, 6769 0xd7, 0x2d, 0xd8, 0xef, 0x14, 0x2d, 0x2d, 0x60, 6770 0x54, 0x22, 0x9d, 0x32, 0x36, 0xcf, 0x4f, 0xf7, 6771 0x37, 0xcc, 0x8e, 0x00, 0x85, 0xb1, 0x00, 0x01 6772 }; 6773 6774 static uchar_t modulus[128] = { 6775 0x87, 0xb2, 0x2a, 0x54, 0x63, 0x83, 0x5e, 0x30, 6776 0xdc, 0x73, 0x03, 0xc6, 0x35, 0xf8, 0xa0, 0x25, 6777 0xa5, 0x6e, 0xcc, 0x14, 0xdd, 0x77, 0x2e, 0x80, 6778 0xd1, 0xa3, 0x05, 0x09, 0x1a, 0x2f, 0x88, 0xec, 6779 0xd1, 0x46, 0x92, 0x19, 0x8c, 0x7a, 0xf7, 0x63, 6780 0x28, 0xbf, 0x7a, 0xea, 0x9f, 0xfe, 0x96, 0x0f, 6781 0x80, 0xa1, 0x3e, 0xa6, 0xe1, 0x89, 0x7c, 0x4c, 6782 0x8e, 0x92, 0xdc, 0x6e, 0x69, 0xba, 0x4b, 0x3f, 6783 0x93, 0xc0, 0xaf, 0xbd, 0xbc, 0x81, 0xf2, 0x1e, 6784 0xc0, 0x7d, 0xc3, 0x4c, 0x8f, 0x5f, 0xfe, 0xdc, 6785 0xdb, 0xdb, 0x52, 0x03, 0x94, 0x78, 0x04, 0xa6, 6786 0x78, 0x1f, 0xdd, 0x5e, 0xd8, 0x85, 0x3e, 0x19, 6787 0x54, 0x7c, 0xd5, 0x81, 0xfb, 0x70, 0x69, 0x5d, 6788 0xbf, 0x23, 0x7a, 0xb1, 0xf9, 0x85, 0x6e, 0xc2, 6789 0x0a, 0x4d, 0x81, 0x21, 0xf8, 0xad, 0x71, 0x65, 6790 0xaf, 0xb6, 0x8f, 0xa1, 0xac, 0x46, 0x8a, 0x4d 6791 }; 6792 6793 pub_template = taskq_req->dr_key_req.kr_template; 6794 pub_attribute_count = taskq_req->dr_key_req.kr_attribute_count; 6795 pub_object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr; 6796 pri_template = taskq_req->dr_key_req.kr_private_key_template; 6797 pri_attribute_count = 6798 taskq_req->dr_key_req.kr_private_key_attribute_count; 6799 pri_object_id_ptr = 6800 taskq_req->dr_key_req.kr_private_key_object_id_ptr; 6801 mechp = taskq_req->dr_key_req.kr_mechanism; 6802 6803 error = CRYPTO_SUCCESS; 6804 6805 /* optional */ 6806 (void) dprov_get_template_attr_ulong(pub_template, 6807 pub_attribute_count, DPROV_CKA_CLASS, &pub_class); 6808 6809 /* optional */ 6810 (void) dprov_get_template_attr_ulong(pri_template, 6811 pri_attribute_count, DPROV_CKA_CLASS, &pri_class); 6812 6813 /* optional */ 6814 (void) dprov_get_template_attr_ulong(pub_template, 6815 pub_attribute_count, DPROV_CKA_KEY_TYPE, &pub_key_type); 6816 6817 /* optional */ 6818 (void) dprov_get_template_attr_ulong(pri_template, 6819 pri_attribute_count, DPROV_CKA_KEY_TYPE, &pri_key_type); 6820 6821 if (pub_class != ~0UL && pub_class != DPROV_CKO_PUBLIC_KEY) { 6822 error = CRYPTO_TEMPLATE_INCONSISTENT; 6823 break; 6824 } 6825 6826 if (pri_class != ~0UL && pri_class != DPROV_CKO_PRIVATE_KEY) { 6827 error = CRYPTO_TEMPLATE_INCONSISTENT; 6828 break; 6829 } 6830 6831 switch (mechp->cm_type) { 6832 case RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE: 6833 if (pub_key_type != ~0UL && 6834 pub_key_type != DPROV_CKK_RSA) { 6835 error = CRYPTO_TEMPLATE_INCONSISTENT; 6836 break; 6837 } 6838 pri_key_type = DPROV_CKK_RSA; 6839 6840 if (pri_key_type != ~0UL && 6841 pri_key_type != DPROV_CKK_RSA) { 6842 error = CRYPTO_TEMPLATE_INCONSISTENT; 6843 break; 6844 } 6845 pri_key_type = DPROV_CKK_RSA; 6846 6847 if (pub_class != ~0UL && 6848 pub_class != DPROV_CKO_PUBLIC_KEY) { 6849 error = CRYPTO_TEMPLATE_INCONSISTENT; 6850 break; 6851 } 6852 pub_class = DPROV_CKO_PUBLIC_KEY; 6853 6854 if (pri_class != ~0UL && 6855 pri_class != DPROV_CKO_PRIVATE_KEY) { 6856 error = CRYPTO_TEMPLATE_INCONSISTENT; 6857 break; 6858 } 6859 pri_class = DPROV_CKO_PRIVATE_KEY; 6860 break; 6861 6862 default: 6863 error = CRYPTO_MECHANISM_INVALID; 6864 } 6865 6866 if (error != CRYPTO_SUCCESS) 6867 break; 6868 6869 error = dprov_create_object_from_template(softc, session, 6870 pub_template, pub_attribute_count, pub_object_id_ptr, 6871 B_FALSE, B_TRUE); 6872 6873 if (error != CRYPTO_SUCCESS) 6874 break; 6875 6876 /* make sure class is set */ 6877 attribute.oa_type = DPROV_CKA_CLASS; 6878 attribute.oa_value = (char *)&pub_class; 6879 attribute.oa_value_len = sizeof (ulong_t); 6880 error = dprov_object_set_attr(session, *pub_object_id_ptr, 6881 &attribute, 1, B_FALSE); 6882 6883 if (error != CRYPTO_SUCCESS) { 6884 goto destroy_public_object; 6885 } 6886 6887 /* make sure key_type is set */ 6888 attribute.oa_type = DPROV_CKA_KEY_TYPE; 6889 attribute.oa_value = (char *)&pub_key_type; 6890 attribute.oa_value_len = sizeof (ulong_t); 6891 error = dprov_object_set_attr(session, *pub_object_id_ptr, 6892 &attribute, 1, B_FALSE); 6893 6894 if (error != CRYPTO_SUCCESS) { 6895 goto destroy_public_object; 6896 } 6897 6898 attribute.oa_type = DPROV_CKA_MODULUS; 6899 attribute.oa_value = (char *)modulus; 6900 attribute.oa_value_len = sizeof (modulus); 6901 error = dprov_object_set_attr(session, *pub_object_id_ptr, 6902 &attribute, 1, B_FALSE); 6903 6904 if (error != CRYPTO_SUCCESS) { 6905 goto destroy_public_object; 6906 } 6907 6908 attribute.oa_type = DPROV_CKA_PUBLIC_EXPONENT; 6909 attribute.oa_value = public_exponent; 6910 attribute.oa_value_len = sizeof (public_exponent); 6911 error = dprov_object_set_attr(session, *pub_object_id_ptr, 6912 &attribute, 1, B_FALSE); 6913 6914 if (error != CRYPTO_SUCCESS) { 6915 goto destroy_public_object; 6916 } 6917 6918 error = dprov_create_object_from_template(softc, session, 6919 pri_template, pri_attribute_count, pri_object_id_ptr, 6920 B_FALSE, B_TRUE); 6921 6922 if (error != CRYPTO_SUCCESS) 6923 break; 6924 6925 /* make sure class is set */ 6926 attribute.oa_type = DPROV_CKA_CLASS; 6927 attribute.oa_value = (char *)&pri_class; 6928 attribute.oa_value_len = sizeof (ulong_t); 6929 error = dprov_object_set_attr(session, *pri_object_id_ptr, 6930 &attribute, 1, B_FALSE); 6931 6932 if (error != CRYPTO_SUCCESS) { 6933 goto destroy_private_object; 6934 } 6935 6936 /* make sure key_type is set */ 6937 attribute.oa_type = DPROV_CKA_KEY_TYPE; 6938 attribute.oa_value = (char *)&pri_key_type; 6939 attribute.oa_value_len = sizeof (ulong_t); 6940 error = dprov_object_set_attr(session, *pri_object_id_ptr, 6941 &attribute, 1, B_FALSE); 6942 6943 if (error != CRYPTO_SUCCESS) { 6944 goto destroy_private_object; 6945 } 6946 6947 attribute.oa_type = DPROV_CKA_MODULUS; 6948 attribute.oa_value = (char *)modulus; 6949 attribute.oa_value_len = sizeof (modulus); 6950 error = dprov_object_set_attr(session, *pri_object_id_ptr, 6951 &attribute, 1, B_FALSE); 6952 6953 if (error != CRYPTO_SUCCESS) { 6954 goto destroy_private_object; 6955 } 6956 6957 attribute.oa_type = DPROV_CKA_PRIVATE_EXPONENT; 6958 attribute.oa_value = (char *)private_exponent; 6959 attribute.oa_value_len = sizeof (private_exponent); 6960 error = dprov_object_set_attr(session, *pri_object_id_ptr, 6961 &attribute, 1, B_FALSE); 6962 6963 if (error != CRYPTO_SUCCESS) { 6964 goto destroy_private_object; 6965 } 6966 break; 6967 6968 destroy_private_object: 6969 (void) dprov_destroy_object(softc, session, 6970 *pri_object_id_ptr); 6971 destroy_public_object: 6972 (void) dprov_destroy_object(softc, session, 6973 *pub_object_id_ptr); 6974 6975 break; 6976 } 6977 6978 case DPROV_REQ_KEY_WRAP: { 6979 crypto_mechanism_t mech, *mechp; 6980 crypto_key_t key, *keyp; 6981 crypto_object_id_t object_id; 6982 ulong_t class = DPROV_CKO_DATA; 6983 boolean_t extractable = B_TRUE; 6984 dprov_object_t *object; 6985 int object_idx; 6986 char *plaintext_key; 6987 size_t plaintext_key_len; 6988 crypto_data_t plaintext; 6989 crypto_data_t ciphertext; 6990 size_t *lenp; 6991 6992 mechp = taskq_req->dr_key_req.kr_mechanism; 6993 /* structure assignment */ 6994 mech = *mechp; 6995 6996 /* get wrapping key value */ 6997 if (is_publickey_mech(mech.cm_type)) { 6998 if ((error = dprov_key_attr_asymmetric(softc, 6999 session_id, taskq_req->dr_type, 7000 taskq_req->dr_key_req.kr_key, 7001 &key)) != CRYPTO_SUCCESS) 7002 break; 7003 keyp = &key; 7004 } else { 7005 if ((error = dprov_key_value_secret(softc, 7006 session_id, taskq_req->dr_type, 7007 taskq_req->dr_key_req.kr_key, 7008 &key)) != CRYPTO_SUCCESS) 7009 break; 7010 keyp = &key; 7011 } 7012 7013 /* get the software provider for this mechanism */ 7014 if ((error = dprov_get_sw_prov(mechp, &pd, 7015 &mech.cm_type)) != CRYPTO_SUCCESS) 7016 break; 7017 7018 object_id = *taskq_req->dr_key_req.kr_object_id_ptr; 7019 if (object_id >= DPROV_MAX_OBJECTS) { 7020 error = CRYPTO_KEY_HANDLE_INVALID; 7021 break; 7022 } 7023 7024 /* get ptr to object */ 7025 if ((object = session->ds_objects[object_id]) == NULL) { 7026 error = CRYPTO_OBJECT_HANDLE_INVALID; 7027 break; 7028 } 7029 7030 (void) dprov_get_object_attr_boolean(object, 7031 DPROV_CKA_EXTRACTABLE, &extractable); 7032 7033 if (!extractable) { 7034 error = CRYPTO_ATTRIBUTE_SENSITIVE; 7035 break; 7036 } 7037 7038 (void) dprov_get_object_attr_ulong(object, 7039 DPROV_CKA_CLASS, &class); 7040 7041 switch (class) { 7042 case DPROV_CKO_SECRET_KEY: 7043 object_idx = dprov_find_attr(object->do_attr, 7044 DPROV_MAX_ATTR, DPROV_CKA_VALUE); 7045 if (object_idx == -1) { 7046 error = CRYPTO_ATTRIBUTE_TYPE_INVALID; 7047 break; 7048 } 7049 break; 7050 7051 case DPROV_CKO_PRIVATE_KEY: 7052 /* 7053 * PKCS#11 says that ASN.1 should be used to encode 7054 * specific attributes before encrypting the blob. 7055 * We only encrypt the private exponent for the 7056 * purpose of testing. 7057 */ 7058 object_idx = dprov_find_attr(object->do_attr, 7059 DPROV_MAX_ATTR, DPROV_CKA_PRIVATE_EXPONENT); 7060 if (object_idx == -1) { 7061 error = CRYPTO_ATTRIBUTE_TYPE_INVALID; 7062 break; 7063 } 7064 break; 7065 default: 7066 error = CRYPTO_KEY_NOT_WRAPPABLE; 7067 break; 7068 } 7069 if (error != CRYPTO_SUCCESS) 7070 break; 7071 7072 plaintext_key = object->do_attr[object_idx].oa_value; 7073 plaintext_key_len = object->do_attr[object_idx].oa_value_len; 7074 lenp = taskq_req->dr_key_req.kr_wrapped_key_len_ptr; 7075 7076 /* session id is 0 for software provider */ 7077 plaintext.cd_format = CRYPTO_DATA_RAW; 7078 plaintext.cd_offset = 0; 7079 plaintext.cd_length = plaintext_key_len; 7080 plaintext.cd_raw.iov_base = plaintext_key; 7081 plaintext.cd_raw.iov_len = plaintext_key_len; 7082 plaintext.cd_miscdata = NULL; 7083 7084 ciphertext.cd_format = CRYPTO_DATA_RAW; 7085 ciphertext.cd_offset = 0; 7086 ciphertext.cd_length = *lenp; 7087 ciphertext.cd_raw.iov_base = 7088 (char *)taskq_req->dr_key_req.kr_wrapped_key; 7089 ciphertext.cd_raw.iov_len = ciphertext.cd_length; 7090 ciphertext.cd_miscdata = NULL; 7091 7092 error = crypto_encrypt_prov(pd, 0, &mech, &plaintext, keyp, 7093 NULL, &ciphertext, NULL); 7094 7095 KCF_PROV_REFRELE(pd); 7096 if (error == CRYPTO_SUCCESS || 7097 error == CRYPTO_BUFFER_TOO_SMALL) { 7098 *lenp = ciphertext.cd_length; 7099 } 7100 break; 7101 } 7102 7103 case DPROV_REQ_KEY_UNWRAP: { 7104 crypto_mechanism_t mech, *mechp; 7105 crypto_key_t key, *keyp; 7106 crypto_object_id_t *object_id_ptr; 7107 ulong_t class = DPROV_CKO_DATA; 7108 uchar_t *wrapped_key; 7109 char *plaintext_buf; 7110 size_t wrapped_key_len; 7111 crypto_data_t plaintext; 7112 crypto_data_t ciphertext; 7113 crypto_object_attribute_t unwrapped_key; 7114 crypto_object_attribute_t *template; 7115 uint_t attribute_count; 7116 7117 template = taskq_req->dr_key_req.kr_template; 7118 attribute_count = taskq_req->dr_key_req.kr_attribute_count; 7119 object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr; 7120 7121 /* all objects must have an object class attribute */ 7122 if (dprov_get_template_attr_ulong(template, attribute_count, 7123 DPROV_CKA_CLASS, &class) != CRYPTO_SUCCESS) { 7124 error = CRYPTO_TEMPLATE_INCOMPLETE; 7125 break; 7126 } 7127 7128 mechp = taskq_req->dr_key_req.kr_mechanism; 7129 /* structure assignment */ 7130 mech = *mechp; 7131 7132 /* get unwrapping key value */ 7133 if (is_publickey_mech(mech.cm_type)) { 7134 if ((error = dprov_key_attr_asymmetric(softc, 7135 session_id, taskq_req->dr_type, 7136 taskq_req->dr_key_req.kr_key, 7137 &key)) != CRYPTO_SUCCESS) 7138 break; 7139 keyp = &key; 7140 } else { 7141 if ((error = dprov_key_value_secret(softc, 7142 session_id, taskq_req->dr_type, 7143 taskq_req->dr_key_req.kr_key, 7144 &key)) != CRYPTO_SUCCESS) 7145 break; 7146 keyp = &key; 7147 } 7148 7149 /* get the software provider for this mechanism */ 7150 if ((error = dprov_get_sw_prov(mechp, &pd, 7151 &mech.cm_type)) != CRYPTO_SUCCESS) 7152 break; 7153 7154 wrapped_key = taskq_req->dr_key_req.kr_wrapped_key; 7155 wrapped_key_len = *taskq_req->dr_key_req.kr_wrapped_key_len_ptr; 7156 ciphertext.cd_format = CRYPTO_DATA_RAW; 7157 ciphertext.cd_offset = 0; 7158 ciphertext.cd_length = wrapped_key_len; 7159 ciphertext.cd_raw.iov_base = (char *)wrapped_key; 7160 ciphertext.cd_raw.iov_len = wrapped_key_len; 7161 ciphertext.cd_miscdata = NULL; 7162 7163 /* 7164 * Plaintext length is less than or equal to 7165 * the length of the ciphertext. 7166 */ 7167 plaintext_buf = kmem_alloc(wrapped_key_len, KM_SLEEP); 7168 plaintext.cd_format = CRYPTO_DATA_RAW; 7169 plaintext.cd_offset = 0; 7170 plaintext.cd_length = wrapped_key_len; 7171 plaintext.cd_raw.iov_base = plaintext_buf; 7172 plaintext.cd_raw.iov_len = wrapped_key_len; 7173 plaintext.cd_miscdata = NULL; 7174 7175 error = crypto_decrypt_prov(pd, 0, &mech, &ciphertext, keyp, 7176 NULL, &plaintext, NULL); 7177 7178 KCF_PROV_REFRELE(pd); 7179 7180 if (error != CRYPTO_SUCCESS) 7181 goto free_unwrapped_key; 7182 7183 error = dprov_create_object_from_template(softc, session, 7184 template, attribute_count, object_id_ptr, B_FALSE, B_FALSE); 7185 7186 if (error != CRYPTO_SUCCESS) 7187 goto free_unwrapped_key; 7188 7189 switch (class) { 7190 case DPROV_CKO_SECRET_KEY: 7191 unwrapped_key.oa_type = DPROV_CKA_VALUE; 7192 unwrapped_key.oa_value_len = plaintext.cd_length; 7193 unwrapped_key.oa_value = plaintext_buf; 7194 break; 7195 case DPROV_CKO_PRIVATE_KEY: 7196 /* 7197 * PKCS#11 says that ASN.1 should be used to encode 7198 * specific attributes before encrypting the blob. 7199 * We only encrypt the private exponent for the 7200 * purpose of testing. 7201 */ 7202 unwrapped_key.oa_type = DPROV_CKA_PRIVATE_EXPONENT; 7203 unwrapped_key.oa_value_len = plaintext.cd_length; 7204 unwrapped_key.oa_value = plaintext_buf; 7205 break; 7206 default: 7207 error = CRYPTO_TEMPLATE_INCONSISTENT; 7208 goto free_unwrapped_key; 7209 } 7210 7211 if ((error = dprov_object_set_attr(session, *object_id_ptr, 7212 &unwrapped_key, 1, B_FALSE)) == CRYPTO_SUCCESS) 7213 break; /* don't free the unwrapped key */ 7214 7215 /* failure */ 7216 (void) dprov_destroy_object(softc, session, *object_id_ptr); 7217 break; 7218 7219 free_unwrapped_key: 7220 bzero(plaintext_buf, wrapped_key_len); 7221 kmem_free(plaintext_buf, wrapped_key_len); 7222 break; 7223 } 7224 7225 case DPROV_REQ_KEY_DERIVE: { 7226 crypto_mechanism_t digest_mech, *mechp; 7227 crypto_key_t key, *base_keyp; 7228 crypto_object_id_t *object_id_ptr; 7229 crypto_data_t data; 7230 crypto_data_t digest; 7231 size_t hash_size; 7232 char *digest_buf; 7233 crypto_object_attribute_t derived_key; 7234 crypto_object_attribute_t *template; 7235 uint_t attribute_count; 7236 ulong_t key_type; 7237 void *value; 7238 size_t value_len = 0; 7239 7240 error = CRYPTO_SUCCESS; 7241 7242 template = taskq_req->dr_key_req.kr_template; 7243 attribute_count = taskq_req->dr_key_req.kr_attribute_count; 7244 object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr; 7245 7246 /* required */ 7247 if (dprov_get_template_attr_ulong(template, attribute_count, 7248 DPROV_CKA_KEY_TYPE, &key_type) != CRYPTO_SUCCESS) { 7249 error = CRYPTO_TEMPLATE_INCOMPLETE; 7250 break; 7251 } 7252 7253 mechp = taskq_req->dr_key_req.kr_mechanism; 7254 /* structure assignment */ 7255 digest_mech = *mechp; 7256 7257 switch (digest_mech.cm_type) { 7258 case SHA1_KEY_DERIVATION_MECH_INFO_TYPE: 7259 hash_size = SHA1_DIGEST_LEN; 7260 digest_mech.cm_type = SHA1_MECH_INFO_TYPE; 7261 break; 7262 7263 case SHA256_KEY_DERIVATION_MECH_INFO_TYPE: 7264 hash_size = SHA256_DIGEST_LENGTH; 7265 digest_mech.cm_type = SHA256_MECH_INFO_TYPE; 7266 break; 7267 7268 case SHA384_KEY_DERIVATION_MECH_INFO_TYPE: 7269 hash_size = SHA384_DIGEST_LENGTH; 7270 digest_mech.cm_type = SHA384_MECH_INFO_TYPE; 7271 break; 7272 7273 case SHA512_KEY_DERIVATION_MECH_INFO_TYPE: 7274 hash_size = SHA512_DIGEST_LENGTH; 7275 digest_mech.cm_type = SHA512_MECH_INFO_TYPE; 7276 break; 7277 7278 case MD5_KEY_DERIVATION_MECH_INFO_TYPE: 7279 hash_size = MD5_DIGEST_LEN; 7280 digest_mech.cm_type = MD5_MECH_INFO_TYPE; 7281 break; 7282 7283 default: 7284 error = CRYPTO_MECHANISM_INVALID; 7285 } 7286 7287 if (error != CRYPTO_SUCCESS) 7288 break; 7289 7290 /* CKA_VALUE is optional */ 7291 (void) dprov_get_template_attr_array(template, attribute_count, 7292 DPROV_CKA_VALUE, &value, &value_len); 7293 7294 /* check for inconsistent value length */ 7295 switch (key_type) { 7296 case DPROV_CKK_GENERIC_SECRET: 7297 if (value_len > 0) { 7298 if (value_len > hash_size) 7299 error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 7300 } else { 7301 value_len = hash_size; 7302 } 7303 break; 7304 7305 case DPROV_CKK_RC4: 7306 case DPROV_CKK_AES: 7307 if (value_len == 0 || 7308 value_len > hash_size) { 7309 error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 7310 } 7311 break; 7312 7313 case DPROV_CKK_DES: 7314 if (value_len > 0 && 7315 value_len != DES_KEY_LEN) { 7316 error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 7317 } 7318 value_len = DES_KEY_LEN; 7319 break; 7320 7321 case DPROV_CKK_DES3: 7322 if (value_len > 0 && 7323 value_len != DES3_KEY_LEN) { 7324 error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 7325 } 7326 value_len = DES3_KEY_LEN; 7327 break; 7328 7329 default: 7330 error = CRYPTO_ATTRIBUTE_VALUE_INVALID; 7331 break; 7332 } 7333 7334 if (error != CRYPTO_SUCCESS) 7335 break; 7336 7337 /* get the software provider for this mechanism */ 7338 if ((error = dprov_get_sw_prov(&digest_mech, &pd, 7339 &digest_mech.cm_type)) != CRYPTO_SUCCESS) 7340 break; 7341 7342 /* get the base key */ 7343 error = dprov_key_value_secret(softc, session_id, 7344 taskq_req->dr_type, taskq_req->dr_key_req.kr_key, &key); 7345 if (error != CRYPTO_SUCCESS) 7346 break; 7347 7348 base_keyp = &key; 7349 7350 data.cd_format = CRYPTO_DATA_RAW; 7351 data.cd_offset = 0; 7352 data.cd_length = CRYPTO_BITS2BYTES(base_keyp->ck_length); 7353 data.cd_raw.iov_base = base_keyp->ck_data; 7354 data.cd_raw.iov_len = data.cd_length; 7355 7356 digest_buf = kmem_alloc(hash_size, KM_SLEEP); 7357 digest.cd_format = CRYPTO_DATA_RAW; 7358 digest.cd_offset = 0; 7359 digest.cd_length = hash_size; 7360 digest.cd_raw.iov_base = digest_buf; 7361 digest.cd_raw.iov_len = hash_size; 7362 7363 error = crypto_digest_prov(pd, 0, &digest_mech, &data, 7364 &digest, NULL); 7365 7366 KCF_PROV_REFRELE(pd); 7367 7368 if (error != CRYPTO_SUCCESS) 7369 goto free_derived_key; 7370 7371 error = dprov_create_object_from_template(softc, session, 7372 template, attribute_count, object_id_ptr, B_FALSE, B_FALSE); 7373 7374 if (error != CRYPTO_SUCCESS) 7375 goto free_derived_key; 7376 7377 derived_key.oa_type = DPROV_CKA_VALUE; 7378 derived_key.oa_value = digest_buf; 7379 derived_key.oa_value_len = value_len; 7380 7381 error = dprov_object_set_attr(session, *object_id_ptr, 7382 &derived_key, 1, B_FALSE); 7383 7384 if (error != CRYPTO_SUCCESS) { 7385 (void) dprov_destroy_object(softc, session, 7386 *object_id_ptr); 7387 } 7388 7389 free_derived_key: 7390 bzero(digest_buf, hash_size); 7391 kmem_free(digest_buf, hash_size); 7392 } 7393 } 7394 7395 mutex_exit(&softc->ds_lock); 7396 dprov_op_done(taskq_req, error); 7397 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_task: end\n", instance)); 7398 } 7399 7400 7401 /* 7402 * taskq dispatcher function for provider management operations. 7403 */ 7404 static void 7405 dprov_mgmt_task(dprov_req_t *taskq_req) 7406 { 7407 dprov_state_t *softc; 7408 /* LINTED E_FUNC_SET_NOT_USED */ 7409 int instance; 7410 int error = CRYPTO_NOT_SUPPORTED; 7411 7412 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance); 7413 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_mgmt_task: started\n", instance)); 7414 7415 mutex_enter(&softc->ds_lock); 7416 7417 switch (taskq_req->dr_type) { 7418 case DPROV_REQ_MGMT_EXTINFO: { 7419 crypto_provider_ext_info_t *ext_info = 7420 taskq_req->dr_mgmt_req.mr_ext_info; 7421 7422 (void) memset(ext_info->ei_label, ' ', CRYPTO_EXT_SIZE_LABEL); 7423 if (!softc->ds_token_initialized) { 7424 bcopy("(not initialized)", ext_info->ei_label, 7425 strlen("(not initialized)")); 7426 } else { 7427 bcopy(softc->ds_label, ext_info->ei_label, 7428 CRYPTO_EXT_SIZE_LABEL); 7429 } 7430 7431 bcopy(DPROV_MANUFACTURER, ext_info->ei_manufacturerID, 7432 CRYPTO_EXT_SIZE_MANUF); 7433 bcopy(DPROV_MODEL, ext_info->ei_model, CRYPTO_EXT_SIZE_MODEL); 7434 7435 (void) snprintf((char *)ext_info->ei_serial_number, 16, "%d%s", 7436 instance, DPROV_ALLSPACES); 7437 /* PKCS#11 blank padding */ 7438 ext_info->ei_serial_number[15] = ' '; 7439 ext_info->ei_max_session_count = CRYPTO_EFFECTIVELY_INFINITE; 7440 ext_info->ei_max_pin_len = (ulong_t)DPROV_MAX_PIN_LEN; 7441 ext_info->ei_min_pin_len = 1; 7442 ext_info->ei_total_public_memory = CRYPTO_EFFECTIVELY_INFINITE; 7443 ext_info->ei_free_public_memory = CRYPTO_EFFECTIVELY_INFINITE; 7444 ext_info->ei_total_private_memory = CRYPTO_EFFECTIVELY_INFINITE; 7445 ext_info->ei_free_private_memory = CRYPTO_EFFECTIVELY_INFINITE; 7446 ext_info->ei_hardware_version.cv_major = 1; 7447 ext_info->ei_hardware_version.cv_minor = 0; 7448 ext_info->ei_firmware_version.cv_major = 1; 7449 ext_info->ei_firmware_version.cv_minor = 0; 7450 7451 ext_info->ei_flags = CRYPTO_EXTF_RNG | 7452 CRYPTO_EXTF_DUAL_CRYPTO_OPERATIONS; 7453 if (softc->ds_user_pin_set) 7454 ext_info->ei_flags |= CRYPTO_EXTF_USER_PIN_INITIALIZED; 7455 if (softc->ds_token_initialized) 7456 ext_info->ei_flags |= CRYPTO_EXTF_TOKEN_INITIALIZED; 7457 7458 error = CRYPTO_SUCCESS; 7459 break; 7460 } 7461 case DPROV_REQ_MGMT_INITTOKEN: { 7462 char *pin = taskq_req->dr_mgmt_req.mr_pin; 7463 size_t pin_len = taskq_req->dr_mgmt_req.mr_pin_len; 7464 char *label = taskq_req->dr_mgmt_req.mr_label; 7465 7466 /* cannot initialize token when a session is open */ 7467 if (softc->ds_sessions_count > 0) { 7468 error = CRYPTO_SESSION_EXISTS; 7469 break; 7470 } 7471 7472 /* check PIN length */ 7473 if (pin_len > DPROV_MAX_PIN_LEN) { 7474 error = CRYPTO_PIN_LEN_RANGE; 7475 break; 7476 } 7477 7478 /* check PIN */ 7479 if (pin == NULL) { 7480 error = CRYPTO_PIN_INVALID; 7481 break; 7482 } 7483 7484 /* 7485 * If the token has already been initialized, need 7486 * to validate supplied PIN. 7487 */ 7488 if (softc->ds_token_initialized && 7489 (softc->ds_so_pin_len != pin_len || 7490 strncmp(softc->ds_so_pin, pin, pin_len) != 0)) { 7491 /* invalid SO PIN */ 7492 error = CRYPTO_PIN_INCORRECT; 7493 break; 7494 } 7495 7496 /* set label */ 7497 bcopy(label, softc->ds_label, CRYPTO_EXT_SIZE_LABEL); 7498 7499 /* set new SO PIN, update state */ 7500 bcopy(pin, softc->ds_so_pin, pin_len); 7501 softc->ds_so_pin_len = pin_len; 7502 softc->ds_token_initialized = B_TRUE; 7503 softc->ds_user_pin_set = B_FALSE; 7504 7505 error = CRYPTO_SUCCESS; 7506 break; 7507 } 7508 case DPROV_REQ_MGMT_INITPIN: { 7509 char *pin = taskq_req->dr_mgmt_req.mr_pin; 7510 size_t pin_len = taskq_req->dr_mgmt_req.mr_pin_len; 7511 crypto_session_id_t session_id = 7512 taskq_req->dr_mgmt_req.mr_session_id; 7513 7514 /* check session id */ 7515 if (softc->ds_sessions[session_id] == NULL) { 7516 error = CRYPTO_SESSION_HANDLE_INVALID; 7517 break; 7518 } 7519 7520 /* fail if not logged in as SO */ 7521 if (softc->ds_sessions[session_id]->ds_state != 7522 DPROV_SESSION_STATE_SO) { 7523 error = CRYPTO_USER_NOT_LOGGED_IN; 7524 break; 7525 } 7526 7527 /* check PIN length */ 7528 if (pin_len > DPROV_MAX_PIN_LEN) { 7529 error = CRYPTO_PIN_LEN_RANGE; 7530 break; 7531 } 7532 7533 /* check PIN */ 7534 if (pin == NULL) { 7535 error = CRYPTO_PIN_INVALID; 7536 break; 7537 } 7538 7539 /* set new normal user PIN */ 7540 bcopy(pin, softc->ds_user_pin, pin_len); 7541 softc->ds_user_pin_len = pin_len; 7542 softc->ds_user_pin_set = B_TRUE; 7543 7544 error = CRYPTO_SUCCESS; 7545 break; 7546 } 7547 case DPROV_REQ_MGMT_SETPIN: { 7548 char *new_pin = taskq_req->dr_mgmt_req.mr_pin; 7549 size_t new_pin_len = taskq_req->dr_mgmt_req.mr_pin_len; 7550 char *old_pin = taskq_req->dr_mgmt_req.mr_old_pin; 7551 size_t old_pin_len = taskq_req->dr_mgmt_req.mr_old_pin_len; 7552 crypto_session_id_t session_id = 7553 taskq_req->dr_mgmt_req.mr_session_id; 7554 7555 /* check session id */ 7556 if (softc->ds_sessions[session_id] == NULL) { 7557 error = CRYPTO_SESSION_HANDLE_INVALID; 7558 break; 7559 } 7560 7561 /* check PIN length */ 7562 if (old_pin_len > DPROV_MAX_PIN_LEN || 7563 new_pin_len > DPROV_MAX_PIN_LEN) { 7564 error = CRYPTO_PIN_LEN_RANGE; 7565 break; 7566 } 7567 7568 /* check PIN */ 7569 if (old_pin == NULL || new_pin == NULL) { 7570 error = CRYPTO_PIN_INVALID; 7571 break; 7572 } 7573 7574 /* check user PIN state */ 7575 if (!softc->ds_user_pin_set) { 7576 error = CRYPTO_USER_PIN_NOT_INITIALIZED; 7577 break; 7578 } 7579 7580 /* 7581 * If the token has already been initialized, need 7582 * to validate supplied PIN. 7583 */ 7584 if (softc->ds_user_pin_len != old_pin_len || 7585 strncmp(softc->ds_user_pin, old_pin, old_pin_len) != 0) { 7586 /* invalid SO PIN */ 7587 error = CRYPTO_PIN_INCORRECT; 7588 break; 7589 } 7590 7591 /* set new PIN */ 7592 bcopy(new_pin, softc->ds_user_pin, new_pin_len); 7593 softc->ds_user_pin_len = new_pin_len; 7594 7595 error = CRYPTO_SUCCESS; 7596 break; 7597 } 7598 } 7599 7600 mutex_exit(&softc->ds_lock); 7601 dprov_op_done(taskq_req, error); 7602 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_mgmt_task: end\n", instance)); 7603 } 7604 7605 /* 7606 * Returns in the location pointed to by pd a pointer to the descriptor 7607 * for the software provider for the specified mechanism. 7608 * The provider descriptor is returned held. Returns one of the CRYPTO_ 7609 * error codes on failure, CRYPTO_SUCCESS on success. 7610 */ 7611 static int 7612 dprov_get_sw_prov(crypto_mechanism_t *mech, kcf_provider_desc_t **pd, 7613 crypto_mech_type_t *provider_mech_type) 7614 { 7615 crypto_mech_type_t kcf_mech_type = CRYPTO_MECH_INVALID; 7616 int i, rv; 7617 7618 /* lookup the KCF mech type associated with our mech type */ 7619 for (i = 0; i < sizeof (dprov_mech_info_tab)/ 7620 sizeof (crypto_mech_info_t); i++) { 7621 if (mech->cm_type == dprov_mech_info_tab[i].cm_mech_number) { 7622 kcf_mech_type = crypto_mech2id_common( 7623 dprov_mech_info_tab[i].cm_mech_name, B_TRUE); 7624 } 7625 } 7626 7627 rv = kcf_get_sw_prov(kcf_mech_type, pd, B_TRUE); 7628 if (rv == CRYPTO_SUCCESS) 7629 *provider_mech_type = kcf_mech_type; 7630 7631 return (rv); 7632 } 7633 7634 /* 7635 * Object management helper functions. 7636 */ 7637 7638 /* 7639 * Given a crypto_key_t, return whether the key can be used or not 7640 * for the specified request. The attributes used here are defined 7641 * in table 42 of the PKCS#11 spec (Common secret key attributes). 7642 */ 7643 static int 7644 dprov_key_can_use(dprov_object_t *object, dprov_req_type_t req_type) 7645 { 7646 boolean_t ret = 0; 7647 int rv = CRYPTO_SUCCESS; 7648 7649 /* check if object is allowed for specified operation */ 7650 switch (req_type) { 7651 case DPROV_REQ_ENCRYPT_INIT: 7652 case DPROV_REQ_ENCRYPT_ATOMIC: 7653 rv = dprov_get_object_attr_boolean(object, 7654 DPROV_CKA_ENCRYPT, &ret); 7655 break; 7656 case DPROV_REQ_DECRYPT_INIT: 7657 case DPROV_REQ_DECRYPT_ATOMIC: 7658 rv = dprov_get_object_attr_boolean(object, 7659 DPROV_CKA_DECRYPT, &ret); 7660 break; 7661 case DPROV_REQ_SIGN_INIT: 7662 case DPROV_REQ_SIGN_ATOMIC: 7663 case DPROV_REQ_MAC_INIT: 7664 case DPROV_REQ_MAC_ATOMIC: 7665 case DPROV_REQ_MAC_VERIFY_ATOMIC: 7666 rv = dprov_get_object_attr_boolean(object, 7667 DPROV_CKA_SIGN, &ret); 7668 break; 7669 case DPROV_REQ_SIGN_RECOVER_INIT: 7670 case DPROV_REQ_SIGN_RECOVER_ATOMIC: 7671 rv = dprov_get_object_attr_boolean(object, 7672 DPROV_CKA_SIGN_RECOVER, &ret); 7673 break; 7674 case DPROV_REQ_VERIFY_INIT: 7675 case DPROV_REQ_VERIFY_ATOMIC: 7676 rv = dprov_get_object_attr_boolean(object, 7677 DPROV_CKA_VERIFY, &ret); 7678 break; 7679 case DPROV_REQ_VERIFY_RECOVER_INIT: 7680 case DPROV_REQ_VERIFY_RECOVER_ATOMIC: 7681 rv = dprov_get_object_attr_boolean(object, 7682 DPROV_CKA_VERIFY_RECOVER, &ret); 7683 break; 7684 case DPROV_REQ_KEY_WRAP: 7685 rv = dprov_get_object_attr_boolean(object, 7686 DPROV_CKA_WRAP, &ret); 7687 break; 7688 case DPROV_REQ_KEY_UNWRAP: 7689 rv = dprov_get_object_attr_boolean(object, 7690 DPROV_CKA_UNWRAP, &ret); 7691 break; 7692 case DPROV_REQ_DIGEST_KEY: 7693 /* 7694 * There is no attribute to check for; therefore, 7695 * any secret key can be used. 7696 */ 7697 ret = B_TRUE; 7698 rv = CRYPTO_SUCCESS; 7699 break; 7700 case DPROV_REQ_KEY_DERIVE: 7701 rv = dprov_get_object_attr_boolean(object, 7702 DPROV_CKA_DERIVE, &ret); 7703 break; 7704 } 7705 7706 if (rv != CRYPTO_SUCCESS || !ret) 7707 return (CRYPTO_KEY_FUNCTION_NOT_PERMITTED); 7708 7709 return (CRYPTO_SUCCESS); 7710 } 7711 7712 /* 7713 * Given a crypto_key_t corresponding to a secret key (i.e. for 7714 * use with symmetric crypto algorithms) specified in raw format, by 7715 * attribute, or by reference, initialize the ck_data and ck_length 7716 * fields of the ret_key argument so that they specify the key value 7717 * and length. 7718 * 7719 * For a key by value, this function uess the ck_data and ck_length, 7720 * for a key by reference, it looks up the corresponding object and 7721 * returns the appropriate attribute. For a key by attribute, it returns 7722 * the appropriate attribute. The attributes used are CKA_VALUE to retrieve 7723 * the value of the key, and CKA_VALUE_LEN to retrieve its length in bytes. 7724 */ 7725 static int 7726 dprov_key_value_secret(dprov_state_t *softc, crypto_session_id_t session_id, 7727 dprov_req_type_t req_type, crypto_key_t *key, crypto_key_t *ret_key) 7728 { 7729 ulong_t key_type; 7730 int ret = CRYPTO_SUCCESS; 7731 7732 ret_key->ck_format = CRYPTO_KEY_RAW; 7733 7734 switch (key->ck_format) { 7735 7736 case CRYPTO_KEY_RAW: 7737 ret_key->ck_data = key->ck_data; 7738 ret_key->ck_length = key->ck_length; 7739 break; 7740 7741 case CRYPTO_KEY_ATTR_LIST: { 7742 void *value; 7743 size_t len, value_len; 7744 7745 if ((ret = dprov_get_key_attr_ulong(key, DPROV_CKA_KEY_TYPE, 7746 &key_type)) != CRYPTO_SUCCESS) 7747 break; 7748 7749 if ((ret = dprov_get_key_attr_array(key, DPROV_CKA_VALUE, 7750 &value, &len)) != CRYPTO_SUCCESS) 7751 break; 7752 7753 /* 7754 * The length of the array is expressed in bytes. 7755 * Convert to bits now since that's how keys are measured. 7756 */ 7757 len = len << 3; 7758 7759 /* optional */ 7760 if ((dprov_get_key_attr_ulong(key, DPROV_CKA_VALUE_LEN, 7761 &value_len)) == CRYPTO_SUCCESS) { 7762 len = value_len; 7763 } 7764 7765 ret_key->ck_data = value; 7766 ret_key->ck_length = (uint_t)len; 7767 7768 break; 7769 } 7770 7771 case CRYPTO_KEY_REFERENCE: { 7772 dprov_object_t *object; 7773 void *value; 7774 size_t len, value_len; 7775 7776 /* check session id */ 7777 if (softc->ds_sessions[session_id] == NULL) { 7778 ret = CRYPTO_SESSION_HANDLE_INVALID; 7779 break; 7780 } 7781 7782 if (key->ck_obj_id >= DPROV_MAX_OBJECTS) { 7783 ret = CRYPTO_KEY_HANDLE_INVALID; 7784 goto bail; 7785 } 7786 7787 /* check if object id specified by key is valid */ 7788 object = softc->ds_sessions[session_id]-> 7789 ds_objects[key->ck_obj_id]; 7790 if (object == NULL) { 7791 ret = CRYPTO_KEY_HANDLE_INVALID; 7792 goto bail; 7793 } 7794 7795 /* check if object can be used for operation */ 7796 if ((ret = dprov_key_can_use(object, req_type)) != 7797 CRYPTO_SUCCESS) 7798 goto bail; 7799 7800 if ((ret = dprov_get_object_attr_ulong(object, 7801 DPROV_CKA_KEY_TYPE, &key_type)) != CRYPTO_SUCCESS) 7802 goto bail; 7803 7804 if ((ret = dprov_get_object_attr_array(object, 7805 DPROV_CKA_VALUE, &value, &len)) != CRYPTO_SUCCESS) 7806 goto bail; 7807 7808 /* optional */ 7809 if ((dprov_get_object_attr_ulong(object, DPROV_CKA_VALUE_LEN, 7810 &value_len)) == CRYPTO_SUCCESS) { 7811 len = value_len; 7812 } 7813 7814 /* 7815 * The length of attributes are in bytes. 7816 * Convert to bits now since that's how keys are measured. 7817 */ 7818 len = len << 3; 7819 7820 ret_key->ck_data = value; 7821 ret_key->ck_length = (uint_t)len; 7822 bail: 7823 break; 7824 } 7825 7826 default: 7827 ret = CRYPTO_ARGUMENTS_BAD; 7828 break; 7829 } 7830 7831 return (ret); 7832 } 7833 7834 /* 7835 * Get the attribute list for the specified asymmetric key. 7836 */ 7837 static int 7838 dprov_key_attr_asymmetric(dprov_state_t *softc, crypto_session_id_t session_id, 7839 dprov_req_type_t req_type, crypto_key_t *key, crypto_key_t *ret_key) 7840 { 7841 int ret = CRYPTO_SUCCESS; 7842 7843 ret_key->ck_format = CRYPTO_KEY_ATTR_LIST; 7844 7845 switch (key->ck_format) { 7846 7847 case CRYPTO_KEY_ATTR_LIST: 7848 ret_key->ck_attrs = key->ck_attrs; 7849 ret_key->ck_count = key->ck_count; 7850 break; 7851 7852 case CRYPTO_KEY_REFERENCE: { 7853 dprov_object_t *object; 7854 7855 /* check session id */ 7856 if (softc->ds_sessions[session_id] == NULL) { 7857 ret = CRYPTO_SESSION_HANDLE_INVALID; 7858 break; 7859 } 7860 7861 /* check if object id specified by key is valid */ 7862 object = softc->ds_sessions[session_id]-> 7863 ds_objects[key->ck_obj_id]; 7864 if (object == NULL) { 7865 ret = CRYPTO_KEY_HANDLE_INVALID; 7866 break; 7867 } 7868 7869 /* check if object can be used for operation */ 7870 if ((ret = dprov_key_can_use(object, req_type)) != 7871 CRYPTO_SUCCESS) 7872 break; 7873 7874 ret_key->ck_attrs = object->do_attr; 7875 ret_key->ck_count = DPROV_MAX_ATTR; 7876 break; 7877 } 7878 7879 default: 7880 ret = CRYPTO_ARGUMENTS_BAD; 7881 } 7882 7883 return (ret); 7884 } 7885 7886 /* 7887 * Return the index of an attribute of specified type found in 7888 * the specified array of attributes. If the attribute cannot 7889 * found, return -1. 7890 */ 7891 static int 7892 dprov_find_attr(crypto_object_attribute_t *attr, uint_t nattr, 7893 uint64_t attr_type) 7894 { 7895 int i; 7896 7897 for (i = 0; i < nattr; i++) 7898 if (attr[i].oa_value != NULL && 7899 attr[i].oa_type == attr_type) 7900 return (i); 7901 7902 return (-1); 7903 } 7904 7905 /* 7906 * Given the given object template and session, return whether 7907 * an object can be created from that template according to the 7908 * following rules: 7909 * - private objects can be created only by a logged-in user 7910 */ 7911 static int 7912 dprov_template_can_create(dprov_session_t *session, 7913 crypto_object_attribute_t *template, uint_t nattr, 7914 boolean_t check_for_secret) 7915 { 7916 boolean_t is_private = B_FALSE; 7917 ulong_t key_type, class; 7918 int error; 7919 7920 /* check CKA_PRIVATE attribute value */ 7921 error = dprov_get_template_attr_boolean(template, nattr, 7922 DPROV_CKA_PRIVATE, &is_private); 7923 if (error == CRYPTO_SUCCESS && is_private) { 7924 /* it's a private object */ 7925 if (session->ds_state != DPROV_SESSION_STATE_USER) { 7926 /* 7927 * Cannot create private object with SO or public 7928 * sessions. 7929 */ 7930 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 7931 } 7932 } 7933 7934 /* all objects must have an object class attribute */ 7935 if (dprov_get_template_attr_ulong(template, nattr, DPROV_CKA_CLASS, 7936 &class) != CRYPTO_SUCCESS) { 7937 return (CRYPTO_TEMPLATE_INCOMPLETE); 7938 } 7939 7940 /* key objects must have a key type attribute */ 7941 if (class == DPROV_CKO_SECRET_KEY || 7942 class == DPROV_CKO_PUBLIC_KEY || 7943 class == DPROV_CKO_PRIVATE_KEY) { 7944 if (!dprov_template_attr_present(template, nattr, 7945 DPROV_CKA_KEY_TYPE)) { 7946 return (CRYPTO_TEMPLATE_INCOMPLETE); 7947 } 7948 } 7949 7950 /* check for RSA public key attributes that must be present */ 7951 if (class == DPROV_CKO_PUBLIC_KEY) { 7952 if (dprov_get_template_attr_ulong(template, nattr, 7953 DPROV_CKA_KEY_TYPE, &key_type) == CRYPTO_SUCCESS) { 7954 if (key_type == DPROV_CKK_RSA) { 7955 if (!dprov_template_attr_present(template, 7956 nattr, DPROV_CKA_MODULUS) || 7957 !dprov_template_attr_present(template, 7958 nattr, DPROV_CKA_PUBLIC_EXPONENT)) { 7959 return (CRYPTO_TEMPLATE_INCOMPLETE); 7960 } 7961 7962 /* these attributes should not be present */ 7963 if (dprov_template_attr_present(template, nattr, 7964 DPROV_CKA_MODULUS_BITS)) { 7965 return (CRYPTO_TEMPLATE_INCONSISTENT); 7966 } 7967 } 7968 } 7969 } 7970 7971 /* check for RSA private key attributes that must be present */ 7972 if (class == DPROV_CKO_PRIVATE_KEY) { 7973 if (dprov_get_template_attr_ulong(template, nattr, 7974 DPROV_CKA_KEY_TYPE, &key_type) == CRYPTO_SUCCESS) { 7975 if (key_type == DPROV_CKK_RSA) { 7976 if (!dprov_template_attr_present(template, 7977 nattr, DPROV_CKA_MODULUS)) 7978 return (CRYPTO_TEMPLATE_INCOMPLETE); 7979 7980 if (check_for_secret) { 7981 if (!dprov_template_attr_present( 7982 template, nattr, 7983 DPROV_CKA_PRIVATE_EXPONENT)) 7984 return ( 7985 CRYPTO_TEMPLATE_INCOMPLETE); 7986 } 7987 } 7988 } 7989 } 7990 7991 /* check for secret key attributes that must be present */ 7992 if (class == DPROV_CKO_SECRET_KEY) { 7993 if (check_for_secret) { 7994 if (!dprov_template_attr_present(template, nattr, 7995 DPROV_CKA_VALUE)) { 7996 return (CRYPTO_TEMPLATE_INCOMPLETE); 7997 } 7998 } 7999 8000 /* these attributes should not be present */ 8001 if (dprov_template_attr_present(template, nattr, 8002 DPROV_CKA_VALUE_LEN)) { 8003 return (CRYPTO_TEMPLATE_INCONSISTENT); 8004 } 8005 } 8006 8007 return (CRYPTO_SUCCESS); 8008 } 8009 8010 /* 8011 * Create an object from the specified template. Checks whether the 8012 * object can be created according to its attributes and the state 8013 * of the session. The new session object id is returned. If the 8014 * object is a token object, it is added to the per-instance object 8015 * table as well. 8016 */ 8017 static int 8018 dprov_create_object_from_template(dprov_state_t *softc, 8019 dprov_session_t *session, crypto_object_attribute_t *template, 8020 uint_t nattr, crypto_object_id_t *object_id, boolean_t check_for_secret, 8021 boolean_t force) 8022 { 8023 dprov_object_t *object; 8024 boolean_t is_token = B_FALSE; 8025 boolean_t extractable_attribute_present = B_FALSE; 8026 boolean_t private_attribute_present = B_FALSE; 8027 uint_t i; 8028 int error; 8029 uint_t attr; 8030 uint_t oattr; 8031 crypto_attr_type_t type; 8032 size_t old_len, new_len; 8033 offset_t offset; 8034 8035 if (nattr > DPROV_MAX_ATTR) 8036 return (CRYPTO_HOST_MEMORY); 8037 8038 if (!force) { 8039 /* verify that object can be created */ 8040 if ((error = dprov_template_can_create(session, template, 8041 nattr, check_for_secret)) != CRYPTO_SUCCESS) 8042 return (error); 8043 } 8044 8045 /* allocate new object */ 8046 object = kmem_zalloc(sizeof (dprov_object_t), KM_SLEEP); 8047 if (object == NULL) 8048 return (CRYPTO_HOST_MEMORY); 8049 8050 /* is it a token object? */ 8051 /* check CKA_TOKEN attribute value */ 8052 error = dprov_get_template_attr_boolean(template, nattr, 8053 DPROV_CKA_TOKEN, &is_token); 8054 if (error == CRYPTO_SUCCESS && is_token) { 8055 /* token object, add it to the per-instance object table */ 8056 for (i = 0; i < DPROV_MAX_OBJECTS; i++) 8057 if (softc->ds_objects[i] == NULL) 8058 break; 8059 if (i == DPROV_MAX_OBJECTS) 8060 /* no free slot */ 8061 return (CRYPTO_HOST_MEMORY); 8062 softc->ds_objects[i] = object; 8063 object->do_token_idx = i; 8064 DPROV_OBJECT_REFHOLD(object); 8065 } 8066 8067 /* add object to session object table */ 8068 for (i = 0; i < DPROV_MAX_OBJECTS; i++) 8069 if (session->ds_objects[i] == NULL) 8070 break; 8071 if (i == DPROV_MAX_OBJECTS) { 8072 /* no more session object slots */ 8073 DPROV_OBJECT_REFRELE(object); 8074 return (CRYPTO_HOST_MEMORY); 8075 } 8076 session->ds_objects[i] = object; 8077 DPROV_OBJECT_REFHOLD(object); 8078 *object_id = i; 8079 8080 /* initialize object from template */ 8081 for (attr = 0, oattr = 0; attr < nattr; attr++) { 8082 if (template[attr].oa_value == NULL) 8083 continue; 8084 type = template[attr].oa_type; 8085 old_len = template[attr].oa_value_len; 8086 new_len = attribute_size(type, old_len); 8087 8088 if (type == DPROV_CKA_EXTRACTABLE) { 8089 extractable_attribute_present = B_TRUE; 8090 } else if (type == DPROV_CKA_PRIVATE) { 8091 private_attribute_present = B_TRUE; 8092 } 8093 object->do_attr[oattr].oa_type = type; 8094 object->do_attr[oattr].oa_value_len = new_len; 8095 8096 object->do_attr[oattr].oa_value = kmem_zalloc(new_len, 8097 KM_SLEEP); 8098 8099 offset = 0; 8100 #ifdef _BIG_ENDIAN 8101 if (fixed_size_attribute(type)) { 8102 offset = old_len - new_len; 8103 } 8104 #endif 8105 bcopy(&template[attr].oa_value[offset], 8106 object->do_attr[oattr].oa_value, new_len); 8107 oattr++; 8108 } 8109 8110 /* add boolean attributes that must be present */ 8111 if (extractable_attribute_present == B_FALSE) { 8112 object->do_attr[oattr].oa_type = DPROV_CKA_EXTRACTABLE; 8113 object->do_attr[oattr].oa_value_len = 1; 8114 object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP); 8115 object->do_attr[oattr].oa_value[0] = B_TRUE; 8116 oattr++; 8117 } 8118 8119 if (private_attribute_present == B_FALSE) { 8120 object->do_attr[oattr].oa_type = DPROV_CKA_PRIVATE; 8121 object->do_attr[oattr].oa_value_len = 1; 8122 object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP); 8123 object->do_attr[oattr].oa_value[0] = B_FALSE; 8124 oattr++; 8125 } 8126 8127 return (CRYPTO_SUCCESS); 8128 } 8129 8130 /* 8131 * Checks whether or not the object matches the specified attributes. 8132 * 8133 * PKCS#11 attributes which are longs are stored in uint32_t containers 8134 * so they can be matched by both 32 and 64-bit applications. 8135 */ 8136 static boolean_t 8137 dprov_attributes_match(dprov_object_t *object, 8138 crypto_object_attribute_t *template, uint_t nattr) 8139 { 8140 crypto_attr_type_t type; 8141 size_t tlen, olen, diff; 8142 int ta_idx; /* template attribute index */ 8143 int oa_idx; /* object attribute index */ 8144 8145 for (ta_idx = 0; ta_idx < nattr; ta_idx++) { 8146 /* no value for template attribute */ 8147 if (template[ta_idx].oa_value == NULL) 8148 continue; 8149 8150 /* find attribute in object */ 8151 type = template[ta_idx].oa_type; 8152 oa_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR, type); 8153 8154 if (oa_idx == -1) 8155 /* attribute not found in object */ 8156 return (B_FALSE); 8157 8158 tlen = template[ta_idx].oa_value_len; 8159 olen = object->do_attr[oa_idx].oa_value_len; 8160 if (tlen < olen) 8161 return (B_FALSE); 8162 8163 diff = 0; 8164 #ifdef _BIG_ENDIAN 8165 /* application may think attribute is 8 bytes */ 8166 if (fixed_size_attribute(type)) 8167 diff = tlen - olen; 8168 #endif 8169 8170 if (bcmp(&template[ta_idx].oa_value[diff], 8171 object->do_attr[oa_idx].oa_value, olen) != 0) 8172 /* value mismatch */ 8173 return (B_FALSE); 8174 } 8175 8176 return (B_TRUE); 8177 } 8178 8179 /* 8180 * Destroy the object specified by its session and object id. 8181 */ 8182 static int 8183 dprov_destroy_object(dprov_state_t *softc, dprov_session_t *session, 8184 crypto_object_id_t object_id) 8185 { 8186 dprov_object_t *object; 8187 8188 if ((object = session->ds_objects[object_id]) == NULL) 8189 return (CRYPTO_OBJECT_HANDLE_INVALID); 8190 8191 if (dprov_object_is_token(object)) { 8192 object->do_destroyed = B_TRUE; 8193 /* it's a token object, remove from per-instance table */ 8194 softc->ds_objects[object->do_token_idx] = NULL; 8195 DPROV_OBJECT_REFRELE(object); 8196 } 8197 8198 /* remove from session table */ 8199 session->ds_objects[object_id] = NULL; 8200 DPROV_OBJECT_REFRELE(object); 8201 return (CRYPTO_SUCCESS); 8202 } 8203 8204 static int 8205 dprov_object_can_modify(dprov_object_t *object, 8206 crypto_object_attribute_t *template, uint_t nattr) 8207 { 8208 ulong_t object_class; 8209 8210 /* all objects should have an object class attribute */ 8211 if (dprov_get_object_attr_ulong(object, DPROV_CKA_CLASS, 8212 &object_class) != CRYPTO_SUCCESS) { 8213 return (CRYPTO_SUCCESS); 8214 } 8215 8216 if (object_class == DPROV_CKO_SECRET_KEY || 8217 object_class == DPROV_CKO_PUBLIC_KEY || 8218 object_class == DPROV_CKO_PRIVATE_KEY) { 8219 if (dprov_template_attr_present(template, nattr, 8220 DPROV_CKA_CLASS) || 8221 dprov_template_attr_present(template, nattr, 8222 DPROV_CKA_KEY_TYPE)) 8223 return (CRYPTO_TEMPLATE_INCONSISTENT); 8224 } 8225 8226 switch (object_class) { 8227 case DPROV_CKO_SECRET_KEY: 8228 if (dprov_template_attr_present(template, nattr, 8229 DPROV_CKA_VALUE)) 8230 return (CRYPTO_TEMPLATE_INCONSISTENT); 8231 break; 8232 8233 case DPROV_CKO_PUBLIC_KEY: 8234 if (dprov_template_attr_present(template, nattr, 8235 DPROV_CKA_MODULUS) || 8236 dprov_template_attr_present(template, nattr, 8237 DPROV_CKA_PUBLIC_EXPONENT)) 8238 return (CRYPTO_TEMPLATE_INCONSISTENT); 8239 break; 8240 8241 case DPROV_CKO_PRIVATE_KEY: 8242 if (dprov_template_attr_present(template, nattr, 8243 DPROV_CKA_MODULUS) || 8244 dprov_template_attr_present(template, nattr, 8245 DPROV_CKA_PRIVATE_EXPONENT)) 8246 return (CRYPTO_TEMPLATE_INCONSISTENT); 8247 break; 8248 8249 default: 8250 return (CRYPTO_SUCCESS); 8251 } 8252 8253 return (CRYPTO_SUCCESS); 8254 } 8255 8256 /* 8257 * Set the attributes specified by the template in the specified object, 8258 * replacing existing ones if needed. 8259 */ 8260 static int 8261 dprov_object_set_attr(dprov_session_t *session, crypto_object_id_t object_id, 8262 crypto_object_attribute_t *template, uint_t nattr, 8263 boolean_t check_attributes) 8264 { 8265 crypto_attr_type_t type; 8266 dprov_object_t *object; 8267 size_t old_len, new_len; 8268 uint_t i, j; 8269 int error; 8270 8271 if ((object = session->ds_objects[object_id]) == NULL) 8272 return (CRYPTO_OBJECT_HANDLE_INVALID); 8273 8274 if (check_attributes) { 8275 /* verify that attributes in the template can be modified */ 8276 if ((error = dprov_object_can_modify(object, template, nattr)) 8277 != CRYPTO_SUCCESS) 8278 return (error); 8279 } 8280 8281 /* go through the attributes specified in the template */ 8282 for (i = 0; i < nattr; i++) { 8283 if (template[i].oa_value == NULL) 8284 continue; 8285 8286 /* find attribute in object */ 8287 type = template[i].oa_type; 8288 j = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR, type); 8289 8290 if (j != -1) { 8291 /* attribute already exists, free old value */ 8292 kmem_free(object->do_attr[j].oa_value, 8293 object->do_attr[j].oa_value_len); 8294 } else { 8295 /* attribute does not exist, create it */ 8296 for (j = 0; j < DPROV_MAX_ATTR; j++) 8297 if (object->do_attr[j].oa_value == NULL) 8298 break; 8299 if (j == DPROV_MAX_ATTR) 8300 /* ran out of attribute slots */ 8301 return (CRYPTO_HOST_MEMORY); 8302 } 8303 8304 old_len = template[i].oa_value_len; 8305 new_len = attribute_size(type, old_len); 8306 8307 /* set object attribute value */ 8308 object->do_attr[j].oa_value = kmem_alloc(new_len, KM_SLEEP); 8309 bcopy(&template[i].oa_value[old_len - new_len], 8310 object->do_attr[j].oa_value, new_len); 8311 object->do_attr[j].oa_value_len = new_len; 8312 8313 /* and the type */ 8314 object->do_attr[j].oa_type = type; 8315 } 8316 8317 return (CRYPTO_SUCCESS); 8318 } 8319 8320 8321 /* 8322 * Free the specified object. 8323 */ 8324 static void 8325 dprov_free_object(dprov_object_t *object) 8326 { 8327 int i; 8328 8329 /* free the object attributes values */ 8330 for (i = 0; i < DPROV_MAX_ATTR; i++) 8331 if (object->do_attr[i].oa_value != NULL) 8332 kmem_free(object->do_attr[i].oa_value, 8333 object->do_attr[i].oa_value_len); 8334 8335 /* free the object */ 8336 kmem_free(object, sizeof (dprov_object_t)); 8337 } 8338 8339 /* 8340 * Checks whether the specified object is a private or public object. 8341 */ 8342 static boolean_t 8343 dprov_object_is_private(dprov_object_t *object) 8344 { 8345 boolean_t ret; 8346 int err; 8347 8348 err = dprov_get_object_attr_boolean(object, DPROV_CKA_PRIVATE, &ret); 8349 8350 if (err != CRYPTO_SUCCESS) 8351 /* by default, CKA_PRIVATE is false */ 8352 ret = B_FALSE; 8353 8354 return (ret); 8355 } 8356 8357 /* 8358 * Checks whether the specified object is a token or session object. 8359 */ 8360 static boolean_t 8361 dprov_object_is_token(dprov_object_t *object) 8362 { 8363 boolean_t ret; 8364 int err; 8365 8366 err = dprov_get_object_attr_boolean(object, DPROV_CKA_TOKEN, &ret); 8367 8368 if (err != CRYPTO_SUCCESS) 8369 /* by default, CKA_TOKEN is false */ 8370 ret = B_FALSE; 8371 8372 return (ret); 8373 } 8374 8375 /* 8376 * Common function used by the dprov_get_object_attr_*() family of 8377 * functions. Returns the value of the specified attribute of specified 8378 * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID 8379 * if the length of the attribute does not match the specified length, 8380 * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found. 8381 */ 8382 static int 8383 dprov_get_object_attr_scalar_common(dprov_object_t *object, uint64_t attr_type, 8384 void *value, size_t value_len) 8385 { 8386 int attr_idx; 8387 size_t oa_value_len; 8388 size_t offset = 0; 8389 8390 if ((attr_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR, 8391 attr_type)) == -1) 8392 return (CRYPTO_ARGUMENTS_BAD); 8393 8394 oa_value_len = object->do_attr[attr_idx].oa_value_len; 8395 if (oa_value_len != value_len) { 8396 /* 8397 * For some attributes, it's okay to copy the value 8398 * into a larger container, e.g. copy an unsigned 8399 * 32-bit integer into a 64-bit container. 8400 */ 8401 if (attr_type == DPROV_CKA_VALUE_LEN || 8402 attr_type == DPROV_CKA_KEY_TYPE || 8403 attr_type == DPROV_CKA_CLASS) { 8404 if (oa_value_len < value_len) { 8405 #ifdef _BIG_ENDIAN 8406 offset = value_len - oa_value_len; 8407 #endif 8408 bzero(value, value_len); 8409 goto do_copy; 8410 } 8411 } 8412 /* incorrect attribute value length */ 8413 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 8414 } 8415 8416 do_copy: 8417 bcopy(object->do_attr[attr_idx].oa_value, (uchar_t *)value + offset, 8418 oa_value_len); 8419 8420 return (CRYPTO_SUCCESS); 8421 } 8422 8423 /* 8424 * Get the value of the a boolean attribute from the specified object. 8425 */ 8426 static int 8427 dprov_get_object_attr_boolean(dprov_object_t *object, uint64_t attr_type, 8428 boolean_t *attr_value) 8429 { 8430 uchar_t val; 8431 int ret; 8432 8433 /* PKCS#11 defines a boolean as one byte */ 8434 ret = dprov_get_object_attr_scalar_common(object, attr_type, &val, 1); 8435 if (ret == CRYPTO_SUCCESS) { 8436 *attr_value = (val == '\0') ? B_FALSE : B_TRUE; 8437 } 8438 return (ret); 8439 } 8440 8441 /* 8442 * Get the value of a ulong_t attribute from the specified object. 8443 */ 8444 static int 8445 dprov_get_object_attr_ulong(dprov_object_t *object, uint64_t attr_type, 8446 ulong_t *attr_value) 8447 { 8448 return (dprov_get_object_attr_scalar_common(object, attr_type, 8449 attr_value, sizeof (ulong_t))); 8450 } 8451 8452 /* 8453 * Find the specified byte array attribute of specified type in 8454 * the specified object. Returns CRYPTO_SUCCESS 8455 * on success or CRYPTO_ARGUMENTS_BAD if the specified 8456 * attribute cannot be found. 8457 */ 8458 static int 8459 dprov_get_object_attr_array(dprov_object_t *object, uint64_t attr_type, 8460 void **array, size_t *len) 8461 { 8462 int attr_idx; 8463 8464 if ((attr_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR, 8465 attr_type)) == -1) 8466 return (CRYPTO_ARGUMENTS_BAD); 8467 8468 *array = object->do_attr[attr_idx].oa_value; 8469 *len = object->do_attr[attr_idx].oa_value_len; 8470 8471 return (CRYPTO_SUCCESS); 8472 } 8473 8474 /* 8475 * Common function used by the dprov_get_template_attr_*() family of 8476 * functions. Returns the value of the specified attribute of specified 8477 * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID 8478 * if the length of the attribute does not match the specified length, 8479 * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found. 8480 */ 8481 static int 8482 dprov_get_template_attr_scalar_common(crypto_object_attribute_t *template, 8483 uint_t nattr, uint64_t attr_type, void *value, size_t value_len) 8484 { 8485 size_t oa_value_len; 8486 size_t offset = 0; 8487 int attr_idx; 8488 8489 if ((attr_idx = dprov_find_attr(template, nattr, attr_type)) == -1) 8490 return (CRYPTO_ARGUMENTS_BAD); 8491 8492 oa_value_len = template[attr_idx].oa_value_len; 8493 if (oa_value_len != value_len) { 8494 /* 8495 * For some attributes, it's okay to copy the value 8496 * into a larger container, e.g. copy an unsigned 8497 * 32-bit integer into a 64-bit container. 8498 */ 8499 if (attr_type == DPROV_CKA_VALUE_LEN || 8500 attr_type == DPROV_CKA_KEY_TYPE || 8501 attr_type == DPROV_CKA_CLASS) { 8502 if (oa_value_len < value_len) { 8503 #ifdef _BIG_ENDIAN 8504 offset = value_len - oa_value_len; 8505 #endif 8506 bzero(value, value_len); 8507 goto do_copy; 8508 } 8509 } 8510 /* incorrect attribute value length */ 8511 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 8512 } 8513 8514 do_copy: 8515 bcopy(template[attr_idx].oa_value, (uchar_t *)value + offset, 8516 oa_value_len); 8517 8518 return (CRYPTO_SUCCESS); 8519 } 8520 8521 /* 8522 * Get the value of the a boolean attribute from the specified template 8523 */ 8524 static int 8525 dprov_get_template_attr_boolean(crypto_object_attribute_t *template, 8526 uint_t nattr, uint64_t attr_type, boolean_t *attr_value) 8527 { 8528 uchar_t val; 8529 int ret; 8530 8531 /* PKCS#11 defines a boolean as one byte */ 8532 ret = dprov_get_template_attr_scalar_common(template, nattr, 8533 attr_type, &val, 1); 8534 if (ret == CRYPTO_SUCCESS) { 8535 *attr_value = (val == '\0') ? B_FALSE : B_TRUE; 8536 } 8537 return (ret); 8538 } 8539 8540 /* 8541 * Get the value of a ulong_t attribute from the specified template. 8542 */ 8543 static int 8544 dprov_get_template_attr_ulong(crypto_object_attribute_t *template, 8545 uint_t nattr, uint64_t attr_type, ulong_t *attr_value) 8546 { 8547 return (dprov_get_template_attr_scalar_common(template, nattr, 8548 attr_type, attr_value, sizeof (ulong_t))); 8549 } 8550 8551 static int 8552 dprov_template_attr_present(crypto_object_attribute_t *template, 8553 uint_t nattr, uint64_t attr_type) 8554 { 8555 return (dprov_find_attr(template, nattr, 8556 attr_type) == -1 ? B_FALSE : B_TRUE); 8557 } 8558 8559 /* 8560 * Find the specified byte array attribute of specified type in 8561 * the specified template. Returns CRYPTO_SUCCESS on success or 8562 * CRYPTO_ARGUMENTS_BAD if the specified attribute cannot be found. 8563 */ 8564 static int 8565 dprov_get_template_attr_array(crypto_object_attribute_t *template, 8566 uint_t nattr, uint64_t attr_type, void **array, size_t *len) 8567 { 8568 int attr_idx; 8569 8570 if ((attr_idx = dprov_find_attr(template, nattr, attr_type)) == -1) 8571 return (CRYPTO_ARGUMENTS_BAD); 8572 8573 *array = template[attr_idx].oa_value; 8574 *len = template[attr_idx].oa_value_len; 8575 8576 return (CRYPTO_SUCCESS); 8577 } 8578 8579 /* 8580 * Common function used by the dprov_get_key_attr_*() family of 8581 * functions. Returns the value of the specified attribute of specified 8582 * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID 8583 * if the length of the attribute does not match the specified length, 8584 * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found. 8585 */ 8586 static int 8587 dprov_get_key_attr_scalar_common(crypto_key_t *key, uint64_t attr_type, 8588 void *value, size_t value_len) 8589 { 8590 int attr_idx; 8591 8592 ASSERT(key->ck_format == CRYPTO_KEY_ATTR_LIST); 8593 8594 if ((attr_idx = dprov_find_attr(key->ck_attrs, key->ck_count, 8595 attr_type)) == -1) 8596 return (CRYPTO_ARGUMENTS_BAD); 8597 8598 if (key->ck_attrs[attr_idx].oa_value_len != value_len) 8599 /* incorrect attribute value length */ 8600 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 8601 8602 bcopy(key->ck_attrs[attr_idx].oa_value, value, value_len); 8603 8604 return (CRYPTO_SUCCESS); 8605 } 8606 8607 /* 8608 * Get the value of a ulong_t attribute from the specified key. 8609 */ 8610 static int 8611 dprov_get_key_attr_ulong(crypto_key_t *key, uint64_t attr_type, 8612 ulong_t *attr_value) 8613 { 8614 return (dprov_get_key_attr_scalar_common(key, attr_type, 8615 attr_value, sizeof (ulong_t))); 8616 } 8617 8618 /* 8619 * Find the specified byte array attribute of specified type in 8620 * the specified key by attributes. Returns CRYPTO_SUCCESS 8621 * on success or CRYPTO_ARGUMENTS_BAD if the specified 8622 * attribute cannot be found. 8623 */ 8624 static int 8625 dprov_get_key_attr_array(crypto_key_t *key, uint64_t attr_type, 8626 void **array, size_t *len) 8627 { 8628 int attr_idx; 8629 8630 ASSERT(key->ck_format == CRYPTO_KEY_ATTR_LIST); 8631 8632 if ((attr_idx = dprov_find_attr(key->ck_attrs, key->ck_count, 8633 attr_type)) == -1) 8634 return (CRYPTO_ARGUMENTS_BAD); 8635 8636 *array = key->ck_attrs[attr_idx].oa_value; 8637 *len = key->ck_attrs[attr_idx].oa_value_len; 8638 8639 return (CRYPTO_SUCCESS); 8640 } 8641 8642 static void 8643 dprov_release_session_objects(dprov_session_t *session) 8644 { 8645 dprov_object_t *object; 8646 int i; 8647 8648 for (i = 0; i < DPROV_MAX_OBJECTS; i++) { 8649 object = session->ds_objects[i]; 8650 if (object != NULL) { 8651 DPROV_OBJECT_REFRELE(object); 8652 } 8653 } 8654 } 8655