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