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