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