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