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