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