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