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