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