5869 Need AES CMAC support in KCF+PKCS11
[unleashed.git] / usr / src / uts / common / crypto / io / dprov.c
blobde0a9b20e938c78d8d67d208037e312aa2e681e5
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
24 * Use is subject to license terms.
29 * Dummy Cryptographic Provider:
31 * This file implements a "dummy" cryptographic provider. It is implemented
32 * as a pseudo device driver.
37 * This driver implements a KEF provider with the following capabilities:
39 * - registration/unregistration with KEF
40 * - digest entry points
41 * - mac entry points
42 * - ctx management
43 * - support for async requests
44 * - cipher entry points
45 * - dual entry points
46 * - sign entry points
47 * - verify entry points
48 * - dual operations entry points
49 * - dual cipher/mac operation entry points
50 * - session management
51 * - object management
52 * - key management
53 * - provider management
55 * In order to avoid duplicating the implementation of algorithms
56 * provided by software providers, this pseudo driver acts as
57 * a consumer of the framework. When invoking one of the framework's
58 * entry points, the driver specifies the software provider to
59 * be used for the operation.
61 * User management: we implement a PKCS#11 style provider which supports:
62 * - one normal user with a PIN, and
63 * - one SO user with a PIN.
64 * These values are kept in the per-instance structure, and are initialized
65 * with the provider management entry points.
70 #include <sys/types.h>
71 #include <sys/modctl.h>
72 #include <sys/conf.h>
73 #include <sys/stat.h>
74 #include <sys/ddi.h>
75 #include <sys/sunddi.h>
76 #include <sys/kmem.h>
77 #include <sys/errno.h>
78 #include <sys/ksynch.h>
79 #include <sys/file.h>
80 #include <sys/open.h>
81 #include <sys/cred.h>
82 #include <sys/model.h>
83 #include <sys/note.h>
84 #include <sys/random.h>
85 #include <sys/byteorder.h>
86 #include <sys/crypto/common.h>
87 #include <sys/crypto/spi.h>
89 #include <sys/taskq.h>
90 #include <sys/disp.h>
91 #include <sys/sysmacros.h>
92 #include <sys/crypto/impl.h>
93 #include <sys/crypto/sched_impl.h>
95 #include <sys/sha2.h>
96 #include <modes/modes.h>
97 #include <aes/aes_impl.h>
98 #include <des/des_impl.h>
99 #include <ecc/ecc_impl.h>
100 #include <blowfish/blowfish_impl.h>
103 * Debugging macros.
105 #ifdef DEBUG
106 #define D_INIT 0x00000001 /* _init/_fini/_info */
107 #define D_ATTACH 0x00000002 /* attach/detach */
108 #define D_DIGEST 0x00000010 /* digest entry points */
109 #define D_MAC 0x00000020 /* mac entry points */
110 #define D_CONTEXT 0x00000040 /* context entry points */
111 #define D_CIPHER 0x00000080 /* cipher entry points */
112 #define D_SIGN 0x00000100 /* sign entry points */
113 #define D_VERIFY 0x00000200 /* verify entry points */
114 #define D_SESSION 0x00000400 /* session management entry points */
115 #define D_MGMT 0x00000800 /* provider management entry points */
116 #define D_DUAL 0x00001000 /* dual ops */
117 #define D_CIPHER_MAC 0x00002000 /* cipher/mac dual ops */
118 #define D_OBJECT 0x00004000 /* object management */
119 #define D_RANDOM 0x00008000 /* random number generation */
120 #define D_KEY 0x00010000 /* key management */
122 static uint32_t dprov_debug = 0;
124 #define DPROV_DEBUG(f, x) if (dprov_debug & (f)) { (void) printf x; }
125 #define DPROV_CALL(f, r, x) if (dprov_debug & (f)) { (void) r x; }
126 #else /* DEBUG */
127 #define DPROV_DEBUG(f, x)
128 #define DPROV_CALL(f, r, x)
129 #endif /* DEBUG */
131 static int nostore_key_gen;
132 static boolean_t dprov_no_multipart = B_FALSE;
133 static int dprov_max_digestsz = INT_MAX;
136 * DDI entry points.
138 static int dprov_attach(dev_info_t *, ddi_attach_cmd_t);
139 static int dprov_detach(dev_info_t *, ddi_detach_cmd_t);
140 static int dprov_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
143 * Module linkage.
145 static struct cb_ops cbops = {
146 nodev, /* cb_open */
147 nodev, /* cb_close */
148 nodev, /* cb_strategy */
149 nodev, /* cb_print */
150 nodev, /* cb_dump */
151 nodev, /* cb_read */
152 nodev, /* cb_write */
153 nodev, /* cb_ioctl */
154 nodev, /* cb_devmap */
155 nodev, /* cb_mmap */
156 nodev, /* cb_segmap */
157 nochpoll, /* cb_chpoll */
158 ddi_prop_op, /* cb_prop_op */
159 NULL, /* cb_streamtab */
160 D_MP, /* cb_flag */
161 CB_REV, /* cb_rev */
162 nodev, /* cb_aread */
163 nodev, /* cb_awrite */
166 static struct dev_ops devops = {
167 DEVO_REV, /* devo_rev */
168 0, /* devo_refcnt */
169 dprov_getinfo, /* devo_getinfo */
170 nulldev, /* devo_identify */
171 nulldev, /* devo_probe */
172 dprov_attach, /* devo_attach */
173 dprov_detach, /* devo_detach */
174 nodev, /* devo_reset */
175 &cbops, /* devo_cb_ops */
176 NULL, /* devo_bus_ops */
177 NULL, /* devo_power */
178 ddi_quiesce_not_needed, /* devo_quiesce */
181 static struct modldrv modldrv = {
182 &mod_driverops,
183 "Pseudo KCF Prov (drv)",
184 &devops
187 static struct modlcrypto modlcrypto = {
188 &mod_cryptoops,
189 "Pseudo KCF Prov (crypto)"
192 static struct modlinkage modlinkage = {
193 MODREV_1,
194 &modldrv,
195 &modlcrypto,
196 NULL
200 * CSPI information (entry points, provider info, etc.)
203 typedef enum dprov_mech_type {
204 MD4_MECH_INFO_TYPE, /* SUN_CKM_MD4 */
206 MD5_MECH_INFO_TYPE, /* SUN_CKM_MD5 */
207 MD5_HMAC_MECH_INFO_TYPE, /* SUN_CKM_MD5_HMAC */
208 MD5_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_MD5_HMAC_GENERAL */
210 SHA1_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA1_HMAC */
211 SHA1_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA1_HMAC_GENERAL */
212 SHA1_MECH_INFO_TYPE, /* SUN_CKM_SHA1 */
214 SHA256_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA256_HMAC */
215 SHA256_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA256_HMAC_GENERAL */
216 SHA256_MECH_INFO_TYPE, /* SUN_CKM_SHA256 */
217 SHA384_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA384_HMAC */
218 SHA384_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA384_HMAC_GENERAL */
219 SHA384_MECH_INFO_TYPE, /* SUN_CKM_SHA384 */
220 SHA512_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA512_HMAC */
221 SHA512_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA512_HMAC_GENERAL */
222 SHA512_MECH_INFO_TYPE, /* SUN_CKM_SHA512 */
224 DES_CBC_MECH_INFO_TYPE, /* SUN_CKM_DES_CBC */
225 DES3_CBC_MECH_INFO_TYPE, /* SUN_CKM_DES3_CBC */
226 DES_ECB_MECH_INFO_TYPE, /* SUN_CKM_DES_ECB */
227 DES3_ECB_MECH_INFO_TYPE, /* SUN_CKM_DES3_ECB */
229 BLOWFISH_CBC_MECH_INFO_TYPE, /* SUN_CKM_BLOWFISH_CBC */
230 BLOWFISH_ECB_MECH_INFO_TYPE, /* SUN_CKM_BLOWFISH_ECB */
231 AES_CBC_MECH_INFO_TYPE, /* SUN_CKM_AES_CBC */
232 AES_CMAC_MECH_INFO_TYPE, /* SUN_CKM_AES_CMAC */
233 AES_ECB_MECH_INFO_TYPE, /* SUN_CKM_AES_ECB */
234 AES_CTR_MECH_INFO_TYPE, /* SUN_CKM_AES_CTR */
235 AES_CCM_MECH_INFO_TYPE, /* SUN_CKM_AES_CCM */
236 AES_GCM_MECH_INFO_TYPE, /* SUN_CKM_AES_GCM */
237 AES_GMAC_MECH_INFO_TYPE, /* SUN_CKM_AES_GMAC */
238 RC4_MECH_INFO_TYPE, /* SUN_CKM_RC4 */
239 RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_RSA_PKCS */
240 RSA_X_509_MECH_INFO_TYPE, /* SUN_CKM_RSA_X_509 */
241 MD5_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_MD5_RSA_PKCS */
242 SHA1_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_SHA1_RSA_PKCS */
243 SHA256_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_SHA256_RSA_PKCS */
244 SHA384_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_SHA384_RSA_PKCS */
245 SHA512_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_SHA512_RSA_PKCS */
246 MD5_KEY_DERIVATION_MECH_INFO_TYPE, /* SUN_CKM_MD5_KEY_DERIVATION */
247 SHA1_KEY_DERIVATION_MECH_INFO_TYPE, /* SUN_CKM_SHA1_KEY_DERIVATION */
248 /* SUN_CKM_SHA256_KEY_DERIVATION */
249 SHA256_KEY_DERIVATION_MECH_INFO_TYPE,
250 /* SUN_CKM_SHA384_KEY_DERIVATION */
251 SHA384_KEY_DERIVATION_MECH_INFO_TYPE,
252 /* SUN_CKM_SHA512_KEY_DERIVATION */
253 SHA512_KEY_DERIVATION_MECH_INFO_TYPE,
254 DES_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_DES_KEY_GEN */
255 DES3_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_DES3_KEY_GEN */
256 AES_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_AES_KEY_GEN */
257 BLOWFISH_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_BLOWFISH_KEY_GEN */
258 RC4_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_RC4_KEY_GEN */
259 EC_KEY_PAIR_GEN_MECH_INFO_TYPE, /* SUN_CKM_EC_KEY_PAIR_GEN */
260 ECDSA_MECH_INFO_TYPE, /* SUN_CKM_ECDSA */
261 ECDSA_SHA1_MECH_INFO_TYPE, /* SUN_CKM_ECDSA_SHA1 */
262 ECDH1_DERIVE_MECH_INFO_TYPE, /* SUN_CKM_ECDH1_DERIVE */
263 DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE, /* SUN_CKM_DH_PKCS_KEY_PAIR_GEN */
264 DH_PKCS_DERIVE_MECH_INFO_TYPE, /* SUN_CKM_DH_PKCS_DERIVE */
265 RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE /* SUN_CKM_RSA_PKCS_KEY_PAIR_GEN */
266 } dprov_mech_type_t;
269 * Mechanism info structure passed to KCF during registration.
271 #define MD5_DIGEST_LEN 16 /* MD5 digest size */
272 #define MD5_HMAC_BLOCK_SIZE 64 /* MD5-HMAC block size */
273 #define MD5_HMAC_MIN_KEY_LEN 1 /* MD5-HMAC min key length in bytes */
274 #define MD5_HMAC_MAX_KEY_LEN INT_MAX /* MD5-HMAC max key length in bytes */
276 #define SHA1_DIGEST_LEN 20 /* SHA1 digest size */
277 #define SHA1_HMAC_BLOCK_SIZE 64 /* SHA1-HMAC block size */
278 #define SHA1_HMAC_MIN_KEY_LEN 1 /* SHA1-HMAC min key length in bytes */
279 #define SHA1_HMAC_MAX_KEY_LEN INT_MAX /* SHA1-HMAC max key length in bytes */
281 #define DES_KEY_LEN 8 /* DES key length in bytes */
282 #define DES3_KEY_LEN 24 /* DES3 key length in bytes */
284 #define BLOWFISH_MIN_KEY_LEN 32 /* Blowfish min key length in bits */
285 #define BLOWFISH_MAX_KEY_LEN 448 /* Blowfish max key length in bits */
287 #define AES_MIN_KEY_LEN 16 /* AES min key length in bytes */
288 #define AES_MAX_KEY_LEN 32 /* AES max key length in bytes */
290 #define ARCFOUR_MIN_KEY_BITS 40 /* RC4 min supported key size */
291 #define ARCFOUR_MAX_KEY_BITS 2048 /* RC4 max supported key size */
293 #define RSA_MIN_KEY_LEN 256 /* RSA min key length in bits */
294 #define RSA_MAX_KEY_LEN 4096 /* RSA max key length in bits */
296 #define DH_MIN_KEY_LEN 64 /* DH min key length in bits */
297 #define DH_MAX_KEY_LEN 4096 /* DH max key length in bits */
299 #define DPROV_CKM_MD5_KEY_DERIVATION "CKM_MD5_KEY_DERIVATION"
300 #define DPROV_CKM_SHA1_KEY_DERIVATION "CKM_SHA1_KEY_DERIVATION"
301 #define DPROV_CKM_SHA256_KEY_DERIVATION "CKM_SHA256_KEY_DERIVATION"
302 #define DPROV_CKM_SHA384_KEY_DERIVATION "CKM_SHA384_KEY_DERIVATION"
303 #define DPROV_CKM_SHA512_KEY_DERIVATION "CKM_SHA512_KEY_DERIVATION"
304 #define DPROV_CKM_DES_KEY_GEN "CKM_DES_KEY_GEN"
305 #define DPROV_CKM_DES3_KEY_GEN "CKM_DES3_KEY_GEN"
306 #define DPROV_CKM_AES_KEY_GEN "CKM_AES_KEY_GEN"
307 #define DPROV_CKM_BLOWFISH_KEY_GEN "CKM_BLOWFISH_KEY_GEN"
308 #define DPROV_CKM_RC4_KEY_GEN "CKM_RC4_KEY_GEN"
309 #define DPROV_CKM_RSA_PKCS_KEY_PAIR_GEN "CKM_RSA_PKCS_KEY_PAIR_GEN"
310 #define DPROV_CKM_EC_KEY_PAIR_GEN "CKM_EC_KEY_PAIR_GEN"
311 #define DPROV_CKM_ECDSA "CKM_ECDSA"
312 #define DPROV_CKM_ECDSA_SHA1 "CKM_ECDSA_SHA1"
313 #define DPROV_CKM_ECDH1_DERIVE "CKM_ECDH1_DERIVE"
314 #define DPROV_CKM_DH_PKCS_KEY_PAIR_GEN "CKM_DH_PKCS_KEY_PAIR_GEN"
315 #define DPROV_CKM_DH_PKCS_DERIVE "CKM_DH_PKCS_DERIVE"
317 static crypto_mech_info_t dprov_mech_info_tab[] = {
318 /* MD4 */
319 {SUN_CKM_MD4, MD4_MECH_INFO_TYPE,
320 CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
321 CRYPTO_KEYSIZE_UNIT_IN_BITS},
322 /* MD5 */
323 {SUN_CKM_MD5, MD5_MECH_INFO_TYPE,
324 CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
325 CRYPTO_KEYSIZE_UNIT_IN_BITS},
326 /* MD5-HMAC */
327 {SUN_CKM_MD5_HMAC, MD5_HMAC_MECH_INFO_TYPE,
328 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
329 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
330 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
331 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
332 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
333 MD5_HMAC_MIN_KEY_LEN, MD5_HMAC_MAX_KEY_LEN,
334 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
335 /* MD5-HMAC GENERAL */
336 {SUN_CKM_MD5_HMAC_GENERAL, MD5_HMAC_GEN_MECH_INFO_TYPE,
337 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
338 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
339 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
340 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
341 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
342 MD5_HMAC_MIN_KEY_LEN, MD5_HMAC_MAX_KEY_LEN,
343 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
344 /* SHA1 */
345 {SUN_CKM_SHA1, SHA1_MECH_INFO_TYPE,
346 CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
347 CRYPTO_KEYSIZE_UNIT_IN_BITS},
348 /* SHA1-HMAC */
349 {SUN_CKM_SHA1_HMAC, SHA1_HMAC_MECH_INFO_TYPE,
350 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
351 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
352 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
353 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
354 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
355 SHA1_HMAC_MIN_KEY_LEN, SHA1_HMAC_MAX_KEY_LEN,
356 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
357 /* SHA1-HMAC GENERAL */
358 {SUN_CKM_SHA1_HMAC_GENERAL, SHA1_HMAC_GEN_MECH_INFO_TYPE,
359 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
360 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
361 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
362 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
363 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
364 SHA1_HMAC_MIN_KEY_LEN, SHA1_HMAC_MAX_KEY_LEN,
365 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
366 /* SHA256 */
367 {SUN_CKM_SHA256, SHA256_MECH_INFO_TYPE,
368 CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
369 CRYPTO_KEYSIZE_UNIT_IN_BITS},
370 /* SHA256-HMAC */
371 {SUN_CKM_SHA256_HMAC, SHA256_HMAC_MECH_INFO_TYPE,
372 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
373 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
374 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
375 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
376 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
377 SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
378 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
379 /* SHA256-HMAC GENERAL */
380 {SUN_CKM_SHA256_HMAC_GENERAL, SHA256_HMAC_GEN_MECH_INFO_TYPE,
381 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
382 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
383 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
384 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
385 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
386 SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
387 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
388 /* SHA384 */
389 {SUN_CKM_SHA384, SHA384_MECH_INFO_TYPE,
390 CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
391 CRYPTO_KEYSIZE_UNIT_IN_BITS},
392 /* SHA384-HMAC */
393 {SUN_CKM_SHA384_HMAC, SHA384_HMAC_MECH_INFO_TYPE,
394 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
395 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
396 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
397 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
398 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
399 SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
400 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
401 /* SHA384-HMAC GENERAL */
402 {SUN_CKM_SHA384_HMAC_GENERAL, SHA384_HMAC_GEN_MECH_INFO_TYPE,
403 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
404 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
405 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
406 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
407 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
408 SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
409 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
410 /* SHA512 */
411 {SUN_CKM_SHA512, SHA512_MECH_INFO_TYPE,
412 CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
413 CRYPTO_KEYSIZE_UNIT_IN_BITS},
414 /* SHA512-HMAC */
415 {SUN_CKM_SHA512_HMAC, SHA512_HMAC_MECH_INFO_TYPE,
416 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
417 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
418 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
419 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
420 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
421 SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
422 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
423 /* SHA512-HMAC GENERAL */
424 {SUN_CKM_SHA512_HMAC_GENERAL, SHA512_HMAC_GEN_MECH_INFO_TYPE,
425 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
426 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
427 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
428 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
429 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
430 SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
431 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
432 /* DES-CBC */
433 {SUN_CKM_DES_CBC, DES_CBC_MECH_INFO_TYPE,
434 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
435 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
436 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
437 CRYPTO_FG_MAC_DECRYPT_ATOMIC,
438 DES_KEY_LEN, DES_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
439 /* DES3-CBC */
440 {SUN_CKM_DES3_CBC, DES3_CBC_MECH_INFO_TYPE,
441 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
442 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
443 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
444 CRYPTO_FG_MAC_DECRYPT_ATOMIC,
445 DES3_KEY_LEN, DES3_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
446 /* DES-ECB */
447 {SUN_CKM_DES_ECB, DES_ECB_MECH_INFO_TYPE,
448 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
449 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
450 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
451 CRYPTO_FG_MAC_DECRYPT_ATOMIC,
452 DES_KEY_LEN, DES_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
453 /* DES3-ECB */
454 {SUN_CKM_DES3_ECB, DES3_ECB_MECH_INFO_TYPE,
455 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
456 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
457 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
458 CRYPTO_FG_MAC_DECRYPT_ATOMIC,
459 DES3_KEY_LEN, DES3_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
460 /* BLOWFISH-CBC */
461 {SUN_CKM_BLOWFISH_CBC, BLOWFISH_CBC_MECH_INFO_TYPE,
462 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
463 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
464 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
465 CRYPTO_FG_MAC_DECRYPT_ATOMIC, BLOWFISH_MIN_KEY_LEN,
466 BLOWFISH_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
467 /* BLOWFISH-ECB */
468 {SUN_CKM_BLOWFISH_ECB, BLOWFISH_ECB_MECH_INFO_TYPE,
469 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
470 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
471 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
472 CRYPTO_FG_MAC_DECRYPT_ATOMIC, BLOWFISH_MIN_KEY_LEN,
473 BLOWFISH_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
474 /* AES-CBC */
475 {SUN_CKM_AES_CBC, AES_CBC_MECH_INFO_TYPE,
476 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
477 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
478 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
479 CRYPTO_FG_MAC_DECRYPT_ATOMIC,
480 AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
481 /* AES-CMAC */
482 {SUN_CKM_AES_CMAC, AES_CMAC_MECH_INFO_TYPE,
483 CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_MAC |
484 CRYPTO_FG_ENCRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
485 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
486 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
487 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
488 AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
489 /* AES-ECB */
490 {SUN_CKM_AES_ECB, AES_ECB_MECH_INFO_TYPE,
491 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
492 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
493 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
494 CRYPTO_FG_MAC_DECRYPT_ATOMIC,
495 AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
496 /* AES-CTR */
497 {SUN_CKM_AES_CTR, AES_CTR_MECH_INFO_TYPE,
498 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
499 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
500 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
501 CRYPTO_FG_MAC_DECRYPT_ATOMIC,
502 AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
503 /* AES-CCM */
504 {SUN_CKM_AES_CCM, AES_CCM_MECH_INFO_TYPE,
505 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
506 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
507 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
508 CRYPTO_FG_MAC_DECRYPT_ATOMIC,
509 AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
510 /* AES-GCM */
511 {SUN_CKM_AES_GCM, AES_GCM_MECH_INFO_TYPE,
512 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
513 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
514 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
515 CRYPTO_FG_MAC_DECRYPT_ATOMIC,
516 AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
517 /* AES-GMAC */
518 {SUN_CKM_AES_GMAC, AES_GMAC_MECH_INFO_TYPE,
519 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
520 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
521 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
522 CRYPTO_FG_MAC_DECRYPT_ATOMIC |
523 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
524 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
525 AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
526 /* RC4 */
527 {SUN_CKM_RC4, RC4_MECH_INFO_TYPE,
528 CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
529 CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
530 ARCFOUR_MIN_KEY_BITS, ARCFOUR_MAX_KEY_BITS,
531 CRYPTO_KEYSIZE_UNIT_IN_BITS | CRYPTO_CAN_SHARE_OPSTATE},
532 /* RSA_PKCS */
533 {SUN_CKM_RSA_PKCS, RSA_PKCS_MECH_INFO_TYPE,
534 CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
535 CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC |
536 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
537 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
538 CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC |
539 CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC,
540 RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
541 /* RSA_X_509 */
542 {SUN_CKM_RSA_X_509, RSA_X_509_MECH_INFO_TYPE,
543 CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
544 CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC |
545 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
546 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
547 CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC |
548 CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC,
549 RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
550 /* MD5_RSA_PKCS */
551 {SUN_CKM_MD5_RSA_PKCS, MD5_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 /* SHA1_RSA_PKCS */
556 {SUN_CKM_SHA1_RSA_PKCS, SHA1_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 /* SHA256_RSA_PKCS */
561 {SUN_CKM_SHA256_RSA_PKCS, SHA256_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 /* SHA384_RSA_PKCS */
566 {SUN_CKM_SHA384_RSA_PKCS, SHA384_RSA_PKCS_MECH_INFO_TYPE,
567 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
568 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
569 RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
570 /* SHA512_RSA_PKCS */
571 {SUN_CKM_SHA512_RSA_PKCS, SHA512_RSA_PKCS_MECH_INFO_TYPE,
572 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
573 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
574 RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
575 /* MD5_KEY_DERIVATION */
576 {DPROV_CKM_MD5_KEY_DERIVATION, MD5_KEY_DERIVATION_MECH_INFO_TYPE,
577 CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
578 /* SHA1_KEY_DERIVATION */
579 {DPROV_CKM_SHA1_KEY_DERIVATION, SHA1_KEY_DERIVATION_MECH_INFO_TYPE,
580 CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
581 /* SHA256_KEY_DERIVATION */
582 {DPROV_CKM_SHA256_KEY_DERIVATION, SHA256_KEY_DERIVATION_MECH_INFO_TYPE,
583 CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
584 /* SHA384_KEY_DERIVATION */
585 {DPROV_CKM_SHA384_KEY_DERIVATION, SHA384_KEY_DERIVATION_MECH_INFO_TYPE,
586 CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
587 /* SHA512_KEY_DERIVATION */
588 {DPROV_CKM_SHA512_KEY_DERIVATION, SHA512_KEY_DERIVATION_MECH_INFO_TYPE,
589 CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
590 /* DES_KEY_GENERATION */
591 {DPROV_CKM_DES_KEY_GEN, DES_KEY_GEN_MECH_INFO_TYPE,
592 CRYPTO_FG_GENERATE, DES_KEY_LEN, DES_KEY_LEN,
593 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
594 /* DES3_KEY_GENERATION */
595 {DPROV_CKM_DES3_KEY_GEN, DES3_KEY_GEN_MECH_INFO_TYPE,
596 CRYPTO_FG_GENERATE, DES3_KEY_LEN, DES3_KEY_LEN,
597 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
598 /* AES_KEY_GENERATION */
599 {DPROV_CKM_AES_KEY_GEN, AES_KEY_GEN_MECH_INFO_TYPE,
600 CRYPTO_FG_GENERATE, AES_MIN_KEY_LEN, AES_MAX_KEY_LEN,
601 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
602 /* BLOWFISH_KEY_GENERATION */
603 {DPROV_CKM_BLOWFISH_KEY_GEN, BLOWFISH_KEY_GEN_MECH_INFO_TYPE,
604 CRYPTO_FG_GENERATE, BLOWFISH_MIN_KEY_LEN, BLOWFISH_MAX_KEY_LEN,
605 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
606 /* RC4_KEY_GENERATION */
607 {DPROV_CKM_RC4_KEY_GEN, RC4_KEY_GEN_MECH_INFO_TYPE,
608 CRYPTO_FG_GENERATE, ARCFOUR_MIN_KEY_BITS, ARCFOUR_MAX_KEY_BITS,
609 CRYPTO_KEYSIZE_UNIT_IN_BITS},
610 /* DH_PKCS_KEY_PAIR_GEN */
611 {DPROV_CKM_DH_PKCS_KEY_PAIR_GEN, DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE,
612 CRYPTO_FG_GENERATE_KEY_PAIR, DH_MIN_KEY_LEN, DH_MAX_KEY_LEN,
613 CRYPTO_KEYSIZE_UNIT_IN_BITS},
614 /* DH_PKCS_DERIVE */
615 {DPROV_CKM_DH_PKCS_DERIVE, DH_PKCS_DERIVE_MECH_INFO_TYPE,
616 CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
617 /* RSA_PKCS_KEY_PAIR_GEN */
618 {DPROV_CKM_RSA_PKCS_KEY_PAIR_GEN, RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE,
619 CRYPTO_FG_GENERATE_KEY_PAIR, RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN,
620 CRYPTO_KEYSIZE_UNIT_IN_BITS},
621 /* EC_KEY_PAIR_GEN */
622 {DPROV_CKM_EC_KEY_PAIR_GEN, EC_KEY_PAIR_GEN_MECH_INFO_TYPE,
623 CRYPTO_FG_GENERATE_KEY_PAIR, EC_MIN_KEY_LEN, EC_MAX_KEY_LEN,
624 CRYPTO_KEYSIZE_UNIT_IN_BITS},
625 /* ECDSA */
626 {DPROV_CKM_ECDSA, ECDSA_MECH_INFO_TYPE,
627 CRYPTO_FG_SIGN | CRYPTO_FG_VERIFY |
628 CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC |
629 EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
630 /* ECDSA_SHA1 */
631 {DPROV_CKM_ECDSA_SHA1, ECDSA_SHA1_MECH_INFO_TYPE,
632 CRYPTO_FG_SIGN | CRYPTO_FG_VERIFY |
633 CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC |
634 EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
635 /* ECDH1_DERIVE */
636 {DPROV_CKM_ECDH1_DERIVE, ECDH1_DERIVE_MECH_INFO_TYPE,
637 CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}
641 * Crypto Values
643 * These values are the used in the STC ef test suite. If they are changed
644 * the test suite needs to be changed.
646 static uchar_t dh_value[8] = { 'd', 'h', 'd', 'h', 'd', 'h', 'd', '\0' };
647 char public_exponent[3] = { 0x01, 0x00, 0x01 };
648 static uchar_t private_exponent[128] = {
649 0x8e, 0xc9, 0x70, 0x57, 0x6b, 0xcd, 0xfb, 0xa9,
650 0x19, 0xad, 0xcd, 0x91, 0x69, 0xd5, 0x52, 0xec,
651 0x72, 0x1e, 0x45, 0x15, 0x06, 0xdc, 0x65, 0x2d,
652 0x98, 0xc4, 0xce, 0x33, 0x54, 0x15, 0x70, 0x8d,
653 0xfa, 0x65, 0xea, 0x53, 0x44, 0xf3, 0x3e, 0x3f,
654 0xb4, 0x4c, 0x60, 0xd5, 0x01, 0x2d, 0xa4, 0x12,
655 0x99, 0xbf, 0x3f, 0x0b, 0xcd, 0xbb, 0x24, 0x10,
656 0x60, 0x30, 0x5e, 0x58, 0xf8, 0x59, 0xaa, 0xd1,
657 0x63, 0x3b, 0xbc, 0xcb, 0x94, 0x58, 0x38, 0x24,
658 0xfc, 0x65, 0x25, 0xc5, 0xa6, 0x51, 0xa2, 0x2e,
659 0xf1, 0x5e, 0xf5, 0xc1, 0xf5, 0x46, 0xf7, 0xbd,
660 0xc7, 0x62, 0xa8, 0xe2, 0x27, 0xd6, 0x94, 0x5b,
661 0xd3, 0xa2, 0xb5, 0x76, 0x42, 0x67, 0x6b, 0x86,
662 0x91, 0x97, 0x4d, 0x07, 0x92, 0x00, 0x4a, 0xdf,
663 0x0b, 0x65, 0x64, 0x05, 0x03, 0x48, 0x27, 0xeb,
664 0xce, 0x9a, 0x49, 0x7f, 0x3e, 0x10, 0xe0, 0x01
667 static uchar_t modulus[128] = {
668 0x94, 0x32, 0xb9, 0x12, 0x1d, 0x68, 0x2c, 0xda,
669 0x2b, 0xe0, 0xe4, 0x97, 0x1b, 0x4d, 0xdc, 0x43,
670 0xdf, 0x38, 0x6e, 0x7b, 0x9f, 0x07, 0x58, 0xae,
671 0x9d, 0x82, 0x1e, 0xc7, 0xbc, 0x92, 0xbf, 0xd3,
672 0xce, 0x00, 0xbb, 0x91, 0xc9, 0x79, 0x06, 0x03,
673 0x1f, 0xbc, 0x9f, 0x94, 0x75, 0x29, 0x5f, 0xd7,
674 0xc5, 0xf3, 0x73, 0x8a, 0xa4, 0x35, 0x43, 0x7a,
675 0x00, 0x32, 0x97, 0x3e, 0x86, 0xef, 0x70, 0x6f,
676 0x18, 0x56, 0x15, 0xaa, 0x6a, 0x87, 0xe7, 0x8d,
677 0x7d, 0xdd, 0x1f, 0xa4, 0xe4, 0x31, 0xd4, 0x7a,
678 0x8c, 0x0e, 0x20, 0xd2, 0x23, 0xf5, 0x57, 0x3c,
679 0x1b, 0xa8, 0x44, 0xa4, 0x57, 0x8f, 0x33, 0x52,
680 0xad, 0x83, 0xae, 0x4a, 0x97, 0xa6, 0x1e, 0xa6,
681 0x2b, 0xfa, 0xea, 0xeb, 0x6e, 0x71, 0xb8, 0xb6,
682 0x0a, 0x36, 0xed, 0x83, 0xce, 0xb0, 0xdf, 0xc1,
683 0xd4, 0x3a, 0xe9, 0x99, 0x6f, 0xf3, 0x96, 0xb7
687 static void dprov_provider_status(crypto_provider_handle_t, uint_t *);
689 static crypto_control_ops_t dprov_control_ops = {
690 dprov_provider_status
693 #define DPROV_MANUFACTURER "SUNW "
694 #define DPROV_MODEL "dprov "
695 #define DPROV_ALLSPACES " "
697 static int dprov_digest_init(crypto_ctx_t *, crypto_mechanism_t *,
698 crypto_req_handle_t);
699 static int dprov_digest(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
700 crypto_req_handle_t);
701 static int dprov_digest_update(crypto_ctx_t *, crypto_data_t *,
702 crypto_req_handle_t);
703 static int dprov_digest_key(crypto_ctx_t *, crypto_key_t *,
704 crypto_req_handle_t);
705 static int dprov_digest_final(crypto_ctx_t *, crypto_data_t *,
706 crypto_req_handle_t);
707 static int dprov_digest_atomic(crypto_provider_handle_t, crypto_session_id_t,
708 crypto_mechanism_t *, crypto_data_t *, crypto_data_t *,
709 crypto_req_handle_t);
711 static crypto_digest_ops_t dprov_digest_ops = {
712 dprov_digest_init,
713 dprov_digest,
714 dprov_digest_update,
715 dprov_digest_key,
716 dprov_digest_final,
717 dprov_digest_atomic
720 static int dprov_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
721 crypto_spi_ctx_template_t, crypto_req_handle_t);
722 static int dprov_mac(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
723 crypto_req_handle_t);
724 static int dprov_mac_update(crypto_ctx_t *, crypto_data_t *,
725 crypto_req_handle_t);
726 static int dprov_mac_final(crypto_ctx_t *, crypto_data_t *,
727 crypto_req_handle_t);
728 static int dprov_mac_atomic(crypto_provider_handle_t, crypto_session_id_t,
729 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
730 crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
731 static int dprov_mac_verify_atomic(crypto_provider_handle_t,
732 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
733 crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
735 static crypto_mac_ops_t dprov_mac_ops = {
736 dprov_mac_init,
737 dprov_mac,
738 dprov_mac_update,
739 dprov_mac_final,
740 dprov_mac_atomic,
741 dprov_mac_verify_atomic
744 static int dprov_encrypt_init(crypto_ctx_t *, crypto_mechanism_t *,
745 crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
746 static int dprov_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
747 crypto_req_handle_t);
748 static int dprov_encrypt_update(crypto_ctx_t *, crypto_data_t *,
749 crypto_data_t *, crypto_req_handle_t);
750 static int dprov_encrypt_final(crypto_ctx_t *, crypto_data_t *,
751 crypto_req_handle_t);
752 static int dprov_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
753 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
754 crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
756 static int dprov_decrypt_init(crypto_ctx_t *, crypto_mechanism_t *,
757 crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
758 static int dprov_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
759 crypto_req_handle_t);
760 static int dprov_decrypt_update(crypto_ctx_t *, crypto_data_t *,
761 crypto_data_t *, crypto_req_handle_t);
762 static int dprov_decrypt_final(crypto_ctx_t *, crypto_data_t *,
763 crypto_req_handle_t);
764 static int dprov_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
765 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
766 crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
768 static crypto_cipher_ops_t dprov_cipher_ops = {
769 dprov_encrypt_init,
770 dprov_encrypt,
771 dprov_encrypt_update,
772 dprov_encrypt_final,
773 dprov_encrypt_atomic,
774 dprov_decrypt_init,
775 dprov_decrypt,
776 dprov_decrypt_update,
777 dprov_decrypt_final,
778 dprov_decrypt_atomic
781 static int dprov_sign_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
782 crypto_spi_ctx_template_t, crypto_req_handle_t);
783 static int dprov_sign(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
784 crypto_req_handle_t);
785 static int dprov_sign_update(crypto_ctx_t *, crypto_data_t *,
786 crypto_req_handle_t);
787 static int dprov_sign_final(crypto_ctx_t *, crypto_data_t *,
788 crypto_req_handle_t);
789 static int dprov_sign_atomic(crypto_provider_handle_t, crypto_session_id_t,
790 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
791 crypto_spi_ctx_template_t, crypto_req_handle_t);
792 static int dprov_sign_recover_init(crypto_ctx_t *, crypto_mechanism_t *,
793 crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
794 static int dprov_sign_recover(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
795 crypto_req_handle_t);
796 static int dprov_sign_recover_atomic(crypto_provider_handle_t,
797 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
798 crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
799 crypto_req_handle_t);
801 static crypto_sign_ops_t dprov_sign_ops = {
802 dprov_sign_init,
803 dprov_sign,
804 dprov_sign_update,
805 dprov_sign_final,
806 dprov_sign_atomic,
807 dprov_sign_recover_init,
808 dprov_sign_recover,
809 dprov_sign_recover_atomic
812 static int dprov_verify_init(crypto_ctx_t *, crypto_mechanism_t *,
813 crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
814 static int dprov_verify(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
815 crypto_req_handle_t);
816 static int dprov_verify_update(crypto_ctx_t *, crypto_data_t *,
817 crypto_req_handle_t);
818 static int dprov_verify_final(crypto_ctx_t *, crypto_data_t *,
819 crypto_req_handle_t);
820 static int dprov_verify_atomic(crypto_provider_handle_t, crypto_session_id_t,
821 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
822 crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
823 static int dprov_verify_recover_init(crypto_ctx_t *, crypto_mechanism_t *,
824 crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
825 static int dprov_verify_recover(crypto_ctx_t *, crypto_data_t *,
826 crypto_data_t *, crypto_req_handle_t);
827 static int dprov_verify_recover_atomic(crypto_provider_handle_t,
828 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
829 crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
830 crypto_req_handle_t);
832 static crypto_verify_ops_t dprov_verify_ops = {
833 dprov_verify_init,
834 dprov_verify,
835 dprov_verify_update,
836 dprov_verify_final,
837 dprov_verify_atomic,
838 dprov_verify_recover_init,
839 dprov_verify_recover,
840 dprov_verify_recover_atomic
843 static int dprov_digest_encrypt_update(crypto_ctx_t *, crypto_ctx_t *,
844 crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
845 static int dprov_decrypt_digest_update(crypto_ctx_t *, crypto_ctx_t *,
846 crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
847 static int dprov_sign_encrypt_update(crypto_ctx_t *, crypto_ctx_t *,
848 crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
849 static int dprov_decrypt_verify_update(crypto_ctx_t *, crypto_ctx_t *,
850 crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
852 static crypto_dual_ops_t dprov_dual_ops = {
853 dprov_digest_encrypt_update,
854 dprov_decrypt_digest_update,
855 dprov_sign_encrypt_update,
856 dprov_decrypt_verify_update
859 static int dprov_encrypt_mac_init(crypto_ctx_t *,
860 crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *,
861 crypto_key_t *, crypto_spi_ctx_template_t,
862 crypto_spi_ctx_template_t, crypto_req_handle_t);
863 static int dprov_encrypt_mac(crypto_ctx_t *,
864 crypto_data_t *, crypto_dual_data_t *, crypto_data_t *,
865 crypto_req_handle_t);
866 static int dprov_encrypt_mac_update(crypto_ctx_t *,
867 crypto_data_t *, crypto_dual_data_t *, crypto_req_handle_t);
868 static int dprov_encrypt_mac_final(crypto_ctx_t *,
869 crypto_dual_data_t *, crypto_data_t *, crypto_req_handle_t);
870 static int dprov_encrypt_mac_atomic(crypto_provider_handle_t,
871 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
872 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
873 crypto_dual_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
874 crypto_spi_ctx_template_t, crypto_req_handle_t);
876 static int dprov_mac_decrypt_init(crypto_ctx_t *,
877 crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *,
878 crypto_key_t *, crypto_spi_ctx_template_t,
879 crypto_spi_ctx_template_t, crypto_req_handle_t);
880 static int dprov_mac_decrypt(crypto_ctx_t *,
881 crypto_dual_data_t *, crypto_data_t *, crypto_data_t *,
882 crypto_req_handle_t);
883 static int dprov_mac_decrypt_update(crypto_ctx_t *,
884 crypto_dual_data_t *, crypto_data_t *, crypto_req_handle_t);
885 static int dprov_mac_decrypt_final(crypto_ctx_t *,
886 crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
887 static int dprov_mac_decrypt_atomic(crypto_provider_handle_t,
888 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
889 crypto_mechanism_t *, crypto_key_t *, crypto_dual_data_t *,
890 crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
891 crypto_spi_ctx_template_t, crypto_req_handle_t);
892 static int dprov_mac_verify_decrypt_atomic(crypto_provider_handle_t,
893 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
894 crypto_mechanism_t *, crypto_key_t *, crypto_dual_data_t *,
895 crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
896 crypto_spi_ctx_template_t, crypto_req_handle_t);
898 static crypto_dual_cipher_mac_ops_t dprov_cipher_mac_ops = {
899 dprov_encrypt_mac_init,
900 dprov_encrypt_mac,
901 dprov_encrypt_mac_update,
902 dprov_encrypt_mac_final,
903 dprov_encrypt_mac_atomic,
904 dprov_mac_decrypt_init,
905 dprov_mac_decrypt,
906 dprov_mac_decrypt_update,
907 dprov_mac_decrypt_final,
908 dprov_mac_decrypt_atomic,
909 dprov_mac_verify_decrypt_atomic
912 static int dprov_seed_random(crypto_provider_handle_t, crypto_session_id_t,
913 uchar_t *, size_t, uint_t, uint32_t, crypto_req_handle_t);
914 static int dprov_generate_random(crypto_provider_handle_t, crypto_session_id_t,
915 uchar_t *, size_t, crypto_req_handle_t);
917 static crypto_random_number_ops_t dprov_random_number_ops = {
918 dprov_seed_random,
919 dprov_generate_random
922 static int dprov_session_open(crypto_provider_handle_t, crypto_session_id_t *,
923 crypto_req_handle_t);
924 static int dprov_session_close(crypto_provider_handle_t, crypto_session_id_t,
925 crypto_req_handle_t);
926 static int dprov_session_login(crypto_provider_handle_t, crypto_session_id_t,
927 crypto_user_type_t, char *, size_t, crypto_req_handle_t);
928 static int dprov_session_logout(crypto_provider_handle_t, crypto_session_id_t,
929 crypto_req_handle_t);
931 static crypto_session_ops_t dprov_session_ops = {
932 dprov_session_open,
933 dprov_session_close,
934 dprov_session_login,
935 dprov_session_logout
938 static int dprov_object_create(crypto_provider_handle_t, crypto_session_id_t,
939 crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
940 crypto_req_handle_t);
941 static int dprov_object_copy(crypto_provider_handle_t, crypto_session_id_t,
942 crypto_object_id_t, crypto_object_attribute_t *, uint_t,
943 crypto_object_id_t *, crypto_req_handle_t);
944 static int dprov_object_destroy(crypto_provider_handle_t, crypto_session_id_t,
945 crypto_object_id_t, crypto_req_handle_t);
946 static int dprov_object_get_size(crypto_provider_handle_t, crypto_session_id_t,
947 crypto_object_id_t, size_t *, crypto_req_handle_t);
948 static int dprov_object_get_attribute_value(crypto_provider_handle_t,
949 crypto_session_id_t, crypto_object_id_t,
950 crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
951 static int dprov_object_set_attribute_value(crypto_provider_handle_t,
952 crypto_session_id_t, crypto_object_id_t,
953 crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
954 static int dprov_object_find_init(crypto_provider_handle_t, crypto_session_id_t,
955 crypto_object_attribute_t *, uint_t, void **,
956 crypto_req_handle_t);
957 static int dprov_object_find(crypto_provider_handle_t, void *,
958 crypto_object_id_t *, uint_t, uint_t *, crypto_req_handle_t);
959 static int dprov_object_find_final(crypto_provider_handle_t, void *,
960 crypto_req_handle_t);
962 static crypto_object_ops_t dprov_object_ops = {
963 dprov_object_create,
964 dprov_object_copy,
965 dprov_object_destroy,
966 dprov_object_get_size,
967 dprov_object_get_attribute_value,
968 dprov_object_set_attribute_value,
969 dprov_object_find_init,
970 dprov_object_find,
971 dprov_object_find_final
974 static int dprov_key_generate(crypto_provider_handle_t, crypto_session_id_t,
975 crypto_mechanism_t *, crypto_object_attribute_t *, uint_t,
976 crypto_object_id_t *, crypto_req_handle_t);
977 static int dprov_key_generate_pair(crypto_provider_handle_t,
978 crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *,
979 uint_t, crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
980 crypto_object_id_t *, crypto_req_handle_t);
981 static int dprov_key_wrap(crypto_provider_handle_t, crypto_session_id_t,
982 crypto_mechanism_t *, crypto_key_t *, crypto_object_id_t *,
983 uchar_t *, size_t *, crypto_req_handle_t);
984 static int dprov_key_unwrap(crypto_provider_handle_t, crypto_session_id_t,
985 crypto_mechanism_t *, crypto_key_t *, uchar_t *, size_t *,
986 crypto_object_attribute_t *, uint_t,
987 crypto_object_id_t *, crypto_req_handle_t);
988 static int dprov_key_derive(crypto_provider_handle_t, crypto_session_id_t,
989 crypto_mechanism_t *, crypto_key_t *, crypto_object_attribute_t *,
990 uint_t, crypto_object_id_t *, crypto_req_handle_t);
992 static crypto_key_ops_t dprov_key_ops = {
993 dprov_key_generate,
994 dprov_key_generate_pair,
995 dprov_key_wrap,
996 dprov_key_unwrap,
997 dprov_key_derive
1000 static int dprov_ext_info(crypto_provider_handle_t,
1001 crypto_provider_ext_info_t *, crypto_req_handle_t);
1002 static int dprov_init_token(crypto_provider_handle_t, char *, size_t,
1003 char *, crypto_req_handle_t);
1004 static int dprov_init_pin(crypto_provider_handle_t, crypto_session_id_t,
1005 char *, size_t, crypto_req_handle_t);
1006 static int dprov_set_pin(crypto_provider_handle_t, crypto_session_id_t,
1007 char *, size_t, char *, size_t, crypto_req_handle_t);
1009 static crypto_provider_management_ops_t dprov_management_ops = {
1010 dprov_ext_info,
1011 dprov_init_token,
1012 dprov_init_pin,
1013 dprov_set_pin
1016 static int dprov_free_context(crypto_ctx_t *);
1017 static int dprov_copyin_mechanism(crypto_provider_handle_t,
1018 crypto_mechanism_t *, crypto_mechanism_t *, int *error, int);
1019 static int dprov_copyout_mechanism(crypto_provider_handle_t,
1020 crypto_mechanism_t *, crypto_mechanism_t *, int *error, int);
1021 static int dprov_free_mechanism(crypto_provider_handle_t,
1022 crypto_mechanism_t *);
1024 static crypto_ctx_ops_t dprov_ctx_ops = {
1025 NULL,
1026 dprov_free_context
1029 static crypto_mech_ops_t dprov_mech_ops = {
1030 dprov_copyin_mechanism,
1031 dprov_copyout_mechanism,
1032 dprov_free_mechanism
1035 static int dprov_nostore_key_generate(crypto_provider_handle_t,
1036 crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *,
1037 uint_t, crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
1038 static int dprov_nostore_key_generate_pair(crypto_provider_handle_t,
1039 crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *,
1040 uint_t, crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *,
1041 uint_t, crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
1042 static int dprov_nostore_key_derive(crypto_provider_handle_t,
1043 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
1044 crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *,
1045 uint_t, crypto_req_handle_t);
1047 static crypto_nostore_key_ops_t dprov_nostore_key_ops = {
1048 dprov_nostore_key_generate,
1049 dprov_nostore_key_generate_pair,
1050 dprov_nostore_key_derive
1053 static crypto_ops_t dprov_crypto_ops = {
1054 &dprov_control_ops,
1055 &dprov_digest_ops,
1056 &dprov_cipher_ops,
1057 &dprov_mac_ops,
1058 &dprov_sign_ops,
1059 &dprov_verify_ops,
1060 &dprov_dual_ops,
1061 &dprov_cipher_mac_ops,
1062 &dprov_random_number_ops,
1063 &dprov_session_ops,
1064 &dprov_object_ops,
1065 &dprov_key_ops,
1066 &dprov_management_ops,
1067 &dprov_ctx_ops,
1068 &dprov_mech_ops
1072 /* maximum SO and user PIN lengths */
1073 #define DPROV_MAX_PIN_LEN 128
1076 * Objects: each session is associated with an array of objects.
1077 * Unlike PKCS#11, the objects cannot be shared between sessions.
1078 * The ioctl driver multiplexes PKCS#11 sessions to providers
1079 * sessions in order to support this semantic. This simplifies
1080 * the CSPI greatly since the provider does not have to associate
1081 * sessions with a user space process.
1082 * There is also a per-instance array of objects, which correspond
1083 * to PKCS#11 token objects. These objects can be shared by multiple
1084 * sesions.
1086 * Token objects are identified by having a CKA_TOKEN attribute B_TRUE.
1087 * Private objects are identified by having a CKA_PRIVATE attribute
1088 * set to B_TRUE.
1091 #define DPROV_MAX_OBJECTS 128 /* max # of objects */
1092 #define DPROV_MAX_ATTR 64 /* max # of attributes per object */
1094 /* object description */
1095 typedef struct dprov_object {
1096 crypto_object_attribute_t do_attr[DPROV_MAX_ATTR]; /* attributes */
1097 uint_t do_token_idx; /* index in per-instance table */
1098 /* for token objects. */
1099 boolean_t do_destroyed; /* object has been destroyed. */
1100 /* keep object around until all */
1101 /* sessions that refer to it */
1102 /* are closed, but mark it */
1103 /* destroyed so that references */
1104 /* to the object fail. */
1105 /* used for token objects only */
1106 uint_t do_refcnt;
1107 } dprov_object_t;
1110 * If a session has a reference to a dprov_object_t,
1111 * it REFHOLD()s.
1113 #define DPROV_OBJECT_REFHOLD(object) { \
1114 atomic_inc_32(&(object)->do_refcnt); \
1115 ASSERT((object)->do_refcnt != 0); \
1119 * Releases a reference to an object. When the last
1120 * reference is released, the object is freed.
1122 #define DPROV_OBJECT_REFRELE(object) { \
1123 ASSERT((object)->do_refcnt != 0); \
1124 membar_exit(); \
1125 if (atomic_dec_32_nv(&(object)->do_refcnt) == 0) \
1126 dprov_free_object(object); \
1130 * Object attributes are passed to the provider using crypto_object_attribute
1131 * structures, which contain the type of the attribute, a pointer to
1132 * it's value, and the length of its value. The attribute types values
1133 * are defined by the PKCS#11 specification. This provider only cares
1134 * about a subset of these attributes. In order to avoid having to
1135 * include the PKCS#11 header files, we define here the attributes values
1136 * which are used by the provider.
1139 #define DPROV_CKA_CLASS 0x00000000
1140 #define DPROV_CKA_TOKEN 0x00000001
1141 #define DPROV_CKA_PRIVATE 0x00000002
1142 #define DPROV_CKA_VALUE 0x00000011
1143 #define DPROV_CKA_CERTIFICATE_TYPE 0x00000080
1144 #define DPROV_CKA_KEY_TYPE 0x00000100
1145 #define DPROV_CKA_SENSITIVE 0x00000103
1146 #define DPROV_CKA_ENCRYPT 0x00000104
1147 #define DPROV_CKA_DECRYPT 0x00000105
1148 #define DPROV_CKA_WRAP 0x00000106
1149 #define DPROV_CKA_UNWRAP 0x00000107
1150 #define DPROV_CKA_SIGN 0x00000108
1151 #define DPROV_CKA_SIGN_RECOVER 0x00000109
1152 #define DPROV_CKA_VERIFY 0x0000010A
1153 #define DPROV_CKA_VERIFY_RECOVER 0x0000010B
1154 #define DPROV_CKA_DERIVE 0x0000010C
1155 #define DPROV_CKA_MODULUS 0x00000120
1156 #define DPROV_CKA_MODULUS_BITS 0x00000121
1157 #define DPROV_CKA_PUBLIC_EXPONENT 0x00000122
1158 #define DPROV_CKA_PRIVATE_EXPONENT 0x00000123
1159 #define DPROV_CKA_PRIME 0x00000130
1160 #define DPROV_CKA_BASE 0x00000132
1161 #define DPROV_CKA_VALUE_BITS 0x00000160
1162 #define DPROV_CKA_VALUE_LEN 0x00000161
1163 #define DPROV_CKA_EXTRACTABLE 0x00000162
1164 #define DPROV_CKA_EC_PARAMS 0x00000180
1165 #define DPROV_CKA_EC_POINT 0x00000181
1166 #define DPROV_HW_FEATURE_TYPE 0x00000300
1169 * Object classes from PKCS#11
1171 #define DPROV_CKO_DATA 0x00000000
1172 #define DPROV_CKO_CERTIFICATE 0x00000001
1173 #define DPROV_CKO_PUBLIC_KEY 0x00000002
1174 #define DPROV_CKO_PRIVATE_KEY 0x00000003
1175 #define DPROV_CKO_SECRET_KEY 0x00000004
1176 #define DPROV_CKO_HW_FEATURE 0x00000005
1177 #define DPROV_CKO_DOMAIN_PARAMETERS 0x00000006
1178 #define DPROV_CKO_VENDOR_DEFINED 0x80000000
1181 * A few key types from PKCS#11
1183 #define DPROV_CKK_RSA 0x00000000
1184 #define DPROV_CKK_GENERIC_SECRET 0x00000010
1185 #define DPROV_CKK_RC4 0x00000012
1186 #define DPROV_CKK_DES 0x00000013
1187 #define DPROV_CKK_DES3 0x00000015
1188 #define DPROV_CKK_AES 0x0000001F
1189 #define DPROV_CKK_BLOWFISH 0x00000020
1192 * Find object context. Allows the find object init/find/final
1193 * to store data persistent across calls.
1195 typedef struct dprov_find_ctx {
1196 crypto_object_id_t fc_ids[DPROV_MAX_OBJECTS]; /* object ids */
1197 uint_t fc_nids; /* number of ids in fc_ids */
1198 uint_t fc_next; /* next id to return */
1199 } dprov_find_ctx_t;
1202 * Session management: each instance is associated with an array
1203 * of sessions. KEF providers sessions are always R/W the library and
1204 * the ioctl maintain the PKCS#11 R/W attributes for the session.
1207 #define DPROV_MIN_SESSIONS 32 /* # of sessions to start with */
1209 typedef enum dprov_session_state {
1210 DPROV_SESSION_STATE_PUBLIC, /* public (default) */
1211 DPROV_SESSION_STATE_SO, /* SO logged in */
1212 DPROV_SESSION_STATE_USER /* user logged in */
1213 } dprov_session_state_t;
1215 /* session description */
1216 typedef struct dprov_session {
1217 dprov_session_state_t ds_state; /* session state */
1218 dprov_object_t *ds_objects[DPROV_MAX_OBJECTS]; /* session objects */
1219 } dprov_session_t;
1222 static crypto_provider_info_t dprov_prov_info = {
1223 CRYPTO_SPI_VERSION_2,
1224 "Dummy Pseudo HW Provider",
1225 CRYPTO_HW_PROVIDER,
1226 NULL, /* pi_provider_dev */
1227 NULL, /* pi_provider_handle */
1228 &dprov_crypto_ops,
1229 sizeof (dprov_mech_info_tab)/sizeof (crypto_mech_info_t),
1230 dprov_mech_info_tab,
1231 0, /* pi_logical_provider_count */
1232 NULL, /* pi_logical_providers */
1233 0 /* pi_flags */
1237 * Per-instance info.
1239 typedef struct dprov_state {
1240 kmutex_t ds_lock; /* per-instance lock */
1241 dev_info_t *ds_dip; /* device info */
1242 crypto_kcf_provider_handle_t ds_prov_handle; /* framework handle */
1243 taskq_t *ds_taskq; /* taskq for async behavior */
1244 char ds_user_pin[DPROV_MAX_PIN_LEN]; /* normal user PIN */
1245 uint_t ds_user_pin_len;
1246 char ds_so_pin[DPROV_MAX_PIN_LEN]; /* SO PIN */
1247 uint_t ds_so_pin_len;
1248 dprov_session_t **ds_sessions; /* sessions for this instance */
1249 uint_t ds_sessions_slots; /* number of session slots */
1250 uint_t ds_sessions_count; /* number of open sessions */
1251 boolean_t ds_token_initialized; /* provider initialized? */
1252 boolean_t ds_user_pin_set; /* user pin set? */
1253 char ds_label[CRYPTO_EXT_SIZE_LABEL]; /* "token" label */
1254 dprov_object_t *ds_objects[DPROV_MAX_OBJECTS]; /* "token" objects */
1255 } dprov_state_t;
1259 * A taskq is associated with each instance of the pseudo driver in order
1260 * to simulate the asynchronous execution of requests.
1261 * The following defines the taskq request structures.
1264 /* request types */
1265 typedef enum dprov_req_type {
1266 /* digest requests */
1267 DPROV_REQ_DIGEST_INIT = 1,
1268 DPROV_REQ_DIGEST,
1269 DPROV_REQ_DIGEST_UPDATE,
1270 DPROV_REQ_DIGEST_KEY,
1271 DPROV_REQ_DIGEST_FINAL,
1272 DPROV_REQ_DIGEST_ATOMIC,
1273 /* cipher requests */
1274 DPROV_REQ_ENCRYPT_INIT,
1275 DPROV_REQ_ENCRYPT,
1276 DPROV_REQ_ENCRYPT_UPDATE,
1277 DPROV_REQ_ENCRYPT_FINAL,
1278 DPROV_REQ_ENCRYPT_ATOMIC,
1279 DPROV_REQ_DECRYPT_INIT,
1280 DPROV_REQ_DECRYPT,
1281 DPROV_REQ_DECRYPT_UPDATE,
1282 DPROV_REQ_DECRYPT_FINAL,
1283 DPROV_REQ_DECRYPT_ATOMIC,
1284 /* mac requests */
1285 DPROV_REQ_MAC_INIT,
1286 DPROV_REQ_MAC,
1287 DPROV_REQ_MAC_UPDATE,
1288 DPROV_REQ_MAC_FINAL,
1289 DPROV_REQ_MAC_ATOMIC,
1290 DPROV_REQ_MAC_VERIFY_ATOMIC,
1291 /* sign requests */
1292 DPROV_REQ_SIGN_INIT,
1293 DPROV_REQ_SIGN,
1294 DPROV_REQ_SIGN_UPDATE,
1295 DPROV_REQ_SIGN_FINAL,
1296 DPROV_REQ_SIGN_ATOMIC,
1297 DPROV_REQ_SIGN_RECOVER_INIT,
1298 DPROV_REQ_SIGN_RECOVER,
1299 DPROV_REQ_SIGN_RECOVER_ATOMIC,
1300 /* verify requests */
1301 DPROV_REQ_VERIFY_INIT,
1302 DPROV_REQ_VERIFY,
1303 DPROV_REQ_VERIFY_UPDATE,
1304 DPROV_REQ_VERIFY_FINAL,
1305 DPROV_REQ_VERIFY_ATOMIC,
1306 DPROV_REQ_VERIFY_RECOVER_INIT,
1307 DPROV_REQ_VERIFY_RECOVER,
1308 DPROV_REQ_VERIFY_RECOVER_ATOMIC,
1309 /* dual ops requests */
1310 DPROV_REQ_DIGEST_ENCRYPT_UPDATE,
1311 DPROV_REQ_DECRYPT_DIGEST_UPDATE,
1312 DPROV_REQ_SIGN_ENCRYPT_UPDATE,
1313 DPROV_REQ_DECRYPT_VERIFY_UPDATE,
1314 /* dual cipher/mac requests */
1315 DPROV_REQ_ENCRYPT_MAC_INIT,
1316 DPROV_REQ_ENCRYPT_MAC,
1317 DPROV_REQ_ENCRYPT_MAC_UPDATE,
1318 DPROV_REQ_ENCRYPT_MAC_FINAL,
1319 DPROV_REQ_ENCRYPT_MAC_ATOMIC,
1320 DPROV_REQ_MAC_DECRYPT_INIT,
1321 DPROV_REQ_MAC_DECRYPT,
1322 DPROV_REQ_MAC_DECRYPT_UPDATE,
1323 DPROV_REQ_MAC_DECRYPT_FINAL,
1324 DPROV_REQ_MAC_DECRYPT_ATOMIC,
1325 DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC,
1326 /* random number ops */
1327 DPROV_REQ_RANDOM_SEED,
1328 DPROV_REQ_RANDOM_GENERATE,
1329 /* session management requests */
1330 DPROV_REQ_SESSION_OPEN,
1331 DPROV_REQ_SESSION_CLOSE,
1332 DPROV_REQ_SESSION_LOGIN,
1333 DPROV_REQ_SESSION_LOGOUT,
1334 /* object management requests */
1335 DPROV_REQ_OBJECT_CREATE,
1336 DPROV_REQ_OBJECT_COPY,
1337 DPROV_REQ_OBJECT_DESTROY,
1338 DPROV_REQ_OBJECT_GET_SIZE,
1339 DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE,
1340 DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE,
1341 DPROV_REQ_OBJECT_FIND_INIT,
1342 DPROV_REQ_OBJECT_FIND,
1343 DPROV_REQ_OBJECT_FIND_FINAL,
1344 /* key management requests */
1345 DPROV_REQ_KEY_GENERATE,
1346 DPROV_REQ_KEY_GENERATE_PAIR,
1347 DPROV_REQ_KEY_WRAP,
1348 DPROV_REQ_KEY_UNWRAP,
1349 DPROV_REQ_KEY_DERIVE,
1350 /* provider management requests */
1351 DPROV_REQ_MGMT_EXTINFO,
1352 DPROV_REQ_MGMT_INITTOKEN,
1353 DPROV_REQ_MGMT_INITPIN,
1354 DPROV_REQ_MGMT_SETPIN,
1355 /* no (key)store key management requests */
1356 DPROV_REQ_NOSTORE_KEY_GENERATE,
1357 DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR,
1358 DPROV_REQ_NOSTORE_KEY_DERIVE
1359 } dprov_req_type_t;
1361 /* for DPROV_REQ_DIGEST requests */
1362 typedef struct dprov_digest_req {
1363 crypto_mechanism_t *dr_mechanism;
1364 crypto_ctx_t *dr_ctx;
1365 crypto_data_t *dr_data;
1366 crypto_key_t *dr_key;
1367 crypto_data_t *dr_digest;
1368 } dprov_digest_req_t;
1370 /* for DPROV_REQ_MAC requests */
1371 typedef struct dprov_mac_req {
1372 crypto_mechanism_t *dr_mechanism;
1373 crypto_ctx_t *dr_ctx;
1374 crypto_key_t *dr_key;
1375 crypto_data_t *dr_data;
1376 crypto_data_t *dr_mac;
1377 crypto_session_id_t dr_session_id;
1378 } dprov_mac_req_t;
1380 /* for DPROV_REQ_ENCRYPT and DPROV_REQ_DECRYPT requests */
1381 typedef struct dprov_cipher_req {
1382 crypto_mechanism_t *dr_mechanism;
1383 crypto_ctx_t *dr_ctx;
1384 crypto_key_t *dr_key;
1385 crypto_data_t *dr_plaintext;
1386 crypto_data_t *dr_ciphertext;
1387 crypto_session_id_t dr_session_id;
1388 } dprov_cipher_req_t;
1390 /* for DPROV_REQ_SIGN requests */
1391 typedef struct dprov_sign_req {
1392 crypto_mechanism_t *sr_mechanism;
1393 crypto_ctx_t *sr_ctx;
1394 crypto_key_t *sr_key;
1395 crypto_data_t *sr_data;
1396 crypto_data_t *sr_signature;
1397 crypto_session_id_t sr_session_id;
1398 } dprov_sign_req_t;
1400 /* for DPROV_REQ_VERIFY requests */
1401 typedef struct dprov_verify_req {
1402 crypto_mechanism_t *vr_mechanism;
1403 crypto_ctx_t *vr_ctx;
1404 crypto_key_t *vr_key;
1405 crypto_data_t *vr_data;
1406 crypto_data_t *vr_signature;
1407 crypto_session_id_t vr_session_id;
1408 } dprov_verify_req_t;
1410 /* for dual ops requests */
1411 typedef struct dprov_dual_req {
1412 crypto_ctx_t *dr_signverify_ctx;
1413 crypto_ctx_t *dr_cipher_ctx;
1414 crypto_data_t *dr_plaintext;
1415 crypto_data_t *dr_ciphertext;
1416 } dprov_dual_req_t;
1418 /* for cipher/mac dual ops requests */
1419 typedef struct dprov_cipher_mac_req {
1420 crypto_session_id_t mr_session_id;
1421 crypto_ctx_t *mr_ctx;
1422 crypto_mechanism_t *mr_cipher_mech;
1423 crypto_key_t *mr_cipher_key;
1424 crypto_mechanism_t *mr_mac_mech;
1425 crypto_key_t *mr_mac_key;
1426 crypto_dual_data_t *mr_dual_data;
1427 crypto_data_t *mr_data;
1428 crypto_data_t *mr_mac;
1429 } dprov_cipher_mac_req_t;
1431 /* for DPROV_REQ_RANDOM requests */
1432 typedef struct dprov_random_req {
1433 uchar_t *rr_buf;
1434 size_t rr_len;
1435 crypto_session_id_t rr_session_id;
1436 uint_t rr_entropy_est;
1437 uint32_t rr_flags;
1438 } dprov_random_req_t;
1440 /* for DPROV_REQ_SESSION requests */
1441 typedef struct dprov_session_req {
1442 crypto_session_id_t *sr_session_id_ptr;
1443 crypto_session_id_t sr_session_id;
1444 crypto_user_type_t sr_user_type;
1445 char *sr_pin;
1446 size_t sr_pin_len;
1447 } dprov_session_req_t;
1449 /* for DPROV_REQ_OBJECT requests */
1450 typedef struct dprov_object_req {
1451 crypto_session_id_t or_session_id;
1452 crypto_object_id_t or_object_id;
1453 crypto_object_attribute_t *or_template;
1454 uint_t or_attribute_count;
1455 crypto_object_id_t *or_object_id_ptr;
1456 size_t *or_object_size;
1457 void **or_find_pp;
1458 void *or_find_p;
1459 uint_t or_max_object_count;
1460 uint_t *or_object_count_ptr;
1461 } dprov_object_req_t;
1463 /* for DPROV_REQ_KEY requests */
1464 typedef struct dprov_key_req {
1465 crypto_session_id_t kr_session_id;
1466 crypto_mechanism_t *kr_mechanism;
1467 crypto_object_attribute_t *kr_template;
1468 uint_t kr_attribute_count;
1469 crypto_object_id_t *kr_object_id_ptr;
1470 crypto_object_attribute_t *kr_private_key_template;
1471 uint_t kr_private_key_attribute_count;
1472 crypto_object_id_t *kr_private_key_object_id_ptr;
1473 crypto_key_t *kr_key;
1474 uchar_t *kr_wrapped_key;
1475 size_t *kr_wrapped_key_len_ptr;
1476 crypto_object_attribute_t *kr_out_template1;
1477 crypto_object_attribute_t *kr_out_template2;
1478 uint_t kr_out_attribute_count1;
1479 uint_t kr_out_attribute_count2;
1480 } dprov_key_req_t;
1482 /* for DPROV_REQ_MGMT requests */
1483 typedef struct dprov_mgmt_req {
1484 crypto_session_id_t mr_session_id;
1485 char *mr_pin;
1486 size_t mr_pin_len;
1487 char *mr_old_pin;
1488 size_t mr_old_pin_len;
1489 char *mr_label;
1490 crypto_provider_ext_info_t *mr_ext_info;
1491 } dprov_mgmt_req_t;
1493 /* request, as queued on taskq */
1494 typedef struct dprov_req {
1495 dprov_req_type_t dr_type;
1496 dprov_state_t *dr_softc;
1497 crypto_req_handle_t dr_kcf_req;
1498 union {
1499 dprov_digest_req_t dru_digest_req;
1500 dprov_mac_req_t dru_mac_req;
1501 dprov_cipher_req_t dru_cipher_req;
1502 dprov_sign_req_t dru_sign_req;
1503 dprov_verify_req_t dru_verify_req;
1504 dprov_dual_req_t dru_dual_req;
1505 dprov_cipher_mac_req_t dru_cipher_mac_req;
1506 dprov_random_req_t dru_random_req;
1507 dprov_session_req_t dru_session_req;
1508 dprov_object_req_t dru_object_req;
1509 dprov_key_req_t dru_key_req;
1510 dprov_mgmt_req_t dru_mgmt_req;
1511 } dr_req;
1512 } dprov_req_t;
1514 /* shortcuts for union fields */
1515 #define dr_digest_req dr_req.dru_digest_req
1516 #define dr_mac_req dr_req.dru_mac_req
1517 #define dr_cipher_req dr_req.dru_cipher_req
1518 #define dr_sign_req dr_req.dru_sign_req
1519 #define dr_verify_req dr_req.dru_verify_req
1520 #define dr_dual_req dr_req.dru_dual_req
1521 #define dr_cipher_mac_req dr_req.dru_cipher_mac_req
1522 #define dr_random_req dr_req.dru_random_req
1523 #define dr_session_req dr_req.dru_session_req
1524 #define dr_object_req dr_req.dru_object_req
1525 #define dr_key_req dr_req.dru_key_req
1526 #define dr_mgmt_req dr_req.dru_mgmt_req
1528 /* prototypes for the tasq dispatcher functions */
1529 static void dprov_digest_task(dprov_req_t *);
1530 static void dprov_mac_task(dprov_req_t *);
1531 static void dprov_sign_task(dprov_req_t *);
1532 static void dprov_verify_task(dprov_req_t *);
1533 static void dprov_dual_task(dprov_req_t *);
1534 static void dprov_cipher_task(dprov_req_t *);
1535 static void dprov_cipher_mac_task(dprov_req_t *);
1536 static void dprov_random_task(dprov_req_t *);
1537 static void dprov_session_task(dprov_req_t *);
1538 static void dprov_object_task(dprov_req_t *);
1539 static void dprov_key_task(dprov_req_t *);
1540 static void dprov_mgmt_task(dprov_req_t *);
1542 /* helper functions */
1543 static int dprov_digest_submit_req(dprov_req_type_t, dprov_state_t *,
1544 crypto_req_handle_t, crypto_mechanism_t *, crypto_data_t *, crypto_key_t *,
1545 crypto_data_t *, crypto_ctx_t *, int);
1546 static int dprov_cipher_submit_req(dprov_req_type_t, dprov_state_t *,
1547 crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
1548 crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
1549 static int dprov_mac_submit_req(dprov_req_type_t, dprov_state_t *,
1550 crypto_req_handle_t, crypto_mechanism_t *, crypto_data_t *,
1551 crypto_key_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
1552 static int dprov_sign_submit_req(dprov_req_type_t, dprov_state_t *,
1553 crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *,
1554 crypto_data_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
1555 static int dprov_verify_submit_req(dprov_req_type_t, dprov_state_t *,
1556 crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *,
1557 crypto_data_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
1558 static int dprov_dual_submit_req(dprov_req_type_t, dprov_state_t *,
1559 crypto_req_handle_t, crypto_ctx_t *, crypto_ctx_t *, crypto_data_t *,
1560 crypto_data_t *);
1561 static int dprov_cipher_mac_submit_req(dprov_req_type_t, dprov_state_t *,
1562 crypto_req_handle_t, crypto_ctx_t *, crypto_session_id_t,
1563 crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *, crypto_key_t *,
1564 crypto_dual_data_t *, crypto_data_t *, crypto_data_t *, int);
1565 static int dprov_random_submit_req(dprov_req_type_t, dprov_state_t *,
1566 crypto_req_handle_t, uchar_t *, size_t, crypto_session_id_t, uint_t,
1567 uint32_t);
1568 static int dprov_session_submit_req(dprov_req_type_t, dprov_state_t *,
1569 crypto_req_handle_t, crypto_session_id_t *, crypto_session_id_t,
1570 crypto_user_type_t, char *, size_t);
1571 static int dprov_object_submit_req(dprov_req_type_t, dprov_state_t *,
1572 crypto_req_handle_t, crypto_session_id_t, crypto_object_id_t,
1573 crypto_object_attribute_t *, uint_t, crypto_object_id_t *, size_t *,
1574 void **, void *, uint_t, uint_t *, int);
1575 static int dprov_key_submit_req(dprov_req_type_t, dprov_state_t *,
1576 crypto_req_handle_t, crypto_session_id_t, crypto_mechanism_t *,
1577 crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
1578 crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
1579 crypto_key_t *, uchar_t *, size_t *, crypto_object_attribute_t *,
1580 uint_t, crypto_object_attribute_t *, uint_t);
1581 static int dprov_mgmt_submit_req(dprov_req_type_t, dprov_state_t *,
1582 crypto_req_handle_t, crypto_session_id_t, char *, size_t, char *, size_t,
1583 char *, crypto_provider_ext_info_t *);
1584 static int dprov_get_sw_prov(crypto_mechanism_t *, kcf_provider_desc_t **,
1585 crypto_mech_type_t *);
1587 /* object management helper functions */
1588 static void dprov_free_object(dprov_object_t *);
1589 static void dprov_release_session_objects(dprov_session_t *);
1590 static void dprov_adjust_attrs(crypto_object_attribute_t *, int);
1591 static boolean_t dprov_object_is_private(dprov_object_t *);
1592 static boolean_t dprov_object_is_token(dprov_object_t *);
1593 static int dprov_key_value_secret(dprov_state_t *, crypto_session_id_t,
1594 dprov_req_type_t, crypto_key_t *, crypto_key_t *);
1595 static int dprov_key_attr_asymmetric(dprov_state_t *, crypto_session_id_t,
1596 dprov_req_type_t, crypto_key_t *, crypto_key_t *);
1597 static int dprov_get_object_attr_boolean(dprov_object_t *, uint64_t,
1598 boolean_t *);
1599 static int dprov_get_object_attr_ulong(dprov_object_t *, uint64_t, ulong_t *);
1600 static int dprov_get_object_attr_array(dprov_object_t *, uint64_t, void **,
1601 size_t *);
1602 static int dprov_get_key_attr_ulong(crypto_key_t *, uint64_t, ulong_t *);
1603 static int dprov_get_key_attr_array(crypto_key_t *, uint64_t, void **,
1604 size_t *);
1605 static int dprov_create_object_from_template(dprov_state_t *, dprov_session_t *,
1606 crypto_object_attribute_t *, uint_t, crypto_object_id_t *, boolean_t,
1607 boolean_t);
1608 static int dprov_get_template_attr_scalar_common(crypto_object_attribute_t *,
1609 uint_t, uint64_t, void *, size_t);
1610 static int dprov_get_template_attr_boolean(crypto_object_attribute_t *,
1611 uint_t, uint64_t, boolean_t *);
1612 static int dprov_get_template_attr_ulong(crypto_object_attribute_t *, uint_t,
1613 uint64_t, ulong_t *);
1614 static int dprov_template_attr_present(crypto_object_attribute_t *, uint_t,
1615 uint64_t);
1616 static int dprov_get_template_attr_array(crypto_object_attribute_t *, uint_t,
1617 uint64_t, void **, size_t *);
1618 static int dprov_destroy_object(dprov_state_t *, dprov_session_t *,
1619 crypto_object_id_t);
1620 static int dprov_object_set_attr(dprov_session_t *, crypto_object_id_t,
1621 crypto_object_attribute_t *, uint_t, boolean_t);
1622 static int dprov_find_attr(crypto_object_attribute_t *, uint_t, uint64_t);
1623 static boolean_t dprov_attributes_match(dprov_object_t *,
1624 crypto_object_attribute_t *, uint_t);
1626 /* retrieve the softc and instance number from a SPI crypto context */
1627 #define DPROV_SOFTC_FROM_CTX(ctx, softc, instance) { \
1628 (softc) = (dprov_state_t *)(ctx)->cc_provider; \
1629 (instance) = ddi_get_instance((softc)->ds_dip); \
1632 /* retrieve the softc and instance number from a taskq request */
1633 #define DPROV_SOFTC_FROM_REQ(req, softc, instance) { \
1634 (softc) = (req)->dr_softc; \
1635 (instance) = ddi_get_instance((softc)->ds_dip); \
1639 * The dprov private context most of the time contains a pointer to the
1640 * crypto_context_t that was allocated when calling a KCF function.
1641 * Dual cipher/mac operations however require the dprov driver
1642 * to maintain the contexts associated with the separate cipher
1643 * and mac operations. These two types of dprov contexts are
1644 * defined below.
1646 typedef enum dprov_ctx_type {
1647 DPROV_CTX_SINGLE,
1648 DPROV_CTX_DUAL
1649 } dprov_ctx_type_t;
1652 * When the context refers to a single KCF context, the
1653 * cc_provider field of a crypto_ctx_t points to a structure of
1654 * type dprov_ctx_single.
1656 typedef struct dprov_ctx_single {
1657 dprov_ctx_type_t dc_type;
1658 crypto_context_t dc_ctx;
1659 boolean_t dc_svrfy_to_mac;
1660 } dprov_ctx_single_t;
1663 * When the context is used for cipher/mac operations, it contains
1664 * pointers to to KCF contexts, one for the cipher operation, the
1665 * other for the mac operation.
1667 typedef struct dprov_ctx_dual {
1668 dprov_ctx_type_t cd_type;
1669 crypto_context_t cd_cipher_ctx;
1670 crypto_context_t cd_mac_ctx;
1671 } dprov_ctx_dual_t;
1674 * Helper macros for context accessors. These macros return the
1675 * k-API context corresponding to the given SPI context for
1676 * single and dual cipher/mac operations.
1679 #define DPROV_CTX_P(_ctx) \
1680 ((dprov_ctx_single_t *)(_ctx)->cc_provider_private)
1682 #define DPROV_CTX_SINGLE(_ctx) ((DPROV_CTX_P(_ctx))->dc_ctx)
1684 #define DPROV_CTX_DUAL_CIPHER(_ctx) \
1685 (((dprov_ctx_dual_t *)(_ctx)->cc_provider_private)->cd_cipher_ctx)
1687 #define DPROV_CTX_DUAL_MAC(_ctx) \
1688 (((dprov_ctx_dual_t *)(_ctx)->cc_provider_private)->cd_mac_ctx)
1690 static int dprov_alloc_context(dprov_req_type_t, crypto_ctx_t *);
1694 static void *statep; /* state pointer */
1697 * DDI entry points.
1700 _init(void)
1702 int error;
1704 DPROV_DEBUG(D_INIT, ("dprov: in _init\n"));
1706 if ((error = ddi_soft_state_init(&statep, sizeof (dprov_state_t),
1707 0)) != 0)
1708 return (error);
1710 return (mod_install(&modlinkage));
1714 _fini(void)
1716 int error;
1718 DPROV_DEBUG(D_INIT, ("dprov: in _fini\n"));
1720 if ((error = mod_remove(&modlinkage)) != 0)
1721 return (error);
1723 ddi_soft_state_fini(&statep);
1725 return (0);
1729 _info(struct modinfo *modinfop)
1731 DPROV_DEBUG(D_INIT, ("dprov: in _info\n"));
1733 return (mod_info(&modlinkage, modinfop));
1736 /* ARGSUSED */
1737 static int
1738 dprov_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
1740 int instance = getminor((dev_t)arg);
1741 dprov_state_t *softc;
1743 DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_getinfo() for %d\n",
1744 instance));
1746 switch (cmd) {
1747 case DDI_INFO_DEVT2DEVINFO:
1748 softc = ddi_get_soft_state(statep, instance);
1749 *result = softc->ds_dip;
1750 return (DDI_SUCCESS);
1752 case DDI_INFO_DEVT2INSTANCE:
1753 *result = (void *)(uintptr_t)instance;
1754 return (DDI_SUCCESS);
1756 return (DDI_FAILURE);
1759 static int
1760 dprov_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1762 int instance = ddi_get_instance(dip);
1763 dprov_state_t *softc;
1764 char devname[256];
1765 int ret;
1767 DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_attach() for %d\n",
1768 instance));
1770 if (cmd != DDI_ATTACH) {
1771 return (DDI_FAILURE);
1774 /* get new softc and initialize it */
1775 if (ddi_soft_state_zalloc(statep, instance) != DDI_SUCCESS)
1776 return (DDI_FAILURE);
1778 softc = ddi_get_soft_state(statep, instance);
1779 mutex_init(&softc->ds_lock, NULL, MUTEX_DRIVER, NULL);
1780 softc->ds_dip = dip;
1781 softc->ds_prov_handle = NULL;
1783 /* create minor node */
1784 (void) sprintf(devname, "dprov%d", instance);
1785 if (ddi_create_minor_node(dip, devname, S_IFCHR, instance,
1786 DDI_PSEUDO, 0) != DDI_SUCCESS) {
1787 cmn_err(CE_WARN, "attach: failed creating minor node");
1788 mutex_destroy(&softc->ds_lock);
1789 ddi_soft_state_free(statep, instance);
1790 return (DDI_FAILURE);
1793 nostore_key_gen = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1794 DDI_PROP_DONTPASS, "nostore_key_gen", 0);
1795 if (nostore_key_gen != 0) {
1796 dprov_prov_info.pi_interface_version = CRYPTO_SPI_VERSION_3;
1797 dprov_crypto_ops.co_object_ops = NULL;
1798 dprov_crypto_ops.co_nostore_key_ops = &dprov_nostore_key_ops;
1801 dprov_max_digestsz = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1802 DDI_PROP_DONTPASS, "max_digest_sz", INT_MAX);
1803 if (dprov_max_digestsz != INT_MAX && dprov_max_digestsz != 0 &&
1804 dprov_max_digestsz != DDI_PROP_NOT_FOUND) {
1805 dprov_no_multipart = B_TRUE;
1806 dprov_prov_info.pi_flags |=
1807 (CRYPTO_HASH_NO_UPDATE | CRYPTO_HMAC_NO_UPDATE);
1810 /* create taskq */
1811 softc->ds_taskq = taskq_create(devname, 1, minclsyspri,
1812 crypto_taskq_minalloc, crypto_taskq_maxalloc, TASKQ_PREPOPULATE);
1814 /* initialize table of sessions */
1815 softc->ds_sessions = kmem_zalloc(DPROV_MIN_SESSIONS *
1816 sizeof (dprov_session_t *), KM_SLEEP);
1817 softc->ds_sessions_slots = DPROV_MIN_SESSIONS;
1818 softc->ds_sessions_count = 0;
1820 /* initialized done by init_token entry point */
1821 softc->ds_token_initialized = B_TRUE;
1823 (void) memset(softc->ds_label, ' ', CRYPTO_EXT_SIZE_LABEL);
1824 bcopy("Dummy Pseudo HW Provider", softc->ds_label, 24);
1826 bcopy("changeme", softc->ds_user_pin, 8);
1827 softc->ds_user_pin_len = 8;
1828 softc->ds_user_pin_set = B_TRUE;
1830 /* register with the crypto framework */
1831 dprov_prov_info.pi_provider_dev.pd_hw = dip;
1832 dprov_prov_info.pi_provider_handle = softc;
1834 if (dprov_no_multipart) { /* Export only single part */
1835 dprov_digest_ops.digest_update = NULL;
1836 dprov_digest_ops.digest_key = NULL;
1837 dprov_digest_ops.digest_final = NULL;
1838 dprov_object_ops.object_create = NULL;
1841 if ((ret = crypto_register_provider(&dprov_prov_info,
1842 &softc->ds_prov_handle)) != CRYPTO_SUCCESS) {
1843 cmn_err(CE_WARN,
1844 "dprov crypto_register_provider() failed (0x%x)", ret);
1845 taskq_destroy(softc->ds_taskq);
1846 kmem_free(softc->ds_sessions, softc->ds_sessions_slots *
1847 sizeof (dprov_session_t *));
1848 mutex_destroy(&softc->ds_lock);
1849 ddi_soft_state_free(statep, instance);
1850 ddi_remove_minor_node(dip, NULL);
1851 return (DDI_FAILURE);
1855 * This call is for testing only; it is not required by the SPI.
1857 crypto_provider_notification(softc->ds_prov_handle,
1858 CRYPTO_PROVIDER_READY);
1860 return (DDI_SUCCESS);
1863 static int
1864 dprov_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1866 int instance = ddi_get_instance(dip);
1867 dprov_state_t *softc = ddi_get_soft_state(statep, instance);
1868 dprov_session_t *session;
1869 int i, ret;
1871 DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_detach() for %d\n",
1872 instance));
1874 if (cmd != DDI_DETACH)
1875 return (DDI_FAILURE);
1877 /* unregister from the crypto framework */
1878 if (softc->ds_prov_handle != NULL)
1879 if ((ret = crypto_unregister_provider(
1880 softc->ds_prov_handle)) != CRYPTO_SUCCESS) {
1881 cmn_err(CE_WARN, "dprov_detach: "
1882 "crypto_unregister_provider() "
1883 "failed (0x%x)", ret);
1884 return (DDI_FAILURE);
1888 taskq_destroy(softc->ds_taskq);
1890 for (i = 0; i < softc->ds_sessions_slots; i++) {
1891 if ((session = softc->ds_sessions[i]) == NULL)
1892 continue;
1894 dprov_release_session_objects(session);
1896 kmem_free(session, sizeof (dprov_session_t));
1897 softc->ds_sessions_count--;
1901 kmem_free(softc->ds_sessions, softc->ds_sessions_slots *
1902 sizeof (dprov_session_t *));
1903 /* free token objects */
1904 for (i = 0; i < DPROV_MAX_OBJECTS; i++)
1905 if (softc->ds_objects[i] != NULL)
1906 dprov_free_object(softc->ds_objects[i]);
1908 mutex_destroy(&softc->ds_lock);
1909 ddi_soft_state_free(statep, instance);
1911 ddi_remove_minor_node(dip, NULL);
1913 return (DDI_SUCCESS);
1917 * Control entry points.
1919 static void
1920 dprov_provider_status(crypto_provider_handle_t provider, uint_t *status)
1922 _NOTE(ARGUNUSED(provider))
1924 *status = CRYPTO_PROVIDER_READY;
1928 * Digest entry points.
1931 static int
1932 dprov_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
1933 crypto_req_handle_t req)
1935 int error = CRYPTO_FAILED;
1936 dprov_state_t *softc;
1937 /* LINTED E_FUNC_SET_NOT_USED */
1938 int instance;
1940 /* extract softc and instance number from context */
1941 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
1942 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_init: started\n", instance));
1944 /* check mechanism */
1945 if (mechanism->cm_type != MD4_MECH_INFO_TYPE &&
1946 mechanism->cm_type != MD5_MECH_INFO_TYPE &&
1947 mechanism->cm_type != SHA1_MECH_INFO_TYPE &&
1948 mechanism->cm_type != SHA256_MECH_INFO_TYPE &&
1949 mechanism->cm_type != SHA384_MECH_INFO_TYPE &&
1950 mechanism->cm_type != SHA512_MECH_INFO_TYPE) {
1951 cmn_err(CE_WARN, "dprov_digest_init: unexpected mech type "
1952 "0x%llx\n", (unsigned long long)mechanism->cm_type);
1953 return (CRYPTO_MECHANISM_INVALID);
1956 /* submit request to the taskq */
1957 error = dprov_digest_submit_req(DPROV_REQ_DIGEST_INIT, softc, req,
1958 mechanism, NULL, NULL, NULL, ctx, KM_SLEEP);
1960 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_init: done err = 0x%x\n",
1961 instance, error));
1963 return (error);
1966 static int
1967 dprov_digest(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *digest,
1968 crypto_req_handle_t req)
1970 int error = CRYPTO_FAILED;
1971 dprov_state_t *softc;
1972 /* LINTED E_FUNC_SET_NOT_USED */
1973 int instance;
1975 if (dprov_no_multipart && data->cd_length > dprov_max_digestsz)
1976 return (CRYPTO_BUFFER_TOO_BIG);
1978 /* extract softc and instance number from context */
1979 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
1980 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest: started\n", instance));
1982 /* submit request to the taskq */
1983 error = dprov_digest_submit_req(DPROV_REQ_DIGEST, softc, req,
1984 NULL, data, NULL, digest, ctx, KM_NOSLEEP);
1986 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest: done, err = 0x%x\n",
1987 instance, error));
1989 return (error);
1992 static int
1993 dprov_digest_update(crypto_ctx_t *ctx, crypto_data_t *data,
1994 crypto_req_handle_t req)
1996 int error = CRYPTO_FAILED;
1997 dprov_state_t *softc;
1998 /* LINTED E_FUNC_SET_NOT_USED */
1999 int instance;
2001 /* extract softc and instance number from context */
2002 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2003 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_update: started\n",
2004 instance));
2006 /* submit request to the taskq */
2007 error = dprov_digest_submit_req(DPROV_REQ_DIGEST_UPDATE, softc,
2008 req, NULL, data, NULL, NULL, ctx, KM_NOSLEEP);
2010 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_update: done err = 0x0%x\n",
2011 instance, error));
2013 return (error);
2016 static int
2017 dprov_digest_key(crypto_ctx_t *ctx, crypto_key_t *key, crypto_req_handle_t req)
2019 int error = CRYPTO_FAILED;
2020 dprov_state_t *softc;
2021 /* LINTED E_FUNC_SET_NOT_USED */
2022 int instance;
2024 /* extract softc and instance number from context */
2025 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2026 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_key: started\n", instance));
2028 /* submit request to the taskq */
2029 error = dprov_digest_submit_req(DPROV_REQ_DIGEST_KEY, softc, req, NULL,
2030 NULL, key, NULL, ctx, KM_NOSLEEP);
2032 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_key: done err = 0x0%x\n",
2033 instance, error));
2035 return (error);
2038 static int
2039 dprov_digest_final(crypto_ctx_t *ctx, crypto_data_t *digest,
2040 crypto_req_handle_t req)
2042 int error = CRYPTO_FAILED;
2043 dprov_state_t *softc;
2044 /* LINTED E_FUNC_SET_NOT_USED */
2045 int instance;
2047 /* extract softc and instance number from context */
2048 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2049 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_final: started\n", instance));
2051 /* submit request to the taskq */
2052 error = dprov_digest_submit_req(DPROV_REQ_DIGEST_FINAL, softc, req,
2053 NULL, NULL, NULL, digest, ctx, KM_NOSLEEP);
2055 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_final: done err = 0x0%x\n",
2056 instance, error));
2058 return (error);
2061 /* ARGSUSED */
2062 static int
2063 dprov_digest_atomic(crypto_provider_handle_t provider,
2064 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
2065 crypto_data_t *data, crypto_data_t *digest,
2066 crypto_req_handle_t req)
2068 int error = CRYPTO_FAILED;
2069 dprov_state_t *softc = (dprov_state_t *)provider;
2070 /* LINTED E_FUNC_SET_NOT_USED */
2071 int instance;
2073 if (dprov_no_multipart && data->cd_length > dprov_max_digestsz)
2074 return (CRYPTO_BUFFER_TOO_BIG);
2076 instance = ddi_get_instance(softc->ds_dip);
2077 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_atomic: started\n",
2078 instance));
2080 /* check mechanism */
2081 if (mechanism->cm_type != MD4_MECH_INFO_TYPE &&
2082 mechanism->cm_type != MD5_MECH_INFO_TYPE &&
2083 mechanism->cm_type != SHA1_MECH_INFO_TYPE &&
2084 mechanism->cm_type != SHA256_MECH_INFO_TYPE &&
2085 mechanism->cm_type != SHA384_MECH_INFO_TYPE &&
2086 mechanism->cm_type != SHA512_MECH_INFO_TYPE) {
2087 cmn_err(CE_WARN, "dprov_digest_atomic: unexpected mech type "
2088 "0x%llx\n", (unsigned long long)mechanism->cm_type);
2089 return (CRYPTO_MECHANISM_INVALID);
2092 /* submit request to the taskq */
2093 error = dprov_digest_submit_req(DPROV_REQ_DIGEST_ATOMIC, softc, req,
2094 mechanism, data, NULL, digest, NULL, KM_SLEEP);
2096 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_atomic: done err = 0x0%x\n",
2097 instance, error));
2099 return (error);
2103 * MAC entry points.
2107 * Checks whether the specified mech_type is supported by mac
2108 * entry points.
2110 static boolean_t
2111 dprov_valid_mac_mech(crypto_mech_type_t mech_type)
2113 return (mech_type == MD5_HMAC_MECH_INFO_TYPE ||
2114 mech_type == MD5_HMAC_GEN_MECH_INFO_TYPE ||
2115 mech_type == SHA1_HMAC_MECH_INFO_TYPE ||
2116 mech_type == SHA1_HMAC_GEN_MECH_INFO_TYPE ||
2117 mech_type == SHA256_HMAC_MECH_INFO_TYPE ||
2118 mech_type == SHA256_HMAC_GEN_MECH_INFO_TYPE ||
2119 mech_type == SHA384_HMAC_MECH_INFO_TYPE ||
2120 mech_type == SHA384_HMAC_GEN_MECH_INFO_TYPE ||
2121 mech_type == SHA512_HMAC_MECH_INFO_TYPE ||
2122 mech_type == SHA512_HMAC_GEN_MECH_INFO_TYPE ||
2123 mech_type == AES_GMAC_MECH_INFO_TYPE ||
2124 mech_type == AES_CMAC_MECH_INFO_TYPE);
2127 static int
2128 dprov_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
2129 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
2130 crypto_req_handle_t req)
2132 int error = CRYPTO_FAILED;
2133 dprov_state_t *softc;
2134 /* LINTED E_FUNC_SET_NOT_USED */
2135 int instance;
2137 /* extract softc and instance number from context */
2138 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2139 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_init: started\n", instance));
2141 /* check mechanism */
2142 if (!dprov_valid_mac_mech(mechanism->cm_type)) {
2143 cmn_err(CE_WARN, "dprov_mac_init: unexpected mech type "
2144 "0x%llx\n", (unsigned long long)mechanism->cm_type);
2145 return (CRYPTO_MECHANISM_INVALID);
2148 if (ctx_template != NULL)
2149 return (CRYPTO_ARGUMENTS_BAD);
2151 /* submit request to the taskq */
2152 error = dprov_mac_submit_req(DPROV_REQ_MAC_INIT, softc, req,
2153 mechanism, NULL, key, NULL, ctx, 0, KM_SLEEP);
2155 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_init: done err = 0x%x\n",
2156 instance, error));
2158 return (error);
2161 static int
2162 dprov_mac(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *mac,
2163 crypto_req_handle_t req)
2165 int error = CRYPTO_FAILED;
2166 dprov_state_t *softc;
2167 /* LINTED E_FUNC_SET_NOT_USED */
2168 int instance;
2170 /* extract softc and instance number from context */
2171 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2172 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac: started\n", instance));
2174 /* submit request to the taskq */
2175 error = dprov_mac_submit_req(DPROV_REQ_MAC, softc, req,
2176 NULL, data, NULL, mac, ctx, 0, KM_NOSLEEP);
2178 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac: done, err = 0x%x\n", instance,
2179 error));
2181 return (error);
2184 static int
2185 dprov_mac_update(crypto_ctx_t *ctx, crypto_data_t *data,
2186 crypto_req_handle_t req)
2188 int error = CRYPTO_FAILED;
2189 dprov_state_t *softc;
2190 /* LINTED E_FUNC_SET_NOT_USED */
2191 int instance;
2193 /* extract softc and instance number from context */
2194 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2195 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_update: started\n", instance));
2197 /* submit request to the taskq */
2198 error = dprov_mac_submit_req(DPROV_REQ_MAC_UPDATE, softc,
2199 req, NULL, data, NULL, NULL, ctx, 0, KM_NOSLEEP);
2201 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_update: done err = 0x0%x\n",
2202 instance, error));
2204 return (error);
2207 static int
2208 dprov_mac_final(crypto_ctx_t *ctx, crypto_data_t *mac, crypto_req_handle_t req)
2210 int error = CRYPTO_FAILED;
2211 dprov_state_t *softc;
2212 /* LINTED E_FUNC_SET_NOT_USED */
2213 int instance;
2215 /* extract softc and instance number from context */
2216 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2217 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_final: started\n", instance));
2219 /* submit request to the taskq */
2220 error = dprov_mac_submit_req(DPROV_REQ_MAC_FINAL, softc, req,
2221 NULL, NULL, NULL, mac, ctx, 0, KM_NOSLEEP);
2223 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_final: done err = 0x0%x\n",
2224 instance, error));
2226 return (error);
2229 static int
2230 dprov_mac_atomic(crypto_provider_handle_t provider,
2231 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
2232 crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
2233 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
2235 int error = CRYPTO_FAILED;
2236 dprov_state_t *softc = (dprov_state_t *)provider;
2237 /* LINTED E_FUNC_SET_NOT_USED */
2238 int instance;
2240 instance = ddi_get_instance(softc->ds_dip);
2241 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_atomic: started\n", instance));
2243 if (ctx_template != NULL)
2244 return (CRYPTO_ARGUMENTS_BAD);
2246 /* check mechanism */
2247 if (!dprov_valid_mac_mech(mechanism->cm_type)) {
2248 cmn_err(CE_WARN, "dprov_mac_atomic: unexpected mech type "
2249 "0x%llx\n", (unsigned long long)mechanism->cm_type);
2250 return (CRYPTO_MECHANISM_INVALID);
2253 /* submit request to the taskq */
2254 error = dprov_mac_submit_req(DPROV_REQ_MAC_ATOMIC, softc, req,
2255 mechanism, data, key, mac, NULL, session_id, KM_SLEEP);
2257 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_atomic: done err = 0x0%x\n",
2258 instance, error));
2260 return (error);
2263 static int
2264 dprov_mac_verify_atomic(crypto_provider_handle_t provider,
2265 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
2266 crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
2267 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
2269 int error = CRYPTO_FAILED;
2270 dprov_state_t *softc = (dprov_state_t *)provider;
2271 /* LINTED E_FUNC_SET_NOT_USED */
2272 int instance;
2274 instance = ddi_get_instance(softc->ds_dip);
2275 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_verify_atomic: started\n",
2276 instance));
2278 if (ctx_template != NULL)
2279 return (CRYPTO_ARGUMENTS_BAD);
2281 /* check mechanism */
2282 if (!dprov_valid_mac_mech(mechanism->cm_type)) {
2283 cmn_err(CE_WARN, "dprov_mac_verify_atomic: unexpected mech "
2284 "type 0x%llx\n", (unsigned long long)mechanism->cm_type);
2285 return (CRYPTO_MECHANISM_INVALID);
2288 /* submit request to the taskq */
2289 error = dprov_mac_submit_req(DPROV_REQ_MAC_VERIFY_ATOMIC, softc, req,
2290 mechanism, data, key, mac, NULL, session_id, KM_SLEEP);
2292 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_verify_atomic: done err = 0x0%x\n",
2293 instance, error));
2295 return (error);
2299 * Cipher (encrypt/decrypt) entry points.
2303 * Checks whether the specified mech_type is supported by cipher entry
2304 * points.
2306 static boolean_t
2307 dprov_valid_cipher_mech(crypto_mech_type_t mech_type)
2309 return (mech_type == DES_CBC_MECH_INFO_TYPE ||
2310 mech_type == DES3_CBC_MECH_INFO_TYPE ||
2311 mech_type == DES_ECB_MECH_INFO_TYPE ||
2312 mech_type == DES3_ECB_MECH_INFO_TYPE ||
2313 mech_type == BLOWFISH_CBC_MECH_INFO_TYPE ||
2314 mech_type == BLOWFISH_ECB_MECH_INFO_TYPE ||
2315 mech_type == AES_CBC_MECH_INFO_TYPE ||
2316 mech_type == AES_CMAC_MECH_INFO_TYPE ||
2317 mech_type == AES_ECB_MECH_INFO_TYPE ||
2318 mech_type == AES_CTR_MECH_INFO_TYPE ||
2319 mech_type == AES_CCM_MECH_INFO_TYPE ||
2320 mech_type == AES_GCM_MECH_INFO_TYPE ||
2321 mech_type == AES_GMAC_MECH_INFO_TYPE ||
2322 mech_type == RC4_MECH_INFO_TYPE ||
2323 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);
2332 static boolean_t
2333 is_publickey_mech(crypto_mech_type_t mech_type)
2335 return (mech_type == RSA_PKCS_MECH_INFO_TYPE ||
2336 mech_type == RSA_X_509_MECH_INFO_TYPE ||
2337 mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE ||
2338 mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE ||
2339 mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE ||
2340 mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE ||
2341 mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE ||
2342 mech_type == ECDSA_SHA1_MECH_INFO_TYPE ||
2343 mech_type == ECDSA_MECH_INFO_TYPE);
2347 /* ARGSUSED */
2348 static int
2349 dprov_encrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
2350 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
2351 crypto_req_handle_t req)
2353 int error = CRYPTO_FAILED;
2354 dprov_state_t *softc;
2355 /* LINTED E_FUNC_SET_NOT_USED */
2356 int instance;
2358 /* extract softc and instance number from context */
2359 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2360 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_init: started\n",
2361 instance));
2363 /* check mechanism */
2364 if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
2365 cmn_err(CE_WARN, "dprov_encrypt_init: unexpected mech type "
2366 "0x%llx\n", (unsigned long long)mechanism->cm_type);
2367 return (CRYPTO_MECHANISM_INVALID);
2370 /* submit request to the taskq */
2371 error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_INIT, softc,
2372 req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
2374 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_init: done err = 0x0%x\n",
2375 instance, error));
2377 return (error);
2380 /* ARGSUSED */
2381 static int
2382 dprov_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
2383 crypto_data_t *ciphertext, crypto_req_handle_t req)
2385 int error = CRYPTO_FAILED;
2386 dprov_state_t *softc;
2387 /* LINTED E_FUNC_SET_NOT_USED */
2388 int instance;
2390 /* extract softc and instance number from context */
2391 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2392 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt: started\n", instance));
2394 /* submit request to the taskq */
2395 error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT, softc,
2396 req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
2398 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt: done err = 0x0%x\n",
2399 instance, error));
2401 return (error);
2404 /* ARGSUSED */
2405 static int
2406 dprov_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
2407 crypto_data_t *ciphertext, crypto_req_handle_t req)
2409 int error = CRYPTO_FAILED;
2410 dprov_state_t *softc;
2411 /* LINTED E_FUNC_SET_NOT_USED */
2412 int instance;
2414 /* extract softc and instance number from context */
2415 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2416 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_update: started\n",
2417 instance));
2419 /* submit request to the taskq */
2420 error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_UPDATE, softc,
2421 req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
2423 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_update: done err = 0x0%x\n",
2424 instance, error));
2426 return (error);
2429 /* ARGSUSED */
2430 static int
2431 dprov_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
2432 crypto_req_handle_t req)
2434 int error = CRYPTO_FAILED;
2435 dprov_state_t *softc;
2436 /* LINTED E_FUNC_SET_NOT_USED */
2437 int instance;
2439 /* extract softc and instance number from context */
2440 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2441 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_final: started\n",
2442 instance));
2444 /* submit request to the taskq */
2445 error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_FINAL, softc,
2446 req, NULL, NULL, NULL, ciphertext, ctx, 0, KM_NOSLEEP);
2448 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_final: done err = 0x0%x\n",
2449 instance, error));
2451 return (error);
2454 static int
2455 dprov_encrypt_atomic(crypto_provider_handle_t provider,
2456 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
2457 crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext,
2458 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
2460 int error = CRYPTO_FAILED;
2461 dprov_state_t *softc = (dprov_state_t *)provider;
2462 /* LINTED E_FUNC_SET_NOT_USED */
2463 int instance;
2465 instance = ddi_get_instance(softc->ds_dip);
2466 DPROV_DEBUG(D_MAC, ("(%d) dprov_encrypt_atomic: started\n", instance));
2468 if (ctx_template != NULL)
2469 return (CRYPTO_ARGUMENTS_BAD);
2471 /* check mechanism */
2472 if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
2473 cmn_err(CE_WARN, "dprov_encrypt_atomic: unexpected mech type "
2474 "0x%llx\n", (unsigned long long)mechanism->cm_type);
2475 return (CRYPTO_MECHANISM_INVALID);
2478 error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_ATOMIC, softc,
2479 req, mechanism, key, plaintext, ciphertext, NULL, session_id,
2480 KM_SLEEP);
2482 DPROV_DEBUG(D_MAC, ("(%d) dprov_encrypt_atomic: done err = 0x0%x\n",
2483 instance, error));
2485 return (error);
2488 /* ARGSUSED */
2489 static int
2490 dprov_decrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
2491 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
2492 crypto_req_handle_t req)
2494 int error = CRYPTO_FAILED;
2495 dprov_state_t *softc;
2496 /* LINTED E_FUNC_SET_NOT_USED */
2497 int instance;
2499 /* extract softc and instance number from context */
2500 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2501 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_init: started\n",
2502 instance));
2504 /* check mechanism */
2505 if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
2506 cmn_err(CE_WARN, "dprov_decrypt_init: unexpected mech type "
2507 "0x%llx\n", (unsigned long long)mechanism->cm_type);
2508 return (CRYPTO_MECHANISM_INVALID);
2511 /* submit request to the taskq */
2512 error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_INIT, softc,
2513 req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
2515 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_init: done err = 0x0%x\n",
2516 instance, error));
2518 return (error);
2521 /* ARGSUSED */
2522 static int
2523 dprov_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
2524 crypto_data_t *plaintext, crypto_req_handle_t req)
2526 int error = CRYPTO_FAILED;
2528 dprov_state_t *softc;
2529 /* LINTED E_FUNC_SET_NOT_USED */
2530 int instance;
2532 /* extract softc and instance number from context */
2533 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2534 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt: started\n", instance));
2536 /* submit request to the taskq */
2537 error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT, softc,
2538 req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
2540 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt: done err = 0x0%x\n",
2541 instance, error));
2543 return (error);
2546 /* ARGSUSED */
2547 static int
2548 dprov_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
2549 crypto_data_t *plaintext, crypto_req_handle_t req)
2551 int error = CRYPTO_FAILED;
2552 dprov_state_t *softc;
2553 /* LINTED E_FUNC_SET_NOT_USED */
2554 int instance;
2556 /* extract softc and instance number from context */
2557 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2558 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_update: started\n",
2559 instance));
2561 /* submit request to the taskq */
2562 error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_UPDATE, softc,
2563 req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
2565 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_update: done err = 0x0%x\n",
2566 instance, error));
2568 return (error);
2571 /* ARGSUSED */
2572 static int
2573 dprov_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *plaintext,
2574 crypto_req_handle_t req)
2576 int error = CRYPTO_FAILED;
2577 dprov_state_t *softc;
2578 /* LINTED E_FUNC_SET_NOT_USED */
2579 int instance;
2581 /* extract softc and instance number from context */
2582 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2583 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_final: started\n",
2584 instance));
2586 /* submit request to the taskq */
2587 error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_FINAL, softc,
2588 req, NULL, NULL, plaintext, NULL, ctx, 0, KM_NOSLEEP);
2590 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_final: done err = 0x0%x\n",
2591 instance, error));
2593 return (error);
2596 static int
2597 dprov_decrypt_atomic(crypto_provider_handle_t provider,
2598 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
2599 crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext,
2600 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
2602 int error = CRYPTO_FAILED;
2603 dprov_state_t *softc = (dprov_state_t *)provider;
2604 /* LINTED E_FUNC_SET_NOT_USED */
2605 int instance;
2607 instance = ddi_get_instance(softc->ds_dip);
2608 DPROV_DEBUG(D_MAC, ("(%d) dprov_decrypt_atomic: started\n", instance));
2610 if (ctx_template != NULL)
2611 return (CRYPTO_ARGUMENTS_BAD);
2613 /* check mechanism */
2614 if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
2615 cmn_err(CE_WARN, "dprov_atomic_init: unexpected mech type "
2616 "0x%llx\n", (unsigned long long)mechanism->cm_type);
2617 return (CRYPTO_MECHANISM_INVALID);
2620 error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_ATOMIC, softc,
2621 req, mechanism, key, plaintext, ciphertext, NULL, session_id,
2622 KM_SLEEP);
2624 DPROV_DEBUG(D_MAC, ("(%d) dprov_decrypt_atomic: done err = 0x0%x\n",
2625 instance, error));
2627 return (error);
2631 * Sign entry points.
2635 * Checks whether the specified mech_type is supported by sign/verify
2636 * entry points.
2638 static boolean_t
2639 dprov_valid_sign_verif_mech(crypto_mech_type_t mech_type)
2641 return (mech_type == MD5_HMAC_MECH_INFO_TYPE ||
2642 mech_type == MD5_HMAC_GEN_MECH_INFO_TYPE ||
2643 mech_type == SHA1_HMAC_MECH_INFO_TYPE ||
2644 mech_type == SHA1_HMAC_GEN_MECH_INFO_TYPE ||
2645 mech_type == SHA256_HMAC_MECH_INFO_TYPE ||
2646 mech_type == SHA256_HMAC_GEN_MECH_INFO_TYPE ||
2647 mech_type == SHA384_HMAC_MECH_INFO_TYPE ||
2648 mech_type == SHA384_HMAC_GEN_MECH_INFO_TYPE ||
2649 mech_type == SHA512_HMAC_MECH_INFO_TYPE ||
2650 mech_type == SHA512_HMAC_GEN_MECH_INFO_TYPE ||
2651 mech_type == RSA_PKCS_MECH_INFO_TYPE ||
2652 mech_type == RSA_X_509_MECH_INFO_TYPE ||
2653 mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE ||
2654 mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE ||
2655 mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE ||
2656 mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE ||
2657 mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE ||
2658 mech_type == ECDSA_SHA1_MECH_INFO_TYPE ||
2659 mech_type == ECDSA_MECH_INFO_TYPE);
2662 static int
2663 dprov_sign_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
2664 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
2665 crypto_req_handle_t req)
2667 int error = CRYPTO_FAILED;
2668 dprov_state_t *softc;
2669 /* LINTED E_FUNC_SET_NOT_USED */
2670 int instance;
2672 /* extract softc and instance number from context */
2673 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2674 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_init: started\n", instance));
2676 /* check mechanism */
2677 if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
2678 cmn_err(CE_WARN, "dprov_sign_init: unexpected mech type "
2679 "0x%llx\n", (unsigned long long)mechanism->cm_type);
2680 return (CRYPTO_MECHANISM_INVALID);
2683 if (ctx_template != NULL)
2684 return (CRYPTO_ARGUMENTS_BAD);
2686 /* submit request to the taskq */
2687 error = dprov_sign_submit_req(DPROV_REQ_SIGN_INIT, softc, req,
2688 mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
2690 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_init: done err = 0x%x\n",
2691 instance, error));
2693 return (error);
2696 static int
2697 dprov_sign(crypto_ctx_t *ctx, crypto_data_t *data,
2698 crypto_data_t *signature, crypto_req_handle_t req)
2700 int error = CRYPTO_FAILED;
2701 dprov_state_t *softc;
2702 /* LINTED E_FUNC_SET_NOT_USED */
2703 int instance;
2705 /* extract softc and instance number from context */
2706 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2707 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign: started\n", instance));
2709 /* submit request to the taskq */
2710 error = dprov_sign_submit_req(DPROV_REQ_SIGN, softc, req,
2711 NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
2713 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign: done err = 0x%x\n",
2714 instance, error));
2716 return (error);
2719 static int
2720 dprov_sign_update(crypto_ctx_t *ctx, crypto_data_t *data,
2721 crypto_req_handle_t req)
2723 int error = CRYPTO_FAILED;
2724 dprov_state_t *softc;
2725 /* LINTED E_FUNC_SET_NOT_USED */
2726 int instance;
2728 /* extract softc and instance number from context */
2729 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2730 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_update: started\n", instance));
2732 /* submit request to the taskq */
2733 error = dprov_sign_submit_req(DPROV_REQ_SIGN_UPDATE, softc, req,
2734 NULL, NULL, data, NULL, ctx, 0, KM_NOSLEEP);
2736 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_update: done err = 0x%x\n",
2737 instance, error));
2739 return (error);
2742 static int
2743 dprov_sign_final(crypto_ctx_t *ctx, crypto_data_t *signature,
2744 crypto_req_handle_t req)
2746 int error = CRYPTO_FAILED;
2747 dprov_state_t *softc;
2748 /* LINTED E_FUNC_SET_NOT_USED */
2749 int instance;
2751 /* extract softc and instance number from context */
2752 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2753 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_final: started\n", instance));
2755 /* submit request to the taskq */
2756 error = dprov_sign_submit_req(DPROV_REQ_SIGN_FINAL, softc, req,
2757 NULL, NULL, NULL, signature, ctx, 0, KM_NOSLEEP);
2759 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_final: done err = 0x%x\n",
2760 instance, error));
2762 return (error);
2765 static int
2766 dprov_sign_atomic(crypto_provider_handle_t provider,
2767 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
2768 crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature,
2769 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
2771 int error = CRYPTO_FAILED;
2772 dprov_state_t *softc = (dprov_state_t *)provider;
2773 /* LINTED E_FUNC_SET_NOT_USED */
2774 int instance;
2776 instance = ddi_get_instance(softc->ds_dip);
2777 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_atomic: started\n", instance));
2779 /* check mechanism */
2780 if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
2781 cmn_err(CE_WARN, "dprov_sign_atomic: unexpected mech type "
2782 "0x%llx\n", (unsigned long long)mechanism->cm_type);
2783 return (CRYPTO_MECHANISM_INVALID);
2786 if (ctx_template != NULL)
2787 return (CRYPTO_ARGUMENTS_BAD);
2789 /* submit request to the taskq */
2790 error = dprov_sign_submit_req(DPROV_REQ_SIGN_ATOMIC, softc, req,
2791 mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
2793 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_atomic: done err = 0x%x\n",
2794 instance, error));
2796 return (error);
2799 static int
2800 dprov_sign_recover_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
2801 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
2802 crypto_req_handle_t req)
2804 int error = CRYPTO_FAILED;
2805 dprov_state_t *softc;
2806 /* LINTED E_FUNC_SET_NOT_USED */
2807 int instance;
2809 /* extract softc and instance number from context */
2810 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2811 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_init: started\n",
2812 instance));
2814 if (ctx_template != NULL)
2815 return (CRYPTO_ARGUMENTS_BAD);
2817 /* submit request to the taskq */
2818 error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER_INIT, softc, req,
2819 mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
2821 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_init: done err = 0x%x\n",
2822 instance, error));
2824 return (error);
2827 static int
2828 dprov_sign_recover(crypto_ctx_t *ctx, crypto_data_t *data,
2829 crypto_data_t *signature, crypto_req_handle_t req)
2831 int error = CRYPTO_FAILED;
2832 dprov_state_t *softc;
2833 /* LINTED E_FUNC_SET_NOT_USED */
2834 int instance;
2836 /* extract softc and instance number from context */
2837 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2838 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover: started\n", instance));
2840 /* submit request to the taskq */
2841 error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER, softc, req,
2842 NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
2844 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover: done err = 0x%x\n",
2845 instance, error));
2847 return (error);
2850 static int
2851 dprov_sign_recover_atomic(crypto_provider_handle_t provider,
2852 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
2853 crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature,
2854 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
2856 int error = CRYPTO_FAILED;
2857 dprov_state_t *softc = (dprov_state_t *)provider;
2858 /* LINTED E_FUNC_SET_NOT_USED */
2859 int instance;
2861 instance = ddi_get_instance(softc->ds_dip);
2862 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_atomic: started\n",
2863 instance));
2865 if (ctx_template != NULL)
2866 return (CRYPTO_ARGUMENTS_BAD);
2868 /* submit request to the taskq */
2869 error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER_ATOMIC, softc, req,
2870 mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
2872 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_atomic: done "
2873 "err = 0x%x\n", instance, error));
2875 return (error);
2879 * Verify entry points.
2882 static int
2883 dprov_verify_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
2884 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
2885 crypto_req_handle_t req)
2887 int error = CRYPTO_FAILED;
2888 dprov_state_t *softc;
2889 /* LINTED E_FUNC_SET_NOT_USED */
2890 int instance;
2892 /* extract softc and instance number from context */
2893 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2894 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_init: started\n", instance));
2896 /* check mechanism */
2897 if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
2898 cmn_err(CE_WARN, "dprov_verify_init: unexpected mech type "
2899 "0x%llx\n", (unsigned long long)mechanism->cm_type);
2900 return (CRYPTO_MECHANISM_INVALID);
2903 if (ctx_template != NULL)
2904 return (CRYPTO_ARGUMENTS_BAD);
2906 error = dprov_verify_submit_req(DPROV_REQ_VERIFY_INIT, softc, req,
2907 mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
2909 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_init: done err = 0x%x\n",
2910 instance, error));
2912 return (error);
2915 static int
2916 dprov_verify(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature,
2917 crypto_req_handle_t req)
2919 int error = CRYPTO_FAILED;
2920 dprov_state_t *softc;
2921 /* LINTED E_FUNC_SET_NOT_USED */
2922 int instance;
2924 /* extract softc and instance number from context */
2925 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2926 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify: started\n", instance));
2928 /* submit request to the taskq */
2929 error = dprov_verify_submit_req(DPROV_REQ_VERIFY, softc, req,
2930 NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
2932 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify: done err = 0x%x\n",
2933 instance, error));
2935 return (error);
2938 static int
2939 dprov_verify_update(crypto_ctx_t *ctx, crypto_data_t *data,
2940 crypto_req_handle_t req)
2942 int error = CRYPTO_FAILED;
2943 dprov_state_t *softc;
2944 /* LINTED E_FUNC_SET_NOT_USED */
2945 int instance;
2947 /* extract softc and instance number from context */
2948 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2949 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_update: started\n",
2950 instance));
2952 /* submit request to the taskq */
2953 error = dprov_verify_submit_req(DPROV_REQ_VERIFY_UPDATE, softc, req,
2954 NULL, NULL, data, NULL, ctx, 0, KM_NOSLEEP);
2956 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_update: done err = 0x%x\n",
2957 instance, error));
2959 return (error);
2962 static int
2963 dprov_verify_final(crypto_ctx_t *ctx, crypto_data_t *signature,
2964 crypto_req_handle_t req)
2966 int error = CRYPTO_FAILED;
2967 dprov_state_t *softc;
2968 /* LINTED E_FUNC_SET_NOT_USED */
2969 int instance;
2971 /* extract softc and instance number from context */
2972 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2973 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_final: started\n", instance));
2975 /* submit request to the taskq */
2976 error = dprov_verify_submit_req(DPROV_REQ_VERIFY_FINAL, softc, req,
2977 NULL, NULL, NULL, signature, ctx, 0, KM_NOSLEEP);
2979 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_final: done err = 0x%x\n",
2980 instance, error));
2982 return (error);
2985 static int
2986 dprov_verify_atomic(crypto_provider_handle_t provider,
2987 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
2988 crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature,
2989 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
2991 int error = CRYPTO_FAILED;
2992 dprov_state_t *softc = (dprov_state_t *)provider;
2993 /* LINTED E_FUNC_SET_NOT_USED */
2994 int instance;
2996 instance = ddi_get_instance(softc->ds_dip);
2997 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_atomic: started\n",
2998 instance));
3000 /* check mechanism */
3001 if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
3002 cmn_err(CE_WARN, "dprov_verify_atomic: unexpected mech type "
3003 "0x%llx\n", (unsigned long long)mechanism->cm_type);
3004 return (CRYPTO_MECHANISM_INVALID);
3007 if (ctx_template != NULL)
3008 return (CRYPTO_ARGUMENTS_BAD);
3010 /* submit request to the taskq */
3011 error = dprov_verify_submit_req(DPROV_REQ_VERIFY_ATOMIC, softc, req,
3012 mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
3014 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_atomic: done err = 0x%x\n",
3015 instance, error));
3017 return (error);
3020 static int
3021 dprov_verify_recover_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
3022 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
3023 crypto_req_handle_t req)
3025 int error = CRYPTO_FAILED;
3026 dprov_state_t *softc;
3027 /* LINTED E_FUNC_SET_NOT_USED */
3028 int instance;
3030 /* extract softc and instance number from context */
3031 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
3032 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_init: started\n",
3033 instance));
3035 if (ctx_template != NULL)
3036 return (CRYPTO_ARGUMENTS_BAD);
3038 /* submit request to the taskq */
3039 error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER_INIT, softc,
3040 req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
3042 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_init: done "
3043 "err = 0x%x\n", instance, error));
3045 return (error);
3048 static int
3049 dprov_verify_recover(crypto_ctx_t *ctx, crypto_data_t *signature,
3050 crypto_data_t *data, crypto_req_handle_t req)
3052 int error = CRYPTO_FAILED;
3053 dprov_state_t *softc;
3054 /* LINTED E_FUNC_SET_NOT_USED */
3055 int instance;
3057 /* extract softc and instance number from context */
3058 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
3059 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover: started\n",
3060 instance));
3062 /* submit request to the taskq */
3063 error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER, softc, req,
3064 NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
3066 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover: done err = 0x%x\n",
3067 instance, error));
3069 return (error);
3072 static int
3073 dprov_verify_recover_atomic(crypto_provider_handle_t provider,
3074 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
3075 crypto_key_t *key, crypto_data_t *signature, crypto_data_t *data,
3076 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
3078 int error = CRYPTO_FAILED;
3079 dprov_state_t *softc = (dprov_state_t *)provider;
3080 /* LINTED E_FUNC_SET_NOT_USED */
3081 int instance;
3083 instance = ddi_get_instance(softc->ds_dip);
3084 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_atomic: started\n",
3085 instance));
3087 if (ctx_template != NULL)
3088 return (CRYPTO_ARGUMENTS_BAD);
3090 /* submit request to the taskq */
3091 error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER_ATOMIC, softc,
3092 req, mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
3094 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_atomic: done "
3095 "err = 0x%x\n", instance, error));
3097 return (error);
3101 * Dual operations entry points.
3104 static int
3105 dprov_digest_encrypt_update(crypto_ctx_t *digest_ctx,
3106 crypto_ctx_t *encrypt_ctx, crypto_data_t *plaintext,
3107 crypto_data_t *ciphertext, crypto_req_handle_t req)
3109 int error = CRYPTO_FAILED;
3110 dprov_state_t *softc;
3111 /* LINTED E_FUNC_SET_NOT_USED */
3112 int instance;
3114 /* extract softc and instance number from context */
3115 DPROV_SOFTC_FROM_CTX(digest_ctx, softc, instance);
3116 DPROV_DEBUG(D_DUAL, ("(%d) dprov_digest_encrypt_update: started\n",
3117 instance));
3119 if (digest_ctx->cc_provider != encrypt_ctx->cc_provider)
3120 return (CRYPTO_INVALID_CONTEXT);
3122 /* submit request to the taskq */
3123 error = dprov_dual_submit_req(DPROV_REQ_DIGEST_ENCRYPT_UPDATE,
3124 softc, req, digest_ctx, encrypt_ctx, plaintext, ciphertext);
3126 DPROV_DEBUG(D_DUAL, ("(%d) dprov_digest_encrypt_update: done "
3127 "err = 0x%x\n", instance, error));
3129 return (error);
3132 static int
3133 dprov_decrypt_digest_update(crypto_ctx_t *decrypt_ctx, crypto_ctx_t *digest_ctx,
3134 crypto_data_t *ciphertext, crypto_data_t *plaintext,
3135 crypto_req_handle_t req)
3137 int error = CRYPTO_FAILED;
3138 dprov_state_t *softc;
3139 /* LINTED E_FUNC_SET_NOT_USED */
3140 int instance;
3142 /* extract softc and instance number from context */
3143 DPROV_SOFTC_FROM_CTX(decrypt_ctx, softc, instance);
3144 DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_digest_update: started\n",
3145 instance));
3147 if (decrypt_ctx->cc_provider != digest_ctx->cc_provider)
3148 return (CRYPTO_INVALID_CONTEXT);
3150 /* submit request to the taskq */
3151 error = dprov_dual_submit_req(DPROV_REQ_DECRYPT_DIGEST_UPDATE,
3152 softc, req, digest_ctx, decrypt_ctx, plaintext, ciphertext);
3154 DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_digest_update: done "
3155 "err = 0x%x\n", instance, error));
3157 return (error);
3160 static int
3161 dprov_sign_encrypt_update(crypto_ctx_t *sign_ctx, crypto_ctx_t *encrypt_ctx,
3162 crypto_data_t *plaintext, crypto_data_t *ciphertext,
3163 crypto_req_handle_t req)
3165 int error = CRYPTO_FAILED;
3166 dprov_state_t *softc;
3167 /* LINTED E_FUNC_SET_NOT_USED */
3168 int instance;
3170 /* extract softc and instance number from context */
3171 DPROV_SOFTC_FROM_CTX(sign_ctx, softc, instance);
3172 DPROV_DEBUG(D_DUAL, ("(%d) dprov_sign_encrypt_update: started\n",
3173 instance));
3175 if (sign_ctx->cc_provider != encrypt_ctx->cc_provider)
3176 return (CRYPTO_INVALID_CONTEXT);
3178 /* submit request to the taskq */
3179 error = dprov_dual_submit_req(DPROV_REQ_SIGN_ENCRYPT_UPDATE,
3180 softc, req, sign_ctx, encrypt_ctx, plaintext, ciphertext);
3182 DPROV_DEBUG(D_DUAL, ("(%d) dprov_sign_encrypt_update: done "
3183 "err = 0x%x\n", instance, error));
3185 return (error);
3188 static int
3189 dprov_decrypt_verify_update(crypto_ctx_t *decrypt_ctx, crypto_ctx_t *verify_ctx,
3190 crypto_data_t *ciphertext, crypto_data_t *plaintext,
3191 crypto_req_handle_t req)
3193 int error = CRYPTO_FAILED;
3194 dprov_state_t *softc;
3195 /* LINTED E_FUNC_SET_NOT_USED */
3196 int instance;
3198 /* extract softc and instance number from context */
3199 DPROV_SOFTC_FROM_CTX(decrypt_ctx, softc, instance);
3200 DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_verify_update: started\n",
3201 instance));
3203 if (decrypt_ctx->cc_provider != verify_ctx->cc_provider)
3204 return (CRYPTO_INVALID_CONTEXT);
3206 /* submit request to the taskq */
3207 error = dprov_dual_submit_req(DPROV_REQ_DECRYPT_VERIFY_UPDATE,
3208 softc, req, verify_ctx, decrypt_ctx, plaintext, ciphertext);
3210 DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_verify_update: done "
3211 "err = 0x%x\n", instance, error));
3213 return (error);
3217 * Dual cipher-mac entry points.
3220 static int
3221 dprov_encrypt_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *encrypt_mech,
3222 crypto_key_t *encrypt_key, crypto_mechanism_t *mac_mech,
3223 crypto_key_t *mac_key, crypto_spi_ctx_template_t encr_ctx_template,
3224 crypto_spi_ctx_template_t mac_ctx_template,
3225 crypto_req_handle_t req)
3227 int error = CRYPTO_FAILED;
3228 dprov_state_t *softc;
3229 /* LINTED E_FUNC_SET_NOT_USED */
3230 int instance;
3232 /* extract softc and instance number from context */
3233 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
3234 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_init: started\n",
3235 instance));
3237 /* check mechanisms */
3238 if (!dprov_valid_cipher_mech(encrypt_mech->cm_type)) {
3239 cmn_err(CE_WARN, "dprov_encrypt_mac_init: unexpected encrypt "
3240 "mech type 0x%llx\n",
3241 (unsigned long long)encrypt_mech->cm_type);
3242 return (CRYPTO_MECHANISM_INVALID);
3244 if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
3245 cmn_err(CE_WARN, "dprov_encrypt_mac_init: unexpected mac "
3246 "mech type 0x%llx\n",
3247 (unsigned long long)mac_mech->cm_type);
3248 return (CRYPTO_MECHANISM_INVALID);
3251 if (encr_ctx_template != NULL || mac_ctx_template != NULL)
3252 return (CRYPTO_ARGUMENTS_BAD);
3254 /* submit request to the taskq */
3255 error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_INIT,
3256 softc, req, ctx, 0, encrypt_mech, encrypt_key, mac_mech, mac_key,
3257 NULL, NULL, NULL, KM_SLEEP);
3259 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_init: done "
3260 "err = 0x%x\n", instance, error));
3262 return (error);
3265 static int
3266 dprov_encrypt_mac(crypto_ctx_t *ctx, crypto_data_t *plaintext,
3267 crypto_dual_data_t *ciphertext, crypto_data_t *mac, crypto_req_handle_t req)
3269 int error = CRYPTO_FAILED;
3270 dprov_state_t *softc;
3271 /* LINTED E_FUNC_SET_NOT_USED */
3272 int instance;
3274 /* extract softc and instance number from context */
3275 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
3276 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac: started\n",
3277 instance));
3280 * submit request to the taskq
3281 * Careful! cihertext/plaintext order inversion
3283 error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC,
3284 softc, req, ctx, 0, NULL, NULL, NULL, NULL,
3285 ciphertext, plaintext, mac, KM_NOSLEEP);
3287 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac: done "
3288 "err = 0x%x\n", instance, error));
3290 return (error);
3293 static int
3294 dprov_encrypt_mac_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
3295 crypto_dual_data_t *ciphertext, crypto_req_handle_t req)
3297 int error = CRYPTO_FAILED;
3298 dprov_state_t *softc;
3299 /* LINTED E_FUNC_SET_NOT_USED */
3300 int instance;
3302 /* extract softc and instance number from context */
3303 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
3304 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_update: started\n",
3305 instance));
3307 /* submit request to the taskq */
3308 error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_UPDATE,
3309 softc, req, ctx, 0, NULL, NULL, NULL, NULL,
3310 ciphertext, plaintext, NULL, KM_NOSLEEP);
3312 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_update: done "
3313 "err = 0x%x\n", instance, error));
3315 return (error);
3318 static int
3319 dprov_encrypt_mac_final(crypto_ctx_t *ctx,
3320 crypto_dual_data_t *ciphertext, crypto_data_t *mac,
3321 crypto_req_handle_t req)
3323 int error = CRYPTO_FAILED;
3324 dprov_state_t *softc;
3325 /* LINTED E_FUNC_SET_NOT_USED */
3326 int instance;
3328 /* extract softc and instance number from context */
3329 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
3330 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_final: started\n",
3331 instance));
3333 /* submit request to the taskq */
3334 error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_FINAL,
3335 softc, req, ctx, 0, NULL, NULL, NULL, NULL,
3336 ciphertext, NULL, mac, KM_NOSLEEP);
3338 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_final: done "
3339 "err = 0x%x\n", instance, error));
3341 return (error);
3344 static int
3345 dprov_encrypt_mac_atomic(crypto_provider_handle_t provider,
3346 crypto_session_id_t session_id, crypto_mechanism_t *encrypt_mech,
3347 crypto_key_t *encrypt_key, crypto_mechanism_t *mac_mech,
3348 crypto_key_t *mac_key, crypto_data_t *plaintext,
3349 crypto_dual_data_t *ciphertext, crypto_data_t *mac,
3350 crypto_spi_ctx_template_t encr_ctx_template,
3351 crypto_spi_ctx_template_t mac_ctx_template,
3352 crypto_req_handle_t req)
3354 int error = CRYPTO_FAILED;
3355 dprov_state_t *softc = (dprov_state_t *)provider;
3356 /* LINTED E_FUNC_SET_NOT_USED */
3357 int instance;
3359 instance = ddi_get_instance(softc->ds_dip);
3360 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_atomic: started\n",
3361 instance));
3363 /* check mechanisms */
3364 if (!dprov_valid_cipher_mech(encrypt_mech->cm_type)) {
3365 cmn_err(CE_WARN, "dprov_encrypt_mac_atomic: unexpected encrypt "
3366 "mech type 0x%llx\n",
3367 (unsigned long long)encrypt_mech->cm_type);
3368 return (CRYPTO_MECHANISM_INVALID);
3370 if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
3371 cmn_err(CE_WARN, "dprov_encrypt_mac_atomic: unexpected mac "
3372 "mech type 0x%llx\n",
3373 (unsigned long long)mac_mech->cm_type);
3374 return (CRYPTO_MECHANISM_INVALID);
3377 if (encr_ctx_template != NULL || mac_ctx_template != NULL)
3378 return (CRYPTO_ARGUMENTS_BAD);
3380 /* submit request to the taskq */
3381 error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_ATOMIC,
3382 softc, req, NULL, session_id, encrypt_mech, encrypt_key, mac_mech,
3383 mac_key, ciphertext, plaintext, mac, KM_SLEEP);
3385 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_atomic: done "
3386 "err = 0x%x\n", instance, error));
3388 return (error);
3391 static int
3392 dprov_mac_decrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mac_mech,
3393 crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech,
3394 crypto_key_t *decrypt_key, crypto_spi_ctx_template_t mac_ctx_template,
3395 crypto_spi_ctx_template_t decr_ctx_template,
3396 crypto_req_handle_t req)
3398 int error = CRYPTO_FAILED;
3399 dprov_state_t *softc;
3400 /* LINTED E_FUNC_SET_NOT_USED */
3401 int instance;
3403 /* extract softc and instance number from context */
3404 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
3405 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_init: started\n",
3406 instance));
3408 /* check mechanisms */
3409 if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) {
3410 cmn_err(CE_WARN, "dprov_mac_decrypt_init: unexpected decrypt "
3411 "mech type 0x%llx\n",
3412 (unsigned long long)decrypt_mech->cm_type);
3413 return (CRYPTO_MECHANISM_INVALID);
3415 if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
3416 cmn_err(CE_WARN, "dprov_mac_decrypt_init: unexpected mac "
3417 "mech type 0x%llx\n",
3418 (unsigned long long)mac_mech->cm_type);
3419 return (CRYPTO_MECHANISM_INVALID);
3422 if (decr_ctx_template != NULL || mac_ctx_template != NULL)
3423 return (CRYPTO_ARGUMENTS_BAD);
3425 /* submit request to the taskq */
3426 error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_INIT,
3427 softc, req, ctx, 0, decrypt_mech, decrypt_key, mac_mech, mac_key,
3428 NULL, NULL, NULL, KM_SLEEP);
3430 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_init: done "
3431 "err = 0x%x\n", instance, error));
3433 return (error);
3436 static int
3437 dprov_mac_decrypt(crypto_ctx_t *ctx, crypto_dual_data_t *ciphertext,
3438 crypto_data_t *mac, crypto_data_t *plaintext, crypto_req_handle_t req)
3440 int error = CRYPTO_FAILED;
3441 dprov_state_t *softc;
3442 /* LINTED E_FUNC_SET_NOT_USED */
3443 int instance;
3445 /* extract softc and instance number from context */
3446 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
3447 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt: started\n",
3448 instance));
3450 /* submit request to the taskq */
3451 error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT,
3452 softc, req, ctx, 0, NULL, NULL, NULL, NULL,
3453 ciphertext, plaintext, mac, KM_NOSLEEP);
3455 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt: done "
3456 "err = 0x%x\n", instance, error));
3458 return (error);
3461 static int
3462 dprov_mac_decrypt_update(crypto_ctx_t *ctx, crypto_dual_data_t *ciphertext,
3463 crypto_data_t *plaintext, crypto_req_handle_t req)
3465 int error = CRYPTO_FAILED;
3466 dprov_state_t *softc;
3467 /* LINTED E_FUNC_SET_NOT_USED */
3468 int instance;
3470 /* extract softc and instance number from context */
3471 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
3472 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_update: started\n",
3473 instance));
3475 /* submit request to the taskq */
3476 error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_UPDATE,
3477 softc, req, ctx, 0, NULL, NULL, NULL, NULL,
3478 ciphertext, plaintext, NULL, KM_NOSLEEP);
3480 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_update: done "
3481 "err = 0x%x\n", instance, error));
3483 return (error);
3486 static int
3487 dprov_mac_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *mac,
3488 crypto_data_t *plaintext, crypto_req_handle_t req)
3490 int error = CRYPTO_FAILED;
3491 dprov_state_t *softc;
3492 /* LINTED E_FUNC_SET_NOT_USED */
3493 int instance;
3495 /* extract softc and instance number from context */
3496 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
3497 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_final: started\n",
3498 instance));
3500 /* submit request to the taskq */
3501 error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_FINAL,
3502 softc, req, ctx, 0, NULL, NULL, NULL, NULL,
3503 NULL, plaintext, mac, KM_NOSLEEP);
3505 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_final: done "
3506 "err = 0x%x\n", instance, error));
3508 return (error);
3511 static int
3512 dprov_mac_decrypt_atomic(crypto_provider_handle_t provider,
3513 crypto_session_id_t session_id, crypto_mechanism_t *mac_mech,
3514 crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech,
3515 crypto_key_t *decrypt_key, crypto_dual_data_t *ciphertext,
3516 crypto_data_t *mac, crypto_data_t *plaintext,
3517 crypto_spi_ctx_template_t mac_ctx_template,
3518 crypto_spi_ctx_template_t decr_ctx_template,
3519 crypto_req_handle_t req)
3521 int error = CRYPTO_FAILED;
3522 dprov_state_t *softc = (dprov_state_t *)provider;
3523 /* LINTED E_FUNC_SET_NOT_USED */
3524 int instance;
3526 instance = ddi_get_instance(softc->ds_dip);
3527 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_atomic: started\n",
3528 instance));
3530 /* check mechanisms */
3531 if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) {
3532 cmn_err(CE_WARN, "dprov_mac_decrypt_atomic: unexpected encrypt "
3533 "mech type 0x%llx\n",
3534 (unsigned long long)decrypt_mech->cm_type);
3535 return (CRYPTO_MECHANISM_INVALID);
3537 if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
3538 cmn_err(CE_WARN, "dprov_mac_decrypt_atomic: unexpected mac "
3539 "mech type 0x%llx\n",
3540 (unsigned long long)mac_mech->cm_type);
3541 return (CRYPTO_MECHANISM_INVALID);
3544 if (decr_ctx_template != NULL || mac_ctx_template != NULL)
3545 return (CRYPTO_ARGUMENTS_BAD);
3547 /* submit request to the taskq */
3548 error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_ATOMIC,
3549 softc, req, NULL, session_id, decrypt_mech, decrypt_key, mac_mech,
3550 mac_key, ciphertext, plaintext, mac, KM_SLEEP);
3552 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_atomic: done "
3553 "err = 0x%x\n", instance, error));
3555 return (error);
3558 static int
3559 dprov_mac_verify_decrypt_atomic(crypto_provider_handle_t provider,
3560 crypto_session_id_t session_id, crypto_mechanism_t *mac_mech,
3561 crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech,
3562 crypto_key_t *decrypt_key, crypto_dual_data_t *ciphertext,
3563 crypto_data_t *mac, crypto_data_t *plaintext,
3564 crypto_spi_ctx_template_t mac_ctx_template,
3565 crypto_spi_ctx_template_t decr_ctx_template,
3566 crypto_req_handle_t req)
3568 int error = CRYPTO_FAILED;
3569 dprov_state_t *softc = (dprov_state_t *)provider;
3570 /* LINTED E_FUNC_SET_NOT_USED */
3571 int instance;
3573 instance = ddi_get_instance(softc->ds_dip);
3574 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_verify_decrypt_atomic:"
3575 "started\n", instance));
3577 /* check mechanisms */
3578 if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) {
3579 cmn_err(CE_WARN, "dprov_mac_verify_decrypt_atomic: "
3580 "unexpected encrypt mech type 0x%llx\n",
3581 (unsigned long long)decrypt_mech->cm_type);
3582 return (CRYPTO_MECHANISM_INVALID);
3584 if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
3585 cmn_err(CE_WARN, "dprov_mac_verify_decrypt_atomic: "
3586 "unexpected mac mech type 0x%llx\n",
3587 (unsigned long long)mac_mech->cm_type);
3588 return (CRYPTO_MECHANISM_INVALID);
3591 if (decr_ctx_template != NULL || mac_ctx_template != NULL)
3592 return (CRYPTO_ARGUMENTS_BAD);
3594 /* submit request to the taskq */
3595 error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC,
3596 softc, req, NULL, session_id, decrypt_mech, decrypt_key, mac_mech,
3597 mac_key, ciphertext, plaintext, mac, KM_SLEEP);
3599 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_verify_decrypt_atomic: done "
3600 "err = 0x%x\n", instance, error));
3602 return (error);
3606 * Random number entry points.
3609 static int
3610 dprov_seed_random(crypto_provider_handle_t provider, crypto_session_id_t sid,
3611 uchar_t *buf, size_t len, uint_t entropy_est, uint32_t flags,
3612 crypto_req_handle_t req)
3614 int error = CRYPTO_FAILED;
3615 dprov_state_t *softc = (dprov_state_t *)provider;
3616 /* LINTED E_FUNC_SET_NOT_USED */
3617 int instance;
3619 instance = ddi_get_instance(softc->ds_dip);
3620 DPROV_DEBUG(D_RANDOM, ("(%d) dprov_seed_random: started\n",
3621 instance));
3623 error = dprov_random_submit_req(DPROV_REQ_RANDOM_SEED, softc,
3624 req, buf, len, sid, entropy_est, flags);
3626 DPROV_DEBUG(D_RANDOM, ("(%d) dprov_seed_random: done err = 0x0%x\n",
3627 instance, error));
3629 return (error);
3632 static int
3633 dprov_generate_random(crypto_provider_handle_t provider,
3634 crypto_session_id_t sid, uchar_t *buf, size_t len, crypto_req_handle_t req)
3636 int error = CRYPTO_FAILED;
3637 dprov_state_t *softc = (dprov_state_t *)provider;
3638 /* LINTED E_FUNC_SET_NOT_USED */
3639 int instance;
3641 instance = ddi_get_instance(softc->ds_dip);
3642 DPROV_DEBUG(D_RANDOM, ("(%d) dprov_generate_random: started\n",
3643 instance));
3645 error = dprov_random_submit_req(DPROV_REQ_RANDOM_GENERATE, softc,
3646 req, buf, len, sid, 0, 0);
3648 DPROV_DEBUG(D_RANDOM, ("(%d) dprov_generate_random: done "
3649 "err = 0x0%x\n", instance, error));
3651 return (error);
3655 * Session Management entry points.
3658 static int
3659 dprov_session_open(crypto_provider_handle_t provider,
3660 crypto_session_id_t *session_id, crypto_req_handle_t req)
3662 int error = CRYPTO_FAILED;
3663 dprov_state_t *softc = (dprov_state_t *)provider;
3664 /* LINTED E_FUNC_SET_NOT_USED */
3665 int instance;
3667 instance = ddi_get_instance(softc->ds_dip);
3668 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_open: started\n",
3669 instance));
3671 error = dprov_session_submit_req(DPROV_REQ_SESSION_OPEN, softc,
3672 req, session_id, 0, 0, NULL, 0);
3674 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_open: done err = 0x0%x\n",
3675 instance, error));
3677 return (error);
3680 static int
3681 dprov_session_close(crypto_provider_handle_t provider,
3682 crypto_session_id_t session_id, crypto_req_handle_t req)
3684 int error = CRYPTO_FAILED;
3685 dprov_state_t *softc = (dprov_state_t *)provider;
3686 /* LINTED E_FUNC_SET_NOT_USED */
3687 int instance;
3689 instance = ddi_get_instance(softc->ds_dip);
3690 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_close: started\n",
3691 instance));
3693 error = dprov_session_submit_req(DPROV_REQ_SESSION_CLOSE, softc,
3694 req, 0, session_id, 0, NULL, 0);
3696 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_close: done err = 0x0%x\n",
3697 instance, error));
3699 return (error);
3702 static int
3703 dprov_session_login(crypto_provider_handle_t provider,
3704 crypto_session_id_t session_id, crypto_user_type_t user_type,
3705 char *pin, size_t pin_len, crypto_req_handle_t req)
3707 int error = CRYPTO_FAILED;
3708 dprov_state_t *softc = (dprov_state_t *)provider;
3709 /* LINTED E_FUNC_SET_NOT_USED */
3710 int instance;
3712 instance = ddi_get_instance(softc->ds_dip);
3713 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_login: started\n",
3714 instance));
3716 error = dprov_session_submit_req(DPROV_REQ_SESSION_LOGIN, softc,
3717 req, 0, session_id, user_type, pin, pin_len);
3719 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_login: done err = 0x0%x\n",
3720 instance, error));
3722 return (error);
3725 static int
3726 dprov_session_logout(crypto_provider_handle_t provider,
3727 crypto_session_id_t session_id, crypto_req_handle_t req)
3729 int error = CRYPTO_FAILED;
3730 dprov_state_t *softc = (dprov_state_t *)provider;
3731 /* LINTED E_FUNC_SET_NOT_USED */
3732 int instance;
3734 instance = ddi_get_instance(softc->ds_dip);
3735 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_logout: started\n",
3736 instance));
3738 error = dprov_session_submit_req(DPROV_REQ_SESSION_LOGOUT, softc,
3739 req, 0, session_id, 0, NULL, 0);
3741 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_logout: done err = 0x0%x\n",
3742 instance, error));
3744 return (error);
3748 * Object management entry points.
3751 static int
3752 dprov_object_create(crypto_provider_handle_t provider,
3753 crypto_session_id_t session_id, crypto_object_attribute_t *template,
3754 uint_t attribute_count, crypto_object_id_t *object,
3755 crypto_req_handle_t req)
3757 int error = CRYPTO_FAILED;
3758 dprov_state_t *softc = (dprov_state_t *)provider;
3759 /* LINTED E_FUNC_SET_NOT_USED */
3760 int instance;
3762 instance = ddi_get_instance(softc->ds_dip);
3763 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_create: started\n",
3764 instance));
3766 /* submit request to the taskq */
3767 error = dprov_object_submit_req(DPROV_REQ_OBJECT_CREATE, softc, req,
3768 session_id, 0, template, attribute_count, object, NULL, NULL,
3769 NULL, 0, NULL, KM_NOSLEEP);
3771 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_create: done err = 0x0%x\n",
3772 instance, error));
3774 return (error);
3777 static int
3778 dprov_object_copy(crypto_provider_handle_t provider,
3779 crypto_session_id_t session_id, crypto_object_id_t object,
3780 crypto_object_attribute_t *template, uint_t attribute_count,
3781 crypto_object_id_t *new_object, crypto_req_handle_t req)
3783 int error = CRYPTO_FAILED;
3784 dprov_state_t *softc = (dprov_state_t *)provider;
3785 /* LINTED E_FUNC_SET_NOT_USED */
3786 int instance;
3788 instance = ddi_get_instance(softc->ds_dip);
3789 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_copy: started\n",
3790 instance));
3792 /* submit request to the taskq */
3793 error = dprov_object_submit_req(DPROV_REQ_OBJECT_COPY, softc, req,
3794 session_id, object, template, attribute_count, new_object,
3795 NULL, NULL, NULL, 0, NULL, KM_NOSLEEP);
3797 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_copy: done err = 0x0%x\n",
3798 instance, error));
3800 return (error);
3803 static int
3804 dprov_object_destroy(crypto_provider_handle_t provider,
3805 crypto_session_id_t session_id, crypto_object_id_t object,
3806 crypto_req_handle_t req)
3808 int error = CRYPTO_FAILED;
3809 dprov_state_t *softc = (dprov_state_t *)provider;
3810 /* LINTED E_FUNC_SET_NOT_USED */
3811 int instance;
3813 instance = ddi_get_instance(softc->ds_dip);
3814 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_destroy: started\n",
3815 instance));
3817 /* submit request to the taskq */
3818 error = dprov_object_submit_req(DPROV_REQ_OBJECT_DESTROY, softc, req,
3819 session_id, object, NULL, 0, NULL, NULL, NULL, NULL, 0, NULL,
3820 KM_NOSLEEP);
3822 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_destroy: done err = 0x0%x\n",
3823 instance, error));
3825 return (error);
3828 static int
3829 dprov_object_get_size(crypto_provider_handle_t provider,
3830 crypto_session_id_t session_id, crypto_object_id_t object,
3831 size_t *size, crypto_req_handle_t req)
3833 int error = CRYPTO_FAILED;
3834 dprov_state_t *softc = (dprov_state_t *)provider;
3835 /* LINTED E_FUNC_SET_NOT_USED */
3836 int instance;
3838 instance = ddi_get_instance(softc->ds_dip);
3839 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_size: started\n",
3840 instance));
3842 /* submit request to the taskq */
3843 error = dprov_object_submit_req(DPROV_REQ_OBJECT_GET_SIZE, softc, req,
3844 session_id, object, NULL, 0, NULL, size, NULL, NULL, 0, NULL,
3845 KM_NOSLEEP);
3847 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_size: done err = 0x0%x\n",
3848 instance, error));
3850 return (error);
3853 static int
3854 dprov_object_get_attribute_value(crypto_provider_handle_t provider,
3855 crypto_session_id_t session_id, crypto_object_id_t object,
3856 crypto_object_attribute_t *template, uint_t attribute_count,
3857 crypto_req_handle_t req)
3859 int error = CRYPTO_FAILED;
3860 dprov_state_t *softc = (dprov_state_t *)provider;
3861 /* LINTED E_FUNC_SET_NOT_USED */
3862 int instance;
3864 instance = ddi_get_instance(softc->ds_dip);
3865 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_attribute_value: "
3866 "started\n", instance));
3868 /* submit request to the taskq */
3869 error = dprov_object_submit_req(DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE,
3870 softc, req, session_id, object, template, attribute_count,
3871 NULL, NULL, NULL, NULL, 0, NULL, KM_NOSLEEP);
3873 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_attribute_value: "
3874 "done err = 0x0%x\n", instance, error));
3876 return (error);
3879 static int
3880 dprov_object_set_attribute_value(crypto_provider_handle_t provider,
3881 crypto_session_id_t session_id, crypto_object_id_t object,
3882 crypto_object_attribute_t *template, uint_t attribute_count,
3883 crypto_req_handle_t req)
3885 int error = CRYPTO_FAILED;
3886 dprov_state_t *softc = (dprov_state_t *)provider;
3887 /* LINTED E_FUNC_SET_NOT_USED */
3888 int instance;
3890 instance = ddi_get_instance(softc->ds_dip);
3891 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_set_attribute_value: "
3892 "started\n", instance));
3894 /* submit request to the taskq */
3895 error = dprov_object_submit_req(DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE,
3896 softc, req, session_id, object, template, attribute_count,
3897 NULL, NULL, NULL, NULL, 0, NULL, KM_NOSLEEP);
3899 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_set_attribute_value: "
3900 "done err = 0x0%x\n", instance, error));
3902 return (error);
3905 static int
3906 dprov_object_find_init(crypto_provider_handle_t provider,
3907 crypto_session_id_t session_id, crypto_object_attribute_t *template,
3908 uint_t attribute_count, void **provider_private,
3909 crypto_req_handle_t req)
3911 int error = CRYPTO_FAILED;
3912 dprov_state_t *softc = (dprov_state_t *)provider;
3913 /* LINTED E_FUNC_SET_NOT_USED */
3914 int instance;
3916 instance = ddi_get_instance(softc->ds_dip);
3917 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_init: started\n",
3918 instance));
3920 /* submit request to the taskq */
3921 error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND_INIT, softc, req,
3922 session_id, 0, template, attribute_count, NULL, NULL,
3923 provider_private, NULL, 0, NULL, KM_SLEEP);
3925 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_init: done "
3926 "err = 0x0%x\n", instance, error));
3928 return (error);
3931 static int
3932 dprov_object_find(crypto_provider_handle_t provider, void *provider_private,
3933 crypto_object_id_t *objects, uint_t max_object_count,
3934 uint_t *object_count, crypto_req_handle_t req)
3936 int error = CRYPTO_FAILED;
3937 dprov_state_t *softc = (dprov_state_t *)provider;
3938 /* LINTED E_FUNC_SET_NOT_USED */
3939 int instance;
3941 instance = ddi_get_instance(softc->ds_dip);
3942 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find: started\n",
3943 instance));
3945 /* submit request to the taskq */
3946 error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND, softc, req,
3947 0, 0, NULL, 0, objects, NULL, NULL, provider_private,
3948 max_object_count, object_count, KM_NOSLEEP);
3951 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find: done err = 0x0%x\n",
3952 instance, error));
3954 return (error);
3957 static int
3958 dprov_object_find_final(crypto_provider_handle_t provider,
3959 void *provider_private, crypto_req_handle_t req)
3961 int error = CRYPTO_FAILED;
3962 dprov_state_t *softc = (dprov_state_t *)provider;
3963 /* LINTED E_FUNC_SET_NOT_USED */
3964 int instance;
3966 instance = ddi_get_instance(softc->ds_dip);
3967 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_final: started\n",
3968 instance));
3970 /* submit request to the taskq */
3971 error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND_FINAL, softc, req,
3972 0, 0, NULL, 0, NULL, NULL, NULL, provider_private,
3973 0, NULL, KM_NOSLEEP);
3975 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_final: done "
3976 "err = 0x0%x\n", instance, error));
3978 return (error);
3982 * Key management entry points.
3985 static int
3986 dprov_key_generate(crypto_provider_handle_t provider,
3987 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
3988 crypto_object_attribute_t *template, uint_t attribute_count,
3989 crypto_object_id_t *object, crypto_req_handle_t req)
3991 int error = CRYPTO_FAILED;
3992 dprov_state_t *softc = (dprov_state_t *)provider;
3993 /* LINTED E_FUNC_SET_NOT_USED */
3994 int instance;
3996 instance = ddi_get_instance(softc->ds_dip);
3997 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate: started\n",
3998 instance));
4000 /* submit request to the taskq */
4001 error = dprov_key_submit_req(DPROV_REQ_KEY_GENERATE, softc, req,
4002 session_id, mechanism, template, attribute_count, object, NULL,
4003 0, NULL, NULL, NULL, 0, NULL, 0, NULL, 0);
4005 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate: done err = 0x0%x\n",
4006 instance, error));
4008 return (error);
4011 static int
4012 dprov_key_generate_pair(crypto_provider_handle_t provider,
4013 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
4014 crypto_object_attribute_t *public_key_template,
4015 uint_t public_key_attribute_count,
4016 crypto_object_attribute_t *private_key_template,
4017 uint_t private_key_attribute_count,
4018 crypto_object_id_t *public_key, crypto_object_id_t *private_key,
4019 crypto_req_handle_t req)
4021 int error = CRYPTO_FAILED;
4022 dprov_state_t *softc = (dprov_state_t *)provider;
4023 /* LINTED E_FUNC_SET_NOT_USED */
4024 int instance;
4026 instance = ddi_get_instance(softc->ds_dip);
4027 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate_pair: started\n",
4028 instance));
4030 /* submit request to the taskq */
4031 error = dprov_key_submit_req(DPROV_REQ_KEY_GENERATE_PAIR, softc, req,
4032 session_id, mechanism, public_key_template,
4033 public_key_attribute_count, public_key, private_key_template,
4034 private_key_attribute_count, private_key, NULL, NULL, 0, NULL, 0,
4035 NULL, 0);
4037 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate_pair: done err = 0x0%x\n",
4038 instance, error));
4040 return (error);
4043 static int
4044 dprov_key_wrap(crypto_provider_handle_t provider,
4045 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
4046 crypto_key_t *wrapping_key, crypto_object_id_t *key,
4047 uchar_t *wrapped_key, size_t *wrapped_key_len_ptr, crypto_req_handle_t req)
4049 int error = CRYPTO_FAILED;
4050 dprov_state_t *softc = (dprov_state_t *)provider;
4051 /* LINTED E_FUNC_SET_NOT_USED */
4052 int instance;
4054 instance = ddi_get_instance(softc->ds_dip);
4055 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_wrap: started\n",
4056 instance));
4058 /* submit request to the taskq */
4059 error = dprov_key_submit_req(DPROV_REQ_KEY_WRAP, softc, req,
4060 session_id, mechanism, NULL, 0, key, NULL,
4061 0, NULL, wrapping_key, wrapped_key, wrapped_key_len_ptr,
4062 NULL, 0, NULL, 0);
4064 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_wrap: done err = 0x0%x\n",
4065 instance, error));
4067 return (error);
4070 static int
4071 dprov_key_unwrap(crypto_provider_handle_t provider,
4072 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
4073 crypto_key_t *unwrapping_key, uchar_t *wrapped_key,
4074 size_t *wrapped_key_len_ptr, crypto_object_attribute_t *template,
4075 uint_t attribute_count, crypto_object_id_t *key, crypto_req_handle_t req)
4077 int error = CRYPTO_FAILED;
4078 dprov_state_t *softc = (dprov_state_t *)provider;
4079 /* LINTED E_FUNC_SET_NOT_USED */
4080 int instance;
4082 instance = ddi_get_instance(softc->ds_dip);
4083 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_unwrap: started\n",
4084 instance));
4086 /* submit request to the taskq */
4087 error = dprov_key_submit_req(DPROV_REQ_KEY_UNWRAP, softc, req,
4088 session_id, mechanism, template, attribute_count, key, NULL,
4089 0, NULL, unwrapping_key, wrapped_key, wrapped_key_len_ptr,
4090 NULL, 0, NULL, 0);
4092 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_unwrap: done err = 0x0%x\n",
4093 instance, error));
4095 return (error);
4098 static int
4099 dprov_key_derive(crypto_provider_handle_t provider,
4100 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
4101 crypto_key_t *base_key, crypto_object_attribute_t *template,
4102 uint_t attribute_count, crypto_object_id_t *key, crypto_req_handle_t req)
4104 int error = CRYPTO_FAILED;
4105 dprov_state_t *softc = (dprov_state_t *)provider;
4106 /* LINTED E_FUNC_SET_NOT_USED */
4107 int instance;
4109 instance = ddi_get_instance(softc->ds_dip);
4110 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_derive: started\n",
4111 instance));
4113 /* submit request to the taskq */
4114 error = dprov_key_submit_req(DPROV_REQ_KEY_DERIVE, softc, req,
4115 session_id, mechanism, template, attribute_count, key, NULL,
4116 0, NULL, base_key, NULL, 0, NULL, 0, NULL, 0);
4118 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_derive: done err = 0x0%x\n",
4119 instance, error));
4121 return (error);
4125 * Provider management entry points.
4128 static int
4129 dprov_ext_info(crypto_provider_handle_t provider,
4130 crypto_provider_ext_info_t *ext_info, crypto_req_handle_t req)
4132 int error = CRYPTO_FAILED;
4133 dprov_state_t *softc = (dprov_state_t *)provider;
4134 /* LINTED E_FUNC_SET_NOT_USED */
4135 int instance;
4137 instance = ddi_get_instance(softc->ds_dip);
4138 DPROV_DEBUG(D_MGMT, ("(%d) dprov_ext_info: started\n",
4139 instance));
4141 error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_EXTINFO, softc, req,
4142 0, NULL, 0, NULL, 0, NULL, ext_info);
4144 DPROV_DEBUG(D_MGMT, ("(%d) dprov_ext_info: done err = 0x0%x\n",
4145 instance, error));
4147 return (error);
4150 static int
4151 dprov_init_token(crypto_provider_handle_t provider, char *pin, size_t pin_len,
4152 char *label, crypto_req_handle_t req)
4154 int error = CRYPTO_FAILED;
4155 dprov_state_t *softc = (dprov_state_t *)provider;
4156 /* LINTED E_FUNC_SET_NOT_USED */
4157 int instance;
4159 instance = ddi_get_instance(softc->ds_dip);
4160 DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_token: started\n",
4161 instance));
4163 error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_INITTOKEN, softc, req,
4164 0, pin, pin_len, NULL, 0, label, NULL);
4166 DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_token: done err = 0x0%x\n",
4167 instance, error));
4169 return (error);
4172 static int
4173 dprov_init_pin(crypto_provider_handle_t provider,
4174 crypto_session_id_t session_id, char *pin, size_t pin_len,
4175 crypto_req_handle_t req)
4177 int error = CRYPTO_FAILED;
4178 dprov_state_t *softc = (dprov_state_t *)provider;
4179 /* LINTED E_FUNC_SET_NOT_USED */
4180 int instance;
4182 instance = ddi_get_instance(softc->ds_dip);
4183 DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_pin: started\n",
4184 instance));
4186 error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_INITPIN, softc, req,
4187 session_id, pin, pin_len, NULL, 0, NULL, NULL);
4189 DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_pin: done err = 0x0%x\n",
4190 instance, error));
4192 return (error);
4195 static int
4196 dprov_set_pin(crypto_provider_handle_t provider, crypto_session_id_t session_id,
4197 char *old_pin, size_t old_pin_len, char *new_pin, size_t new_pin_len,
4198 crypto_req_handle_t req)
4200 int error = CRYPTO_FAILED;
4201 dprov_state_t *softc = (dprov_state_t *)provider;
4202 /* LINTED E_FUNC_SET_NOT_USED */
4203 int instance;
4205 instance = ddi_get_instance(softc->ds_dip);
4206 DPROV_DEBUG(D_MGMT, ("(%d) dprov_set_pin: started\n",
4207 instance));
4209 error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_SETPIN, softc, req,
4210 session_id, new_pin, new_pin_len, old_pin, old_pin_len, NULL, NULL);
4212 DPROV_DEBUG(D_MGMT, ("(%d) dprov_set_pin: done err = 0x0%x\n",
4213 instance, error));
4215 return (error);
4220 * Context management entry points.
4224 * Allocate a dprov-private context based on the specified dprov request.
4225 * For dual cipher/mac requests, the allocated context will
4226 * contain a structure dprov_ctx_dual_t, for other request types,
4227 * it will contain a dprov_ctx_single.
4228 * Returns one of the CRYPTO_ status codes.
4230 static int
4231 dprov_alloc_context(dprov_req_type_t req_type, crypto_ctx_t *spi_ctx)
4233 dprov_ctx_single_t *dprov_private;
4235 switch (req_type) {
4236 case DPROV_REQ_ENCRYPT_MAC_INIT:
4237 case DPROV_REQ_MAC_DECRYPT_INIT:
4238 dprov_private = kmem_zalloc(sizeof (dprov_ctx_dual_t),
4239 KM_NOSLEEP);
4240 if (dprov_private == NULL)
4241 return (CRYPTO_HOST_MEMORY);
4242 dprov_private->dc_type = DPROV_CTX_DUAL;
4243 break;
4244 default:
4245 dprov_private = kmem_zalloc(sizeof (dprov_ctx_single_t),
4246 KM_NOSLEEP);
4247 if (dprov_private == NULL)
4248 return (CRYPTO_HOST_MEMORY);
4249 dprov_private->dc_type = DPROV_CTX_SINGLE;
4250 dprov_private->dc_svrfy_to_mac = B_FALSE;
4251 break;
4254 spi_ctx->cc_provider_private = (void *)dprov_private;
4256 return (CRYPTO_SUCCESS);
4259 static int
4260 dprov_free_context(crypto_ctx_t *ctx)
4262 if (ctx->cc_provider_private == NULL)
4263 return (CRYPTO_SUCCESS);
4265 DPROV_DEBUG(D_CONTEXT, ("dprov_free_context\n"));
4269 * The dprov private context could contain either
4270 * a dprov_ctx_single_t or a dprov_ctx_dual_t. Free
4271 * the context based on its type. The k-API contexts
4272 * that were attached to the dprov private context
4273 * are freed by the framework.
4275 dprov_ctx_single_t *ctx_single =
4276 (dprov_ctx_single_t *)(ctx->cc_provider_private);
4278 if (ctx_single->dc_type == DPROV_CTX_SINGLE) {
4279 crypto_context_t context = DPROV_CTX_SINGLE(ctx);
4282 * This case happens for the crypto_cancel_ctx() case.
4283 * We have to cancel the SW provider context also.
4285 if (context != NULL)
4286 crypto_cancel_ctx(context);
4288 kmem_free(ctx_single, sizeof (dprov_ctx_single_t));
4289 } else {
4290 crypto_context_t cipher_context =
4291 DPROV_CTX_DUAL_CIPHER(ctx);
4292 crypto_context_t mac_context = DPROV_CTX_DUAL_MAC(ctx);
4294 /* See comments above. */
4295 if (cipher_context != NULL)
4296 crypto_cancel_ctx(cipher_context);
4297 if (mac_context != NULL)
4298 crypto_cancel_ctx(mac_context);
4300 ASSERT(ctx_single->dc_type == DPROV_CTX_DUAL);
4301 kmem_free(ctx_single, sizeof (dprov_ctx_dual_t));
4303 ctx->cc_provider_private = NULL;
4306 return (CRYPTO_SUCCESS);
4310 * Resource control checks don't need to be done. Why? Because this routine
4311 * knows the size of the structure, and it can't be overridden by a user.
4312 * This is different from the crypto module, which has no knowledge of
4313 * specific mechanisms, and therefore has to trust specified size of the
4314 * parameter. This trust, or lack of trust, is why the size of the
4315 * parameter has to be charged against the project resource control.
4317 static int
4318 copyin_aes_ccm_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
4319 int *out_error, int mode)
4321 STRUCT_DECL(crypto_mechanism, mech);
4322 STRUCT_DECL(CK_AES_CCM_PARAMS, params);
4323 CK_AES_CCM_PARAMS *aes_ccm_params;
4324 caddr_t pp;
4325 size_t param_len;
4326 int error = 0;
4327 int rv = 0;
4329 STRUCT_INIT(mech, mode);
4330 STRUCT_INIT(params, mode);
4331 bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4332 pp = STRUCT_FGETP(mech, cm_param);
4333 param_len = STRUCT_FGET(mech, cm_param_len);
4335 if (param_len != STRUCT_SIZE(params)) {
4336 rv = CRYPTO_ARGUMENTS_BAD;
4337 goto out;
4340 out_mech->cm_type = STRUCT_FGET(mech, cm_type);
4341 out_mech->cm_param = NULL;
4342 out_mech->cm_param_len = 0;
4343 if (pp != NULL) {
4344 size_t nonce_len, auth_data_len, total_param_len;
4346 if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
4347 out_mech->cm_param = NULL;
4348 error = EFAULT;
4349 goto out;
4352 nonce_len = STRUCT_FGET(params, ulNonceSize);
4353 auth_data_len = STRUCT_FGET(params, ulAuthDataSize);
4355 /* allocate param structure */
4356 total_param_len =
4357 sizeof (CK_AES_CCM_PARAMS) + nonce_len + auth_data_len;
4358 aes_ccm_params = kmem_alloc(total_param_len, KM_NOSLEEP);
4359 if (aes_ccm_params == NULL) {
4360 rv = CRYPTO_HOST_MEMORY;
4361 goto out;
4363 aes_ccm_params->ulMACSize = STRUCT_FGET(params, ulMACSize);
4364 aes_ccm_params->ulNonceSize = nonce_len;
4365 aes_ccm_params->ulAuthDataSize = auth_data_len;
4366 aes_ccm_params->ulDataSize
4367 = STRUCT_FGET(params, ulDataSize);
4368 aes_ccm_params->nonce
4369 = (uchar_t *)aes_ccm_params + sizeof (CK_AES_CCM_PARAMS);
4370 aes_ccm_params->authData
4371 = aes_ccm_params->nonce + nonce_len;
4373 if (copyin((char *)STRUCT_FGETP(params, nonce),
4374 aes_ccm_params->nonce, nonce_len) != 0) {
4375 kmem_free(aes_ccm_params, total_param_len);
4376 out_mech->cm_param = NULL;
4377 error = EFAULT;
4378 goto out;
4380 if (copyin((char *)STRUCT_FGETP(params, authData),
4381 aes_ccm_params->authData, auth_data_len) != 0) {
4382 kmem_free(aes_ccm_params, total_param_len);
4383 out_mech->cm_param = NULL;
4384 error = EFAULT;
4385 goto out;
4387 out_mech->cm_param = (char *)aes_ccm_params;
4388 out_mech->cm_param_len = sizeof (CK_AES_CCM_PARAMS);
4390 out:
4391 *out_error = error;
4392 return (rv);
4396 * Resource control checks don't need to be done. Why? Because this routine
4397 * knows the size of the structure, and it can't be overridden by a user.
4398 * This is different from the crypto module, which has no knowledge of
4399 * specific mechanisms, and therefore has to trust specified size of the
4400 * parameter. This trust, or lack of trust, is why the size of the
4401 * parameter has to be charged against the project resource control.
4403 static int
4404 copyin_aes_gcm_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
4405 int *out_error, int mode)
4407 STRUCT_DECL(crypto_mechanism, mech);
4408 STRUCT_DECL(CK_AES_GCM_PARAMS, params);
4409 CK_AES_GCM_PARAMS *aes_gcm_params;
4410 caddr_t pp;
4411 size_t param_len;
4412 int error = 0;
4413 int rv = 0;
4415 STRUCT_INIT(mech, mode);
4416 STRUCT_INIT(params, mode);
4417 bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4418 pp = STRUCT_FGETP(mech, cm_param);
4419 param_len = STRUCT_FGET(mech, cm_param_len);
4421 if (param_len != STRUCT_SIZE(params)) {
4422 rv = CRYPTO_ARGUMENTS_BAD;
4423 goto out;
4426 out_mech->cm_type = STRUCT_FGET(mech, cm_type);
4427 out_mech->cm_param = NULL;
4428 out_mech->cm_param_len = 0;
4429 if (pp != NULL) {
4430 size_t nonce_len, auth_data_len, total_param_len;
4432 if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
4433 out_mech->cm_param = NULL;
4434 error = EFAULT;
4435 goto out;
4438 nonce_len = STRUCT_FGET(params, ulIvLen);
4439 auth_data_len = STRUCT_FGET(params, ulAADLen);
4441 /* allocate param structure */
4442 total_param_len =
4443 sizeof (CK_AES_GCM_PARAMS) + nonce_len + auth_data_len;
4444 aes_gcm_params = kmem_alloc(total_param_len, KM_NOSLEEP);
4445 if (aes_gcm_params == NULL) {
4446 rv = CRYPTO_HOST_MEMORY;
4447 goto out;
4449 aes_gcm_params->ulTagBits = STRUCT_FGET(params, ulTagBits);
4450 aes_gcm_params->ulIvLen = nonce_len;
4451 aes_gcm_params->ulAADLen = auth_data_len;
4452 aes_gcm_params->pIv
4453 = (uchar_t *)aes_gcm_params + sizeof (CK_AES_GCM_PARAMS);
4454 aes_gcm_params->pAAD = aes_gcm_params->pIv + nonce_len;
4456 if (copyin((char *)STRUCT_FGETP(params, pIv),
4457 aes_gcm_params->pIv, nonce_len) != 0) {
4458 kmem_free(aes_gcm_params, total_param_len);
4459 out_mech->cm_param = NULL;
4460 error = EFAULT;
4461 goto out;
4463 if (copyin((char *)STRUCT_FGETP(params, pAAD),
4464 aes_gcm_params->pAAD, auth_data_len) != 0) {
4465 kmem_free(aes_gcm_params, total_param_len);
4466 out_mech->cm_param = NULL;
4467 error = EFAULT;
4468 goto out;
4470 out_mech->cm_param = (char *)aes_gcm_params;
4471 out_mech->cm_param_len = sizeof (CK_AES_GCM_PARAMS);
4473 out:
4474 *out_error = error;
4475 return (rv);
4478 static int
4479 copyin_aes_gmac_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
4480 int *out_error, int mode)
4482 STRUCT_DECL(crypto_mechanism, mech);
4483 STRUCT_DECL(CK_AES_GMAC_PARAMS, params);
4484 CK_AES_GMAC_PARAMS *aes_gmac_params;
4485 caddr_t pp;
4486 size_t param_len;
4487 int error = 0;
4488 int rv = 0;
4490 STRUCT_INIT(mech, mode);
4491 STRUCT_INIT(params, mode);
4492 bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4493 pp = STRUCT_FGETP(mech, cm_param);
4494 param_len = STRUCT_FGET(mech, cm_param_len);
4496 if (param_len != STRUCT_SIZE(params)) {
4497 rv = CRYPTO_ARGUMENTS_BAD;
4498 goto out;
4501 out_mech->cm_type = STRUCT_FGET(mech, cm_type);
4502 out_mech->cm_param = NULL;
4503 out_mech->cm_param_len = 0;
4504 if (pp != NULL) {
4505 size_t auth_data_len, total_param_len;
4507 if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
4508 out_mech->cm_param = NULL;
4509 error = EFAULT;
4510 goto out;
4513 auth_data_len = STRUCT_FGET(params, ulAADLen);
4515 /* allocate param structure */
4516 total_param_len = sizeof (CK_AES_GMAC_PARAMS) +
4517 AES_GMAC_IV_LEN + auth_data_len;
4518 aes_gmac_params = kmem_alloc(total_param_len, KM_NOSLEEP);
4519 if (aes_gmac_params == NULL) {
4520 rv = CRYPTO_HOST_MEMORY;
4521 goto out;
4523 aes_gmac_params->ulAADLen = auth_data_len;
4524 aes_gmac_params->pIv
4525 = (uchar_t *)aes_gmac_params + sizeof (CK_AES_GMAC_PARAMS);
4526 aes_gmac_params->pAAD = aes_gmac_params->pIv + AES_GMAC_IV_LEN;
4528 if (copyin((char *)STRUCT_FGETP(params, pIv),
4529 aes_gmac_params->pIv, AES_GMAC_IV_LEN) != 0) {
4530 kmem_free(aes_gmac_params, total_param_len);
4531 out_mech->cm_param = NULL;
4532 error = EFAULT;
4533 goto out;
4535 if (copyin((char *)STRUCT_FGETP(params, pAAD),
4536 aes_gmac_params->pAAD, auth_data_len) != 0) {
4537 kmem_free(aes_gmac_params, total_param_len);
4538 out_mech->cm_param = NULL;
4539 error = EFAULT;
4540 goto out;
4542 out_mech->cm_param = (char *)aes_gmac_params;
4543 out_mech->cm_param_len = sizeof (CK_AES_GMAC_PARAMS);
4545 out:
4546 *out_error = error;
4547 return (rv);
4551 * Resource control checks don't need to be done. Why? Because this routine
4552 * knows the size of the structure, and it can't be overridden by a user.
4553 * This is different from the crypto module, which has no knowledge of
4554 * specific mechanisms, and therefore has to trust specified size of the
4555 * parameter. This trust, or lack of trust, is why the size of the
4556 * parameter has to be charged against the project resource control.
4558 static int
4559 copyin_aes_ctr_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
4560 int *out_error, int mode)
4562 STRUCT_DECL(crypto_mechanism, mech);
4563 STRUCT_DECL(CK_AES_CTR_PARAMS, params);
4564 CK_AES_CTR_PARAMS *aes_ctr_params;
4565 caddr_t pp;
4566 size_t param_len;
4567 int error = 0;
4568 int rv = 0;
4570 STRUCT_INIT(mech, mode);
4571 STRUCT_INIT(params, mode);
4572 bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4573 pp = STRUCT_FGETP(mech, cm_param);
4574 param_len = STRUCT_FGET(mech, cm_param_len);
4576 if (param_len != STRUCT_SIZE(params)) {
4577 rv = CRYPTO_ARGUMENTS_BAD;
4578 goto out;
4581 out_mech->cm_type = STRUCT_FGET(mech, cm_type);
4582 out_mech->cm_param = NULL;
4583 out_mech->cm_param_len = 0;
4584 if (pp != NULL) {
4585 if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
4586 out_mech->cm_param = NULL;
4587 error = EFAULT;
4588 goto out;
4590 /* allocate param structure and counter block */
4591 aes_ctr_params = kmem_alloc(sizeof (CK_AES_CTR_PARAMS),
4592 KM_NOSLEEP);
4593 if (aes_ctr_params == NULL) {
4594 rv = CRYPTO_HOST_MEMORY;
4595 goto out;
4597 aes_ctr_params->ulCounterBits = STRUCT_FGET(params,
4598 ulCounterBits);
4599 bcopy(STRUCT_FGETP(params, cb), aes_ctr_params->cb, 16);
4600 out_mech->cm_param = (char *)aes_ctr_params;
4601 out_mech->cm_param_len = sizeof (CK_AES_CTR_PARAMS);
4603 out:
4604 *out_error = error;
4605 return (rv);
4608 static int
4609 copyin_ecc_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
4610 int *out_error, int mode)
4612 STRUCT_DECL(crypto_mechanism, mech);
4613 STRUCT_DECL(CK_ECDH1_DERIVE_PARAMS, params);
4614 CK_ECDH1_DERIVE_PARAMS *ecc_params;
4615 caddr_t pp;
4616 size_t param_len, shared_data_len, public_data_len;
4617 int error = 0;
4618 int rv = 0;
4620 STRUCT_INIT(mech, mode);
4621 STRUCT_INIT(params, mode);
4622 bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4623 pp = STRUCT_FGETP(mech, cm_param);
4624 param_len = STRUCT_FGET(mech, cm_param_len);
4626 if (param_len != STRUCT_SIZE(params)) {
4627 rv = CRYPTO_ARGUMENTS_BAD;
4628 goto out;
4631 out_mech->cm_type = STRUCT_FGET(mech, cm_type);
4632 out_mech->cm_param = NULL;
4633 out_mech->cm_param_len = 0;
4634 if (pp != NULL) {
4635 if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
4636 out_mech->cm_param = NULL;
4637 error = EFAULT;
4638 goto out;
4640 shared_data_len = STRUCT_FGET(params, ulSharedDataLen);
4641 public_data_len = STRUCT_FGET(params, ulPublicDataLen);
4642 /* allocate param structure and buffers */
4643 ecc_params = kmem_alloc(sizeof (CK_ECDH1_DERIVE_PARAMS) +
4644 roundup(shared_data_len, sizeof (caddr_t)) +
4645 roundup(public_data_len, sizeof (caddr_t)), KM_NOSLEEP);
4646 if (ecc_params == NULL) {
4647 rv = CRYPTO_HOST_MEMORY;
4648 goto out;
4650 ecc_params->pSharedData = (uchar_t *)ecc_params +
4651 sizeof (CK_ECDH1_DERIVE_PARAMS);
4652 ecc_params->pPublicData = (uchar_t *)ecc_params->pSharedData +
4653 roundup(shared_data_len, sizeof (caddr_t));
4654 if (copyin((char *)STRUCT_FGETP(params, pSharedData),
4655 ecc_params->pSharedData, shared_data_len) != 0) {
4656 kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) +
4657 roundup(shared_data_len, sizeof (caddr_t)) +
4658 roundup(public_data_len, sizeof (caddr_t)));
4659 out_mech->cm_param = NULL;
4660 error = EFAULT;
4661 goto out;
4663 ecc_params->ulSharedDataLen = shared_data_len;
4665 if (copyin((char *)STRUCT_FGETP(params, pPublicData),
4666 ecc_params->pPublicData, public_data_len) != 0) {
4667 kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) +
4668 roundup(shared_data_len, sizeof (caddr_t)) +
4669 roundup(public_data_len, sizeof (caddr_t)));
4670 out_mech->cm_param = NULL;
4671 error = EFAULT;
4672 goto out;
4674 ecc_params->ulPublicDataLen = public_data_len;
4675 ecc_params->kdf = STRUCT_FGET(params, kdf);
4676 out_mech->cm_param = (char *)ecc_params;
4677 out_mech->cm_param_len = sizeof (CK_ECDH1_DERIVE_PARAMS);
4679 out:
4680 *out_error = error;
4681 return (rv);
4684 /* ARGSUSED */
4685 static int
4686 copyout_aes_ctr_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
4687 int *out_error, int mode)
4689 STRUCT_DECL(crypto_mechanism, mech);
4690 STRUCT_DECL(CK_AES_CTR_PARAMS, params);
4691 caddr_t pp;
4692 size_t param_len;
4693 int error = 0;
4694 int rv = 0;
4696 STRUCT_INIT(mech, mode);
4697 STRUCT_INIT(params, mode);
4698 bcopy(out_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4699 pp = STRUCT_FGETP(mech, cm_param);
4700 param_len = STRUCT_FGET(mech, cm_param_len);
4701 if (param_len != STRUCT_SIZE(params)) {
4702 rv = CRYPTO_ARGUMENTS_BAD;
4703 goto out;
4706 if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
4707 error = EFAULT;
4708 goto out;
4711 /* for testing, overwrite the iv with 16 X 'A' */
4712 (void) memset(STRUCT_FGETP(params, cb), 'A', 16);
4713 if (copyout((char *)pp, STRUCT_BUF(params), param_len) != 0) {
4714 error = EFAULT;
4715 goto out;
4717 out:
4718 *out_error = error;
4719 return (rv);
4722 /* ARGSUSED */
4723 static int
4724 dprov_copyin_mechanism(crypto_provider_handle_t provider,
4725 crypto_mechanism_t *umech, crypto_mechanism_t *kmech,
4726 int *out_error, int mode)
4728 STRUCT_DECL(crypto_mechanism, mech);
4729 size_t param_len, expected_param_len;
4730 caddr_t pp;
4731 char *param;
4732 int rv;
4733 int error = 0;
4735 ASSERT(!servicing_interrupt());
4737 STRUCT_INIT(mech, mode);
4738 bcopy(umech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4739 pp = STRUCT_FGETP(mech, cm_param);
4740 param_len = STRUCT_FGET(mech, cm_param_len);
4742 kmech->cm_param = NULL;
4743 kmech->cm_param_len = 0;
4745 switch (kmech->cm_type) {
4746 case DES_CBC_MECH_INFO_TYPE:
4747 case DES3_CBC_MECH_INFO_TYPE:
4748 expected_param_len = DES_BLOCK_LEN;
4749 break;
4751 case BLOWFISH_CBC_MECH_INFO_TYPE:
4752 expected_param_len = BLOWFISH_BLOCK_LEN;
4753 break;
4755 case AES_CBC_MECH_INFO_TYPE:
4756 expected_param_len = AES_BLOCK_LEN;
4757 break;
4759 case AES_CTR_MECH_INFO_TYPE:
4760 case SHA1_KEY_DERIVATION_MECH_INFO_TYPE: /* for testing only */
4761 rv = copyin_aes_ctr_mech(umech, kmech, &error, mode);
4762 goto out;
4764 case ECDH1_DERIVE_MECH_INFO_TYPE:
4765 rv = copyin_ecc_mech(umech, kmech, &error, mode);
4766 goto out;
4768 case AES_CCM_MECH_INFO_TYPE:
4769 rv = copyin_aes_ccm_mech(umech, kmech, &error, mode);
4770 goto out;
4772 case AES_GCM_MECH_INFO_TYPE:
4773 rv = copyin_aes_gcm_mech(umech, kmech, &error, mode);
4774 goto out;
4776 case AES_GMAC_MECH_INFO_TYPE:
4777 rv = copyin_aes_gmac_mech(umech, kmech, &error, mode);
4778 goto out;
4780 case DH_PKCS_DERIVE_MECH_INFO_TYPE:
4781 expected_param_len = param_len;
4782 break;
4784 default:
4785 /* nothing to do - mechanism has no parameters */
4786 rv = CRYPTO_SUCCESS;
4787 goto out;
4790 if (param_len != expected_param_len) {
4791 rv = CRYPTO_MECHANISM_PARAM_INVALID;
4792 goto out;
4794 if (pp == NULL) {
4795 rv = CRYPTO_MECHANISM_PARAM_INVALID;
4796 goto out;
4798 if ((param = kmem_alloc(param_len, KM_NOSLEEP)) == NULL) {
4799 rv = CRYPTO_HOST_MEMORY;
4800 goto out;
4802 if (copyin((char *)pp, param, param_len) != 0) {
4803 kmem_free(param, param_len);
4804 error = EFAULT;
4805 rv = CRYPTO_FAILED;
4806 goto out;
4808 kmech->cm_param = (char *)param;
4809 kmech->cm_param_len = param_len;
4810 rv = CRYPTO_SUCCESS;
4811 out:
4812 *out_error = error;
4813 return (rv);
4816 /* ARGSUSED */
4817 static int
4818 dprov_copyout_mechanism(crypto_provider_handle_t provider,
4819 crypto_mechanism_t *kmech, crypto_mechanism_t *umech,
4820 int *out_error, int mode)
4822 ASSERT(!servicing_interrupt());
4824 switch (kmech->cm_type) {
4825 case AES_CTR_MECH_INFO_TYPE:
4826 case SHA1_KEY_DERIVATION_MECH_INFO_TYPE: /* for testing only */
4827 return (copyout_aes_ctr_mech(kmech, umech, out_error, mode));
4828 case ECDH1_DERIVE_MECH_INFO_TYPE:
4829 return (CRYPTO_SUCCESS);
4830 default:
4831 return (CRYPTO_MECHANISM_INVALID);
4836 * Free mechanism parameter that was allocated by the provider.
4838 /* ARGSUSED */
4839 static int
4840 dprov_free_mechanism(crypto_provider_handle_t provider,
4841 crypto_mechanism_t *mech)
4843 size_t len;
4845 if (mech->cm_param == NULL || mech->cm_param_len == 0)
4846 return (CRYPTO_SUCCESS);
4848 switch (mech->cm_type) {
4849 case AES_CTR_MECH_INFO_TYPE:
4850 case SHA1_KEY_DERIVATION_MECH_INFO_TYPE:
4851 len = sizeof (CK_AES_CTR_PARAMS);
4852 break;
4853 case ECDH1_DERIVE_MECH_INFO_TYPE: {
4854 CK_ECDH1_DERIVE_PARAMS *ecc_params;
4856 /* LINTED: pointer alignment */
4857 ecc_params = (CK_ECDH1_DERIVE_PARAMS *)mech->cm_param;
4858 kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) +
4859 roundup(ecc_params->ulSharedDataLen, sizeof (caddr_t)) +
4860 roundup(ecc_params->ulPublicDataLen, sizeof (caddr_t)));
4861 return (CRYPTO_SUCCESS);
4863 case AES_CCM_MECH_INFO_TYPE: {
4864 CK_AES_CCM_PARAMS *params;
4865 size_t total_param_len;
4867 if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) {
4868 /* LINTED: pointer alignment */
4869 params = (CK_AES_CCM_PARAMS *)mech->cm_param;
4870 total_param_len = mech->cm_param_len +
4871 params->ulNonceSize + params->ulAuthDataSize;
4872 kmem_free(params, total_param_len);
4873 mech->cm_param = NULL;
4874 mech->cm_param_len = 0;
4876 return (CRYPTO_SUCCESS);
4878 case AES_GMAC_MECH_INFO_TYPE: {
4879 CK_AES_GMAC_PARAMS *params;
4880 size_t total_param_len;
4882 if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) {
4883 /* LINTED: pointer alignment */
4884 params = (CK_AES_GMAC_PARAMS *)mech->cm_param;
4885 total_param_len = mech->cm_param_len +
4886 AES_GMAC_IV_LEN + params->ulAADLen;
4887 kmem_free(params, total_param_len);
4888 mech->cm_param = NULL;
4889 mech->cm_param_len = 0;
4891 return (CRYPTO_SUCCESS);
4893 case AES_GCM_MECH_INFO_TYPE: {
4894 CK_AES_GCM_PARAMS *params;
4895 size_t total_param_len;
4897 if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) {
4898 /* LINTED: pointer alignment */
4899 params = (CK_AES_GCM_PARAMS *)mech->cm_param;
4900 total_param_len = mech->cm_param_len +
4901 params->ulIvLen + params->ulAADLen;
4902 kmem_free(params, total_param_len);
4903 mech->cm_param = NULL;
4904 mech->cm_param_len = 0;
4906 return (CRYPTO_SUCCESS);
4909 default:
4910 len = mech->cm_param_len;
4912 kmem_free(mech->cm_param, len);
4913 return (CRYPTO_SUCCESS);
4917 * No (Key)Store Key management entry point.
4919 static int
4920 dprov_nostore_key_generate(crypto_provider_handle_t provider,
4921 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
4922 crypto_object_attribute_t *template, uint_t attribute_count,
4923 crypto_object_attribute_t *out_template, uint_t out_attribute_count,
4924 crypto_req_handle_t req)
4926 int error = CRYPTO_FAILED;
4927 dprov_state_t *softc = (dprov_state_t *)provider;
4928 /* LINTED E_FUNC_SET_NOT_USED */
4929 int instance;
4931 instance = ddi_get_instance(softc->ds_dip);
4932 DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate: started\n",
4933 instance));
4935 /* submit request to the taskq */
4936 error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_GENERATE,
4937 softc, req, session_id, mechanism, template, attribute_count,
4938 NULL, NULL, 0, NULL, NULL, NULL, 0, out_template,
4939 out_attribute_count, NULL, 0);
4941 DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate: "
4942 "done err = 0x0%x\n", instance, error));
4944 return (error);
4947 static int
4948 dprov_nostore_key_generate_pair(crypto_provider_handle_t provider,
4949 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
4950 crypto_object_attribute_t *public_key_template,
4951 uint_t public_key_attribute_count,
4952 crypto_object_attribute_t *private_key_template,
4953 uint_t private_key_attribute_count,
4954 crypto_object_attribute_t *out_public_key_template,
4955 uint_t out_public_key_attribute_count,
4956 crypto_object_attribute_t *out_private_key_template,
4957 uint_t out_private_key_attribute_count,
4958 crypto_req_handle_t req)
4960 int error = CRYPTO_FAILED;
4961 dprov_state_t *softc = (dprov_state_t *)provider;
4962 /* LINTED E_FUNC_SET_NOT_USED */
4963 int instance;
4965 instance = ddi_get_instance(softc->ds_dip);
4966 DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate_pair: started\n",
4967 instance));
4969 /* submit request to the taskq */
4970 error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR,
4971 softc, req, session_id, mechanism, public_key_template,
4972 public_key_attribute_count, NULL, private_key_template,
4973 private_key_attribute_count, NULL, NULL, NULL, 0,
4974 out_public_key_template, out_public_key_attribute_count,
4975 out_private_key_template, out_private_key_attribute_count);
4977 DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate_pair: "
4978 "done err = 0x0%x\n", instance, error));
4980 return (error);
4983 static int
4984 dprov_nostore_key_derive(crypto_provider_handle_t provider,
4985 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
4986 crypto_key_t *base_key, crypto_object_attribute_t *template,
4987 uint_t attribute_count, crypto_object_attribute_t *out_template,
4988 uint_t out_attribute_count, crypto_req_handle_t req)
4990 int error = CRYPTO_FAILED;
4991 dprov_state_t *softc = (dprov_state_t *)provider;
4992 /* LINTED E_FUNC_SET_NOT_USED */
4993 int instance;
4995 instance = ddi_get_instance(softc->ds_dip);
4996 DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_derive: started\n",
4997 instance));
4999 /* submit request to the taskq */
5000 error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_DERIVE, softc, req,
5001 session_id, mechanism, template, attribute_count, NULL, NULL,
5002 0, NULL, base_key, NULL, 0, out_template, out_attribute_count,
5003 NULL, 0);
5005 DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_derive: "
5006 "done err = 0x0%x\n", instance, error));
5008 return (error);
5012 * Allocate a dprov taskq request and initialize the common fields.
5013 * Return NULL if the memory allocation failed.
5015 static dprov_req_t *
5016 dprov_alloc_req(dprov_req_type_t req_type, dprov_state_t *softc,
5017 crypto_req_handle_t kcf_req, int kmflag)
5019 dprov_req_t *taskq_req;
5021 if ((taskq_req = kmem_alloc(sizeof (dprov_req_t), kmflag)) == NULL)
5022 return (NULL);
5024 taskq_req->dr_type = req_type;
5025 taskq_req->dr_softc = softc;
5026 taskq_req->dr_kcf_req = kcf_req;
5028 return (taskq_req);
5032 * Dispatch a dprov request on the taskq associated with a softc.
5033 * Returns CRYPTO_HOST_MEMORY if the request cannot be queued,
5034 * CRYPTO_QUEUED on success.
5036 static int
5037 dprov_taskq_dispatch(dprov_state_t *softc, dprov_req_t *taskq_req,
5038 task_func_t *func, int kmflag)
5040 if (taskq_dispatch(softc->ds_taskq, func, taskq_req,
5041 kmflag == KM_NOSLEEP ? TQ_NOSLEEP : TQ_SLEEP) == (taskqid_t)0) {
5042 kmem_free(taskq_req, sizeof (dprov_req_t));
5043 return (CRYPTO_HOST_MEMORY);
5044 } else
5045 return (CRYPTO_QUEUED);
5049 * Helper function to submit digest operations to the taskq.
5050 * Returns one of the CRYPTO_ errors.
5052 static int
5053 dprov_digest_submit_req(dprov_req_type_t req_type,
5054 dprov_state_t *softc, crypto_req_handle_t req,
5055 crypto_mechanism_t *mechanism, crypto_data_t *data, crypto_key_t *key,
5056 crypto_data_t *digest, crypto_ctx_t *ctx, int kmflag)
5058 dprov_req_t *taskq_req;
5060 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
5061 return (CRYPTO_HOST_MEMORY);
5063 taskq_req->dr_digest_req.dr_mechanism = mechanism;
5064 taskq_req->dr_digest_req.dr_ctx = ctx;
5065 taskq_req->dr_digest_req.dr_data = data;
5066 taskq_req->dr_digest_req.dr_key = key;
5067 taskq_req->dr_digest_req.dr_digest = digest;
5069 return (dprov_taskq_dispatch(softc, taskq_req,
5070 (task_func_t *)dprov_digest_task, kmflag));
5074 * Helper function to submit mac operations to the taskq.
5075 * Returns one of the CRYPTO_ errors.
5077 static int
5078 dprov_mac_submit_req(dprov_req_type_t req_type,
5079 dprov_state_t *softc, crypto_req_handle_t req,
5080 crypto_mechanism_t *mechanism, crypto_data_t *data, crypto_key_t *key,
5081 crypto_data_t *mac, crypto_ctx_t *ctx, crypto_session_id_t sid, int kmflag)
5083 dprov_req_t *taskq_req;
5085 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
5086 return (CRYPTO_HOST_MEMORY);
5088 taskq_req->dr_mac_req.dr_mechanism = mechanism;
5089 taskq_req->dr_mac_req.dr_ctx = ctx;
5090 taskq_req->dr_mac_req.dr_data = data;
5091 taskq_req->dr_mac_req.dr_key = key;
5092 taskq_req->dr_mac_req.dr_mac = mac;
5093 taskq_req->dr_mac_req.dr_session_id = sid;
5095 return (dprov_taskq_dispatch(softc, taskq_req,
5096 (task_func_t *)dprov_mac_task, kmflag));
5100 * Helper function to submit sign operations to the taskq.
5101 * Returns one of the CRYPTO_ errors.
5103 static int
5104 dprov_sign_submit_req(dprov_req_type_t req_type,
5105 dprov_state_t *softc, crypto_req_handle_t req,
5106 crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data,
5107 crypto_data_t *signature, crypto_ctx_t *ctx, crypto_session_id_t sid,
5108 int kmflag)
5110 dprov_req_t *taskq_req;
5112 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
5113 return (CRYPTO_HOST_MEMORY);
5115 taskq_req->dr_sign_req.sr_mechanism = mechanism;
5116 taskq_req->dr_sign_req.sr_ctx = ctx;
5117 taskq_req->dr_sign_req.sr_key = key;
5118 taskq_req->dr_sign_req.sr_data = data;
5119 taskq_req->dr_sign_req.sr_signature = signature;
5120 taskq_req->dr_sign_req.sr_session_id = sid;
5122 return (dprov_taskq_dispatch(softc, taskq_req,
5123 (task_func_t *)dprov_sign_task, kmflag));
5127 * Helper function to submit verify operations to the taskq.
5128 * Returns one of the CRYPTO_ errors.
5130 static int
5131 dprov_verify_submit_req(dprov_req_type_t req_type,
5132 dprov_state_t *softc, crypto_req_handle_t req,
5133 crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data,
5134 crypto_data_t *signature, crypto_ctx_t *ctx, crypto_session_id_t sid,
5135 int kmflag)
5137 dprov_req_t *taskq_req;
5139 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
5140 return (CRYPTO_HOST_MEMORY);
5142 taskq_req->dr_verify_req.vr_mechanism = mechanism;
5143 taskq_req->dr_verify_req.vr_ctx = ctx;
5144 taskq_req->dr_verify_req.vr_key = key;
5145 taskq_req->dr_verify_req.vr_data = data;
5146 taskq_req->dr_verify_req.vr_signature = signature;
5147 taskq_req->dr_verify_req.vr_session_id = sid;
5149 return (dprov_taskq_dispatch(softc, taskq_req,
5150 (task_func_t *)dprov_verify_task, kmflag));
5154 * Helper function to submit dual operations to the taskq.
5155 * Returns one of the CRYPTO_ errors.
5157 static int
5158 dprov_dual_submit_req(dprov_req_type_t req_type, dprov_state_t *softc,
5159 crypto_req_handle_t req, crypto_ctx_t *signverify_ctx,
5160 crypto_ctx_t *cipher_ctx, crypto_data_t *plaintext,
5161 crypto_data_t *ciphertext)
5163 dprov_req_t *taskq_req;
5165 if ((taskq_req = dprov_alloc_req(req_type, softc, req,
5166 KM_NOSLEEP)) == NULL)
5167 return (CRYPTO_HOST_MEMORY);
5169 taskq_req->dr_dual_req.dr_signverify_ctx = signverify_ctx;
5170 taskq_req->dr_dual_req.dr_cipher_ctx = cipher_ctx;
5171 taskq_req->dr_dual_req.dr_plaintext = plaintext;
5172 taskq_req->dr_dual_req.dr_ciphertext = ciphertext;
5174 return (dprov_taskq_dispatch(softc, taskq_req,
5175 (task_func_t *)dprov_dual_task, KM_NOSLEEP));
5179 * Helper function to submit dual cipher/mac operations to the taskq.
5180 * Returns one of the CRYPTO_ errors.
5182 static int
5183 dprov_cipher_mac_submit_req(dprov_req_type_t req_type,
5184 dprov_state_t *softc, crypto_req_handle_t req, crypto_ctx_t *ctx,
5185 crypto_session_id_t sid, crypto_mechanism_t *cipher_mech,
5186 crypto_key_t *cipher_key, crypto_mechanism_t *mac_mech,
5187 crypto_key_t *mac_key, crypto_dual_data_t *dual_data,
5188 crypto_data_t *data, crypto_data_t *mac, int kmflag)
5190 dprov_req_t *taskq_req;
5192 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
5193 return (CRYPTO_HOST_MEMORY);
5195 taskq_req->dr_cipher_mac_req.mr_session_id = sid;
5196 taskq_req->dr_cipher_mac_req.mr_ctx = ctx;
5197 taskq_req->dr_cipher_mac_req.mr_cipher_mech = cipher_mech;
5198 taskq_req->dr_cipher_mac_req.mr_cipher_key = cipher_key;
5199 taskq_req->dr_cipher_mac_req.mr_mac_mech = mac_mech;
5200 taskq_req->dr_cipher_mac_req.mr_mac_key = mac_key;
5201 taskq_req->dr_cipher_mac_req.mr_dual_data = dual_data;
5202 taskq_req->dr_cipher_mac_req.mr_data = data;
5203 taskq_req->dr_cipher_mac_req.mr_mac = mac;
5205 return (dprov_taskq_dispatch(softc, taskq_req,
5206 (task_func_t *)dprov_cipher_mac_task, kmflag));
5210 * Helper function to submit cipher operations to the taskq.
5211 * Returns one of the CRYPTO_ errors.
5213 static int
5214 dprov_cipher_submit_req(dprov_req_type_t req_type,
5215 dprov_state_t *softc, crypto_req_handle_t req,
5216 crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *plaintext,
5217 crypto_data_t *ciphertext, crypto_ctx_t *ctx, crypto_session_id_t sid,
5218 int kmflag)
5220 dprov_req_t *taskq_req;
5222 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
5223 return (CRYPTO_HOST_MEMORY);
5225 taskq_req->dr_cipher_req.dr_mechanism = mechanism;
5226 taskq_req->dr_cipher_req.dr_ctx = ctx;
5227 taskq_req->dr_cipher_req.dr_key = key;
5228 taskq_req->dr_cipher_req.dr_plaintext = plaintext;
5229 taskq_req->dr_cipher_req.dr_ciphertext = ciphertext;
5230 taskq_req->dr_cipher_req.dr_session_id = sid;
5232 return (dprov_taskq_dispatch(softc, taskq_req,
5233 (task_func_t *)dprov_cipher_task, kmflag));
5237 * Helper function to submit random number operations to the taskq.
5238 * Returns one of the CRYPTO_ errors.
5240 static int
5241 dprov_random_submit_req(dprov_req_type_t req_type,
5242 dprov_state_t *softc, crypto_req_handle_t req, uchar_t *buf, size_t len,
5243 crypto_session_id_t sid, uint_t entropy_est, uint32_t flags)
5245 dprov_req_t *taskq_req;
5247 if ((taskq_req = dprov_alloc_req(req_type, softc, req,
5248 KM_NOSLEEP)) == NULL)
5249 return (CRYPTO_HOST_MEMORY);
5251 taskq_req->dr_random_req.rr_buf = buf;
5252 taskq_req->dr_random_req.rr_len = len;
5253 taskq_req->dr_random_req.rr_session_id = sid;
5254 taskq_req->dr_random_req.rr_entropy_est = entropy_est;
5255 taskq_req->dr_random_req.rr_flags = flags;
5257 return (dprov_taskq_dispatch(softc, taskq_req,
5258 (task_func_t *)dprov_random_task, KM_NOSLEEP));
5263 * Helper function to submit session management operations to the taskq.
5264 * Returns one of the CRYPTO_ errors.
5266 static int
5267 dprov_session_submit_req(dprov_req_type_t req_type,
5268 dprov_state_t *softc, crypto_req_handle_t req,
5269 crypto_session_id_t *session_id_ptr, crypto_session_id_t session_id,
5270 crypto_user_type_t user_type, char *pin, size_t pin_len)
5272 dprov_req_t *taskq_req;
5274 if ((taskq_req = dprov_alloc_req(req_type, softc, req,
5275 KM_NOSLEEP)) == NULL)
5276 return (CRYPTO_HOST_MEMORY);
5278 taskq_req->dr_session_req.sr_session_id_ptr = session_id_ptr;
5279 taskq_req->dr_session_req.sr_session_id = session_id;
5280 taskq_req->dr_session_req.sr_user_type = user_type;
5281 taskq_req->dr_session_req.sr_pin = pin;
5282 taskq_req->dr_session_req.sr_pin_len = pin_len;
5284 return (dprov_taskq_dispatch(softc, taskq_req,
5285 (task_func_t *)dprov_session_task, KM_NOSLEEP));
5289 * Helper function to submit object management operations to the taskq.
5290 * Returns one of the CRYPTO_ errors.
5292 static int
5293 dprov_object_submit_req(dprov_req_type_t req_type,
5294 dprov_state_t *softc, crypto_req_handle_t req,
5295 crypto_session_id_t session_id, crypto_object_id_t object_id,
5296 crypto_object_attribute_t *template, uint_t attribute_count,
5297 crypto_object_id_t *object_id_ptr, size_t *object_size,
5298 void **find_pp, void *find_p, uint_t max_object_count,
5299 uint_t *object_count_ptr, int kmflag)
5301 dprov_req_t *taskq_req;
5303 if ((taskq_req = dprov_alloc_req(req_type, softc, req,
5304 kmflag)) == NULL)
5305 return (CRYPTO_HOST_MEMORY);
5307 taskq_req->dr_object_req.or_session_id = session_id;
5308 taskq_req->dr_object_req.or_object_id = object_id;
5309 taskq_req->dr_object_req.or_template = template;
5310 taskq_req->dr_object_req.or_attribute_count = attribute_count;
5311 taskq_req->dr_object_req.or_object_id_ptr = object_id_ptr;
5312 taskq_req->dr_object_req.or_object_size = object_size;
5313 taskq_req->dr_object_req.or_find_pp = find_pp;
5314 taskq_req->dr_object_req.or_find_p = find_p;
5315 taskq_req->dr_object_req.or_max_object_count = max_object_count;
5316 taskq_req->dr_object_req.or_object_count_ptr = object_count_ptr;
5318 return (dprov_taskq_dispatch(softc, taskq_req,
5319 (task_func_t *)dprov_object_task, KM_NOSLEEP));
5323 * Helper function to submit key management operations to the taskq.
5324 * Returns one of the CRYPTO_ errors.
5326 static int
5327 dprov_key_submit_req(dprov_req_type_t req_type,
5328 dprov_state_t *softc, crypto_req_handle_t req,
5329 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
5330 crypto_object_attribute_t *template, uint_t attribute_count,
5331 crypto_object_id_t *object_id_ptr,
5332 crypto_object_attribute_t *private_key_template,
5333 uint_t private_key_attribute_count,
5334 crypto_object_id_t *private_key_object_id_ptr, crypto_key_t *key,
5335 uchar_t *wrapped_key, size_t *wrapped_key_len_ptr,
5336 crypto_object_attribute_t *out_template1, uint_t out_attribute_count1,
5337 crypto_object_attribute_t *out_template2, uint_t out_attribute_count2)
5339 dprov_req_t *taskq_req;
5341 if ((taskq_req = dprov_alloc_req(req_type, softc, req,
5342 KM_NOSLEEP)) == NULL)
5343 return (CRYPTO_HOST_MEMORY);
5345 taskq_req->dr_key_req.kr_session_id = session_id;
5346 taskq_req->dr_key_req.kr_mechanism = mechanism;
5347 taskq_req->dr_key_req.kr_template = template;
5348 taskq_req->dr_key_req.kr_attribute_count = attribute_count;
5349 taskq_req->dr_key_req.kr_object_id_ptr = object_id_ptr;
5350 taskq_req->dr_key_req.kr_private_key_template = private_key_template;
5351 taskq_req->dr_key_req.kr_private_key_attribute_count =
5352 private_key_attribute_count;
5353 taskq_req->dr_key_req.kr_private_key_object_id_ptr =
5354 private_key_object_id_ptr;
5355 taskq_req->dr_key_req.kr_key = key;
5356 taskq_req->dr_key_req.kr_wrapped_key = wrapped_key;
5357 taskq_req->dr_key_req.kr_wrapped_key_len_ptr = wrapped_key_len_ptr;
5358 taskq_req->dr_key_req.kr_out_template1 = out_template1;
5359 taskq_req->dr_key_req.kr_out_attribute_count1 = out_attribute_count1;
5360 taskq_req->dr_key_req.kr_out_template2 = out_template2;
5361 taskq_req->dr_key_req.kr_out_attribute_count2 = out_attribute_count2;
5363 return (dprov_taskq_dispatch(softc, taskq_req,
5364 (task_func_t *)dprov_key_task, KM_NOSLEEP));
5368 * Helper function to submit provider management operations to the taskq.
5369 * Returns one of the CRYPTO_ errors.
5371 static int
5372 dprov_mgmt_submit_req(dprov_req_type_t req_type,
5373 dprov_state_t *softc, crypto_req_handle_t req,
5374 crypto_session_id_t session_id, char *pin, size_t pin_len,
5375 char *old_pin, size_t old_pin_len, char *label,
5376 crypto_provider_ext_info_t *ext_info)
5378 dprov_req_t *taskq_req;
5380 if ((taskq_req = dprov_alloc_req(req_type, softc, req,
5381 KM_NOSLEEP)) == NULL)
5382 return (CRYPTO_HOST_MEMORY);
5384 taskq_req->dr_mgmt_req.mr_session_id = session_id;
5385 taskq_req->dr_mgmt_req.mr_pin = pin;
5386 taskq_req->dr_mgmt_req.mr_pin_len = pin_len;
5387 taskq_req->dr_mgmt_req.mr_old_pin = old_pin;
5388 taskq_req->dr_mgmt_req.mr_old_pin_len = old_pin_len;
5389 taskq_req->dr_mgmt_req.mr_label = label;
5390 taskq_req->dr_mgmt_req.mr_ext_info = ext_info;
5392 return (dprov_taskq_dispatch(softc, taskq_req,
5393 (task_func_t *)dprov_mgmt_task, KM_NOSLEEP));
5397 * Helper function for taskq dispatcher routines. Notify the framework
5398 * that the operation corresponding to the specified request is done,
5399 * and pass it the error code. Finally, free the taskq_req.
5401 static void
5402 dprov_op_done(dprov_req_t *taskq_req, int error)
5404 /* notify framework that request is completed */
5405 crypto_op_notification(taskq_req->dr_kcf_req, error);
5407 /* free taskq request structure */
5408 kmem_free(taskq_req, sizeof (dprov_req_t));
5412 * taskq dispatcher function for digest operations.
5414 static void
5415 dprov_digest_task(dprov_req_t *taskq_req)
5417 kcf_provider_desc_t *pd;
5418 dprov_state_t *softc;
5419 /* LINTED E_FUNC_SET_NOT_USED */
5420 int instance;
5421 int error = CRYPTO_NOT_SUPPORTED;
5422 crypto_ctx_t *ctx = taskq_req->dr_digest_req.dr_ctx;
5423 crypto_mechanism_t mech;
5425 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
5426 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_task: started\n", instance));
5428 switch (taskq_req->dr_type) {
5430 case DPROV_REQ_DIGEST_INIT:
5431 /* allocate a dprov-private context */
5432 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
5433 CRYPTO_SUCCESS)
5434 break;
5436 /* structure assignment */
5437 mech = *taskq_req->dr_digest_req.dr_mechanism;
5439 /* get the software provider for this mechanism */
5440 if ((error = dprov_get_sw_prov(
5441 taskq_req->dr_digest_req.dr_mechanism, &pd,
5442 &mech.cm_type)) != CRYPTO_SUCCESS)
5443 break;
5445 /* Use a session id of zero since we use a software provider */
5446 error = crypto_digest_init_prov(pd, 0, &mech,
5447 &DPROV_CTX_SINGLE(ctx), NULL);
5449 /* release provider reference */
5450 KCF_PROV_REFRELE(pd);
5451 break;
5453 case DPROV_REQ_DIGEST:
5454 error = crypto_digest_single(DPROV_CTX_SINGLE(ctx),
5455 taskq_req->dr_digest_req.dr_data,
5456 taskq_req->dr_digest_req.dr_digest, NULL);
5458 if (error != CRYPTO_BUFFER_TOO_SMALL) {
5459 DPROV_CTX_SINGLE(ctx) = NULL;
5460 (void) dprov_free_context(ctx);
5462 break;
5464 case DPROV_REQ_DIGEST_UPDATE:
5465 error = crypto_digest_update(DPROV_CTX_SINGLE(ctx),
5466 taskq_req->dr_digest_req.dr_data, NULL);
5467 break;
5469 case DPROV_REQ_DIGEST_KEY: {
5470 crypto_data_t data;
5471 crypto_key_t key;
5472 size_t len;
5474 mutex_enter(&softc->ds_lock);
5475 error = dprov_key_value_secret(softc, ctx->cc_session,
5476 taskq_req->dr_type, taskq_req->dr_digest_req.dr_key, &key);
5477 mutex_exit(&softc->ds_lock);
5478 if (error != CRYPTO_SUCCESS)
5479 break;
5481 /* key lengths are specified in bits */
5482 len = CRYPTO_BITS2BYTES(key.ck_length);
5483 data.cd_format = CRYPTO_DATA_RAW;
5484 data.cd_offset = 0;
5485 data.cd_length = len;
5486 data.cd_raw.iov_base = key.ck_data;
5487 data.cd_raw.iov_len = len;
5488 error = crypto_digest_update(DPROV_CTX_SINGLE(ctx),
5489 &data, NULL);
5490 break;
5493 case DPROV_REQ_DIGEST_FINAL:
5494 error = crypto_digest_final(DPROV_CTX_SINGLE(ctx),
5495 taskq_req->dr_digest_req.dr_digest, NULL);
5496 if (error != CRYPTO_BUFFER_TOO_SMALL) {
5497 DPROV_CTX_SINGLE(ctx) = NULL;
5498 (void) dprov_free_context(ctx);
5500 break;
5502 case DPROV_REQ_DIGEST_ATOMIC:
5503 /* structure assignment */
5504 mech = *taskq_req->dr_digest_req.dr_mechanism;
5506 /* get the software provider for this mechanism */
5507 if ((error = dprov_get_sw_prov(
5508 taskq_req->dr_digest_req.dr_mechanism, &pd,
5509 &mech.cm_type)) != CRYPTO_SUCCESS)
5510 break;
5512 /* use a session id of zero since we use a software provider */
5513 error = crypto_digest_prov(pd, 0, &mech,
5514 taskq_req->dr_digest_req.dr_data,
5515 taskq_req->dr_digest_req.dr_digest, NULL);
5517 /* release provider reference */
5518 KCF_PROV_REFRELE(pd);
5520 break;
5523 dprov_op_done(taskq_req, error);
5524 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_task: end\n", instance));
5528 * taskq dispatcher function for mac operations.
5530 static void
5531 dprov_mac_task(dprov_req_t *taskq_req)
5533 kcf_provider_desc_t *pd;
5534 dprov_state_t *softc;
5535 /* LINTED E_FUNC_SET_NOT_USED */
5536 int instance;
5537 int error = CRYPTO_NOT_SUPPORTED;
5538 crypto_ctx_t *ctx = taskq_req->dr_mac_req.dr_ctx;
5539 crypto_key_t key;
5540 crypto_mechanism_t mech;
5542 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
5543 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: started\n", instance));
5545 switch (taskq_req->dr_type) {
5547 case DPROV_REQ_MAC_INIT:
5548 /* allocate a dprov-private context */
5549 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
5550 CRYPTO_SUCCESS)
5551 break;
5553 /* get key value */
5554 mutex_enter(&softc->ds_lock);
5555 error = dprov_key_value_secret(softc, ctx->cc_session,
5556 taskq_req->dr_type, taskq_req->dr_mac_req.dr_key, &key);
5557 mutex_exit(&softc->ds_lock);
5558 if (error != CRYPTO_SUCCESS)
5559 break;
5561 /* structure assignment */
5562 mech = *taskq_req->dr_mac_req.dr_mechanism;
5564 /* get the software provider for this mechanism */
5565 if ((error = dprov_get_sw_prov(
5566 taskq_req->dr_mac_req.dr_mechanism, &pd,
5567 &mech.cm_type)) != CRYPTO_SUCCESS)
5568 break;
5570 /* Use a session id of zero since we use a software provider */
5571 error = crypto_mac_init_prov(pd, 0, &mech, &key, NULL,
5572 &DPROV_CTX_SINGLE(ctx), NULL);
5574 /* release provider reference */
5575 KCF_PROV_REFRELE(pd);
5576 break;
5578 case DPROV_REQ_MAC:
5579 error = crypto_mac_single(DPROV_CTX_SINGLE(ctx),
5580 taskq_req->dr_mac_req.dr_data,
5581 taskq_req->dr_mac_req.dr_mac, NULL);
5583 if (error != CRYPTO_BUFFER_TOO_SMALL) {
5584 DPROV_CTX_SINGLE(ctx) = NULL;
5585 (void) dprov_free_context(ctx);
5587 break;
5589 case DPROV_REQ_MAC_UPDATE:
5590 error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
5591 taskq_req->dr_mac_req.dr_data, NULL);
5592 break;
5594 case DPROV_REQ_MAC_FINAL:
5595 error = crypto_mac_final(DPROV_CTX_SINGLE(ctx),
5596 taskq_req->dr_mac_req.dr_mac, NULL);
5597 if (error != CRYPTO_BUFFER_TOO_SMALL) {
5598 DPROV_CTX_SINGLE(ctx) = NULL;
5599 (void) dprov_free_context(ctx);
5601 break;
5603 case DPROV_REQ_MAC_ATOMIC:
5604 case DPROV_REQ_MAC_VERIFY_ATOMIC:
5605 /* get key value */
5606 mutex_enter(&softc->ds_lock);
5607 error = dprov_key_value_secret(softc,
5608 taskq_req->dr_mac_req.dr_session_id,
5609 taskq_req->dr_type, taskq_req->dr_mac_req.dr_key, &key);
5610 mutex_exit(&softc->ds_lock);
5611 if (error != CRYPTO_SUCCESS)
5612 break;
5614 /* structure assignment */
5615 mech = *taskq_req->dr_mac_req.dr_mechanism;
5617 /* get the software provider for this mechanism */
5618 if ((error = dprov_get_sw_prov(
5619 taskq_req->dr_mac_req.dr_mechanism, &pd,
5620 &mech.cm_type)) != CRYPTO_SUCCESS)
5621 break;
5623 /* use a session id of zero since we use a software provider */
5624 if (taskq_req->dr_type == DPROV_REQ_MAC_ATOMIC)
5625 error = crypto_mac_prov(pd, 0, &mech,
5626 taskq_req->dr_mac_req.dr_data,
5627 &key, NULL, taskq_req->dr_mac_req.dr_mac, NULL);
5628 else
5629 error = crypto_mac_verify_prov(pd, 0, &mech,
5630 taskq_req->dr_mac_req.dr_data,
5631 &key, NULL, taskq_req->dr_mac_req.dr_mac, NULL);
5633 /* release provider reference */
5634 KCF_PROV_REFRELE(pd);
5636 break;
5639 dprov_op_done(taskq_req, error);
5640 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: end\n", instance));
5644 * taskq dispatcher function for sign operations.
5646 static void
5647 dprov_sign_task(dprov_req_t *taskq_req)
5649 kcf_provider_desc_t *pd;
5650 dprov_state_t *softc;
5651 /* LINTED E_FUNC_SET_NOT_USED */
5652 int instance;
5653 int error = CRYPTO_NOT_SUPPORTED;
5654 crypto_ctx_t *ctx = taskq_req->dr_sign_req.sr_ctx;
5655 crypto_key_t key, *keyp;
5656 crypto_mechanism_t mech;
5658 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
5659 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_task: started\n", instance));
5661 switch (taskq_req->dr_type) {
5663 case DPROV_REQ_SIGN_INIT:
5664 case DPROV_REQ_SIGN_RECOVER_INIT:
5665 /* allocate a dprov-private context */
5666 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
5667 CRYPTO_SUCCESS)
5668 break;
5670 /* structure assignment */
5671 mech = *taskq_req->dr_sign_req.sr_mechanism;
5672 if (dprov_valid_mac_mech(mech.cm_type)) {
5673 DPROV_CTX_P(ctx)->dc_svrfy_to_mac = B_TRUE;
5676 mutex_enter(&softc->ds_lock);
5677 if (is_publickey_mech(mech.cm_type)) {
5678 if ((error = dprov_key_attr_asymmetric(softc,
5679 ctx->cc_session, taskq_req->dr_type,
5680 taskq_req->dr_sign_req.sr_key, &key))
5681 != CRYPTO_SUCCESS) {
5682 mutex_exit(&softc->ds_lock);
5683 break;
5685 keyp = &key;
5686 } else {
5687 if ((error = dprov_key_value_secret(softc,
5688 ctx->cc_session, taskq_req->dr_type,
5689 taskq_req->dr_sign_req.sr_key, &key))
5690 != CRYPTO_SUCCESS) {
5691 mutex_exit(&softc->ds_lock);
5692 break;
5694 keyp = &key;
5696 mutex_exit(&softc->ds_lock);
5698 /* get the software provider for this mechanism */
5699 if ((error = dprov_get_sw_prov(
5700 taskq_req->dr_sign_req.sr_mechanism, &pd,
5701 &mech.cm_type)) != CRYPTO_SUCCESS)
5702 break;
5704 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5705 error = crypto_mac_init_prov(pd, 0, &mech, keyp, NULL,
5706 &DPROV_CTX_SINGLE(ctx), NULL);
5708 /* release provider reference */
5709 KCF_PROV_REFRELE(pd);
5710 break;
5713 /* Use a session id of zero since we use a software provider */
5714 if (taskq_req->dr_type == DPROV_REQ_SIGN_INIT)
5715 error = crypto_sign_init_prov(pd, 0, &mech, keyp,
5716 NULL, &DPROV_CTX_SINGLE(ctx), NULL);
5717 else
5718 error = crypto_sign_recover_init_prov(pd, 0, &mech,
5719 keyp, NULL, &DPROV_CTX_SINGLE(ctx), NULL);
5721 /* release provider reference */
5722 KCF_PROV_REFRELE(pd);
5724 break;
5726 case DPROV_REQ_SIGN:
5727 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5728 /* Emulate using update and final */
5729 error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
5730 taskq_req->dr_mac_req.dr_data, NULL);
5731 if (error == CRYPTO_SUCCESS) {
5732 error = crypto_mac_final(DPROV_CTX_SINGLE(ctx),
5733 taskq_req->dr_mac_req.dr_mac, NULL);
5735 } else {
5736 error = crypto_sign_single(DPROV_CTX_SINGLE(ctx),
5737 taskq_req->dr_sign_req.sr_data,
5738 taskq_req->dr_sign_req.sr_signature, NULL);
5741 if (error != CRYPTO_BUFFER_TOO_SMALL) {
5742 DPROV_CTX_SINGLE(ctx) = NULL;
5743 (void) dprov_free_context(ctx);
5745 break;
5747 case DPROV_REQ_SIGN_UPDATE:
5748 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5749 error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
5750 taskq_req->dr_mac_req.dr_data, NULL);
5751 } else {
5752 error = crypto_sign_update(DPROV_CTX_SINGLE(ctx),
5753 taskq_req->dr_sign_req.sr_data, NULL);
5755 break;
5757 case DPROV_REQ_SIGN_FINAL:
5758 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5759 error = crypto_mac_final(DPROV_CTX_SINGLE(ctx),
5760 taskq_req->dr_mac_req.dr_mac, NULL);
5761 } else {
5762 error = crypto_sign_final(DPROV_CTX_SINGLE(ctx),
5763 taskq_req->dr_sign_req.sr_signature, NULL);
5766 if (error != CRYPTO_BUFFER_TOO_SMALL) {
5767 DPROV_CTX_SINGLE(ctx) = NULL;
5768 (void) dprov_free_context(ctx);
5770 break;
5772 case DPROV_REQ_SIGN_ATOMIC:
5773 case DPROV_REQ_SIGN_RECOVER_ATOMIC:
5774 /* structure assignment */
5775 mech = *taskq_req->dr_sign_req.sr_mechanism;
5777 mutex_enter(&softc->ds_lock);
5778 /* get key value for secret key algorithms */
5779 if (is_publickey_mech(mech.cm_type)) {
5780 if ((error = dprov_key_attr_asymmetric(softc,
5781 taskq_req->dr_sign_req.sr_session_id,
5782 taskq_req->dr_type,
5783 taskq_req->dr_sign_req.sr_key, &key))
5784 != CRYPTO_SUCCESS) {
5785 mutex_exit(&softc->ds_lock);
5786 break;
5788 keyp = &key;
5789 } else {
5790 if ((error = dprov_key_value_secret(softc,
5791 taskq_req->dr_sign_req.sr_session_id,
5792 taskq_req->dr_type,
5793 taskq_req->dr_sign_req.sr_key, &key))
5794 != CRYPTO_SUCCESS) {
5795 mutex_exit(&softc->ds_lock);
5796 break;
5798 keyp = &key;
5800 mutex_exit(&softc->ds_lock);
5802 /* get the software provider for this mechanism */
5803 if ((error = dprov_get_sw_prov(
5804 taskq_req->dr_sign_req.sr_mechanism, &pd,
5805 &mech.cm_type)) != CRYPTO_SUCCESS)
5806 break;
5808 /* Use a session id of zero since we use a software provider */
5809 if (taskq_req->dr_type == DPROV_REQ_SIGN_ATOMIC)
5810 error = crypto_sign_prov(pd, 0, &mech, keyp,
5811 taskq_req->dr_sign_req.sr_data,
5812 NULL, taskq_req->dr_sign_req.sr_signature, NULL);
5813 else
5814 error = crypto_sign_recover_prov(pd, 0, &mech, keyp,
5815 taskq_req->dr_sign_req.sr_data,
5816 NULL, taskq_req->dr_sign_req.sr_signature, NULL);
5818 /* release provider reference */
5819 KCF_PROV_REFRELE(pd);
5820 break;
5822 case DPROV_REQ_SIGN_RECOVER:
5823 error = crypto_sign_recover_single(DPROV_CTX_SINGLE(ctx),
5824 taskq_req->dr_sign_req.sr_data,
5825 taskq_req->dr_sign_req.sr_signature, NULL);
5827 if (error != CRYPTO_BUFFER_TOO_SMALL) {
5828 DPROV_CTX_SINGLE(ctx) = NULL;
5829 (void) dprov_free_context(ctx);
5831 break;
5834 dprov_op_done(taskq_req, error);
5835 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_task: end\n", instance));
5838 static int
5839 emulate_verify_with_mac(crypto_ctx_t *ctx, crypto_data_t *in_mac)
5841 int error;
5842 crypto_data_t tmpd;
5843 crypto_data_t *out_mac;
5844 char digest[SHA512_DIGEST_LENGTH];
5846 bzero(&tmpd, sizeof (crypto_data_t));
5847 tmpd.cd_format = CRYPTO_DATA_RAW;
5848 tmpd.cd_length = SHA512_DIGEST_LENGTH;
5849 tmpd.cd_raw.iov_base = digest;
5850 tmpd.cd_raw.iov_len = SHA512_DIGEST_LENGTH;
5851 out_mac = &tmpd;
5853 error = crypto_mac_final(DPROV_CTX_SINGLE(ctx), out_mac, NULL);
5854 if (in_mac->cd_length != out_mac->cd_length ||
5855 (bcmp(digest, (unsigned char *)in_mac->cd_raw.iov_base +
5856 in_mac->cd_offset, out_mac->cd_length) != 0)) {
5857 error = CRYPTO_INVALID_MAC;
5860 return (error);
5864 * taskq dispatcher function for verify operations.
5866 static void
5867 dprov_verify_task(dprov_req_t *taskq_req)
5869 kcf_provider_desc_t *pd;
5870 dprov_state_t *softc;
5871 /* LINTED E_FUNC_SET_NOT_USED */
5872 int instance;
5873 int error = CRYPTO_NOT_SUPPORTED;
5874 crypto_ctx_t *ctx = taskq_req->dr_verify_req.vr_ctx;
5875 crypto_key_t key, *keyp;
5876 crypto_mechanism_t mech;
5878 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
5879 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_task: started\n", instance));
5881 switch (taskq_req->dr_type) {
5883 case DPROV_REQ_VERIFY_INIT:
5884 case DPROV_REQ_VERIFY_RECOVER_INIT:
5885 /* allocate a dprov-private context */
5886 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
5887 CRYPTO_SUCCESS)
5888 break;
5890 /* structure assignment */
5891 mech = *taskq_req->dr_verify_req.vr_mechanism;
5892 if (dprov_valid_mac_mech(mech.cm_type)) {
5893 DPROV_CTX_P(ctx)->dc_svrfy_to_mac = B_TRUE;
5896 mutex_enter(&softc->ds_lock);
5897 /* get key value for secret key algorithms */
5898 if (is_publickey_mech(mech.cm_type)) {
5899 if ((error = dprov_key_attr_asymmetric(softc,
5900 ctx->cc_session, taskq_req->dr_type,
5901 taskq_req->dr_verify_req.vr_key, &key))
5902 != CRYPTO_SUCCESS) {
5903 mutex_exit(&softc->ds_lock);
5904 break;
5906 keyp = &key;
5907 } else {
5908 if ((error = dprov_key_value_secret(softc,
5909 ctx->cc_session, taskq_req->dr_type,
5910 taskq_req->dr_verify_req.vr_key, &key))
5911 != CRYPTO_SUCCESS) {
5912 mutex_exit(&softc->ds_lock);
5913 break;
5915 keyp = &key;
5917 mutex_exit(&softc->ds_lock);
5919 /* get the software provider for this mechanism */
5920 if ((error = dprov_get_sw_prov(
5921 taskq_req->dr_verify_req.vr_mechanism, &pd,
5922 &mech.cm_type)) != CRYPTO_SUCCESS)
5923 break;
5926 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5927 error = crypto_mac_init_prov(pd, 0, &mech, keyp, NULL,
5928 &DPROV_CTX_SINGLE(ctx), NULL);
5930 /* release provider reference */
5931 KCF_PROV_REFRELE(pd);
5932 break;
5935 /* Use a session id of zero since we use a software provider */
5936 if (taskq_req->dr_type == DPROV_REQ_VERIFY_INIT)
5937 error = crypto_verify_init_prov(pd, 0, &mech, keyp,
5938 NULL, &DPROV_CTX_SINGLE(ctx), NULL);
5939 else
5940 error = crypto_verify_recover_init_prov(pd, 0, &mech,
5941 keyp, NULL, &DPROV_CTX_SINGLE(ctx), NULL);
5943 /* release provider reference */
5944 KCF_PROV_REFRELE(pd);
5946 break;
5948 case DPROV_REQ_VERIFY:
5949 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5950 /* Emulate using update and final */
5951 error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
5952 taskq_req->dr_mac_req.dr_data, NULL);
5953 if (error == CRYPTO_SUCCESS) {
5954 error = emulate_verify_with_mac(ctx,
5955 taskq_req->dr_mac_req.dr_mac);
5957 } else {
5958 error = crypto_verify_single(DPROV_CTX_SINGLE(ctx),
5959 taskq_req->dr_verify_req.vr_data,
5960 taskq_req->dr_verify_req.vr_signature, NULL);
5963 ASSERT(error != CRYPTO_BUFFER_TOO_SMALL);
5964 DPROV_CTX_SINGLE(ctx) = NULL;
5965 (void) dprov_free_context(ctx);
5966 break;
5968 case DPROV_REQ_VERIFY_UPDATE:
5969 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5970 error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
5971 taskq_req->dr_mac_req.dr_data, NULL);
5972 } else {
5973 error = crypto_verify_update(DPROV_CTX_SINGLE(ctx),
5974 taskq_req->dr_verify_req.vr_data, NULL);
5976 break;
5978 case DPROV_REQ_VERIFY_FINAL:
5979 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5980 error = emulate_verify_with_mac(ctx,
5981 taskq_req->dr_mac_req.dr_mac);
5982 } else {
5983 error = crypto_verify_final(DPROV_CTX_SINGLE(ctx),
5984 taskq_req->dr_verify_req.vr_signature, NULL);
5987 ASSERT(error != CRYPTO_BUFFER_TOO_SMALL);
5988 DPROV_CTX_SINGLE(ctx) = NULL;
5989 (void) dprov_free_context(ctx);
5990 break;
5992 case DPROV_REQ_VERIFY_ATOMIC:
5993 case DPROV_REQ_VERIFY_RECOVER_ATOMIC:
5994 /* structure assignment */
5995 mech = *taskq_req->dr_verify_req.vr_mechanism;
5997 mutex_enter(&softc->ds_lock);
5998 /* get key value for secret key algorithms */
5999 if (is_publickey_mech(mech.cm_type)) {
6000 if ((error = dprov_key_attr_asymmetric(softc,
6001 taskq_req->dr_verify_req.vr_session_id,
6002 taskq_req->dr_type,
6003 taskq_req->dr_verify_req.vr_key, &key))
6004 != CRYPTO_SUCCESS) {
6005 mutex_exit(&softc->ds_lock);
6006 break;
6008 keyp = &key;
6009 } else {
6010 if ((error = dprov_key_value_secret(softc,
6011 taskq_req->dr_verify_req.vr_session_id,
6012 taskq_req->dr_type,
6013 taskq_req->dr_verify_req.vr_key, &key))
6014 != CRYPTO_SUCCESS) {
6015 mutex_exit(&softc->ds_lock);
6016 break;
6018 keyp = &key;
6020 mutex_exit(&softc->ds_lock);
6022 /* get the software provider for this mechanism */
6023 if ((error = dprov_get_sw_prov(
6024 taskq_req->dr_verify_req.vr_mechanism, &pd,
6025 &mech.cm_type)) != CRYPTO_SUCCESS)
6026 break;
6028 /* Use a session id of zero since we use a software provider */
6029 if (taskq_req->dr_type == DPROV_REQ_VERIFY_ATOMIC)
6030 error = crypto_verify_prov(pd, 0, &mech, keyp,
6031 taskq_req->dr_verify_req.vr_data,
6032 NULL, taskq_req->dr_verify_req.vr_signature, NULL);
6033 else
6035 * crypto_verify_recover_prov() has different argument
6036 * order than crypto_verify_prov().
6038 error = crypto_verify_recover_prov(pd, 0, &mech, keyp,
6039 taskq_req->dr_verify_req.vr_signature,
6040 NULL, taskq_req->dr_verify_req.vr_data, NULL);
6042 /* release provider reference */
6043 KCF_PROV_REFRELE(pd);
6044 break;
6046 case DPROV_REQ_VERIFY_RECOVER:
6048 * crypto_verify_recover_single() has different argument
6049 * order than crypto_verify_single().
6051 error = crypto_verify_recover_single(DPROV_CTX_SINGLE(ctx),
6052 taskq_req->dr_verify_req.vr_signature,
6053 taskq_req->dr_verify_req.vr_data, NULL);
6055 if (error != CRYPTO_BUFFER_TOO_SMALL) {
6056 DPROV_CTX_SINGLE(ctx) = NULL;
6057 (void) dprov_free_context(ctx);
6059 break;
6062 dprov_op_done(taskq_req, error);
6063 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_task: end\n", instance));
6067 * taskq dispatcher function for dual operations.
6069 static void
6070 dprov_dual_task(dprov_req_t *taskq_req)
6072 dprov_state_t *softc;
6073 /* LINTED E_FUNC_SET_NOT_USED */
6074 int instance;
6075 int error = CRYPTO_NOT_SUPPORTED;
6076 crypto_ctx_t *signverify_ctx = taskq_req->dr_dual_req.dr_signverify_ctx;
6077 crypto_ctx_t *cipher_ctx = taskq_req->dr_dual_req.dr_cipher_ctx;
6079 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
6080 DPROV_DEBUG(D_DUAL, ("(%d) dprov_dual_task: started\n", instance));
6082 switch (taskq_req->dr_type) {
6084 case DPROV_REQ_DIGEST_ENCRYPT_UPDATE:
6085 error = crypto_digest_encrypt_update(
6086 DPROV_CTX_SINGLE(signverify_ctx),
6087 DPROV_CTX_SINGLE(cipher_ctx),
6088 taskq_req->dr_dual_req.dr_plaintext,
6089 taskq_req->dr_dual_req.dr_ciphertext, NULL);
6090 break;
6092 case DPROV_REQ_DECRYPT_DIGEST_UPDATE:
6093 error = crypto_decrypt_digest_update(
6094 DPROV_CTX_SINGLE(cipher_ctx),
6095 DPROV_CTX_SINGLE(signverify_ctx),
6096 taskq_req->dr_dual_req.dr_ciphertext,
6097 taskq_req->dr_dual_req.dr_plaintext, NULL);
6098 break;
6100 case DPROV_REQ_SIGN_ENCRYPT_UPDATE:
6101 error = crypto_sign_encrypt_update(
6102 DPROV_CTX_SINGLE(signverify_ctx),
6103 DPROV_CTX_SINGLE(cipher_ctx),
6104 taskq_req->dr_dual_req.dr_plaintext,
6105 taskq_req->dr_dual_req.dr_ciphertext, NULL);
6106 break;
6108 case DPROV_REQ_DECRYPT_VERIFY_UPDATE:
6109 error = crypto_decrypt_verify_update(
6110 DPROV_CTX_SINGLE(cipher_ctx),
6111 DPROV_CTX_SINGLE(signverify_ctx),
6112 taskq_req->dr_dual_req.dr_ciphertext,
6113 taskq_req->dr_dual_req.dr_plaintext, NULL);
6114 break;
6117 dprov_op_done(taskq_req, error);
6118 DPROV_DEBUG(D_DUAL, ("(%d) dprov_dual_task: end\n", instance));
6122 * taskq dispatcher function for cipher operations.
6124 static void
6125 dprov_cipher_task(dprov_req_t *taskq_req)
6127 kcf_provider_desc_t *pd;
6128 dprov_state_t *softc;
6129 /* LINTED E_FUNC_SET_NOT_USED */
6130 int instance;
6131 int error = CRYPTO_NOT_SUPPORTED;
6132 crypto_ctx_t *ctx = taskq_req->dr_cipher_req.dr_ctx;
6133 crypto_key_t key, *keyp;
6134 crypto_mechanism_t mech;
6136 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
6137 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_cipher_task: started\n", instance));
6139 switch (taskq_req->dr_type) {
6141 case DPROV_REQ_ENCRYPT_INIT:
6142 case DPROV_REQ_DECRYPT_INIT:
6143 /* allocate a dprov-private context */
6144 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
6145 CRYPTO_SUCCESS)
6146 break;
6148 /* structure assignment */
6149 mech = *taskq_req->dr_cipher_req.dr_mechanism;
6151 mutex_enter(&softc->ds_lock);
6152 /* get key value for secret key algorithms */
6153 if (is_publickey_mech(mech.cm_type)) {
6154 if ((error = dprov_key_attr_asymmetric(softc,
6155 ctx->cc_session, taskq_req->dr_type,
6156 taskq_req->dr_cipher_req.dr_key, &key))
6157 != CRYPTO_SUCCESS) {
6158 mutex_exit(&softc->ds_lock);
6159 break;
6161 keyp = &key;
6162 } else {
6163 if ((error = dprov_key_value_secret(softc,
6164 ctx->cc_session, taskq_req->dr_type,
6165 taskq_req->dr_cipher_req.dr_key, &key))
6166 != CRYPTO_SUCCESS) {
6167 mutex_exit(&softc->ds_lock);
6168 break;
6170 keyp = &key;
6172 mutex_exit(&softc->ds_lock);
6174 /* get the software provider for this mechanism */
6175 if ((error = dprov_get_sw_prov(
6176 taskq_req->dr_cipher_req.dr_mechanism, &pd,
6177 &mech.cm_type)) != CRYPTO_SUCCESS)
6178 break;
6180 /* Use a session id of zero since we use a software provider */
6181 if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_INIT)
6182 error = crypto_encrypt_init_prov(pd, 0, &mech, keyp,
6183 NULL, &DPROV_CTX_SINGLE(ctx), NULL);
6184 else
6185 error = crypto_decrypt_init_prov(pd, 0, &mech, keyp,
6186 NULL, &DPROV_CTX_SINGLE(ctx), NULL);
6188 if (ctx->cc_flags & CRYPTO_INIT_OPSTATE) {
6189 crypto_ctx_t *lctx =
6190 (crypto_ctx_t *)(DPROV_CTX_SINGLE(ctx));
6192 ctx->cc_opstate = lctx->cc_provider_private;
6193 ctx->cc_flags |= CRYPTO_USE_OPSTATE;
6196 /* release provider reference */
6197 KCF_PROV_REFRELE(pd);
6198 break;
6200 case DPROV_REQ_ENCRYPT:
6201 error = crypto_encrypt_single(DPROV_CTX_SINGLE(ctx),
6202 taskq_req->dr_cipher_req.dr_plaintext,
6203 taskq_req->dr_cipher_req.dr_ciphertext, NULL);
6205 if (error != CRYPTO_BUFFER_TOO_SMALL) {
6206 DPROV_CTX_SINGLE(ctx) = NULL;
6207 (void) dprov_free_context(ctx);
6209 break;
6211 case DPROV_REQ_DECRYPT:
6212 error = crypto_decrypt_single(DPROV_CTX_SINGLE(ctx),
6213 taskq_req->dr_cipher_req.dr_ciphertext,
6214 taskq_req->dr_cipher_req.dr_plaintext, NULL);
6216 if (error != CRYPTO_BUFFER_TOO_SMALL) {
6217 DPROV_CTX_SINGLE(ctx) = NULL;
6218 (void) dprov_free_context(ctx);
6220 break;
6222 case DPROV_REQ_ENCRYPT_UPDATE:
6223 ASSERT(!(ctx->cc_flags & CRYPTO_INIT_OPSTATE) ||
6224 (ctx->cc_flags & CRYPTO_USE_OPSTATE));
6225 error = crypto_encrypt_update(DPROV_CTX_SINGLE(ctx),
6226 taskq_req->dr_cipher_req.dr_plaintext,
6227 taskq_req->dr_cipher_req.dr_ciphertext, NULL);
6228 break;
6230 case DPROV_REQ_DECRYPT_UPDATE:
6231 ASSERT(!(ctx->cc_flags & CRYPTO_INIT_OPSTATE) ||
6232 (ctx->cc_flags & CRYPTO_USE_OPSTATE));
6233 error = crypto_decrypt_update(DPROV_CTX_SINGLE(ctx),
6234 taskq_req->dr_cipher_req.dr_ciphertext,
6235 taskq_req->dr_cipher_req.dr_plaintext, NULL);
6236 break;
6238 case DPROV_REQ_ENCRYPT_FINAL:
6239 error = crypto_encrypt_final(DPROV_CTX_SINGLE(ctx),
6240 taskq_req->dr_cipher_req.dr_ciphertext, NULL);
6241 if (error != CRYPTO_BUFFER_TOO_SMALL) {
6242 DPROV_CTX_SINGLE(ctx) = NULL;
6243 (void) dprov_free_context(ctx);
6245 break;
6247 case DPROV_REQ_DECRYPT_FINAL:
6248 error = crypto_decrypt_final(DPROV_CTX_SINGLE(ctx),
6249 taskq_req->dr_cipher_req.dr_plaintext, NULL);
6250 if (error != CRYPTO_BUFFER_TOO_SMALL) {
6251 DPROV_CTX_SINGLE(ctx) = NULL;
6252 (void) dprov_free_context(ctx);
6254 break;
6256 case DPROV_REQ_ENCRYPT_ATOMIC:
6257 case DPROV_REQ_DECRYPT_ATOMIC:
6258 /* structure assignment */
6259 mech = *taskq_req->dr_cipher_req.dr_mechanism;
6261 mutex_enter(&softc->ds_lock);
6262 /* get key value for secret key algorithms */
6263 if (is_publickey_mech(mech.cm_type)) {
6264 if ((error = dprov_key_attr_asymmetric(softc,
6265 taskq_req->dr_cipher_req.dr_session_id,
6266 taskq_req->dr_type,
6267 taskq_req->dr_cipher_req.dr_key,
6268 &key)) != CRYPTO_SUCCESS) {
6269 mutex_exit(&softc->ds_lock);
6270 break;
6272 keyp = &key;
6273 } else {
6274 if ((error = dprov_key_value_secret(softc,
6275 taskq_req->dr_cipher_req.dr_session_id,
6276 taskq_req->dr_type, taskq_req->dr_cipher_req.dr_key,
6277 &key))
6278 != CRYPTO_SUCCESS) {
6279 mutex_exit(&softc->ds_lock);
6280 break;
6282 keyp = &key;
6284 mutex_exit(&softc->ds_lock);
6286 /* get the software provider for this mechanism */
6287 if ((error = dprov_get_sw_prov(
6288 taskq_req->dr_cipher_req.dr_mechanism, &pd,
6289 &mech.cm_type)) != CRYPTO_SUCCESS)
6290 break;
6292 /* use a session id of zero since we use a software provider */
6293 if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_ATOMIC)
6294 error = crypto_encrypt_prov(pd, 0, &mech,
6295 taskq_req->dr_cipher_req.dr_plaintext,
6296 keyp, NULL,
6297 taskq_req->dr_cipher_req.dr_ciphertext, NULL);
6298 else
6299 error = crypto_decrypt_prov(pd, 0, &mech,
6300 taskq_req->dr_cipher_req.dr_ciphertext,
6301 keyp, NULL,
6302 taskq_req->dr_cipher_req.dr_plaintext, NULL);
6304 /* release provider reference */
6305 KCF_PROV_REFRELE(pd);
6307 break;
6310 dprov_op_done(taskq_req, error);
6311 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: end\n", instance));
6315 * Helper function for the cipher/mac dual operation taskq dispatch
6316 * function. Initialize the cipher and mac key values and find the
6317 * providers that can process the request for the specified mechanisms.
6319 static int
6320 dprov_cipher_mac_key_pd(dprov_state_t *softc, crypto_session_id_t sid,
6321 dprov_req_t *taskq_req, crypto_key_t *cipher_key, crypto_key_t *mac_key,
6322 kcf_provider_desc_t **cipher_pd, kcf_provider_desc_t **mac_pd,
6323 crypto_mech_type_t *cipher_mech_type, crypto_mech_type_t *mac_mech_type)
6325 int error;
6327 /* get the cipher key value */
6328 mutex_enter(&softc->ds_lock);
6329 error = dprov_key_value_secret(softc, sid, DPROV_REQ_ENCRYPT_ATOMIC,
6330 taskq_req->dr_cipher_mac_req.mr_cipher_key, cipher_key);
6331 if (error != CRYPTO_SUCCESS) {
6332 mutex_exit(&softc->ds_lock);
6333 return (error);
6336 /* get the mac key value */
6337 error = dprov_key_value_secret(softc, sid, DPROV_REQ_MAC_ATOMIC,
6338 taskq_req->dr_cipher_mac_req.mr_mac_key, mac_key);
6339 mutex_exit(&softc->ds_lock);
6340 if (error != CRYPTO_SUCCESS)
6341 return (error);
6343 /* get the SW provider to perform the cipher operation */
6344 if ((error = dprov_get_sw_prov(
6345 taskq_req->dr_cipher_mac_req.mr_cipher_mech, cipher_pd,
6346 cipher_mech_type)) != CRYPTO_SUCCESS)
6347 return (error);
6349 /* get the SW provider to perform the mac operation */
6350 error = dprov_get_sw_prov(taskq_req->dr_cipher_mac_req.mr_mac_mech,
6351 mac_pd, mac_mech_type);
6353 return (error);
6357 * taskq dispatcher function for cipher/mac dual operations.
6359 static void
6360 dprov_cipher_mac_task(dprov_req_t *taskq_req)
6362 dprov_state_t *softc;
6363 /* LINTED E_FUNC_SET_NOT_USED */
6364 int instance;
6365 int error = CRYPTO_NOT_SUPPORTED;
6366 crypto_ctx_t *ctx = taskq_req->dr_cipher_mac_req.mr_ctx;
6367 kcf_provider_desc_t *cipher_pd;
6368 kcf_provider_desc_t *mac_pd;
6369 crypto_key_t cipher_key;
6370 crypto_key_t mac_key;
6371 crypto_dual_data_t *dual_data =
6372 taskq_req->dr_cipher_mac_req.mr_dual_data;
6373 crypto_data_t cipher_data;
6374 crypto_data_t mac_data;
6375 crypto_mechanism_t cipher_mech, mac_mech;
6376 crypto_session_id_t session_id;
6378 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
6379 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_cipher_mac_task: started\n",
6380 instance));
6382 switch (taskq_req->dr_type) {
6383 case DPROV_REQ_ENCRYPT_MAC_INIT:
6384 case DPROV_REQ_MAC_DECRYPT_INIT:
6385 /* structure assignment */
6386 cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech;
6387 mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech;
6389 /* get the keys values and providers to use for operations */
6390 if ((error = dprov_cipher_mac_key_pd(softc, ctx->cc_session,
6391 taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd,
6392 &cipher_mech.cm_type, &mac_mech.cm_type)) != CRYPTO_SUCCESS)
6393 break;
6395 /* allocate a dprov-private context */
6396 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
6397 CRYPTO_SUCCESS)
6398 break;
6400 if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_MAC_INIT)
6401 /* do the encryption initialization */
6402 error = crypto_encrypt_init_prov(cipher_pd, 0,
6403 &cipher_mech, &cipher_key, NULL,
6404 &DPROV_CTX_DUAL_CIPHER(ctx), NULL);
6405 else
6406 /* do the decryption initialization */
6407 error = crypto_decrypt_init_prov(cipher_pd, 0,
6408 &cipher_mech, &cipher_key, NULL,
6409 &DPROV_CTX_DUAL_CIPHER(ctx), NULL);
6410 if (error != CRYPTO_SUCCESS)
6411 break;
6413 /* do the mac initialization */
6414 if ((error = crypto_mac_init_prov(mac_pd, 0,
6415 &mac_mech, &mac_key, NULL, &DPROV_CTX_DUAL_MAC(ctx),
6416 NULL)) != CRYPTO_SUCCESS)
6417 break;
6419 /* release references to providers */
6420 KCF_PROV_REFRELE(cipher_pd);
6421 KCF_PROV_REFRELE(mac_pd);
6423 break;
6425 case DPROV_REQ_ENCRYPT_MAC: {
6426 size_t encrypted;
6427 boolean_t inplace;
6429 crypto_data_t *plaintext_tmp, *ciphertext_tmp;
6431 cipher_data = *((crypto_data_t *)dual_data);
6433 /* do an encrypt update */
6434 inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL);
6435 if (inplace) {
6436 plaintext_tmp = &cipher_data;
6437 ciphertext_tmp = NULL;
6438 } else {
6439 plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data;
6440 ciphertext_tmp = &cipher_data;
6442 if ((error = crypto_encrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
6443 plaintext_tmp, ciphertext_tmp, NULL)) != CRYPTO_SUCCESS)
6444 break;
6446 /* do an encrypt final */
6447 encrypted = cipher_data.cd_length;
6449 cipher_data.cd_offset += encrypted;
6450 cipher_data.cd_length = dual_data->dd_len1 - encrypted;
6452 if ((error = crypto_encrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
6453 &cipher_data, NULL)) != CRYPTO_SUCCESS)
6454 break;
6457 * Do a mac update on the resulting ciphertext, but with no
6458 * more bytes than specified by dual_data, and starting at
6459 * offset specified by dual_data. For in-place operations,
6460 * we use the length specified by the dual_data.
6462 mac_data = cipher_data;
6463 mac_data.cd_offset = dual_data->dd_offset2;
6464 mac_data.cd_length = dual_data->dd_len2;
6465 if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
6466 &mac_data, NULL)) != CRYPTO_SUCCESS)
6467 break;
6469 /* do a mac final */
6470 error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
6471 taskq_req->dr_cipher_mac_req.mr_mac, NULL);
6473 /* Set the total size of the ciphertext, when successful */
6474 if (error == CRYPTO_SUCCESS)
6475 dual_data->dd_len1 = encrypted + cipher_data.cd_length;
6477 if (error != CRYPTO_BUFFER_TOO_SMALL) {
6478 DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
6479 DPROV_CTX_DUAL_MAC(ctx) = NULL;
6480 (void) dprov_free_context(ctx);
6482 break;
6485 case DPROV_REQ_ENCRYPT_MAC_UPDATE: {
6486 crypto_data_t *plaintext_tmp, *ciphertext_tmp;
6487 size_t encrypted;
6488 ssize_t maclen;
6489 boolean_t inplace;
6491 cipher_data = *((crypto_data_t *)dual_data);
6493 /* do an encrypt update */
6494 inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL);
6495 if (inplace) {
6496 plaintext_tmp = &cipher_data;
6497 ciphertext_tmp = NULL;
6498 } else {
6499 plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data;
6500 ciphertext_tmp = &cipher_data;
6502 if ((error = crypto_encrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
6503 plaintext_tmp, ciphertext_tmp, NULL)) != CRYPTO_SUCCESS)
6504 break;
6506 encrypted = cipher_data.cd_length;
6509 * Do a mac update on the resulting ciphertext, but with no
6510 * more bytes than specified by dual_data, and starting at
6511 * offset specified by dual_data. For in-place operations,
6512 * we use the length specified by the dual_data.
6513 * There is an edge case, when the encryption step produced
6514 * zero bytes in the ciphertext. Only the portion between
6515 * offset2 and offset1 is then thrown in the MAC mix.
6517 maclen = dual_data->dd_offset1 - dual_data->dd_offset2 +
6518 encrypted;
6519 if (maclen > 0) {
6520 mac_data = cipher_data;
6521 mac_data.cd_offset = dual_data->dd_offset2;
6522 mac_data.cd_length = min(dual_data->dd_len2, maclen);
6523 if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
6524 &mac_data, NULL)) != CRYPTO_SUCCESS)
6525 break;
6527 /* Set the total size of the ciphertext, when successful */
6528 if (error == CRYPTO_SUCCESS)
6529 dual_data->dd_len1 = encrypted;
6531 break;
6534 case DPROV_REQ_ENCRYPT_MAC_FINAL:
6535 cipher_data = *((crypto_data_t *)dual_data);
6537 /* do an encrypt final */
6538 if ((error = crypto_encrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
6539 taskq_req->dr_cipher_mac_req.mr_data == NULL ?
6540 &cipher_data : taskq_req->dr_cipher_mac_req.mr_data,
6541 NULL)) != CRYPTO_SUCCESS)
6542 break;
6545 * If ciphertext length is different from zero, do a mac
6546 * update on it. This does not apply to in-place since we
6547 * do not allow partial updates, hence no final residual.
6549 if (taskq_req->dr_cipher_mac_req.mr_data != NULL &&
6550 taskq_req->dr_cipher_mac_req.mr_data->cd_length > 0)
6551 if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
6552 taskq_req->dr_cipher_mac_req.mr_data, NULL)) !=
6553 CRYPTO_SUCCESS)
6554 break;
6556 /* do a mac final */
6557 error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
6558 taskq_req->dr_cipher_mac_req.mr_mac, NULL);
6560 if (error != CRYPTO_BUFFER_TOO_SMALL) {
6561 DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
6562 DPROV_CTX_DUAL_MAC(ctx) = NULL;
6563 (void) dprov_free_context(ctx);
6565 break;
6567 case DPROV_REQ_ENCRYPT_MAC_ATOMIC: {
6568 crypto_data_t *plaintext_tmp, *ciphertext_tmp;
6569 boolean_t inplace;
6571 cipher_data = *((crypto_data_t *)dual_data);
6573 /* do an encrypt atomic */
6574 inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL);
6575 if (inplace) {
6576 plaintext_tmp = &cipher_data;
6577 ciphertext_tmp = NULL;
6578 } else {
6579 plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data;
6580 ciphertext_tmp = &cipher_data;
6583 /* structure assignment */
6584 cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech;
6585 mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech;
6586 session_id = taskq_req->dr_cipher_mac_req.mr_session_id;
6588 /* get the keys values and providers to use for operations */
6589 if ((error = dprov_cipher_mac_key_pd(softc, session_id,
6590 taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd,
6591 &cipher_mech.cm_type, &mac_mech.cm_type)) !=
6592 CRYPTO_SUCCESS)
6593 break;
6595 /* do the atomic encrypt */
6596 if ((error = crypto_encrypt_prov(cipher_pd, 0,
6597 &cipher_mech, plaintext_tmp, &cipher_key, NULL,
6598 ciphertext_tmp, NULL)) != CRYPTO_SUCCESS)
6599 break;
6601 /* do the atomic mac */
6602 mac_data = cipher_data;
6603 mac_data.cd_length = dual_data->dd_len2;
6604 mac_data.cd_offset = dual_data->dd_offset2;
6605 error = crypto_mac_prov(mac_pd, 0, &mac_mech, &mac_data,
6606 &mac_key, NULL, taskq_req->dr_cipher_mac_req.mr_mac, NULL);
6608 dual_data->dd_len1 = cipher_data.cd_length;
6610 break;
6613 case DPROV_REQ_MAC_DECRYPT: {
6614 uint_t decrypted;
6615 crypto_data_t plaintext_tmp;
6617 cipher_data = *((crypto_data_t *)dual_data);
6619 /* do a mac update and final on the ciphertext */
6620 if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
6621 &mac_data, NULL)) != CRYPTO_SUCCESS)
6622 break;
6624 /* do a mac final */
6625 if ((error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
6626 taskq_req->dr_cipher_mac_req.mr_mac, NULL)) !=
6627 CRYPTO_SUCCESS)
6628 break;
6630 /* do an decrypt update */
6631 cipher_data = mac_data;
6632 cipher_data.cd_length = dual_data->dd_len2;
6633 cipher_data.cd_offset = dual_data->dd_offset2;
6634 if (taskq_req->dr_cipher_mac_req.mr_data == NULL)
6635 /* in-place */
6636 plaintext_tmp = cipher_data;
6637 else
6638 plaintext_tmp = *taskq_req->dr_cipher_mac_req.mr_data;
6640 if ((error = crypto_decrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
6641 &cipher_data, taskq_req->dr_cipher_mac_req.mr_data,
6642 NULL)) != CRYPTO_SUCCESS)
6643 break;
6645 /* do an decrypt final */
6646 if (taskq_req->dr_cipher_mac_req.mr_data == NULL)
6647 /* in-place, everything must have been decrypted */
6648 decrypted = cipher_data.cd_length;
6649 else
6650 decrypted =
6651 taskq_req->dr_cipher_mac_req.mr_data->cd_length;
6652 plaintext_tmp.cd_offset += decrypted;
6653 plaintext_tmp.cd_length -= decrypted;
6655 error = crypto_decrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
6656 &plaintext_tmp, NULL);
6657 if (taskq_req->dr_cipher_mac_req.mr_data != NULL)
6658 taskq_req->dr_cipher_mac_req.mr_data->cd_length +=
6659 plaintext_tmp.cd_length;
6661 if (error != CRYPTO_BUFFER_TOO_SMALL) {
6662 DPROV_CTX_DUAL_MAC(ctx) = NULL;
6663 DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
6664 (void) dprov_free_context(ctx);
6666 break;
6669 case DPROV_REQ_MAC_DECRYPT_UPDATE:
6670 cipher_data = *((crypto_data_t *)dual_data);
6672 /* do mac update */
6673 if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
6674 &cipher_data, NULL)) != CRYPTO_SUCCESS)
6675 break;
6677 /* do a decrypt update */
6678 cipher_data.cd_length = dual_data->dd_len2;
6679 cipher_data.cd_offset = dual_data->dd_offset2;
6680 error = crypto_decrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
6681 &cipher_data, taskq_req->dr_cipher_mac_req.mr_data, NULL);
6683 break;
6685 case DPROV_REQ_MAC_DECRYPT_FINAL:
6686 /* do a mac final */
6687 if ((error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
6688 taskq_req->dr_cipher_mac_req.mr_mac, NULL)) !=
6689 CRYPTO_SUCCESS)
6690 break;
6692 /* do a decrypt final */
6693 error = crypto_decrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
6694 taskq_req->dr_cipher_mac_req.mr_data, NULL);
6696 if (error != CRYPTO_BUFFER_TOO_SMALL) {
6697 DPROV_CTX_DUAL_MAC(ctx) = NULL;
6698 DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
6699 (void) dprov_free_context(ctx);
6701 break;
6703 case DPROV_REQ_MAC_DECRYPT_ATOMIC:
6704 case DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC:
6705 cipher_data = *((crypto_data_t *)dual_data);
6707 /* structure assignment */
6708 cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech;
6709 mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech;
6710 session_id = taskq_req->dr_cipher_mac_req.mr_session_id;
6712 /* get the keys values and providers to use for operations */
6713 if ((error = dprov_cipher_mac_key_pd(softc, session_id,
6714 taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd,
6715 &cipher_mech.cm_type, &mac_mech.cm_type)) != CRYPTO_SUCCESS)
6716 break;
6718 /* do the atomic mac */
6719 if (taskq_req->dr_type == DPROV_REQ_MAC_DECRYPT_ATOMIC)
6720 error = crypto_mac_prov(mac_pd, 0, &mac_mech,
6721 &cipher_data, &mac_key, NULL,
6722 taskq_req->dr_cipher_mac_req.mr_mac, NULL);
6723 else
6724 /* DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC */
6725 error = crypto_mac_verify_prov(mac_pd, 0, &mac_mech,
6726 &cipher_data, &mac_key, NULL,
6727 taskq_req->dr_cipher_mac_req.mr_mac, NULL);
6729 if (error != CRYPTO_SUCCESS)
6730 break;
6732 /* do the atomic decrypt */
6733 cipher_data.cd_length = dual_data->dd_len2;
6734 cipher_data.cd_offset = dual_data->dd_offset2;
6735 error = crypto_decrypt_prov(cipher_pd, 0, &cipher_mech,
6736 &cipher_data, &cipher_key, NULL,
6737 taskq_req->dr_cipher_mac_req.mr_data, NULL);
6739 break;
6742 dprov_op_done(taskq_req, error);
6743 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_cipher_mac_task: end\n",
6744 instance));
6748 * taskq dispatcher function for random number generation.
6750 static void
6751 dprov_random_task(dprov_req_t *taskq_req)
6753 dprov_state_t *softc;
6754 /* LINTED E_FUNC_SET_NOT_USED */
6755 int instance;
6756 int error = CRYPTO_SUCCESS;
6758 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
6759 DPROV_DEBUG(D_RANDOM, ("(%d) dprov_random_task: started\n", instance));
6761 mutex_enter(&softc->ds_lock);
6763 switch (taskq_req->dr_type) {
6765 DPROV_REQ_RANDOM_SEED:
6767 * Since we don't really generate random numbers
6768 * nothing to do.
6770 break;
6772 case DPROV_REQ_RANDOM_GENERATE: {
6773 uint_t i;
6774 uchar_t c = 0;
6777 * We don't generate random numbers so that the result
6778 * of the operation can be checked during testing.
6781 for (i = 0; i < taskq_req->dr_random_req.rr_len; i++)
6782 taskq_req->dr_random_req.rr_buf[i] = c++;
6784 break;
6788 mutex_exit(&softc->ds_lock);
6789 dprov_op_done(taskq_req, error);
6790 DPROV_DEBUG(D_RANDOM, ("(%d) dprov_random_task: end\n", instance));
6795 * taskq dispatcher function for session management operations.
6797 static void
6798 dprov_session_task(dprov_req_t *taskq_req)
6800 dprov_state_t *softc;
6801 /* LINTED E_FUNC_SET_NOT_USED */
6802 int instance;
6803 int error = CRYPTO_NOT_SUPPORTED;
6804 crypto_session_id_t session_id =
6805 taskq_req->dr_session_req.sr_session_id;
6806 dprov_session_t *session;
6807 dprov_object_t *object;
6808 int i;
6810 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
6811 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_task: started\n",
6812 instance));
6814 mutex_enter(&softc->ds_lock);
6816 if (taskq_req->dr_type != DPROV_REQ_SESSION_OPEN)
6817 /* validate session id and get ptr to session */
6818 if ((session = softc->ds_sessions[session_id]) == NULL) {
6819 mutex_exit(&softc->ds_lock);
6820 dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID);
6821 return;
6824 switch (taskq_req->dr_type) {
6826 case DPROV_REQ_SESSION_OPEN: {
6827 dprov_session_t **new_sessions;
6829 if (softc->ds_token_initialized == B_FALSE) {
6830 error = CRYPTO_OPERATION_NOT_INITIALIZED;
6831 break;
6834 /* search for available session slot */
6835 for (i = 0; i < softc->ds_sessions_slots; i++)
6836 if (softc->ds_sessions[i] == NULL)
6837 break;
6839 if (i == softc->ds_sessions_slots) {
6840 /* ran out of slots, grow sessions array */
6841 new_sessions = kmem_zalloc(
6842 2 * softc->ds_sessions_slots *
6843 sizeof (dprov_session_t *), KM_NOSLEEP);
6844 if (new_sessions == NULL) {
6845 error = CRYPTO_SESSION_COUNT;
6846 break;
6848 bcopy(softc->ds_sessions, new_sessions,
6849 softc->ds_sessions_slots *
6850 sizeof (dprov_session_t *));
6851 kmem_free(softc->ds_sessions, softc->ds_sessions_slots *
6852 sizeof (dprov_session_t *));
6853 softc->ds_sessions = new_sessions;
6854 softc->ds_sessions_slots *= 2;
6857 /* allocate and initialize new session */
6858 softc->ds_sessions[i] = kmem_zalloc(
6859 sizeof (dprov_session_t), KM_NOSLEEP);
6860 if (softc->ds_sessions[i] == NULL) {
6861 error = CRYPTO_HOST_MEMORY;
6862 break;
6864 softc->ds_sessions_count++;
6866 /* initialize session state */
6867 softc->ds_sessions[i]->ds_state = DPROV_SESSION_STATE_PUBLIC;
6869 /* return new session id to caller */
6870 *(taskq_req->dr_session_req.sr_session_id_ptr) = i;
6872 error = CRYPTO_SUCCESS;
6873 break;
6876 case DPROV_REQ_SESSION_CLOSE:
6877 softc->ds_sessions[session_id] = NULL;
6879 if (softc->ds_token_initialized == B_FALSE) {
6880 error = CRYPTO_OPERATION_NOT_INITIALIZED;
6881 break;
6884 dprov_release_session_objects(session);
6886 /* free session state and corresponding slot */
6887 kmem_free(session, sizeof (dprov_session_t));
6888 softc->ds_sessions_count--;
6890 error = CRYPTO_SUCCESS;
6891 break;
6893 case DPROV_REQ_SESSION_LOGIN: {
6894 char *pin = taskq_req->dr_session_req.sr_pin;
6895 size_t pin_len = taskq_req->dr_session_req.sr_pin_len;
6896 crypto_user_type_t user_type =
6897 taskq_req->dr_session_req.sr_user_type;
6899 /* check user type */
6900 if (user_type != CRYPTO_SO && user_type != CRYPTO_USER) {
6901 error = CRYPTO_USER_TYPE_INVALID;
6902 break;
6905 /* check pin length */
6906 if (pin_len > DPROV_MAX_PIN_LEN) {
6907 error = CRYPTO_PIN_LEN_RANGE;
6908 break;
6911 /* check pin */
6912 if (pin == NULL) {
6913 error = CRYPTO_PIN_INVALID;
6914 break;
6917 /* validate PIN state */
6918 if ((user_type == CRYPTO_SO) && !softc->ds_token_initialized ||
6919 (user_type == CRYPTO_USER) && !softc->ds_user_pin_set) {
6920 error = CRYPTO_USER_PIN_NOT_INITIALIZED;
6921 break;
6924 if ((user_type == CRYPTO_SO &&
6925 softc->ds_sessions[session_id]->ds_state ==
6926 DPROV_SESSION_STATE_SO) ||
6927 (user_type == CRYPTO_USER &&
6928 softc->ds_sessions[session_id]->ds_state ==
6929 DPROV_SESSION_STATE_USER)) {
6930 /* SO or user already logged in */
6931 error = CRYPTO_USER_ALREADY_LOGGED_IN;
6932 break;
6935 if (softc->ds_sessions[session_id]->ds_state !=
6936 DPROV_SESSION_STATE_PUBLIC) {
6937 /* another user already logged in */
6938 error = CRYPTO_USER_ANOTHER_ALREADY_LOGGED_IN;
6939 break;
6942 /* everything's fine, update session */
6943 softc->ds_sessions[session_id]->ds_state =
6944 user_type == CRYPTO_SO ?
6945 DPROV_SESSION_STATE_SO : DPROV_SESSION_STATE_USER;
6947 error = CRYPTO_SUCCESS;
6948 break;
6951 case DPROV_REQ_SESSION_LOGOUT:
6952 /* fail if not logged in */
6953 if (softc->ds_sessions[session_id]->ds_state ==
6954 DPROV_SESSION_STATE_PUBLIC) {
6955 error = CRYPTO_USER_NOT_LOGGED_IN;
6956 break;
6960 * Destroy all private session objects.
6961 * Invalidate handles to all private objects.
6963 for (i = 0; i < DPROV_MAX_OBJECTS; i++) {
6964 object = softc->ds_sessions[session_id]->ds_objects[i];
6965 if (object != NULL && dprov_object_is_private(object)) {
6966 if (!dprov_object_is_token(object))
6967 /* It's a session object, free it */
6968 DPROV_OBJECT_REFRELE(object);
6969 softc->ds_sessions[session_id]->ds_objects[i] =
6970 NULL;
6974 /* update session state */
6975 softc->ds_sessions[session_id]->ds_state =
6976 DPROV_SESSION_STATE_PUBLIC;
6978 error = CRYPTO_SUCCESS;
6979 break;
6982 mutex_exit(&softc->ds_lock);
6983 dprov_op_done(taskq_req, error);
6984 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_task: end\n", instance));
6987 /* return true if attribute is defined to be a PKCS#11 long */
6988 static boolean_t
6989 fixed_size_attribute(crypto_attr_type_t type)
6991 return (type == DPROV_CKA_CLASS ||
6992 type == DPROV_CKA_CERTIFICATE_TYPE ||
6993 type == DPROV_CKA_KEY_TYPE ||
6994 type == DPROV_HW_FEATURE_TYPE);
6998 * Attributes defined to be a PKCS#11 long causes problems for dprov
6999 * because 32-bit applications set the size to 4 and 64-bit applications
7000 * set the size to 8. dprov always stores these fixed-size attributes
7001 * as uint32_t.
7003 static ssize_t
7004 attribute_size(crypto_attr_type_t type, ssize_t len)
7006 if (fixed_size_attribute(type))
7007 return (sizeof (uint32_t));
7009 return (len);
7013 * taskq dispatcher function for object management operations.
7015 static void
7016 dprov_object_task(dprov_req_t *taskq_req)
7018 dprov_state_t *softc;
7019 /* LINTED E_FUNC_SET_NOT_USED */
7020 int instance;
7021 int error = CRYPTO_NOT_SUPPORTED;
7022 crypto_object_id_t object_id = taskq_req->dr_object_req.or_object_id;
7023 crypto_session_id_t session_id = taskq_req->dr_object_req.or_session_id;
7024 crypto_object_attribute_t *template =
7025 taskq_req->dr_object_req.or_template;
7026 uint_t attr_count = taskq_req->dr_object_req.or_attribute_count;
7027 dprov_object_t *object;
7028 dprov_session_t *session;
7030 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
7031 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_task: started\n", instance));
7033 mutex_enter(&softc->ds_lock);
7035 /* validate session id and get ptr to session */
7036 if ((session = softc->ds_sessions[session_id]) == NULL) {
7037 mutex_exit(&softc->ds_lock);
7038 dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID);
7039 return;
7042 switch (taskq_req->dr_type) {
7044 case DPROV_REQ_OBJECT_CREATE:
7045 /* create the object from the specified template */
7046 if ((error = dprov_create_object_from_template(softc, session,
7047 template, attr_count,
7048 taskq_req->dr_object_req.or_object_id_ptr, B_TRUE,
7049 B_FALSE)) != CRYPTO_SUCCESS)
7050 break;
7052 break;
7054 case DPROV_REQ_OBJECT_COPY:
7055 /* check object id */
7056 if (object_id >= DPROV_MAX_OBJECTS ||
7057 (object = session->ds_objects[object_id]) == NULL) {
7058 error = CRYPTO_OBJECT_HANDLE_INVALID;
7059 break;
7063 * Create a new object from the object passed as
7064 * argument.
7066 if ((error = dprov_create_object_from_template(softc, session,
7067 object->do_attr, DPROV_MAX_ATTR,
7068 taskq_req->dr_object_req.or_object_id_ptr, B_TRUE,
7069 B_FALSE)) != CRYPTO_SUCCESS)
7070 break;
7073 * Add the attributes specified by the template to the
7074 * newly created object, replacing existing ones if needed.
7076 error = dprov_object_set_attr(session,
7077 *taskq_req->dr_object_req.or_object_id_ptr,
7078 taskq_req->dr_object_req.or_template,
7079 taskq_req->dr_object_req.or_attribute_count, B_TRUE);
7081 break;
7083 case DPROV_REQ_OBJECT_DESTROY:
7084 /* destroy the object */
7085 error = dprov_destroy_object(softc, session,
7086 taskq_req->dr_object_req.or_object_id);
7088 break;
7090 case DPROV_REQ_OBJECT_GET_SIZE:
7091 /* get ptr to object */
7092 if (object_id >= DPROV_MAX_OBJECTS ||
7093 session->ds_objects[object_id] == NULL) {
7094 error = CRYPTO_OBJECT_HANDLE_INVALID;
7095 break;
7099 * The PKCS11 specification does not specifies what
7100 * the object size really is, here we just return
7101 * the number of possible attributes of the object.
7103 *taskq_req->dr_object_req.or_object_size = DPROV_MAX_ATTR;
7105 error = CRYPTO_SUCCESS;
7106 break;
7108 case DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE: {
7109 crypto_attr_type_t type;
7110 size_t olen, tlen;
7111 offset_t offset;
7112 int tmpl_idx;
7113 int object_idx;
7114 ulong_t class = DPROV_CKO_DATA;
7115 boolean_t extractable = B_TRUE;
7117 error = CRYPTO_SUCCESS;
7119 /* get ptr to object */
7120 if (object_id >= DPROV_MAX_OBJECTS ||
7121 (object = session->ds_objects[object_id]) == NULL) {
7122 error = CRYPTO_OBJECT_HANDLE_INVALID;
7123 break;
7126 (void) dprov_get_object_attr_boolean(object,
7127 DPROV_CKA_EXTRACTABLE, &extractable);
7129 (void) dprov_get_object_attr_ulong(object,
7130 DPROV_CKA_CLASS, &class);
7132 /* return the specified attributes, when possible */
7133 for (tmpl_idx = 0; tmpl_idx < attr_count; tmpl_idx++) {
7135 * Attribute can't be revealed if the CKA_EXTRACTABLE
7136 * attribute is set to false.
7138 type = template[tmpl_idx].oa_type;
7139 if (!extractable && class == DPROV_CKO_SECRET_KEY) {
7140 if (type == DPROV_CKA_VALUE) {
7141 template[tmpl_idx].oa_value_len = -1;
7142 error = CRYPTO_ATTRIBUTE_SENSITIVE;
7143 continue;
7146 if (!extractable && class == DPROV_CKO_PRIVATE_KEY) {
7147 if (type == DPROV_CKA_PRIVATE_EXPONENT) {
7148 template[tmpl_idx].oa_value_len = -1;
7149 error = CRYPTO_ATTRIBUTE_SENSITIVE;
7150 continue;
7154 object_idx = dprov_find_attr(object->do_attr,
7155 DPROV_MAX_ATTR, type);
7156 if (object_idx == -1) {
7157 /* attribute not found in object */
7158 template[tmpl_idx].oa_value_len = -1;
7159 error = CRYPTO_ATTRIBUTE_TYPE_INVALID;
7160 continue;
7163 tlen = template[tmpl_idx].oa_value_len;
7164 olen = object->do_attr[object_idx].oa_value_len;
7165 /* return attribute length */
7166 if (template[tmpl_idx].oa_value == NULL) {
7168 * The size of the attribute is set by the
7169 * library according to the data model of the
7170 * application, so don't overwrite it with
7171 * dprov's size.
7173 if (!fixed_size_attribute(type))
7174 template[tmpl_idx].oa_value_len = olen;
7175 continue;
7178 if (tlen < olen) {
7179 template[tmpl_idx].oa_value_len = -1;
7180 error = CRYPTO_BUFFER_TOO_SMALL;
7181 continue;
7184 /* copy attribute value */
7185 bzero(template[tmpl_idx].oa_value, tlen);
7187 offset = 0;
7188 #ifdef _BIG_ENDIAN
7189 if (fixed_size_attribute(type)) {
7190 offset = tlen - olen;
7192 #endif
7193 bcopy(object->do_attr[object_idx].oa_value,
7194 &template[tmpl_idx].oa_value[offset], olen);
7196 /* don't update length for fixed-size attributes */
7197 if (!fixed_size_attribute(type))
7198 template[tmpl_idx].oa_value_len = olen;
7201 break;
7204 case DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE:
7206 * Add the attributes specified by the template to the
7207 * newly created object, replacing existing ones if needed.
7209 error = dprov_object_set_attr(session,
7210 taskq_req->dr_object_req.or_object_id,
7211 taskq_req->dr_object_req.or_template,
7212 taskq_req->dr_object_req.or_attribute_count, B_TRUE);
7214 break;
7216 case DPROV_REQ_OBJECT_FIND_INIT: {
7217 dprov_find_ctx_t *find_ctx;
7218 int so_idx; /* session object index */
7219 int to_idx; /* token object index */
7221 error = CRYPTO_SUCCESS;
7222 /* allocate find context */
7223 find_ctx = kmem_zalloc(sizeof (dprov_find_ctx_t), KM_SLEEP);
7224 *taskq_req->dr_object_req.or_find_pp = find_ctx;
7226 /* first go through the existing session objects */
7227 for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++) {
7228 if ((object = session->ds_objects[so_idx]) == NULL)
7229 continue;
7231 /* setting count to zero means find all objects */
7232 if (attr_count > 0) {
7233 if (!dprov_attributes_match(object, template,
7234 attr_count))
7235 continue;
7238 /* session object attributes matches template */
7239 find_ctx->fc_ids[find_ctx->fc_nids] = so_idx;
7240 find_ctx->fc_nids++;
7244 * Go through the token object. For each token object
7245 * that can be accessed:
7246 * If there was already an session object id assigned
7247 * to that token object, skip it, since it was returned
7248 * during the check of session objects, else,
7249 * assign a new object id for that token object and
7250 * add it to the array of matching objects.
7252 for (to_idx = 0; to_idx < DPROV_MAX_OBJECTS &&
7253 error == CRYPTO_SUCCESS; to_idx++) {
7254 if ((object = softc->ds_objects[to_idx]) == NULL)
7255 continue;
7257 /* setting count to zero means find all objects */
7258 if (attr_count > 0) {
7259 if (!dprov_attributes_match(object, template,
7260 attr_count))
7261 continue;
7264 /* if the the object has been destroyed, skip it */
7265 if (object->do_destroyed)
7266 continue;
7268 /* skip object if it cannot be accessed from session */
7269 if (dprov_object_is_private(object) &&
7270 session->ds_state != DPROV_SESSION_STATE_USER)
7271 continue;
7274 * Is there already a session object id for this
7275 * token object?
7277 for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++)
7278 if (session->ds_objects[so_idx] != NULL &&
7279 session->ds_objects[so_idx]->do_token_idx ==
7280 to_idx)
7281 break;
7282 if (so_idx < DPROV_MAX_OBJECTS)
7283 /* object found in session table, skip it */
7284 continue;
7286 /* find free session slot for this object */
7287 for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++)
7288 if (session->ds_objects[so_idx] == NULL)
7289 break;
7290 if (so_idx == DPROV_MAX_OBJECTS) {
7291 /* ran out of session objects slots */
7292 kmem_free(find_ctx, sizeof (dprov_find_ctx_t));
7293 error = CRYPTO_HOST_MEMORY;
7294 break;
7297 /* add object to session objects table */
7298 session->ds_objects[so_idx] = object;
7299 DPROV_OBJECT_REFHOLD(object);
7301 /* add object to list of objects to return */
7302 find_ctx->fc_ids[find_ctx->fc_nids] = so_idx;
7303 find_ctx->fc_nids++;
7306 break;
7309 case DPROV_REQ_OBJECT_FIND: {
7310 crypto_object_id_t *object_ids =
7311 taskq_req->dr_object_req.or_object_id_ptr;
7312 uint_t max_object_count =
7313 taskq_req->dr_object_req.or_max_object_count;
7314 dprov_find_ctx_t *find_ctx =
7315 taskq_req->dr_object_req.or_find_p;
7316 uint_t ret_oid_idx;
7318 /* return the desired number of object ids */
7319 for (ret_oid_idx = 0; ret_oid_idx < max_object_count &&
7320 find_ctx->fc_next < find_ctx->fc_nids; ret_oid_idx++)
7321 object_ids[ret_oid_idx] =
7322 find_ctx->fc_ids[find_ctx->fc_next++];
7324 *taskq_req->dr_object_req.or_object_count_ptr = ret_oid_idx;
7326 error = CRYPTO_SUCCESS;
7327 break;
7330 case DPROV_REQ_OBJECT_FIND_FINAL:
7331 kmem_free(taskq_req->dr_object_req.or_find_p,
7332 sizeof (dprov_find_ctx_t));
7334 error = CRYPTO_SUCCESS;
7335 break;
7338 mutex_exit(&softc->ds_lock);
7339 dprov_op_done(taskq_req, error);
7340 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_task: end\n", instance));
7344 * Copy attribute values into a template. RSA values are precomputed.
7346 static int
7347 nostore_copy_attribute(crypto_object_attribute_t *template, uint_t count,
7348 uint64_t attr_type)
7350 void *value, *dprov_attribute_value;
7351 size_t dprov_attribute_size;
7352 size_t value_len = 0;
7353 int error;
7355 switch (attr_type) {
7356 case DPROV_CKA_VALUE:
7357 dprov_attribute_size = sizeof (dh_value);
7358 dprov_attribute_value = dh_value;
7359 break;
7361 case DPROV_CKA_MODULUS:
7362 dprov_attribute_size = sizeof (modulus);
7363 dprov_attribute_value = modulus;
7364 break;
7366 case DPROV_CKA_PUBLIC_EXPONENT:
7367 dprov_attribute_size = sizeof (public_exponent);
7368 dprov_attribute_value = public_exponent;
7369 break;
7371 case DPROV_CKA_PRIVATE_EXPONENT:
7372 dprov_attribute_size = sizeof (private_exponent);
7373 dprov_attribute_value = private_exponent;
7374 break;
7376 default:
7377 return (CRYPTO_ATTRIBUTE_TYPE_INVALID);
7380 error = dprov_get_template_attr_array(template, count, attr_type,
7381 &value, &value_len);
7382 if (error != CRYPTO_SUCCESS)
7383 return (error);
7385 if (value_len < dprov_attribute_size)
7386 return (CRYPTO_BUFFER_TOO_SMALL);
7389 * The updated template will be returned to libpkcs11.
7391 bcopy(dprov_attribute_value, value, dprov_attribute_size);
7393 return (CRYPTO_SUCCESS);
7396 static void
7397 fill_dh(void *value, size_t len)
7399 int i = 0;
7400 char *p = value;
7401 while (i < len) {
7402 p[i++] = 'D';
7403 if (i >= len)
7404 break;
7405 p[i++] = 'H';
7410 * taskq dispatcher function for key management operations.
7412 static void
7413 dprov_key_task(dprov_req_t *taskq_req)
7415 dprov_state_t *softc;
7416 /* LINTED E_FUNC_SET_NOT_USED */
7417 int instance;
7418 int error = CRYPTO_NOT_SUPPORTED;
7419 kcf_provider_desc_t *pd;
7420 crypto_session_id_t session_id = taskq_req->dr_key_req.kr_session_id;
7421 dprov_session_t *session;
7423 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
7424 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_task: started\n", instance));
7426 mutex_enter(&softc->ds_lock);
7428 /* validate session id and get ptr to session */
7429 if ((session = softc->ds_sessions[session_id]) == NULL) {
7430 mutex_exit(&softc->ds_lock);
7431 dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID);
7432 return;
7435 switch (taskq_req->dr_type) {
7436 case DPROV_REQ_KEY_GENERATE: {
7437 crypto_mechanism_t *mechp;
7438 crypto_object_id_t *object_id_ptr;
7439 crypto_object_attribute_t *template;
7440 crypto_object_attribute_t attribute;
7441 uint_t attribute_count;
7442 ulong_t key_type = ~0UL, class = ~0UL;
7443 ulong_t value_len;
7444 size_t key_len = 0;
7446 error = CRYPTO_SUCCESS;
7448 template = taskq_req->dr_key_req.kr_template;
7449 attribute_count = taskq_req->dr_key_req.kr_attribute_count;
7450 object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr;
7451 mechp = taskq_req->dr_key_req.kr_mechanism;
7453 /* optional */
7454 (void) dprov_get_template_attr_ulong(template, attribute_count,
7455 DPROV_CKA_CLASS, &class);
7457 /* optional */
7458 (void) dprov_get_template_attr_ulong(template, attribute_count,
7459 DPROV_CKA_KEY_TYPE, &key_type);
7461 if (class != ~0UL && class != DPROV_CKO_SECRET_KEY) {
7462 error = CRYPTO_TEMPLATE_INCONSISTENT;
7463 break;
7466 switch (mechp->cm_type) {
7467 case DES_KEY_GEN_MECH_INFO_TYPE:
7468 if (key_type != ~0UL && key_type != DPROV_CKK_DES) {
7469 error = CRYPTO_TEMPLATE_INCONSISTENT;
7470 break;
7472 key_len = DES_KEY_LEN;
7473 key_type = DPROV_CKK_DES;
7474 break;
7476 case DES3_KEY_GEN_MECH_INFO_TYPE:
7477 if (key_type != ~0UL && key_type != DPROV_CKK_DES3) {
7478 error = CRYPTO_TEMPLATE_INCONSISTENT;
7479 break;
7481 key_len = DES3_KEY_LEN;
7482 key_type = DPROV_CKK_DES3;
7483 break;
7485 case AES_KEY_GEN_MECH_INFO_TYPE:
7486 if (key_type != ~0UL && key_type != DPROV_CKK_AES) {
7487 error = CRYPTO_TEMPLATE_INCONSISTENT;
7488 break;
7490 if (dprov_get_template_attr_ulong(template,
7491 attribute_count, DPROV_CKA_VALUE_LEN,
7492 &value_len) != CRYPTO_SUCCESS) {
7493 error = CRYPTO_TEMPLATE_INCOMPLETE;
7494 break;
7496 if (value_len >= AES_MAX_KEY_LEN) {
7497 error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
7498 break;
7500 key_len = value_len;
7501 key_type = DPROV_CKK_AES;
7502 break;
7504 case BLOWFISH_KEY_GEN_MECH_INFO_TYPE:
7505 if (key_type != ~0UL &&
7506 key_type != DPROV_CKK_BLOWFISH) {
7507 error = CRYPTO_TEMPLATE_INCONSISTENT;
7508 break;
7510 if (dprov_get_template_attr_ulong(template,
7511 attribute_count, DPROV_CKA_VALUE_LEN,
7512 &value_len) != CRYPTO_SUCCESS) {
7513 error = CRYPTO_TEMPLATE_INCOMPLETE;
7514 break;
7516 if (value_len >= BLOWFISH_MAX_KEY_LEN) {
7517 error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
7518 break;
7520 key_len = value_len;
7521 key_type = DPROV_CKK_BLOWFISH;
7522 break;
7524 case RC4_KEY_GEN_MECH_INFO_TYPE:
7525 if (key_type != ~0UL && key_type != DPROV_CKK_RC4) {
7526 error = CRYPTO_TEMPLATE_INCONSISTENT;
7527 break;
7529 if (dprov_get_template_attr_ulong(template,
7530 attribute_count, DPROV_CKA_VALUE_LEN,
7531 &value_len) != CRYPTO_SUCCESS) {
7532 error = CRYPTO_TEMPLATE_INCOMPLETE;
7533 break;
7535 if (value_len >=
7536 CRYPTO_BITS2BYTES(ARCFOUR_MAX_KEY_BITS)) {
7537 error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
7538 break;
7540 key_len = value_len;
7541 key_type = DPROV_CKK_RC4;
7542 break;
7544 default:
7545 error = CRYPTO_MECHANISM_INVALID;
7548 if (error != CRYPTO_SUCCESS)
7549 break;
7551 error = dprov_create_object_from_template(softc, session,
7552 template, attribute_count, object_id_ptr, B_FALSE, B_TRUE);
7554 if (error != CRYPTO_SUCCESS)
7555 break;
7557 /* make sure class is set */
7558 attribute.oa_type = DPROV_CKA_CLASS;
7559 attribute.oa_value = (char *)&class;
7560 attribute.oa_value_len = sizeof (ulong_t);
7561 error = dprov_object_set_attr(session, *object_id_ptr,
7562 &attribute, 1, B_FALSE);
7564 if (error != CRYPTO_SUCCESS) {
7565 goto destroy_object;
7568 /* make sure key_type is set */
7569 attribute.oa_type = DPROV_CKA_KEY_TYPE;
7570 attribute.oa_value = (char *)&key_type;
7571 attribute.oa_value_len = sizeof (ulong_t);
7572 error = dprov_object_set_attr(session, *object_id_ptr,
7573 &attribute, 1, B_FALSE);
7575 if (error != CRYPTO_SUCCESS) {
7576 goto destroy_object;
7579 attribute.oa_type = DPROV_CKA_VALUE;
7580 attribute.oa_value = kmem_alloc(key_len, KM_SLEEP);
7581 attribute.oa_value_len = key_len;
7583 if (random_get_pseudo_bytes((uchar_t *)attribute.oa_value,
7584 key_len) != 0) {
7585 bzero(attribute.oa_value, key_len);
7586 kmem_free(attribute.oa_value, key_len);
7587 goto destroy_object;
7589 error = dprov_object_set_attr(session, *object_id_ptr,
7590 &attribute, 1, B_FALSE);
7592 bzero(attribute.oa_value, key_len);
7593 kmem_free(attribute.oa_value, key_len);
7595 if (error != CRYPTO_SUCCESS) {
7596 goto destroy_object;
7598 break;
7600 destroy_object:
7601 (void) dprov_destroy_object(softc, session, *object_id_ptr);
7602 break;
7605 case DPROV_REQ_KEY_GENERATE_PAIR: {
7606 crypto_mechanism_t *mechp;
7607 crypto_object_id_t *pub_object_id_ptr;
7608 crypto_object_id_t *pri_object_id_ptr;
7609 crypto_object_attribute_t *pub_template;
7610 crypto_object_attribute_t *pri_template;
7611 crypto_object_attribute_t attribute;
7612 uint_t pub_attribute_count;
7613 uint_t pri_attribute_count;
7614 ulong_t pub_key_type = ~0UL, pub_class = ~0UL;
7615 ulong_t pri_key_type = ~0UL, pri_class = ~0UL;
7617 pub_template = taskq_req->dr_key_req.kr_template;
7618 pub_attribute_count = taskq_req->dr_key_req.kr_attribute_count;
7619 pub_object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr;
7620 pri_template = taskq_req->dr_key_req.kr_private_key_template;
7621 pri_attribute_count =
7622 taskq_req->dr_key_req.kr_private_key_attribute_count;
7623 pri_object_id_ptr =
7624 taskq_req->dr_key_req.kr_private_key_object_id_ptr;
7625 mechp = taskq_req->dr_key_req.kr_mechanism;
7627 error = CRYPTO_SUCCESS;
7629 /* optional */
7630 (void) dprov_get_template_attr_ulong(pub_template,
7631 pub_attribute_count, DPROV_CKA_CLASS, &pub_class);
7633 /* optional */
7634 (void) dprov_get_template_attr_ulong(pri_template,
7635 pri_attribute_count, DPROV_CKA_CLASS, &pri_class);
7637 /* optional */
7638 (void) dprov_get_template_attr_ulong(pub_template,
7639 pub_attribute_count, DPROV_CKA_KEY_TYPE, &pub_key_type);
7641 /* optional */
7642 (void) dprov_get_template_attr_ulong(pri_template,
7643 pri_attribute_count, DPROV_CKA_KEY_TYPE, &pri_key_type);
7645 if (pub_class != ~0UL && pub_class != DPROV_CKO_PUBLIC_KEY) {
7646 error = CRYPTO_TEMPLATE_INCONSISTENT;
7647 break;
7650 if (pri_class != ~0UL && pri_class != DPROV_CKO_PRIVATE_KEY) {
7651 error = CRYPTO_TEMPLATE_INCONSISTENT;
7652 break;
7655 switch (mechp->cm_type) {
7656 case RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE:
7657 if (pub_key_type != ~0UL &&
7658 pub_key_type != DPROV_CKK_RSA) {
7659 error = CRYPTO_TEMPLATE_INCONSISTENT;
7660 break;
7662 pub_key_type = DPROV_CKK_RSA;
7664 if (pri_key_type != ~0UL &&
7665 pri_key_type != DPROV_CKK_RSA) {
7666 error = CRYPTO_TEMPLATE_INCONSISTENT;
7667 break;
7669 pri_key_type = DPROV_CKK_RSA;
7671 if (pub_class != ~0UL &&
7672 pub_class != DPROV_CKO_PUBLIC_KEY) {
7673 error = CRYPTO_TEMPLATE_INCONSISTENT;
7674 break;
7676 pub_class = DPROV_CKO_PUBLIC_KEY;
7678 if (pri_class != ~0UL &&
7679 pri_class != DPROV_CKO_PRIVATE_KEY) {
7680 error = CRYPTO_TEMPLATE_INCONSISTENT;
7681 break;
7683 pri_class = DPROV_CKO_PRIVATE_KEY;
7684 break;
7686 default:
7687 error = CRYPTO_MECHANISM_INVALID;
7690 if (error != CRYPTO_SUCCESS)
7691 break;
7693 error = dprov_create_object_from_template(softc, session,
7694 pub_template, pub_attribute_count, pub_object_id_ptr,
7695 B_FALSE, B_TRUE);
7697 if (error != CRYPTO_SUCCESS)
7698 break;
7700 /* make sure class is set */
7701 attribute.oa_type = DPROV_CKA_CLASS;
7702 attribute.oa_value = (char *)&pub_class;
7703 attribute.oa_value_len = sizeof (ulong_t);
7704 error = dprov_object_set_attr(session, *pub_object_id_ptr,
7705 &attribute, 1, B_FALSE);
7707 if (error != CRYPTO_SUCCESS) {
7708 goto destroy_public_object;
7711 /* make sure key_type is set */
7712 attribute.oa_type = DPROV_CKA_KEY_TYPE;
7713 attribute.oa_value = (char *)&pub_key_type;
7714 attribute.oa_value_len = sizeof (ulong_t);
7715 error = dprov_object_set_attr(session, *pub_object_id_ptr,
7716 &attribute, 1, B_FALSE);
7718 if (error != CRYPTO_SUCCESS) {
7719 goto destroy_public_object;
7722 attribute.oa_type = DPROV_CKA_MODULUS;
7723 attribute.oa_value = (char *)modulus;
7724 attribute.oa_value_len = sizeof (modulus);
7725 error = dprov_object_set_attr(session, *pub_object_id_ptr,
7726 &attribute, 1, B_FALSE);
7728 if (error != CRYPTO_SUCCESS) {
7729 goto destroy_public_object;
7732 attribute.oa_type = DPROV_CKA_PUBLIC_EXPONENT;
7733 attribute.oa_value = public_exponent;
7734 attribute.oa_value_len = sizeof (public_exponent);
7735 error = dprov_object_set_attr(session, *pub_object_id_ptr,
7736 &attribute, 1, B_FALSE);
7738 if (error != CRYPTO_SUCCESS) {
7739 goto destroy_public_object;
7742 error = dprov_create_object_from_template(softc, session,
7743 pri_template, pri_attribute_count, pri_object_id_ptr,
7744 B_FALSE, B_TRUE);
7746 if (error != CRYPTO_SUCCESS)
7747 break;
7749 /* make sure class is set */
7750 attribute.oa_type = DPROV_CKA_CLASS;
7751 attribute.oa_value = (char *)&pri_class;
7752 attribute.oa_value_len = sizeof (ulong_t);
7753 error = dprov_object_set_attr(session, *pri_object_id_ptr,
7754 &attribute, 1, B_FALSE);
7756 if (error != CRYPTO_SUCCESS) {
7757 goto destroy_private_object;
7760 /* make sure key_type is set */
7761 attribute.oa_type = DPROV_CKA_KEY_TYPE;
7762 attribute.oa_value = (char *)&pri_key_type;
7763 attribute.oa_value_len = sizeof (ulong_t);
7764 error = dprov_object_set_attr(session, *pri_object_id_ptr,
7765 &attribute, 1, B_FALSE);
7767 if (error != CRYPTO_SUCCESS) {
7768 goto destroy_private_object;
7771 attribute.oa_type = DPROV_CKA_MODULUS;
7772 attribute.oa_value = (char *)modulus;
7773 attribute.oa_value_len = sizeof (modulus);
7774 error = dprov_object_set_attr(session, *pri_object_id_ptr,
7775 &attribute, 1, B_FALSE);
7777 if (error != CRYPTO_SUCCESS) {
7778 goto destroy_private_object;
7781 attribute.oa_type = DPROV_CKA_PRIVATE_EXPONENT;
7782 attribute.oa_value = (char *)private_exponent;
7783 attribute.oa_value_len = sizeof (private_exponent);
7784 error = dprov_object_set_attr(session, *pri_object_id_ptr,
7785 &attribute, 1, B_FALSE);
7787 if (error != CRYPTO_SUCCESS) {
7788 goto destroy_private_object;
7790 break;
7792 destroy_private_object:
7793 (void) dprov_destroy_object(softc, session,
7794 *pri_object_id_ptr);
7795 destroy_public_object:
7796 (void) dprov_destroy_object(softc, session,
7797 *pub_object_id_ptr);
7799 break;
7802 case DPROV_REQ_KEY_WRAP: {
7803 crypto_mechanism_t mech, *mechp;
7804 crypto_key_t key, *keyp;
7805 crypto_object_id_t object_id;
7806 ulong_t class = DPROV_CKO_DATA;
7807 boolean_t extractable = B_TRUE;
7808 dprov_object_t *object;
7809 int object_idx;
7810 char *plaintext_key;
7811 size_t plaintext_key_len;
7812 crypto_data_t plaintext;
7813 crypto_data_t ciphertext;
7814 size_t *lenp;
7816 mechp = taskq_req->dr_key_req.kr_mechanism;
7817 /* structure assignment */
7818 mech = *mechp;
7820 /* get wrapping key value */
7821 if (is_publickey_mech(mech.cm_type)) {
7822 if ((error = dprov_key_attr_asymmetric(softc,
7823 session_id, taskq_req->dr_type,
7824 taskq_req->dr_key_req.kr_key,
7825 &key)) != CRYPTO_SUCCESS)
7826 break;
7827 keyp = &key;
7828 } else {
7829 if ((error = dprov_key_value_secret(softc,
7830 session_id, taskq_req->dr_type,
7831 taskq_req->dr_key_req.kr_key,
7832 &key)) != CRYPTO_SUCCESS)
7833 break;
7834 keyp = &key;
7837 /* get the software provider for this mechanism */
7838 if ((error = dprov_get_sw_prov(mechp, &pd,
7839 &mech.cm_type)) != CRYPTO_SUCCESS)
7840 break;
7842 object_id = *taskq_req->dr_key_req.kr_object_id_ptr;
7843 if (object_id >= DPROV_MAX_OBJECTS) {
7844 error = CRYPTO_KEY_HANDLE_INVALID;
7845 break;
7848 /* get ptr to object */
7849 if ((object = session->ds_objects[object_id]) == NULL) {
7850 error = CRYPTO_OBJECT_HANDLE_INVALID;
7851 break;
7854 (void) dprov_get_object_attr_boolean(object,
7855 DPROV_CKA_EXTRACTABLE, &extractable);
7857 if (!extractable) {
7858 error = CRYPTO_ATTRIBUTE_SENSITIVE;
7859 break;
7862 (void) dprov_get_object_attr_ulong(object,
7863 DPROV_CKA_CLASS, &class);
7865 switch (class) {
7866 case DPROV_CKO_SECRET_KEY:
7867 object_idx = dprov_find_attr(object->do_attr,
7868 DPROV_MAX_ATTR, DPROV_CKA_VALUE);
7869 if (object_idx == -1) {
7870 error = CRYPTO_ATTRIBUTE_TYPE_INVALID;
7871 break;
7873 break;
7875 case DPROV_CKO_PRIVATE_KEY:
7877 * PKCS#11 says that ASN.1 should be used to encode
7878 * specific attributes before encrypting the blob.
7879 * We only encrypt the private exponent for the
7880 * purpose of testing.
7882 object_idx = dprov_find_attr(object->do_attr,
7883 DPROV_MAX_ATTR, DPROV_CKA_PRIVATE_EXPONENT);
7884 if (object_idx == -1) {
7885 error = CRYPTO_ATTRIBUTE_TYPE_INVALID;
7886 break;
7888 break;
7889 default:
7890 error = CRYPTO_KEY_NOT_WRAPPABLE;
7891 break;
7893 if (error != CRYPTO_SUCCESS)
7894 break;
7896 plaintext_key = object->do_attr[object_idx].oa_value;
7897 plaintext_key_len = object->do_attr[object_idx].oa_value_len;
7898 lenp = taskq_req->dr_key_req.kr_wrapped_key_len_ptr;
7900 /* session id is 0 for software provider */
7901 plaintext.cd_format = CRYPTO_DATA_RAW;
7902 plaintext.cd_offset = 0;
7903 plaintext.cd_length = plaintext_key_len;
7904 plaintext.cd_raw.iov_base = plaintext_key;
7905 plaintext.cd_raw.iov_len = plaintext_key_len;
7906 plaintext.cd_miscdata = NULL;
7908 ciphertext.cd_format = CRYPTO_DATA_RAW;
7909 ciphertext.cd_offset = 0;
7910 ciphertext.cd_length = *lenp;
7911 ciphertext.cd_raw.iov_base =
7912 (char *)taskq_req->dr_key_req.kr_wrapped_key;
7913 ciphertext.cd_raw.iov_len = ciphertext.cd_length;
7914 ciphertext.cd_miscdata = NULL;
7916 error = crypto_encrypt_prov(pd, 0, &mech, &plaintext, keyp,
7917 NULL, &ciphertext, NULL);
7919 KCF_PROV_REFRELE(pd);
7920 if (error == CRYPTO_SUCCESS ||
7921 error == CRYPTO_BUFFER_TOO_SMALL) {
7922 *lenp = ciphertext.cd_length;
7924 break;
7927 case DPROV_REQ_KEY_UNWRAP: {
7928 crypto_mechanism_t mech, *mechp;
7929 crypto_key_t key, *keyp;
7930 crypto_object_id_t *object_id_ptr;
7931 ulong_t class = DPROV_CKO_DATA;
7932 uchar_t *wrapped_key;
7933 char *plaintext_buf;
7934 size_t wrapped_key_len;
7935 crypto_data_t plaintext;
7936 crypto_data_t ciphertext;
7937 crypto_object_attribute_t unwrapped_key;
7938 crypto_object_attribute_t *template;
7939 uint_t attribute_count;
7941 template = taskq_req->dr_key_req.kr_template;
7942 attribute_count = taskq_req->dr_key_req.kr_attribute_count;
7943 object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr;
7945 /* all objects must have an object class attribute */
7946 if (dprov_get_template_attr_ulong(template, attribute_count,
7947 DPROV_CKA_CLASS, &class) != CRYPTO_SUCCESS) {
7948 error = CRYPTO_TEMPLATE_INCOMPLETE;
7949 break;
7952 mechp = taskq_req->dr_key_req.kr_mechanism;
7953 /* structure assignment */
7954 mech = *mechp;
7956 /* get unwrapping key value */
7957 if (is_publickey_mech(mech.cm_type)) {
7958 if ((error = dprov_key_attr_asymmetric(softc,
7959 session_id, taskq_req->dr_type,
7960 taskq_req->dr_key_req.kr_key,
7961 &key)) != CRYPTO_SUCCESS)
7962 break;
7963 keyp = &key;
7964 } else {
7965 if ((error = dprov_key_value_secret(softc,
7966 session_id, taskq_req->dr_type,
7967 taskq_req->dr_key_req.kr_key,
7968 &key)) != CRYPTO_SUCCESS)
7969 break;
7970 keyp = &key;
7973 /* get the software provider for this mechanism */
7974 if ((error = dprov_get_sw_prov(mechp, &pd,
7975 &mech.cm_type)) != CRYPTO_SUCCESS)
7976 break;
7978 wrapped_key = taskq_req->dr_key_req.kr_wrapped_key;
7979 wrapped_key_len = *taskq_req->dr_key_req.kr_wrapped_key_len_ptr;
7980 ciphertext.cd_format = CRYPTO_DATA_RAW;
7981 ciphertext.cd_offset = 0;
7982 ciphertext.cd_length = wrapped_key_len;
7983 ciphertext.cd_raw.iov_base = (char *)wrapped_key;
7984 ciphertext.cd_raw.iov_len = wrapped_key_len;
7985 ciphertext.cd_miscdata = NULL;
7988 * Plaintext length is less than or equal to
7989 * the length of the ciphertext.
7991 plaintext_buf = kmem_alloc(wrapped_key_len, KM_SLEEP);
7992 plaintext.cd_format = CRYPTO_DATA_RAW;
7993 plaintext.cd_offset = 0;
7994 plaintext.cd_length = wrapped_key_len;
7995 plaintext.cd_raw.iov_base = plaintext_buf;
7996 plaintext.cd_raw.iov_len = wrapped_key_len;
7997 plaintext.cd_miscdata = NULL;
7999 error = crypto_decrypt_prov(pd, 0, &mech, &ciphertext, keyp,
8000 NULL, &plaintext, NULL);
8002 KCF_PROV_REFRELE(pd);
8004 if (error != CRYPTO_SUCCESS)
8005 goto free_unwrapped_key;
8007 error = dprov_create_object_from_template(softc, session,
8008 template, attribute_count, object_id_ptr, B_FALSE, B_FALSE);
8010 if (error != CRYPTO_SUCCESS)
8011 goto free_unwrapped_key;
8013 switch (class) {
8014 case DPROV_CKO_SECRET_KEY:
8015 unwrapped_key.oa_type = DPROV_CKA_VALUE;
8016 unwrapped_key.oa_value_len = plaintext.cd_length;
8017 unwrapped_key.oa_value = plaintext_buf;
8018 break;
8019 case DPROV_CKO_PRIVATE_KEY:
8021 * PKCS#11 says that ASN.1 should be used to encode
8022 * specific attributes before encrypting the blob.
8023 * We only encrypt the private exponent for the
8024 * purpose of testing.
8026 unwrapped_key.oa_type = DPROV_CKA_PRIVATE_EXPONENT;
8027 unwrapped_key.oa_value_len = plaintext.cd_length;
8028 unwrapped_key.oa_value = plaintext_buf;
8029 break;
8030 default:
8031 error = CRYPTO_TEMPLATE_INCONSISTENT;
8032 goto free_unwrapped_key;
8035 if ((error = dprov_object_set_attr(session, *object_id_ptr,
8036 &unwrapped_key, 1, B_FALSE)) == CRYPTO_SUCCESS)
8037 break; /* don't free the unwrapped key */
8039 /* failure */
8040 (void) dprov_destroy_object(softc, session, *object_id_ptr);
8041 break;
8043 free_unwrapped_key:
8044 bzero(plaintext_buf, wrapped_key_len);
8045 kmem_free(plaintext_buf, wrapped_key_len);
8046 break;
8049 case DPROV_REQ_KEY_DERIVE: {
8050 crypto_mechanism_t digest_mech, *mechp;
8051 crypto_key_t key, *base_keyp;
8052 crypto_object_id_t *object_id_ptr;
8053 crypto_data_t data;
8054 crypto_data_t digest;
8055 size_t hash_size;
8056 char *digest_buf;
8057 crypto_object_attribute_t derived_key;
8058 crypto_object_attribute_t *template;
8059 uint_t attribute_count;
8060 ulong_t key_type;
8061 void *value;
8062 size_t value_len = 0;
8064 error = CRYPTO_SUCCESS;
8066 template = taskq_req->dr_key_req.kr_template;
8067 attribute_count = taskq_req->dr_key_req.kr_attribute_count;
8068 object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr;
8070 /* required */
8071 if (dprov_get_template_attr_ulong(template, attribute_count,
8072 DPROV_CKA_KEY_TYPE, &key_type) != CRYPTO_SUCCESS) {
8073 error = CRYPTO_TEMPLATE_INCOMPLETE;
8074 break;
8077 mechp = taskq_req->dr_key_req.kr_mechanism;
8078 /* structure assignment */
8079 digest_mech = *mechp;
8081 switch (digest_mech.cm_type) {
8082 case SHA1_KEY_DERIVATION_MECH_INFO_TYPE:
8083 hash_size = SHA1_DIGEST_LEN;
8084 digest_mech.cm_type = SHA1_MECH_INFO_TYPE;
8085 break;
8087 case SHA256_KEY_DERIVATION_MECH_INFO_TYPE:
8088 hash_size = SHA256_DIGEST_LENGTH;
8089 digest_mech.cm_type = SHA256_MECH_INFO_TYPE;
8090 break;
8092 case SHA384_KEY_DERIVATION_MECH_INFO_TYPE:
8093 hash_size = SHA384_DIGEST_LENGTH;
8094 digest_mech.cm_type = SHA384_MECH_INFO_TYPE;
8095 break;
8097 case SHA512_KEY_DERIVATION_MECH_INFO_TYPE:
8098 hash_size = SHA512_DIGEST_LENGTH;
8099 digest_mech.cm_type = SHA512_MECH_INFO_TYPE;
8100 break;
8102 case MD5_KEY_DERIVATION_MECH_INFO_TYPE:
8103 hash_size = MD5_DIGEST_LEN;
8104 digest_mech.cm_type = MD5_MECH_INFO_TYPE;
8105 break;
8107 default:
8108 error = CRYPTO_MECHANISM_INVALID;
8111 if (error != CRYPTO_SUCCESS)
8112 break;
8114 /* CKA_VALUE is optional */
8115 (void) dprov_get_template_attr_array(template, attribute_count,
8116 DPROV_CKA_VALUE, &value, &value_len);
8118 /* check for inconsistent value length */
8119 switch (key_type) {
8120 case DPROV_CKK_GENERIC_SECRET:
8121 if (value_len > 0) {
8122 if (value_len > hash_size)
8123 error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
8124 } else {
8125 value_len = hash_size;
8127 break;
8129 case DPROV_CKK_RC4:
8130 case DPROV_CKK_AES:
8131 if (value_len == 0 ||
8132 value_len > hash_size) {
8133 error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
8135 break;
8137 case DPROV_CKK_DES:
8138 if (value_len > 0 &&
8139 value_len != DES_KEY_LEN) {
8140 error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
8142 value_len = DES_KEY_LEN;
8143 break;
8145 case DPROV_CKK_DES3:
8146 if (value_len > 0 &&
8147 value_len != DES3_KEY_LEN) {
8148 error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
8150 value_len = DES3_KEY_LEN;
8151 break;
8153 default:
8154 error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
8155 break;
8158 if (error != CRYPTO_SUCCESS)
8159 break;
8161 /* get the software provider for this mechanism */
8162 if ((error = dprov_get_sw_prov(&digest_mech, &pd,
8163 &digest_mech.cm_type)) != CRYPTO_SUCCESS)
8164 break;
8166 /* get the base key */
8167 error = dprov_key_value_secret(softc, session_id,
8168 taskq_req->dr_type, taskq_req->dr_key_req.kr_key, &key);
8169 if (error != CRYPTO_SUCCESS)
8170 break;
8172 base_keyp = &key;
8174 data.cd_format = CRYPTO_DATA_RAW;
8175 data.cd_offset = 0;
8176 data.cd_length = CRYPTO_BITS2BYTES(base_keyp->ck_length);
8177 data.cd_raw.iov_base = base_keyp->ck_data;
8178 data.cd_raw.iov_len = data.cd_length;
8180 digest_buf = kmem_alloc(hash_size, KM_SLEEP);
8181 digest.cd_format = CRYPTO_DATA_RAW;
8182 digest.cd_offset = 0;
8183 digest.cd_length = hash_size;
8184 digest.cd_raw.iov_base = digest_buf;
8185 digest.cd_raw.iov_len = hash_size;
8187 error = crypto_digest_prov(pd, 0, &digest_mech, &data,
8188 &digest, NULL);
8190 KCF_PROV_REFRELE(pd);
8192 if (error != CRYPTO_SUCCESS)
8193 goto free_derived_key;
8195 error = dprov_create_object_from_template(softc, session,
8196 template, attribute_count, object_id_ptr, B_FALSE, B_FALSE);
8198 if (error != CRYPTO_SUCCESS)
8199 goto free_derived_key;
8201 derived_key.oa_type = DPROV_CKA_VALUE;
8202 derived_key.oa_value = digest_buf;
8203 derived_key.oa_value_len = value_len;
8205 error = dprov_object_set_attr(session, *object_id_ptr,
8206 &derived_key, 1, B_FALSE);
8208 if (error != CRYPTO_SUCCESS) {
8209 (void) dprov_destroy_object(softc, session,
8210 *object_id_ptr);
8213 free_derived_key:
8214 bzero(digest_buf, hash_size);
8215 kmem_free(digest_buf, hash_size);
8216 break;
8219 case DPROV_REQ_NOSTORE_KEY_GENERATE: {
8220 crypto_object_attribute_t *out_template;
8221 uint_t out_attribute_count;
8222 void *value;
8223 size_t value_len = 0;
8225 out_template = taskq_req->dr_key_req.kr_out_template1;
8226 out_attribute_count =
8227 taskq_req->dr_key_req.kr_out_attribute_count1;
8229 error = dprov_get_template_attr_array(out_template,
8230 out_attribute_count, DPROV_CKA_VALUE, &value, &value_len);
8231 if (error != CRYPTO_SUCCESS)
8232 break;
8234 /* fill the entire array with pattern */
8236 int i = 0;
8237 char *p = value;
8238 while (i < value_len) {
8239 p[i++] = 'A';
8240 if (i >= value_len)
8241 break;
8242 p[i++] = 'B';
8243 if (i >= value_len)
8244 break;
8245 p[i++] = 'C';
8249 error = CRYPTO_SUCCESS;
8250 break;
8253 case DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR: {
8254 crypto_mechanism_t *mechp;
8255 crypto_object_attribute_t *pub_template;
8256 crypto_object_attribute_t *pri_template;
8257 uint_t pub_attribute_count;
8258 uint_t pri_attribute_count;
8259 crypto_object_attribute_t *out_pub_template;
8260 crypto_object_attribute_t *out_pri_template;
8261 uint_t out_pub_attribute_count;
8262 uint_t out_pri_attribute_count;
8264 mechp = taskq_req->dr_key_req.kr_mechanism;
8265 pub_template = taskq_req->dr_key_req.kr_template;
8266 pub_attribute_count = taskq_req->dr_key_req.kr_attribute_count;
8267 pri_template = taskq_req->dr_key_req.kr_private_key_template;
8268 pri_attribute_count =
8269 taskq_req->dr_key_req.kr_private_key_attribute_count;
8270 out_pub_template = taskq_req->dr_key_req.kr_out_template1;
8271 out_pub_attribute_count =
8272 taskq_req->dr_key_req.kr_out_attribute_count1;
8273 out_pri_template = taskq_req->dr_key_req.kr_out_template2;
8274 out_pri_attribute_count =
8275 taskq_req->dr_key_req.kr_out_attribute_count2;
8277 switch (mechp->cm_type) {
8278 case RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE:
8279 error = nostore_copy_attribute(out_pub_template,
8280 out_pub_attribute_count, DPROV_CKA_MODULUS);
8281 if (error != CRYPTO_SUCCESS)
8282 break;
8284 error = nostore_copy_attribute(out_pub_template,
8285 out_pub_attribute_count, DPROV_CKA_PUBLIC_EXPONENT);
8286 if (error == CRYPTO_ARGUMENTS_BAD) {
8287 size_t tmp_len = 0;
8288 void *tmp;
8290 /* public exponent must be here */
8291 error = dprov_get_template_attr_array(
8292 pub_template, pub_attribute_count,
8293 DPROV_CKA_PUBLIC_EXPONENT, &tmp, &tmp_len);
8294 if (error != CRYPTO_SUCCESS)
8295 break;
8297 error = nostore_copy_attribute(out_pri_template,
8298 out_pri_attribute_count, DPROV_CKA_MODULUS);
8299 if (error != CRYPTO_SUCCESS)
8300 break;
8302 error = nostore_copy_attribute(out_pri_template,
8303 out_pri_attribute_count,
8304 DPROV_CKA_PRIVATE_EXPONENT);
8305 break;
8307 case DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE:
8309 * There is no software provider for DH mechanism;
8310 * Just return pre-defined values.
8312 error = nostore_copy_attribute(out_pub_template,
8313 out_pub_attribute_count, DPROV_CKA_VALUE);
8314 error = nostore_copy_attribute(out_pri_template,
8315 out_pri_attribute_count, DPROV_CKA_VALUE);
8316 break;
8318 case EC_KEY_PAIR_GEN_MECH_INFO_TYPE: {
8319 crypto_mechanism_t mech, *mechp;
8320 kcf_req_params_t params;
8321 crypto_object_attribute_t *pub_template;
8322 uint_t pub_attribute_count;
8323 crypto_object_attribute_t *out_pub_template;
8324 crypto_object_attribute_t *out_pri_template;
8325 uint_t out_pub_attribute_count;
8326 uint_t out_pri_attribute_count;
8328 mechp = taskq_req->dr_key_req.kr_mechanism;
8329 pub_template = taskq_req->dr_key_req.kr_template;
8330 pub_attribute_count =
8331 taskq_req->dr_key_req.kr_attribute_count;
8332 out_pub_template =
8333 taskq_req->dr_key_req.kr_out_template1;
8334 out_pub_attribute_count =
8335 taskq_req->dr_key_req.kr_out_attribute_count1;
8336 out_pri_template =
8337 taskq_req->dr_key_req.kr_out_template2;
8338 out_pri_attribute_count =
8339 taskq_req->dr_key_req.kr_out_attribute_count2;
8341 /* get the software provider for this mechanism */
8342 mech = *mechp;
8343 if ((error = dprov_get_sw_prov(mechp, &pd,
8344 &mech.cm_type)) != CRYPTO_SUCCESS)
8345 break;
8347 * Turn 32-bit values into 64-bit values for certain
8348 * attributes like CKA_CLASS.
8350 dprov_adjust_attrs(pub_template, pub_attribute_count);
8351 dprov_adjust_attrs(pri_template, pri_attribute_count);
8353 /* bypass the kernel API for now */
8354 KCF_WRAP_NOSTORE_KEY_OPS_PARAMS(&params,
8355 KCF_OP_KEY_GENERATE_PAIR,
8356 0, /* session 0 for sw provider */
8357 &mech, pub_template, pub_attribute_count,
8358 pri_template, pri_attribute_count, NULL,
8359 out_pub_template, out_pub_attribute_count,
8360 out_pri_template, out_pri_attribute_count);
8362 error = kcf_submit_request(pd, NULL, NULL, &params,
8363 B_FALSE);
8365 KCF_PROV_REFRELE(pd);
8366 break;
8368 default:
8369 error = CRYPTO_MECHANISM_INVALID;
8371 break;
8374 case DPROV_REQ_NOSTORE_KEY_DERIVE: {
8375 crypto_mechanism_t *mechp;
8376 crypto_object_attribute_t *in_template, *out_template;
8377 crypto_key_t *base_key;
8378 uint_t in_attribute_count, out_attribute_count;
8379 ulong_t key_type;
8380 void *value;
8381 size_t value_len = 0;
8382 size_t value_len_value = 0;
8384 in_template = taskq_req->dr_key_req.kr_template;
8385 out_template = taskq_req->dr_key_req.kr_out_template1;
8386 in_attribute_count = taskq_req->dr_key_req.kr_attribute_count;
8387 out_attribute_count =
8388 taskq_req->dr_key_req.kr_out_attribute_count1;
8389 mechp = taskq_req->dr_key_req.kr_mechanism;
8390 base_key = taskq_req->dr_key_req.kr_key;
8393 * CKA_VALUE must be present so the derived key can
8394 * be returned by value.
8396 if (dprov_get_template_attr_array(out_template,
8397 out_attribute_count, DPROV_CKA_VALUE, &value,
8398 &value_len) != CRYPTO_SUCCESS) {
8399 error = CRYPTO_TEMPLATE_INCOMPLETE;
8400 break;
8403 if (dprov_get_template_attr_ulong(in_template,
8404 in_attribute_count, DPROV_CKA_KEY_TYPE,
8405 &key_type) != CRYPTO_SUCCESS) {
8406 error = CRYPTO_TEMPLATE_INCOMPLETE;
8407 break;
8409 switch (mechp->cm_type) {
8410 case DH_PKCS_DERIVE_MECH_INFO_TYPE: {
8411 size_t tmp_len = 0;
8412 void *tmp;
8414 if (base_key->ck_format != CRYPTO_KEY_ATTR_LIST) {
8415 error = CRYPTO_ARGUMENTS_BAD;
8416 break;
8419 if ((dprov_get_template_attr_array(base_key->ck_attrs,
8420 base_key->ck_count, DPROV_CKA_BASE, &tmp,
8421 &tmp_len) != CRYPTO_SUCCESS) ||
8422 (dprov_get_template_attr_array(base_key->ck_attrs,
8423 base_key->ck_count, DPROV_CKA_PRIME, &tmp,
8424 &tmp_len) != CRYPTO_SUCCESS) ||
8425 (dprov_get_template_attr_array(base_key->ck_attrs,
8426 base_key->ck_count, DPROV_CKA_VALUE, &tmp,
8427 &tmp_len) != CRYPTO_SUCCESS)) {
8428 error = CRYPTO_TEMPLATE_INCOMPLETE;
8429 break;
8433 * CKA_VALUE is added to the derived key template by
8434 * the library.
8436 error = CRYPTO_SUCCESS;
8437 switch (key_type) {
8438 case DPROV_CKK_AES:
8439 if (dprov_get_template_attr_ulong(in_template,
8440 in_attribute_count, DPROV_CKA_VALUE_LEN,
8441 &value_len_value) != CRYPTO_SUCCESS) {
8442 error = CRYPTO_TEMPLATE_INCOMPLETE;
8443 break;
8445 if (value_len != value_len_value) {
8446 error = CRYPTO_TEMPLATE_INCONSISTENT;
8447 break;
8449 default:
8450 error = CRYPTO_MECHANISM_INVALID;
8452 if (error == CRYPTO_SUCCESS)
8453 fill_dh(value, value_len);
8454 break;
8456 case ECDH1_DERIVE_MECH_INFO_TYPE: {
8457 crypto_mechanism_t mech;
8458 kcf_req_params_t params;
8460 /* get the software provider for this mechanism */
8461 mech = *mechp;
8462 if ((error = dprov_get_sw_prov(mechp, &pd,
8463 &mech.cm_type)) != CRYPTO_SUCCESS)
8464 break;
8467 * Turn 32-bit values into 64-bit values for certain
8468 * attributes like CKA_VALUE_LEN.
8470 dprov_adjust_attrs(in_template, in_attribute_count);
8472 /* bypass the kernel API for now */
8473 KCF_WRAP_NOSTORE_KEY_OPS_PARAMS(&params,
8474 KCF_OP_KEY_DERIVE,
8475 0, /* session 0 for sw provider */
8476 &mech, in_template, in_attribute_count,
8477 NULL, 0, base_key,
8478 out_template, out_attribute_count,
8479 NULL, 0);
8481 error = kcf_submit_request(pd, NULL, NULL, &params,
8482 B_FALSE);
8484 KCF_PROV_REFRELE(pd);
8485 break;
8488 default:
8489 error = CRYPTO_MECHANISM_INVALID;
8491 break;
8492 default:
8493 error = CRYPTO_MECHANISM_INVALID;
8495 } /* end case */
8497 mutex_exit(&softc->ds_lock);
8498 dprov_op_done(taskq_req, error);
8499 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_task: end\n", instance));
8503 * taskq dispatcher function for provider management operations.
8505 static void
8506 dprov_mgmt_task(dprov_req_t *taskq_req)
8508 dprov_state_t *softc;
8509 /* LINTED E_FUNC_SET_NOT_USED */
8510 int instance;
8511 int error = CRYPTO_NOT_SUPPORTED;
8513 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
8514 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_mgmt_task: started\n", instance));
8516 mutex_enter(&softc->ds_lock);
8518 switch (taskq_req->dr_type) {
8519 case DPROV_REQ_MGMT_EXTINFO: {
8520 crypto_provider_ext_info_t *ext_info =
8521 taskq_req->dr_mgmt_req.mr_ext_info;
8523 (void) memset(ext_info->ei_label, ' ', CRYPTO_EXT_SIZE_LABEL);
8524 if (!softc->ds_token_initialized) {
8525 bcopy("(not initialized)", ext_info->ei_label,
8526 strlen("(not initialized)"));
8527 } else {
8528 bcopy(softc->ds_label, ext_info->ei_label,
8529 CRYPTO_EXT_SIZE_LABEL);
8532 bcopy(DPROV_MANUFACTURER, ext_info->ei_manufacturerID,
8533 CRYPTO_EXT_SIZE_MANUF);
8534 bcopy(DPROV_MODEL, ext_info->ei_model, CRYPTO_EXT_SIZE_MODEL);
8536 (void) snprintf((char *)ext_info->ei_serial_number, 16, "%d%s",
8537 instance, DPROV_ALLSPACES);
8538 /* PKCS#11 blank padding */
8539 ext_info->ei_serial_number[15] = ' ';
8540 ext_info->ei_max_session_count = CRYPTO_EFFECTIVELY_INFINITE;
8541 ext_info->ei_max_pin_len = (ulong_t)DPROV_MAX_PIN_LEN;
8542 ext_info->ei_min_pin_len = 1;
8543 ext_info->ei_total_public_memory = CRYPTO_EFFECTIVELY_INFINITE;
8544 ext_info->ei_free_public_memory = CRYPTO_EFFECTIVELY_INFINITE;
8545 ext_info->ei_total_private_memory = CRYPTO_EFFECTIVELY_INFINITE;
8546 ext_info->ei_free_private_memory = CRYPTO_EFFECTIVELY_INFINITE;
8547 ext_info->ei_hardware_version.cv_major = 1;
8548 ext_info->ei_hardware_version.cv_minor = 0;
8549 ext_info->ei_firmware_version.cv_major = 1;
8550 ext_info->ei_firmware_version.cv_minor = 0;
8552 ext_info->ei_flags = CRYPTO_EXTF_RNG |
8553 CRYPTO_EXTF_LOGIN_REQUIRED |
8554 CRYPTO_EXTF_DUAL_CRYPTO_OPERATIONS;
8555 if (softc->ds_user_pin_set)
8556 ext_info->ei_flags |= CRYPTO_EXTF_USER_PIN_INITIALIZED;
8557 if (softc->ds_token_initialized)
8558 ext_info->ei_flags |= CRYPTO_EXTF_TOKEN_INITIALIZED;
8560 ext_info->ei_hash_max_input_len = dprov_max_digestsz;
8561 ext_info->ei_hmac_max_input_len = dprov_max_digestsz;
8562 error = CRYPTO_SUCCESS;
8563 break;
8565 case DPROV_REQ_MGMT_INITTOKEN: {
8566 char *pin = taskq_req->dr_mgmt_req.mr_pin;
8567 size_t pin_len = taskq_req->dr_mgmt_req.mr_pin_len;
8568 char *label = taskq_req->dr_mgmt_req.mr_label;
8570 /* cannot initialize token when a session is open */
8571 if (softc->ds_sessions_count > 0) {
8572 error = CRYPTO_SESSION_EXISTS;
8573 break;
8576 /* check PIN length */
8577 if (pin_len > DPROV_MAX_PIN_LEN) {
8578 error = CRYPTO_PIN_LEN_RANGE;
8579 break;
8582 /* check PIN */
8583 if (pin == NULL) {
8584 error = CRYPTO_PIN_INVALID;
8585 break;
8589 * If the token has already been initialized, need
8590 * to validate supplied PIN.
8592 if (softc->ds_token_initialized &&
8593 (softc->ds_so_pin_len != pin_len ||
8594 strncmp(softc->ds_so_pin, pin, pin_len) != 0)) {
8595 /* invalid SO PIN */
8596 error = CRYPTO_PIN_INCORRECT;
8597 break;
8600 /* set label */
8601 bcopy(label, softc->ds_label, CRYPTO_EXT_SIZE_LABEL);
8603 /* set new SO PIN, update state */
8604 bcopy(pin, softc->ds_so_pin, pin_len);
8605 softc->ds_so_pin_len = pin_len;
8606 softc->ds_token_initialized = B_TRUE;
8607 softc->ds_user_pin_set = B_FALSE;
8609 error = CRYPTO_SUCCESS;
8610 break;
8612 case DPROV_REQ_MGMT_INITPIN: {
8613 char *pin = taskq_req->dr_mgmt_req.mr_pin;
8614 size_t pin_len = taskq_req->dr_mgmt_req.mr_pin_len;
8615 crypto_session_id_t session_id =
8616 taskq_req->dr_mgmt_req.mr_session_id;
8618 /* check session id */
8619 if (softc->ds_sessions[session_id] == NULL) {
8620 error = CRYPTO_SESSION_HANDLE_INVALID;
8621 break;
8624 /* fail if not logged in as SO */
8625 if (softc->ds_sessions[session_id]->ds_state !=
8626 DPROV_SESSION_STATE_SO) {
8627 error = CRYPTO_USER_NOT_LOGGED_IN;
8628 break;
8631 /* check PIN length */
8632 if (pin_len > DPROV_MAX_PIN_LEN) {
8633 error = CRYPTO_PIN_LEN_RANGE;
8634 break;
8637 /* check PIN */
8638 if (pin == NULL) {
8639 error = CRYPTO_PIN_INVALID;
8640 break;
8643 /* set new normal user PIN */
8644 bcopy(pin, softc->ds_user_pin, pin_len);
8645 softc->ds_user_pin_len = pin_len;
8646 softc->ds_user_pin_set = B_TRUE;
8648 error = CRYPTO_SUCCESS;
8649 break;
8651 case DPROV_REQ_MGMT_SETPIN: {
8652 char *new_pin = taskq_req->dr_mgmt_req.mr_pin;
8653 size_t new_pin_len = taskq_req->dr_mgmt_req.mr_pin_len;
8654 char *old_pin = taskq_req->dr_mgmt_req.mr_old_pin;
8655 size_t old_pin_len = taskq_req->dr_mgmt_req.mr_old_pin_len;
8656 crypto_session_id_t session_id =
8657 taskq_req->dr_mgmt_req.mr_session_id;
8659 /* check session id */
8660 if (softc->ds_sessions[session_id] == NULL) {
8661 error = CRYPTO_SESSION_HANDLE_INVALID;
8662 break;
8665 /* check PIN length */
8666 if (old_pin_len > DPROV_MAX_PIN_LEN ||
8667 new_pin_len > DPROV_MAX_PIN_LEN) {
8668 error = CRYPTO_PIN_LEN_RANGE;
8669 break;
8672 /* check PIN */
8673 if (old_pin == NULL || new_pin == NULL) {
8674 error = CRYPTO_PIN_INVALID;
8675 break;
8678 /* check user PIN state */
8679 if (!softc->ds_user_pin_set) {
8680 error = CRYPTO_USER_PIN_NOT_INITIALIZED;
8681 break;
8685 * If the token has already been initialized, need
8686 * to validate supplied PIN.
8688 if (softc->ds_user_pin_len != old_pin_len ||
8689 strncmp(softc->ds_user_pin, old_pin, old_pin_len) != 0) {
8690 /* invalid SO PIN */
8691 error = CRYPTO_PIN_INCORRECT;
8692 break;
8695 /* set new PIN */
8696 bcopy(new_pin, softc->ds_user_pin, new_pin_len);
8697 softc->ds_user_pin_len = new_pin_len;
8699 error = CRYPTO_SUCCESS;
8700 break;
8704 mutex_exit(&softc->ds_lock);
8705 dprov_op_done(taskq_req, error);
8706 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_mgmt_task: end\n", instance));
8710 * Returns in the location pointed to by pd a pointer to the descriptor
8711 * for the software provider for the specified mechanism.
8712 * The provider descriptor is returned held. Returns one of the CRYPTO_
8713 * error codes on failure, CRYPTO_SUCCESS on success.
8715 static int
8716 dprov_get_sw_prov(crypto_mechanism_t *mech, kcf_provider_desc_t **pd,
8717 crypto_mech_type_t *provider_mech_type)
8719 crypto_mech_type_t kcf_mech_type = CRYPTO_MECH_INVALID;
8720 int i, rv;
8722 /* lookup the KCF mech type associated with our mech type */
8723 for (i = 0; i < sizeof (dprov_mech_info_tab)/
8724 sizeof (crypto_mech_info_t); i++) {
8725 if (mech->cm_type == dprov_mech_info_tab[i].cm_mech_number) {
8726 kcf_mech_type = crypto_mech2id_common(
8727 dprov_mech_info_tab[i].cm_mech_name, B_TRUE);
8731 rv = kcf_get_sw_prov(kcf_mech_type, pd, NULL, B_TRUE);
8732 if (rv == CRYPTO_SUCCESS)
8733 *provider_mech_type = kcf_mech_type;
8735 return (rv);
8739 * Object management helper functions.
8743 * Given a crypto_key_t, return whether the key can be used or not
8744 * for the specified request. The attributes used here are defined
8745 * in table 42 of the PKCS#11 spec (Common secret key attributes).
8747 static int
8748 dprov_key_can_use(dprov_object_t *object, dprov_req_type_t req_type)
8750 boolean_t ret = 0;
8751 int rv = CRYPTO_SUCCESS;
8753 /* check if object is allowed for specified operation */
8754 switch (req_type) {
8755 case DPROV_REQ_ENCRYPT_INIT:
8756 case DPROV_REQ_ENCRYPT_ATOMIC:
8757 rv = dprov_get_object_attr_boolean(object,
8758 DPROV_CKA_ENCRYPT, &ret);
8759 break;
8760 case DPROV_REQ_DECRYPT_INIT:
8761 case DPROV_REQ_DECRYPT_ATOMIC:
8762 rv = dprov_get_object_attr_boolean(object,
8763 DPROV_CKA_DECRYPT, &ret);
8764 break;
8765 case DPROV_REQ_SIGN_INIT:
8766 case DPROV_REQ_SIGN_ATOMIC:
8767 case DPROV_REQ_MAC_INIT:
8768 case DPROV_REQ_MAC_ATOMIC:
8769 case DPROV_REQ_MAC_VERIFY_ATOMIC:
8770 rv = dprov_get_object_attr_boolean(object,
8771 DPROV_CKA_SIGN, &ret);
8772 break;
8773 case DPROV_REQ_SIGN_RECOVER_INIT:
8774 case DPROV_REQ_SIGN_RECOVER_ATOMIC:
8775 rv = dprov_get_object_attr_boolean(object,
8776 DPROV_CKA_SIGN_RECOVER, &ret);
8777 break;
8778 case DPROV_REQ_VERIFY_INIT:
8779 case DPROV_REQ_VERIFY_ATOMIC:
8780 rv = dprov_get_object_attr_boolean(object,
8781 DPROV_CKA_VERIFY, &ret);
8782 break;
8783 case DPROV_REQ_VERIFY_RECOVER_INIT:
8784 case DPROV_REQ_VERIFY_RECOVER_ATOMIC:
8785 rv = dprov_get_object_attr_boolean(object,
8786 DPROV_CKA_VERIFY_RECOVER, &ret);
8787 break;
8788 case DPROV_REQ_KEY_WRAP:
8789 rv = dprov_get_object_attr_boolean(object,
8790 DPROV_CKA_WRAP, &ret);
8791 break;
8792 case DPROV_REQ_KEY_UNWRAP:
8793 rv = dprov_get_object_attr_boolean(object,
8794 DPROV_CKA_UNWRAP, &ret);
8795 break;
8796 case DPROV_REQ_DIGEST_KEY:
8798 * There is no attribute to check for; therefore,
8799 * any secret key can be used.
8801 ret = B_TRUE;
8802 rv = CRYPTO_SUCCESS;
8803 break;
8804 case DPROV_REQ_KEY_DERIVE:
8805 rv = dprov_get_object_attr_boolean(object,
8806 DPROV_CKA_DERIVE, &ret);
8807 break;
8810 if (rv != CRYPTO_SUCCESS || !ret)
8811 return (CRYPTO_KEY_FUNCTION_NOT_PERMITTED);
8813 return (CRYPTO_SUCCESS);
8817 * Given a crypto_key_t corresponding to a secret key (i.e. for
8818 * use with symmetric crypto algorithms) specified in raw format, by
8819 * attribute, or by reference, initialize the ck_data and ck_length
8820 * fields of the ret_key argument so that they specify the key value
8821 * and length.
8823 * For a key by value, this function uess the ck_data and ck_length,
8824 * for a key by reference, it looks up the corresponding object and
8825 * returns the appropriate attribute. For a key by attribute, it returns
8826 * the appropriate attribute. The attributes used are CKA_VALUE to retrieve
8827 * the value of the key, and CKA_VALUE_LEN to retrieve its length in bytes.
8829 static int
8830 dprov_key_value_secret(dprov_state_t *softc, crypto_session_id_t session_id,
8831 dprov_req_type_t req_type, crypto_key_t *key, crypto_key_t *ret_key)
8833 ulong_t key_type;
8834 int ret = CRYPTO_SUCCESS;
8836 ret_key->ck_format = CRYPTO_KEY_RAW;
8838 switch (key->ck_format) {
8840 case CRYPTO_KEY_RAW:
8841 ret_key->ck_data = key->ck_data;
8842 ret_key->ck_length = key->ck_length;
8843 break;
8845 case CRYPTO_KEY_ATTR_LIST: {
8846 void *value;
8847 size_t len, value_len;
8849 if ((ret = dprov_get_key_attr_ulong(key, DPROV_CKA_KEY_TYPE,
8850 &key_type)) != CRYPTO_SUCCESS)
8851 break;
8853 if ((ret = dprov_get_key_attr_array(key, DPROV_CKA_VALUE,
8854 &value, &len)) != CRYPTO_SUCCESS)
8855 break;
8858 * The length of the array is expressed in bytes.
8859 * Convert to bits now since that's how keys are measured.
8861 len = CRYPTO_BYTES2BITS(len);
8863 /* optional */
8864 if ((dprov_get_key_attr_ulong(key, DPROV_CKA_VALUE_LEN,
8865 &value_len)) == CRYPTO_SUCCESS) {
8866 len = value_len;
8869 ret_key->ck_data = value;
8870 ret_key->ck_length = (uint_t)len;
8872 break;
8875 case CRYPTO_KEY_REFERENCE: {
8876 dprov_object_t *object;
8877 void *value;
8878 size_t len, value_len;
8880 /* check session id */
8881 if (softc->ds_sessions[session_id] == NULL) {
8882 ret = CRYPTO_SESSION_HANDLE_INVALID;
8883 break;
8886 if (key->ck_obj_id >= DPROV_MAX_OBJECTS) {
8887 ret = CRYPTO_KEY_HANDLE_INVALID;
8888 goto bail;
8891 /* check if object id specified by key is valid */
8892 object = softc->ds_sessions[session_id]->
8893 ds_objects[key->ck_obj_id];
8894 if (object == NULL) {
8895 ret = CRYPTO_KEY_HANDLE_INVALID;
8896 goto bail;
8899 /* check if object can be used for operation */
8900 if ((ret = dprov_key_can_use(object, req_type)) !=
8901 CRYPTO_SUCCESS)
8902 goto bail;
8904 if ((ret = dprov_get_object_attr_ulong(object,
8905 DPROV_CKA_KEY_TYPE, &key_type)) != CRYPTO_SUCCESS)
8906 goto bail;
8908 if ((ret = dprov_get_object_attr_array(object,
8909 DPROV_CKA_VALUE, &value, &len)) != CRYPTO_SUCCESS)
8910 goto bail;
8912 /* optional */
8913 if ((dprov_get_object_attr_ulong(object, DPROV_CKA_VALUE_LEN,
8914 &value_len)) == CRYPTO_SUCCESS) {
8915 len = value_len;
8919 * The length of attributes are in bytes.
8920 * Convert to bits now since that's how keys are measured.
8922 len = CRYPTO_BYTES2BITS(len);
8924 ret_key->ck_data = value;
8925 ret_key->ck_length = (uint_t)len;
8926 bail:
8927 break;
8930 default:
8931 ret = CRYPTO_ARGUMENTS_BAD;
8932 break;
8935 return (ret);
8939 * Get the attribute list for the specified asymmetric key.
8941 static int
8942 dprov_key_attr_asymmetric(dprov_state_t *softc, crypto_session_id_t session_id,
8943 dprov_req_type_t req_type, crypto_key_t *key, crypto_key_t *ret_key)
8945 int ret = CRYPTO_SUCCESS;
8947 ret_key->ck_format = CRYPTO_KEY_ATTR_LIST;
8949 switch (key->ck_format) {
8951 case CRYPTO_KEY_ATTR_LIST:
8952 ret_key->ck_attrs = key->ck_attrs;
8953 ret_key->ck_count = key->ck_count;
8954 break;
8956 case CRYPTO_KEY_REFERENCE: {
8957 dprov_object_t *object;
8959 /* check session id */
8960 if (softc->ds_sessions[session_id] == NULL) {
8961 ret = CRYPTO_SESSION_HANDLE_INVALID;
8962 break;
8965 /* check if object id specified by key is valid */
8966 object = softc->ds_sessions[session_id]->
8967 ds_objects[key->ck_obj_id];
8968 if (object == NULL) {
8969 ret = CRYPTO_KEY_HANDLE_INVALID;
8970 break;
8973 /* check if object can be used for operation */
8974 if ((ret = dprov_key_can_use(object, req_type)) !=
8975 CRYPTO_SUCCESS)
8976 break;
8978 ret_key->ck_attrs = object->do_attr;
8979 ret_key->ck_count = DPROV_MAX_ATTR;
8980 break;
8983 default:
8984 ret = CRYPTO_ARGUMENTS_BAD;
8987 return (ret);
8991 * Return the index of an attribute of specified type found in
8992 * the specified array of attributes. If the attribute cannot
8993 * found, return -1.
8995 static int
8996 dprov_find_attr(crypto_object_attribute_t *attr, uint_t nattr,
8997 uint64_t attr_type)
8999 int i;
9001 for (i = 0; i < nattr; i++)
9002 if (attr[i].oa_value != NULL &&
9003 attr[i].oa_type == attr_type)
9004 return (i);
9006 return (-1);
9010 * Given the given object template and session, return whether
9011 * an object can be created from that template according to the
9012 * following rules:
9013 * - private objects can be created only by a logged-in user
9015 static int
9016 dprov_template_can_create(dprov_session_t *session,
9017 crypto_object_attribute_t *template, uint_t nattr,
9018 boolean_t check_for_secret)
9020 boolean_t is_private = B_FALSE;
9021 ulong_t key_type, class;
9022 int error;
9024 /* check CKA_PRIVATE attribute value */
9025 error = dprov_get_template_attr_boolean(template, nattr,
9026 DPROV_CKA_PRIVATE, &is_private);
9027 if (error == CRYPTO_SUCCESS && is_private) {
9028 /* it's a private object */
9029 if (session->ds_state != DPROV_SESSION_STATE_USER) {
9031 * Cannot create private object with SO or public
9032 * sessions.
9034 return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
9038 /* all objects must have an object class attribute */
9039 if (dprov_get_template_attr_ulong(template, nattr, DPROV_CKA_CLASS,
9040 &class) != CRYPTO_SUCCESS) {
9041 return (CRYPTO_TEMPLATE_INCOMPLETE);
9044 /* key objects must have a key type attribute */
9045 if (class == DPROV_CKO_SECRET_KEY ||
9046 class == DPROV_CKO_PUBLIC_KEY ||
9047 class == DPROV_CKO_PRIVATE_KEY) {
9048 if (!dprov_template_attr_present(template, nattr,
9049 DPROV_CKA_KEY_TYPE)) {
9050 return (CRYPTO_TEMPLATE_INCOMPLETE);
9054 /* check for RSA public key attributes that must be present */
9055 if (class == DPROV_CKO_PUBLIC_KEY) {
9056 if (dprov_get_template_attr_ulong(template, nattr,
9057 DPROV_CKA_KEY_TYPE, &key_type) == CRYPTO_SUCCESS) {
9058 if (key_type == DPROV_CKK_RSA) {
9059 if (!dprov_template_attr_present(template,
9060 nattr, DPROV_CKA_MODULUS) ||
9061 !dprov_template_attr_present(template,
9062 nattr, DPROV_CKA_PUBLIC_EXPONENT)) {
9063 return (CRYPTO_TEMPLATE_INCOMPLETE);
9066 /* these attributes should not be present */
9067 if (dprov_template_attr_present(template, nattr,
9068 DPROV_CKA_MODULUS_BITS)) {
9069 return (CRYPTO_TEMPLATE_INCONSISTENT);
9075 /* check for RSA private key attributes that must be present */
9076 if (class == DPROV_CKO_PRIVATE_KEY) {
9077 if (dprov_get_template_attr_ulong(template, nattr,
9078 DPROV_CKA_KEY_TYPE, &key_type) == CRYPTO_SUCCESS) {
9079 if (key_type == DPROV_CKK_RSA) {
9080 if (!dprov_template_attr_present(template,
9081 nattr, DPROV_CKA_MODULUS))
9082 return (CRYPTO_TEMPLATE_INCOMPLETE);
9084 if (check_for_secret) {
9085 if (!dprov_template_attr_present(
9086 template, nattr,
9087 DPROV_CKA_PRIVATE_EXPONENT))
9088 return (
9089 CRYPTO_TEMPLATE_INCOMPLETE);
9095 /* check for secret key attributes that must be present */
9096 if (class == DPROV_CKO_SECRET_KEY) {
9097 if (check_for_secret) {
9098 if (!dprov_template_attr_present(template, nattr,
9099 DPROV_CKA_VALUE)) {
9100 return (CRYPTO_TEMPLATE_INCOMPLETE);
9104 /* these attributes should not be present */
9105 if (dprov_template_attr_present(template, nattr,
9106 DPROV_CKA_VALUE_LEN)) {
9107 return (CRYPTO_TEMPLATE_INCONSISTENT);
9111 return (CRYPTO_SUCCESS);
9115 * Create an object from the specified template. Checks whether the
9116 * object can be created according to its attributes and the state
9117 * of the session. The new session object id is returned. If the
9118 * object is a token object, it is added to the per-instance object
9119 * table as well.
9121 static int
9122 dprov_create_object_from_template(dprov_state_t *softc,
9123 dprov_session_t *session, crypto_object_attribute_t *template,
9124 uint_t nattr, crypto_object_id_t *object_id, boolean_t check_for_secret,
9125 boolean_t force)
9127 dprov_object_t *object;
9128 boolean_t is_token = B_FALSE;
9129 boolean_t extractable_attribute_present = B_FALSE;
9130 boolean_t sensitive_attribute_present = B_FALSE;
9131 boolean_t private_attribute_present = B_FALSE;
9132 boolean_t token_attribute_present = B_FALSE;
9133 uint_t i;
9134 int error;
9135 uint_t attr;
9136 uint_t oattr;
9137 crypto_attr_type_t type;
9138 size_t old_len, new_len;
9139 offset_t offset;
9141 if (nattr > DPROV_MAX_ATTR)
9142 return (CRYPTO_HOST_MEMORY);
9144 if (!force) {
9145 /* verify that object can be created */
9146 if ((error = dprov_template_can_create(session, template,
9147 nattr, check_for_secret)) != CRYPTO_SUCCESS)
9148 return (error);
9151 /* allocate new object */
9152 object = kmem_zalloc(sizeof (dprov_object_t), KM_SLEEP);
9153 if (object == NULL)
9154 return (CRYPTO_HOST_MEMORY);
9156 /* is it a token object? */
9157 /* check CKA_TOKEN attribute value */
9158 error = dprov_get_template_attr_boolean(template, nattr,
9159 DPROV_CKA_TOKEN, &is_token);
9160 if (error == CRYPTO_SUCCESS && is_token) {
9161 /* token object, add it to the per-instance object table */
9162 for (i = 0; i < DPROV_MAX_OBJECTS; i++)
9163 if (softc->ds_objects[i] == NULL)
9164 break;
9165 if (i == DPROV_MAX_OBJECTS)
9166 /* no free slot */
9167 return (CRYPTO_HOST_MEMORY);
9168 softc->ds_objects[i] = object;
9169 object->do_token_idx = i;
9170 DPROV_OBJECT_REFHOLD(object);
9173 /* add object to session object table */
9174 for (i = 0; i < DPROV_MAX_OBJECTS; i++)
9175 if (session->ds_objects[i] == NULL)
9176 break;
9177 if (i == DPROV_MAX_OBJECTS) {
9178 /* no more session object slots */
9179 DPROV_OBJECT_REFRELE(object);
9180 return (CRYPTO_HOST_MEMORY);
9182 session->ds_objects[i] = object;
9183 DPROV_OBJECT_REFHOLD(object);
9184 *object_id = i;
9186 /* initialize object from template */
9187 for (attr = 0, oattr = 0; attr < nattr; attr++) {
9188 if (template[attr].oa_value == NULL)
9189 continue;
9190 type = template[attr].oa_type;
9191 old_len = template[attr].oa_value_len;
9192 new_len = attribute_size(type, old_len);
9194 if (type == DPROV_CKA_EXTRACTABLE) {
9195 extractable_attribute_present = B_TRUE;
9196 } else if (type == DPROV_CKA_PRIVATE) {
9197 private_attribute_present = B_TRUE;
9198 } else if (type == DPROV_CKA_TOKEN) {
9199 token_attribute_present = B_TRUE;
9201 object->do_attr[oattr].oa_type = type;
9202 object->do_attr[oattr].oa_value_len = new_len;
9204 object->do_attr[oattr].oa_value = kmem_zalloc(new_len,
9205 KM_SLEEP);
9207 offset = 0;
9208 #ifdef _BIG_ENDIAN
9209 if (fixed_size_attribute(type)) {
9210 offset = old_len - new_len;
9212 #endif
9213 bcopy(&template[attr].oa_value[offset],
9214 object->do_attr[oattr].oa_value, new_len);
9215 oattr++;
9218 /* add boolean attributes that must be present */
9219 if (extractable_attribute_present == B_FALSE) {
9220 object->do_attr[oattr].oa_type = DPROV_CKA_EXTRACTABLE;
9221 object->do_attr[oattr].oa_value_len = 1;
9222 object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP);
9223 object->do_attr[oattr].oa_value[0] = B_TRUE;
9224 oattr++;
9227 if (private_attribute_present == B_FALSE) {
9228 object->do_attr[oattr].oa_type = DPROV_CKA_PRIVATE;
9229 object->do_attr[oattr].oa_value_len = 1;
9230 object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP);
9231 object->do_attr[oattr].oa_value[0] = B_FALSE;
9232 oattr++;
9235 if (token_attribute_present == B_FALSE) {
9236 object->do_attr[oattr].oa_type = DPROV_CKA_TOKEN;
9237 object->do_attr[oattr].oa_value_len = 1;
9238 object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP);
9239 object->do_attr[oattr].oa_value[0] = B_FALSE;
9240 oattr++;
9243 if (sensitive_attribute_present == B_FALSE) {
9244 object->do_attr[oattr].oa_type = DPROV_CKA_SENSITIVE;
9245 object->do_attr[oattr].oa_value_len = 1;
9246 object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP);
9247 object->do_attr[oattr].oa_value[0] = B_FALSE;
9248 oattr++;
9250 return (CRYPTO_SUCCESS);
9254 * Checks whether or not the object matches the specified attributes.
9256 * PKCS#11 attributes which are longs are stored in uint32_t containers
9257 * so they can be matched by both 32 and 64-bit applications.
9259 static boolean_t
9260 dprov_attributes_match(dprov_object_t *object,
9261 crypto_object_attribute_t *template, uint_t nattr)
9263 crypto_attr_type_t type;
9264 size_t tlen, olen, diff;
9265 int ta_idx; /* template attribute index */
9266 int oa_idx; /* object attribute index */
9268 for (ta_idx = 0; ta_idx < nattr; ta_idx++) {
9269 /* no value for template attribute */
9270 if (template[ta_idx].oa_value == NULL)
9271 continue;
9273 /* find attribute in object */
9274 type = template[ta_idx].oa_type;
9275 oa_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR, type);
9277 if (oa_idx == -1)
9278 /* attribute not found in object */
9279 return (B_FALSE);
9281 tlen = template[ta_idx].oa_value_len;
9282 olen = object->do_attr[oa_idx].oa_value_len;
9283 if (tlen < olen)
9284 return (B_FALSE);
9286 diff = 0;
9287 #ifdef _BIG_ENDIAN
9288 /* application may think attribute is 8 bytes */
9289 if (fixed_size_attribute(type))
9290 diff = tlen - olen;
9291 #endif
9293 if (bcmp(&template[ta_idx].oa_value[diff],
9294 object->do_attr[oa_idx].oa_value, olen) != 0)
9295 /* value mismatch */
9296 return (B_FALSE);
9299 return (B_TRUE);
9303 * Destroy the object specified by its session and object id.
9305 static int
9306 dprov_destroy_object(dprov_state_t *softc, dprov_session_t *session,
9307 crypto_object_id_t object_id)
9309 dprov_object_t *object;
9311 if ((object = session->ds_objects[object_id]) == NULL)
9312 return (CRYPTO_OBJECT_HANDLE_INVALID);
9314 /* remove from session table */
9315 session->ds_objects[object_id] = NULL;
9317 if (dprov_object_is_token(object)) {
9318 if (!object->do_destroyed) {
9319 object->do_destroyed = B_TRUE;
9320 /* remove from per-instance token table */
9321 softc->ds_objects[object->do_token_idx] = NULL;
9322 DPROV_OBJECT_REFRELE(object);
9323 } else {
9324 DPROV_DEBUG(D_OBJECT, ("dprov_destroy_object: "
9325 "object %p already destroyed\n", (void *)object));
9329 DPROV_OBJECT_REFRELE(object);
9330 return (CRYPTO_SUCCESS);
9333 static int
9334 dprov_object_can_modify(dprov_object_t *object,
9335 crypto_object_attribute_t *template, uint_t nattr)
9337 ulong_t object_class;
9339 /* all objects should have an object class attribute */
9340 if (dprov_get_object_attr_ulong(object, DPROV_CKA_CLASS,
9341 &object_class) != CRYPTO_SUCCESS) {
9342 return (CRYPTO_SUCCESS);
9345 if (object_class == DPROV_CKO_SECRET_KEY ||
9346 object_class == DPROV_CKO_PUBLIC_KEY ||
9347 object_class == DPROV_CKO_PRIVATE_KEY) {
9348 if (dprov_template_attr_present(template, nattr,
9349 DPROV_CKA_CLASS) ||
9350 dprov_template_attr_present(template, nattr,
9351 DPROV_CKA_KEY_TYPE))
9352 return (CRYPTO_TEMPLATE_INCONSISTENT);
9355 switch (object_class) {
9356 case DPROV_CKO_SECRET_KEY:
9357 if (dprov_template_attr_present(template, nattr,
9358 DPROV_CKA_VALUE))
9359 return (CRYPTO_TEMPLATE_INCONSISTENT);
9360 break;
9362 case DPROV_CKO_PUBLIC_KEY:
9363 if (dprov_template_attr_present(template, nattr,
9364 DPROV_CKA_MODULUS) ||
9365 dprov_template_attr_present(template, nattr,
9366 DPROV_CKA_PUBLIC_EXPONENT))
9367 return (CRYPTO_TEMPLATE_INCONSISTENT);
9368 break;
9370 case DPROV_CKO_PRIVATE_KEY:
9371 if (dprov_template_attr_present(template, nattr,
9372 DPROV_CKA_MODULUS) ||
9373 dprov_template_attr_present(template, nattr,
9374 DPROV_CKA_PRIVATE_EXPONENT))
9375 return (CRYPTO_TEMPLATE_INCONSISTENT);
9376 break;
9378 default:
9379 return (CRYPTO_SUCCESS);
9382 return (CRYPTO_SUCCESS);
9386 * Set the attributes specified by the template in the specified object,
9387 * replacing existing ones if needed.
9389 static int
9390 dprov_object_set_attr(dprov_session_t *session, crypto_object_id_t object_id,
9391 crypto_object_attribute_t *template, uint_t nattr,
9392 boolean_t check_attributes)
9394 crypto_attr_type_t type;
9395 dprov_object_t *object;
9396 size_t old_len, new_len;
9397 uint_t i, j;
9398 int error;
9400 if ((object = session->ds_objects[object_id]) == NULL)
9401 return (CRYPTO_OBJECT_HANDLE_INVALID);
9403 if (check_attributes) {
9404 /* verify that attributes in the template can be modified */
9405 if ((error = dprov_object_can_modify(object, template, nattr))
9406 != CRYPTO_SUCCESS)
9407 return (error);
9410 /* go through the attributes specified in the template */
9411 for (i = 0; i < nattr; i++) {
9412 if (template[i].oa_value == NULL)
9413 continue;
9415 /* find attribute in object */
9416 type = template[i].oa_type;
9417 j = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR, type);
9419 if (j != -1) {
9420 /* attribute already exists, free old value */
9421 kmem_free(object->do_attr[j].oa_value,
9422 object->do_attr[j].oa_value_len);
9423 } else {
9424 /* attribute does not exist, create it */
9425 for (j = 0; j < DPROV_MAX_ATTR; j++)
9426 if (object->do_attr[j].oa_value == NULL)
9427 break;
9428 if (j == DPROV_MAX_ATTR)
9429 /* ran out of attribute slots */
9430 return (CRYPTO_HOST_MEMORY);
9433 old_len = template[i].oa_value_len;
9434 new_len = attribute_size(type, old_len);
9436 /* set object attribute value */
9437 object->do_attr[j].oa_value = kmem_alloc(new_len, KM_SLEEP);
9438 bcopy(&template[i].oa_value[old_len - new_len],
9439 object->do_attr[j].oa_value, new_len);
9440 object->do_attr[j].oa_value_len = new_len;
9442 /* and the type */
9443 object->do_attr[j].oa_type = type;
9446 return (CRYPTO_SUCCESS);
9451 * Free the specified object.
9453 static void
9454 dprov_free_object(dprov_object_t *object)
9456 int i;
9458 /* free the object attributes values */
9459 for (i = 0; i < DPROV_MAX_ATTR; i++)
9460 if (object->do_attr[i].oa_value != NULL)
9461 kmem_free(object->do_attr[i].oa_value,
9462 object->do_attr[i].oa_value_len);
9464 /* free the object */
9465 kmem_free(object, sizeof (dprov_object_t));
9469 * Checks whether the specified object is a private or public object.
9471 static boolean_t
9472 dprov_object_is_private(dprov_object_t *object)
9474 boolean_t ret;
9475 int err;
9477 err = dprov_get_object_attr_boolean(object, DPROV_CKA_PRIVATE, &ret);
9479 if (err != CRYPTO_SUCCESS)
9480 /* by default, CKA_PRIVATE is false */
9481 ret = B_FALSE;
9483 return (ret);
9487 * Checks whether the specified object is a token or session object.
9489 static boolean_t
9490 dprov_object_is_token(dprov_object_t *object)
9492 boolean_t ret;
9493 int err;
9495 err = dprov_get_object_attr_boolean(object, DPROV_CKA_TOKEN, &ret);
9497 if (err != CRYPTO_SUCCESS)
9498 /* by default, CKA_TOKEN is false */
9499 ret = B_FALSE;
9501 return (ret);
9505 * Common function used by the dprov_get_object_attr_*() family of
9506 * functions. Returns the value of the specified attribute of specified
9507 * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID
9508 * if the length of the attribute does not match the specified length,
9509 * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found.
9511 static int
9512 dprov_get_object_attr_scalar_common(dprov_object_t *object, uint64_t attr_type,
9513 void *value, size_t value_len)
9515 int attr_idx;
9516 size_t oa_value_len;
9517 size_t offset = 0;
9519 if ((attr_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR,
9520 attr_type)) == -1)
9521 return (CRYPTO_ARGUMENTS_BAD);
9523 oa_value_len = object->do_attr[attr_idx].oa_value_len;
9524 if (oa_value_len != value_len) {
9526 * For some attributes, it's okay to copy the value
9527 * into a larger container, e.g. copy an unsigned
9528 * 32-bit integer into a 64-bit container.
9530 if (attr_type == DPROV_CKA_VALUE_LEN ||
9531 attr_type == DPROV_CKA_KEY_TYPE ||
9532 attr_type == DPROV_CKA_CLASS) {
9533 if (oa_value_len < value_len) {
9534 #ifdef _BIG_ENDIAN
9535 offset = value_len - oa_value_len;
9536 #endif
9537 bzero(value, value_len);
9538 goto do_copy;
9541 /* incorrect attribute value length */
9542 return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
9545 do_copy:
9546 bcopy(object->do_attr[attr_idx].oa_value, (uchar_t *)value + offset,
9547 oa_value_len);
9549 return (CRYPTO_SUCCESS);
9553 * Get the value of the a boolean attribute from the specified object.
9555 static int
9556 dprov_get_object_attr_boolean(dprov_object_t *object, uint64_t attr_type,
9557 boolean_t *attr_value)
9559 uchar_t val;
9560 int ret;
9562 /* PKCS#11 defines a boolean as one byte */
9563 ret = dprov_get_object_attr_scalar_common(object, attr_type, &val, 1);
9564 if (ret == CRYPTO_SUCCESS) {
9565 *attr_value = (val == '\0') ? B_FALSE : B_TRUE;
9567 return (ret);
9571 * Get the value of a ulong_t attribute from the specified object.
9573 static int
9574 dprov_get_object_attr_ulong(dprov_object_t *object, uint64_t attr_type,
9575 ulong_t *attr_value)
9577 return (dprov_get_object_attr_scalar_common(object, attr_type,
9578 attr_value, sizeof (ulong_t)));
9582 * Find the specified byte array attribute of specified type in
9583 * the specified object. Returns CRYPTO_SUCCESS
9584 * on success or CRYPTO_ARGUMENTS_BAD if the specified
9585 * attribute cannot be found.
9587 static int
9588 dprov_get_object_attr_array(dprov_object_t *object, uint64_t attr_type,
9589 void **array, size_t *len)
9591 int attr_idx;
9593 if ((attr_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR,
9594 attr_type)) == -1)
9595 return (CRYPTO_ARGUMENTS_BAD);
9597 *array = object->do_attr[attr_idx].oa_value;
9598 *len = object->do_attr[attr_idx].oa_value_len;
9600 return (CRYPTO_SUCCESS);
9604 * Common function used by the dprov_get_template_attr_*() family of
9605 * functions. Returns the value of the specified attribute of specified
9606 * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID
9607 * if the length of the attribute does not match the specified length,
9608 * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found.
9610 static int
9611 dprov_get_template_attr_scalar_common(crypto_object_attribute_t *template,
9612 uint_t nattr, uint64_t attr_type, void *value, size_t value_len)
9614 size_t oa_value_len;
9615 size_t offset = 0;
9616 int attr_idx;
9618 if ((attr_idx = dprov_find_attr(template, nattr, attr_type)) == -1)
9619 return (CRYPTO_ARGUMENTS_BAD);
9621 oa_value_len = template[attr_idx].oa_value_len;
9622 if (oa_value_len != value_len) {
9624 * For some attributes, it's okay to copy the value
9625 * into a larger container, e.g. copy an unsigned
9626 * 32-bit integer into a 64-bit container.
9628 if (attr_type == DPROV_CKA_VALUE_LEN ||
9629 attr_type == DPROV_CKA_KEY_TYPE ||
9630 attr_type == DPROV_CKA_CLASS) {
9631 if (oa_value_len < value_len) {
9632 #ifdef _BIG_ENDIAN
9633 offset = value_len - oa_value_len;
9634 #endif
9635 bzero(value, value_len);
9636 goto do_copy;
9639 /* incorrect attribute value length */
9640 return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
9643 do_copy:
9644 bcopy(template[attr_idx].oa_value, (uchar_t *)value + offset,
9645 oa_value_len);
9647 return (CRYPTO_SUCCESS);
9651 * Get the value of the a boolean attribute from the specified template
9653 static int
9654 dprov_get_template_attr_boolean(crypto_object_attribute_t *template,
9655 uint_t nattr, uint64_t attr_type, boolean_t *attr_value)
9657 uchar_t val;
9658 int ret;
9660 /* PKCS#11 defines a boolean as one byte */
9661 ret = dprov_get_template_attr_scalar_common(template, nattr,
9662 attr_type, &val, 1);
9663 if (ret == CRYPTO_SUCCESS) {
9664 *attr_value = (val == '\0') ? B_FALSE : B_TRUE;
9666 return (ret);
9670 * Get the value of a ulong_t attribute from the specified template.
9672 static int
9673 dprov_get_template_attr_ulong(crypto_object_attribute_t *template,
9674 uint_t nattr, uint64_t attr_type, ulong_t *attr_value)
9676 return (dprov_get_template_attr_scalar_common(template, nattr,
9677 attr_type, attr_value, sizeof (ulong_t)));
9680 static int
9681 dprov_template_attr_present(crypto_object_attribute_t *template,
9682 uint_t nattr, uint64_t attr_type)
9684 return (dprov_find_attr(template, nattr,
9685 attr_type) == -1 ? B_FALSE : B_TRUE);
9689 * Find the specified byte array attribute of specified type in
9690 * the specified template. Returns CRYPTO_SUCCESS on success or
9691 * CRYPTO_ARGUMENTS_BAD if the specified attribute cannot be found.
9693 static int
9694 dprov_get_template_attr_array(crypto_object_attribute_t *template,
9695 uint_t nattr, uint64_t attr_type, void **array, size_t *len)
9697 int attr_idx;
9699 if ((attr_idx = dprov_find_attr(template, nattr, attr_type)) == -1)
9700 return (CRYPTO_ARGUMENTS_BAD);
9702 *array = template[attr_idx].oa_value;
9703 *len = template[attr_idx].oa_value_len;
9705 return (CRYPTO_SUCCESS);
9709 * Common function used by the dprov_get_key_attr_*() family of
9710 * functions. Returns the value of the specified attribute of specified
9711 * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID
9712 * if the length of the attribute does not match the specified length,
9713 * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found.
9715 static int
9716 dprov_get_key_attr_scalar_common(crypto_key_t *key, uint64_t attr_type,
9717 void *value, size_t value_len)
9719 int attr_idx;
9721 ASSERT(key->ck_format == CRYPTO_KEY_ATTR_LIST);
9723 if ((attr_idx = dprov_find_attr(key->ck_attrs, key->ck_count,
9724 attr_type)) == -1)
9725 return (CRYPTO_ARGUMENTS_BAD);
9727 if (key->ck_attrs[attr_idx].oa_value_len != value_len)
9728 /* incorrect attribute value length */
9729 return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
9731 bcopy(key->ck_attrs[attr_idx].oa_value, value, value_len);
9733 return (CRYPTO_SUCCESS);
9737 * Get the value of a ulong_t attribute from the specified key.
9739 static int
9740 dprov_get_key_attr_ulong(crypto_key_t *key, uint64_t attr_type,
9741 ulong_t *attr_value)
9743 return (dprov_get_key_attr_scalar_common(key, attr_type,
9744 attr_value, sizeof (ulong_t)));
9748 * Find the specified byte array attribute of specified type in
9749 * the specified key by attributes. Returns CRYPTO_SUCCESS
9750 * on success or CRYPTO_ARGUMENTS_BAD if the specified
9751 * attribute cannot be found.
9753 static int
9754 dprov_get_key_attr_array(crypto_key_t *key, uint64_t attr_type,
9755 void **array, size_t *len)
9757 int attr_idx;
9759 ASSERT(key->ck_format == CRYPTO_KEY_ATTR_LIST);
9761 if ((attr_idx = dprov_find_attr(key->ck_attrs, key->ck_count,
9762 attr_type)) == -1)
9763 return (CRYPTO_ARGUMENTS_BAD);
9765 *array = key->ck_attrs[attr_idx].oa_value;
9766 *len = key->ck_attrs[attr_idx].oa_value_len;
9768 return (CRYPTO_SUCCESS);
9771 static void
9772 dprov_release_session_objects(dprov_session_t *session)
9774 dprov_object_t *object;
9775 int i;
9777 for (i = 0; i < DPROV_MAX_OBJECTS; i++) {
9778 object = session->ds_objects[i];
9779 if (object != NULL) {
9780 DPROV_OBJECT_REFRELE(object);
9786 * Adjust an attribute list by turning 32-bit values into 64-bit values
9787 * for certain attributes like CKA_CLASS. Assumes that at least 8 bytes
9788 * of storage have been allocated for all attributes.
9790 static void
9791 dprov_adjust_attrs(crypto_object_attribute_t *in, int in_count)
9793 int i;
9794 size_t offset = 0;
9795 ulong_t tmp = 0;
9797 for (i = 0; i < in_count; i++) {
9799 * For some attributes, it's okay to copy the value
9800 * into a larger container, e.g. copy an unsigned
9801 * 32-bit integer into a 64-bit container.
9803 if (in[i].oa_type == CKA_VALUE_LEN ||
9804 in[i].oa_type == CKA_KEY_TYPE ||
9805 in[i].oa_type == CKA_CLASS) {
9806 if (in[i].oa_value_len < sizeof (ulong_t)) {
9807 #ifdef _BIG_ENDIAN
9808 offset = sizeof (ulong_t) - in[i].oa_value_len;
9809 #endif
9810 bcopy(in[i].oa_value, (uchar_t *)&tmp + offset,
9811 in[i].oa_value_len);
9812 bcopy(&tmp, in[i].oa_value, sizeof (ulong_t));
9813 in[i].oa_value_len = sizeof (ulong_t);