Merge illumos-gate
[unleashed/lotheac.git] / usr / src / uts / common / crypto / io / dprov.c
blob10f57b332185ef99f73057b6c13217e5570f1d86
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.
25 * Copyright 2018, Joyent, Inc.
30 * Dummy Cryptographic Provider:
32 * This file implements a "dummy" cryptographic provider. It is implemented
33 * as a pseudo device driver.
38 * This driver implements a KEF provider with the following capabilities:
40 * - registration/unregistration with KEF
41 * - digest entry points
42 * - mac entry points
43 * - ctx management
44 * - support for async requests
45 * - cipher entry points
46 * - dual entry points
47 * - sign entry points
48 * - verify entry points
49 * - dual operations entry points
50 * - dual cipher/mac operation entry points
51 * - session management
52 * - object management
53 * - key management
54 * - provider management
56 * In order to avoid duplicating the implementation of algorithms
57 * provided by software providers, this pseudo driver acts as
58 * a consumer of the framework. When invoking one of the framework's
59 * entry points, the driver specifies the software provider to
60 * be used for the operation.
62 * User management: we implement a PKCS#11 style provider which supports:
63 * - one normal user with a PIN, and
64 * - one SO user with a PIN.
65 * These values are kept in the per-instance structure, and are initialized
66 * with the provider management entry points.
71 #include <sys/types.h>
72 #include <sys/modctl.h>
73 #include <sys/conf.h>
74 #include <sys/stat.h>
75 #include <sys/ddi.h>
76 #include <sys/sunddi.h>
77 #include <sys/kmem.h>
78 #include <sys/errno.h>
79 #include <sys/ksynch.h>
80 #include <sys/file.h>
81 #include <sys/open.h>
82 #include <sys/cred.h>
83 #include <sys/model.h>
84 #include <sys/note.h>
85 #include <sys/random.h>
86 #include <sys/byteorder.h>
87 #include <sys/crypto/common.h>
88 #include <sys/crypto/spi.h>
90 #include <sys/taskq.h>
91 #include <sys/disp.h>
92 #include <sys/sysmacros.h>
93 #include <sys/crypto/impl.h>
94 #include <sys/crypto/sched_impl.h>
96 #include <sys/sha2.h>
97 #include <modes/modes.h>
98 #include <aes/aes_impl.h>
99 #include <des/des_impl.h>
100 #include <ecc/ecc_impl.h>
101 #include <blowfish/blowfish_impl.h>
104 * Debugging macros.
106 #ifdef DEBUG
107 #define D_INIT 0x00000001 /* _init/_fini/_info */
108 #define D_ATTACH 0x00000002 /* attach/detach */
109 #define D_DIGEST 0x00000010 /* digest entry points */
110 #define D_MAC 0x00000020 /* mac entry points */
111 #define D_CONTEXT 0x00000040 /* context entry points */
112 #define D_CIPHER 0x00000080 /* cipher entry points */
113 #define D_SIGN 0x00000100 /* sign entry points */
114 #define D_VERIFY 0x00000200 /* verify entry points */
115 #define D_SESSION 0x00000400 /* session management entry points */
116 #define D_MGMT 0x00000800 /* provider management entry points */
117 #define D_DUAL 0x00001000 /* dual ops */
118 #define D_CIPHER_MAC 0x00002000 /* cipher/mac dual ops */
119 #define D_OBJECT 0x00004000 /* object management */
120 #define D_RANDOM 0x00008000 /* random number generation */
121 #define D_KEY 0x00010000 /* key management */
123 static uint32_t dprov_debug = 0;
125 #define DPROV_DEBUG(f, x) if (dprov_debug & (f)) { (void) printf x; }
126 #define DPROV_CALL(f, r, x) if (dprov_debug & (f)) { (void) r x; }
127 #else /* DEBUG */
128 #define DPROV_DEBUG(f, x)
129 #define DPROV_CALL(f, r, x)
130 #endif /* DEBUG */
132 static int nostore_key_gen;
133 static boolean_t dprov_no_multipart = B_FALSE;
134 static int dprov_max_digestsz = INT_MAX;
137 * DDI entry points.
139 static int dprov_attach(dev_info_t *, ddi_attach_cmd_t);
140 static int dprov_detach(dev_info_t *, ddi_detach_cmd_t);
141 static int dprov_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
144 * Module linkage.
146 static struct cb_ops cbops = {
147 nodev, /* cb_open */
148 nodev, /* cb_close */
149 nodev, /* cb_strategy */
150 nodev, /* cb_print */
151 nodev, /* cb_dump */
152 nodev, /* cb_read */
153 nodev, /* cb_write */
154 nodev, /* cb_ioctl */
155 nodev, /* cb_devmap */
156 nodev, /* cb_mmap */
157 nodev, /* cb_segmap */
158 nochpoll, /* cb_chpoll */
159 ddi_prop_op, /* cb_prop_op */
160 NULL, /* cb_streamtab */
161 D_MP, /* cb_flag */
162 CB_REV, /* cb_rev */
163 nodev, /* cb_aread */
164 nodev, /* cb_awrite */
167 static struct dev_ops devops = {
168 DEVO_REV, /* devo_rev */
169 0, /* devo_refcnt */
170 dprov_getinfo, /* devo_getinfo */
171 nulldev, /* devo_identify */
172 nulldev, /* devo_probe */
173 dprov_attach, /* devo_attach */
174 dprov_detach, /* devo_detach */
175 nodev, /* devo_reset */
176 &cbops, /* devo_cb_ops */
177 NULL, /* devo_bus_ops */
178 NULL, /* devo_power */
179 ddi_quiesce_not_needed, /* devo_quiesce */
182 static struct modldrv modldrv = {
183 &mod_driverops,
184 "Pseudo KCF Prov (drv)",
185 &devops
188 static struct modlcrypto modlcrypto = {
189 &mod_cryptoops,
190 "Pseudo KCF Prov (crypto)"
193 static struct modlinkage modlinkage = {
194 MODREV_1,
195 &modldrv,
196 &modlcrypto,
197 NULL
201 * CSPI information (entry points, provider info, etc.)
204 typedef enum dprov_mech_type {
205 MD4_MECH_INFO_TYPE, /* SUN_CKM_MD4 */
207 MD5_MECH_INFO_TYPE, /* SUN_CKM_MD5 */
208 MD5_HMAC_MECH_INFO_TYPE, /* SUN_CKM_MD5_HMAC */
209 MD5_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_MD5_HMAC_GENERAL */
211 SHA1_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA1_HMAC */
212 SHA1_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA1_HMAC_GENERAL */
213 SHA1_MECH_INFO_TYPE, /* SUN_CKM_SHA1 */
215 SHA256_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA256_HMAC */
216 SHA256_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA256_HMAC_GENERAL */
217 SHA256_MECH_INFO_TYPE, /* SUN_CKM_SHA256 */
218 SHA384_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA384_HMAC */
219 SHA384_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA384_HMAC_GENERAL */
220 SHA384_MECH_INFO_TYPE, /* SUN_CKM_SHA384 */
221 SHA512_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA512_HMAC */
222 SHA512_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA512_HMAC_GENERAL */
223 SHA512_MECH_INFO_TYPE, /* SUN_CKM_SHA512 */
225 DES_CBC_MECH_INFO_TYPE, /* SUN_CKM_DES_CBC */
226 DES3_CBC_MECH_INFO_TYPE, /* SUN_CKM_DES3_CBC */
227 DES_ECB_MECH_INFO_TYPE, /* SUN_CKM_DES_ECB */
228 DES3_ECB_MECH_INFO_TYPE, /* SUN_CKM_DES3_ECB */
230 BLOWFISH_CBC_MECH_INFO_TYPE, /* SUN_CKM_BLOWFISH_CBC */
231 BLOWFISH_ECB_MECH_INFO_TYPE, /* SUN_CKM_BLOWFISH_ECB */
232 AES_CBC_MECH_INFO_TYPE, /* SUN_CKM_AES_CBC */
233 AES_CMAC_MECH_INFO_TYPE, /* SUN_CKM_AES_CMAC */
234 AES_ECB_MECH_INFO_TYPE, /* SUN_CKM_AES_ECB */
235 AES_CTR_MECH_INFO_TYPE, /* SUN_CKM_AES_CTR */
236 AES_CCM_MECH_INFO_TYPE, /* SUN_CKM_AES_CCM */
237 AES_GCM_MECH_INFO_TYPE, /* SUN_CKM_AES_GCM */
238 AES_GMAC_MECH_INFO_TYPE, /* SUN_CKM_AES_GMAC */
239 RC4_MECH_INFO_TYPE, /* SUN_CKM_RC4 */
240 RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_RSA_PKCS */
241 RSA_X_509_MECH_INFO_TYPE, /* SUN_CKM_RSA_X_509 */
242 MD5_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_MD5_RSA_PKCS */
243 SHA1_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_SHA1_RSA_PKCS */
244 SHA256_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_SHA256_RSA_PKCS */
245 SHA384_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_SHA384_RSA_PKCS */
246 SHA512_RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_SHA512_RSA_PKCS */
247 MD5_KEY_DERIVATION_MECH_INFO_TYPE, /* SUN_CKM_MD5_KEY_DERIVATION */
248 SHA1_KEY_DERIVATION_MECH_INFO_TYPE, /* SUN_CKM_SHA1_KEY_DERIVATION */
249 /* SUN_CKM_SHA256_KEY_DERIVATION */
250 SHA256_KEY_DERIVATION_MECH_INFO_TYPE,
251 /* SUN_CKM_SHA384_KEY_DERIVATION */
252 SHA384_KEY_DERIVATION_MECH_INFO_TYPE,
253 /* SUN_CKM_SHA512_KEY_DERIVATION */
254 SHA512_KEY_DERIVATION_MECH_INFO_TYPE,
255 DES_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_DES_KEY_GEN */
256 DES3_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_DES3_KEY_GEN */
257 AES_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_AES_KEY_GEN */
258 BLOWFISH_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_BLOWFISH_KEY_GEN */
259 RC4_KEY_GEN_MECH_INFO_TYPE, /* SUN_CKM_RC4_KEY_GEN */
260 EC_KEY_PAIR_GEN_MECH_INFO_TYPE, /* SUN_CKM_EC_KEY_PAIR_GEN */
261 ECDSA_MECH_INFO_TYPE, /* SUN_CKM_ECDSA */
262 ECDSA_SHA1_MECH_INFO_TYPE, /* SUN_CKM_ECDSA_SHA1 */
263 ECDH1_DERIVE_MECH_INFO_TYPE, /* SUN_CKM_ECDH1_DERIVE */
264 DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE, /* SUN_CKM_DH_PKCS_KEY_PAIR_GEN */
265 DH_PKCS_DERIVE_MECH_INFO_TYPE, /* SUN_CKM_DH_PKCS_DERIVE */
266 RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE /* SUN_CKM_RSA_PKCS_KEY_PAIR_GEN */
267 } dprov_mech_type_t;
270 * Mechanism info structure passed to KCF during registration.
272 #define MD5_DIGEST_LEN 16 /* MD5 digest size */
273 #define MD5_HMAC_BLOCK_SIZE 64 /* MD5-HMAC block size */
274 #define MD5_HMAC_MIN_KEY_LEN 1 /* MD5-HMAC min key length in bytes */
275 #define MD5_HMAC_MAX_KEY_LEN INT_MAX /* MD5-HMAC max key length in bytes */
277 #define SHA1_DIGEST_LEN 20 /* SHA1 digest size */
278 #define SHA1_HMAC_BLOCK_SIZE 64 /* SHA1-HMAC block size */
279 #define SHA1_HMAC_MIN_KEY_LEN 1 /* SHA1-HMAC min key length in bytes */
280 #define SHA1_HMAC_MAX_KEY_LEN INT_MAX /* SHA1-HMAC max key length in bytes */
282 #define DES_KEY_LEN 8 /* DES key length in bytes */
283 #define DES3_KEY_LEN 24 /* DES3 key length in bytes */
285 #define BLOWFISH_MIN_KEY_LEN 32 /* Blowfish min key length in bits */
286 #define BLOWFISH_MAX_KEY_LEN 448 /* Blowfish max key length in bits */
288 #define AES_MIN_KEY_LEN 16 /* AES min key length in bytes */
289 #define AES_MAX_KEY_LEN 32 /* AES max key length in bytes */
291 #define ARCFOUR_MIN_KEY_BITS 40 /* RC4 min supported key size */
292 #define ARCFOUR_MAX_KEY_BITS 2048 /* RC4 max supported key size */
294 #define RSA_MIN_KEY_LEN 256 /* RSA min key length in bits */
295 #define RSA_MAX_KEY_LEN 4096 /* RSA max key length in bits */
297 #define DH_MIN_KEY_LEN 64 /* DH min key length in bits */
298 #define DH_MAX_KEY_LEN 4096 /* DH max key length in bits */
300 #define DPROV_CKM_MD5_KEY_DERIVATION "CKM_MD5_KEY_DERIVATION"
301 #define DPROV_CKM_SHA1_KEY_DERIVATION "CKM_SHA1_KEY_DERIVATION"
302 #define DPROV_CKM_SHA256_KEY_DERIVATION "CKM_SHA256_KEY_DERIVATION"
303 #define DPROV_CKM_SHA384_KEY_DERIVATION "CKM_SHA384_KEY_DERIVATION"
304 #define DPROV_CKM_SHA512_KEY_DERIVATION "CKM_SHA512_KEY_DERIVATION"
305 #define DPROV_CKM_DES_KEY_GEN "CKM_DES_KEY_GEN"
306 #define DPROV_CKM_DES3_KEY_GEN "CKM_DES3_KEY_GEN"
307 #define DPROV_CKM_AES_KEY_GEN "CKM_AES_KEY_GEN"
308 #define DPROV_CKM_BLOWFISH_KEY_GEN "CKM_BLOWFISH_KEY_GEN"
309 #define DPROV_CKM_RC4_KEY_GEN "CKM_RC4_KEY_GEN"
310 #define DPROV_CKM_RSA_PKCS_KEY_PAIR_GEN "CKM_RSA_PKCS_KEY_PAIR_GEN"
311 #define DPROV_CKM_EC_KEY_PAIR_GEN "CKM_EC_KEY_PAIR_GEN"
312 #define DPROV_CKM_ECDSA "CKM_ECDSA"
313 #define DPROV_CKM_ECDSA_SHA1 "CKM_ECDSA_SHA1"
314 #define DPROV_CKM_ECDH1_DERIVE "CKM_ECDH1_DERIVE"
315 #define DPROV_CKM_DH_PKCS_KEY_PAIR_GEN "CKM_DH_PKCS_KEY_PAIR_GEN"
316 #define DPROV_CKM_DH_PKCS_DERIVE "CKM_DH_PKCS_DERIVE"
318 static crypto_mech_info_t dprov_mech_info_tab[] = {
319 /* MD4 */
320 {SUN_CKM_MD4, MD4_MECH_INFO_TYPE,
321 CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
322 CRYPTO_KEYSIZE_UNIT_IN_BITS},
323 /* MD5 */
324 {SUN_CKM_MD5, MD5_MECH_INFO_TYPE,
325 CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
326 CRYPTO_KEYSIZE_UNIT_IN_BITS},
327 /* MD5-HMAC */
328 {SUN_CKM_MD5_HMAC, MD5_HMAC_MECH_INFO_TYPE,
329 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
330 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
331 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
332 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
333 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
334 MD5_HMAC_MIN_KEY_LEN, MD5_HMAC_MAX_KEY_LEN,
335 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
336 /* MD5-HMAC GENERAL */
337 {SUN_CKM_MD5_HMAC_GENERAL, MD5_HMAC_GEN_MECH_INFO_TYPE,
338 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
339 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
340 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
341 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
342 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
343 MD5_HMAC_MIN_KEY_LEN, MD5_HMAC_MAX_KEY_LEN,
344 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
345 /* SHA1 */
346 {SUN_CKM_SHA1, SHA1_MECH_INFO_TYPE,
347 CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
348 CRYPTO_KEYSIZE_UNIT_IN_BITS},
349 /* SHA1-HMAC */
350 {SUN_CKM_SHA1_HMAC, SHA1_HMAC_MECH_INFO_TYPE,
351 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
352 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
353 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
354 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
355 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
356 SHA1_HMAC_MIN_KEY_LEN, SHA1_HMAC_MAX_KEY_LEN,
357 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
358 /* SHA1-HMAC GENERAL */
359 {SUN_CKM_SHA1_HMAC_GENERAL, SHA1_HMAC_GEN_MECH_INFO_TYPE,
360 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
361 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
362 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
363 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
364 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
365 SHA1_HMAC_MIN_KEY_LEN, SHA1_HMAC_MAX_KEY_LEN,
366 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
367 /* SHA256 */
368 {SUN_CKM_SHA256, SHA256_MECH_INFO_TYPE,
369 CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
370 CRYPTO_KEYSIZE_UNIT_IN_BITS},
371 /* SHA256-HMAC */
372 {SUN_CKM_SHA256_HMAC, SHA256_HMAC_MECH_INFO_TYPE,
373 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
374 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
375 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
376 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
377 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
378 SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
379 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
380 /* SHA256-HMAC GENERAL */
381 {SUN_CKM_SHA256_HMAC_GENERAL, SHA256_HMAC_GEN_MECH_INFO_TYPE,
382 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
383 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
384 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
385 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
386 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
387 SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
388 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
389 /* SHA384 */
390 {SUN_CKM_SHA384, SHA384_MECH_INFO_TYPE,
391 CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
392 CRYPTO_KEYSIZE_UNIT_IN_BITS},
393 /* SHA384-HMAC */
394 {SUN_CKM_SHA384_HMAC, SHA384_HMAC_MECH_INFO_TYPE,
395 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
396 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
397 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
398 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
399 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
400 SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
401 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
402 /* SHA384-HMAC GENERAL */
403 {SUN_CKM_SHA384_HMAC_GENERAL, SHA384_HMAC_GEN_MECH_INFO_TYPE,
404 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
405 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
406 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
407 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
408 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
409 SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
410 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
411 /* SHA512 */
412 {SUN_CKM_SHA512, SHA512_MECH_INFO_TYPE,
413 CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 0, 0,
414 CRYPTO_KEYSIZE_UNIT_IN_BITS},
415 /* SHA512-HMAC */
416 {SUN_CKM_SHA512_HMAC, SHA512_HMAC_MECH_INFO_TYPE,
417 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
418 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
419 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
420 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
421 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
422 SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
423 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
424 /* SHA512-HMAC GENERAL */
425 {SUN_CKM_SHA512_HMAC_GENERAL, SHA512_HMAC_GEN_MECH_INFO_TYPE,
426 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
427 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
428 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
429 CRYPTO_FG_ENCRYPT_MAC | CRYPTO_FG_MAC_DECRYPT |
430 CRYPTO_FG_ENCRYPT_MAC_ATOMIC | CRYPTO_FG_MAC_DECRYPT_ATOMIC,
431 SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
432 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
433 /* DES-CBC */
434 {SUN_CKM_DES_CBC, DES_CBC_MECH_INFO_TYPE,
435 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
436 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
437 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
438 CRYPTO_FG_MAC_DECRYPT_ATOMIC,
439 DES_KEY_LEN, DES_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
440 /* DES3-CBC */
441 {SUN_CKM_DES3_CBC, DES3_CBC_MECH_INFO_TYPE,
442 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
443 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
444 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
445 CRYPTO_FG_MAC_DECRYPT_ATOMIC,
446 DES3_KEY_LEN, DES3_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
447 /* DES-ECB */
448 {SUN_CKM_DES_ECB, DES_ECB_MECH_INFO_TYPE,
449 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
450 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
451 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
452 CRYPTO_FG_MAC_DECRYPT_ATOMIC,
453 DES_KEY_LEN, DES_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
454 /* DES3-ECB */
455 {SUN_CKM_DES3_ECB, DES3_ECB_MECH_INFO_TYPE,
456 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
457 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
458 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
459 CRYPTO_FG_MAC_DECRYPT_ATOMIC,
460 DES3_KEY_LEN, DES3_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
461 /* BLOWFISH-CBC */
462 {SUN_CKM_BLOWFISH_CBC, BLOWFISH_CBC_MECH_INFO_TYPE,
463 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
464 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
465 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
466 CRYPTO_FG_MAC_DECRYPT_ATOMIC, BLOWFISH_MIN_KEY_LEN,
467 BLOWFISH_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
468 /* BLOWFISH-ECB */
469 {SUN_CKM_BLOWFISH_ECB, BLOWFISH_ECB_MECH_INFO_TYPE,
470 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
471 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
472 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
473 CRYPTO_FG_MAC_DECRYPT_ATOMIC, BLOWFISH_MIN_KEY_LEN,
474 BLOWFISH_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
475 /* AES-CBC */
476 {SUN_CKM_AES_CBC, AES_CBC_MECH_INFO_TYPE,
477 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
478 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
479 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
480 CRYPTO_FG_MAC_DECRYPT_ATOMIC,
481 AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
482 /* AES-CMAC */
483 {SUN_CKM_AES_CMAC, AES_CMAC_MECH_INFO_TYPE,
484 CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_MAC |
485 CRYPTO_FG_ENCRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
486 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC |
487 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
488 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
489 AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
490 /* AES-ECB */
491 {SUN_CKM_AES_ECB, AES_ECB_MECH_INFO_TYPE,
492 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
493 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
494 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
495 CRYPTO_FG_MAC_DECRYPT_ATOMIC,
496 AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
497 /* AES-CTR */
498 {SUN_CKM_AES_CTR, AES_CTR_MECH_INFO_TYPE,
499 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
500 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
501 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
502 CRYPTO_FG_MAC_DECRYPT_ATOMIC,
503 AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
504 /* AES-CCM */
505 {SUN_CKM_AES_CCM, AES_CCM_MECH_INFO_TYPE,
506 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
507 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
508 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
509 CRYPTO_FG_MAC_DECRYPT_ATOMIC,
510 AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
511 /* AES-GCM */
512 {SUN_CKM_AES_GCM, AES_GCM_MECH_INFO_TYPE,
513 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
514 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
515 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
516 CRYPTO_FG_MAC_DECRYPT_ATOMIC,
517 AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
518 /* AES-GMAC */
519 {SUN_CKM_AES_GMAC, AES_GMAC_MECH_INFO_TYPE,
520 CRYPTO_FG_ENCRYPT | CRYPTO_FG_DECRYPT | CRYPTO_FG_ENCRYPT_MAC |
521 CRYPTO_FG_MAC_DECRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
522 CRYPTO_FG_DECRYPT_ATOMIC | CRYPTO_FG_ENCRYPT_MAC_ATOMIC |
523 CRYPTO_FG_MAC_DECRYPT_ATOMIC |
524 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
525 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
526 AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
527 /* RC4 */
528 {SUN_CKM_RC4, RC4_MECH_INFO_TYPE,
529 CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
530 CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
531 ARCFOUR_MIN_KEY_BITS, ARCFOUR_MAX_KEY_BITS,
532 CRYPTO_KEYSIZE_UNIT_IN_BITS | CRYPTO_CAN_SHARE_OPSTATE},
533 /* RSA_PKCS */
534 {SUN_CKM_RSA_PKCS, RSA_PKCS_MECH_INFO_TYPE,
535 CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
536 CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC |
537 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
538 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
539 CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC |
540 CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC,
541 RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
542 /* RSA_X_509 */
543 {SUN_CKM_RSA_X_509, RSA_X_509_MECH_INFO_TYPE,
544 CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
545 CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC |
546 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
547 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
548 CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC |
549 CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC,
550 RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
551 /* MD5_RSA_PKCS */
552 {SUN_CKM_MD5_RSA_PKCS, MD5_RSA_PKCS_MECH_INFO_TYPE,
553 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
554 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
555 RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
556 /* SHA1_RSA_PKCS */
557 {SUN_CKM_SHA1_RSA_PKCS, SHA1_RSA_PKCS_MECH_INFO_TYPE,
558 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
559 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
560 RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
561 /* SHA256_RSA_PKCS */
562 {SUN_CKM_SHA256_RSA_PKCS, SHA256_RSA_PKCS_MECH_INFO_TYPE,
563 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
564 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
565 RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
566 /* SHA384_RSA_PKCS */
567 {SUN_CKM_SHA384_RSA_PKCS, SHA384_RSA_PKCS_MECH_INFO_TYPE,
568 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
569 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
570 RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
571 /* SHA512_RSA_PKCS */
572 {SUN_CKM_SHA512_RSA_PKCS, SHA512_RSA_PKCS_MECH_INFO_TYPE,
573 CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
574 CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
575 RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
576 /* MD5_KEY_DERIVATION */
577 {DPROV_CKM_MD5_KEY_DERIVATION, MD5_KEY_DERIVATION_MECH_INFO_TYPE,
578 CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
579 /* SHA1_KEY_DERIVATION */
580 {DPROV_CKM_SHA1_KEY_DERIVATION, SHA1_KEY_DERIVATION_MECH_INFO_TYPE,
581 CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
582 /* SHA256_KEY_DERIVATION */
583 {DPROV_CKM_SHA256_KEY_DERIVATION, SHA256_KEY_DERIVATION_MECH_INFO_TYPE,
584 CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
585 /* SHA384_KEY_DERIVATION */
586 {DPROV_CKM_SHA384_KEY_DERIVATION, SHA384_KEY_DERIVATION_MECH_INFO_TYPE,
587 CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
588 /* SHA512_KEY_DERIVATION */
589 {DPROV_CKM_SHA512_KEY_DERIVATION, SHA512_KEY_DERIVATION_MECH_INFO_TYPE,
590 CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
591 /* DES_KEY_GENERATION */
592 {DPROV_CKM_DES_KEY_GEN, DES_KEY_GEN_MECH_INFO_TYPE,
593 CRYPTO_FG_GENERATE, DES_KEY_LEN, DES_KEY_LEN,
594 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
595 /* DES3_KEY_GENERATION */
596 {DPROV_CKM_DES3_KEY_GEN, DES3_KEY_GEN_MECH_INFO_TYPE,
597 CRYPTO_FG_GENERATE, DES3_KEY_LEN, DES3_KEY_LEN,
598 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
599 /* AES_KEY_GENERATION */
600 {DPROV_CKM_AES_KEY_GEN, AES_KEY_GEN_MECH_INFO_TYPE,
601 CRYPTO_FG_GENERATE, AES_MIN_KEY_LEN, AES_MAX_KEY_LEN,
602 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
603 /* BLOWFISH_KEY_GENERATION */
604 {DPROV_CKM_BLOWFISH_KEY_GEN, BLOWFISH_KEY_GEN_MECH_INFO_TYPE,
605 CRYPTO_FG_GENERATE, BLOWFISH_MIN_KEY_LEN, BLOWFISH_MAX_KEY_LEN,
606 CRYPTO_KEYSIZE_UNIT_IN_BYTES},
607 /* RC4_KEY_GENERATION */
608 {DPROV_CKM_RC4_KEY_GEN, RC4_KEY_GEN_MECH_INFO_TYPE,
609 CRYPTO_FG_GENERATE, ARCFOUR_MIN_KEY_BITS, ARCFOUR_MAX_KEY_BITS,
610 CRYPTO_KEYSIZE_UNIT_IN_BITS},
611 /* DH_PKCS_KEY_PAIR_GEN */
612 {DPROV_CKM_DH_PKCS_KEY_PAIR_GEN, DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE,
613 CRYPTO_FG_GENERATE_KEY_PAIR, DH_MIN_KEY_LEN, DH_MAX_KEY_LEN,
614 CRYPTO_KEYSIZE_UNIT_IN_BITS},
615 /* DH_PKCS_DERIVE */
616 {DPROV_CKM_DH_PKCS_DERIVE, DH_PKCS_DERIVE_MECH_INFO_TYPE,
617 CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
618 /* RSA_PKCS_KEY_PAIR_GEN */
619 {DPROV_CKM_RSA_PKCS_KEY_PAIR_GEN, RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE,
620 CRYPTO_FG_GENERATE_KEY_PAIR, RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN,
621 CRYPTO_KEYSIZE_UNIT_IN_BITS},
622 /* EC_KEY_PAIR_GEN */
623 {DPROV_CKM_EC_KEY_PAIR_GEN, EC_KEY_PAIR_GEN_MECH_INFO_TYPE,
624 CRYPTO_FG_GENERATE_KEY_PAIR, EC_MIN_KEY_LEN, EC_MAX_KEY_LEN,
625 CRYPTO_KEYSIZE_UNIT_IN_BITS},
626 /* ECDSA */
627 {DPROV_CKM_ECDSA, ECDSA_MECH_INFO_TYPE,
628 CRYPTO_FG_SIGN | CRYPTO_FG_VERIFY |
629 CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC |
630 EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
631 /* ECDSA_SHA1 */
632 {DPROV_CKM_ECDSA_SHA1, ECDSA_SHA1_MECH_INFO_TYPE,
633 CRYPTO_FG_SIGN | CRYPTO_FG_VERIFY |
634 CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC |
635 EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
636 /* ECDH1_DERIVE */
637 {DPROV_CKM_ECDH1_DERIVE, ECDH1_DERIVE_MECH_INFO_TYPE,
638 CRYPTO_FG_DERIVE, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}
642 * Crypto Values
644 * These values are the used in the STC ef test suite. If they are changed
645 * the test suite needs to be changed.
647 static uchar_t dh_value[8] = { 'd', 'h', 'd', 'h', 'd', 'h', 'd', '\0' };
648 char public_exponent[3] = { 0x01, 0x00, 0x01 };
649 static uchar_t private_exponent[128] = {
650 0x8e, 0xc9, 0x70, 0x57, 0x6b, 0xcd, 0xfb, 0xa9,
651 0x19, 0xad, 0xcd, 0x91, 0x69, 0xd5, 0x52, 0xec,
652 0x72, 0x1e, 0x45, 0x15, 0x06, 0xdc, 0x65, 0x2d,
653 0x98, 0xc4, 0xce, 0x33, 0x54, 0x15, 0x70, 0x8d,
654 0xfa, 0x65, 0xea, 0x53, 0x44, 0xf3, 0x3e, 0x3f,
655 0xb4, 0x4c, 0x60, 0xd5, 0x01, 0x2d, 0xa4, 0x12,
656 0x99, 0xbf, 0x3f, 0x0b, 0xcd, 0xbb, 0x24, 0x10,
657 0x60, 0x30, 0x5e, 0x58, 0xf8, 0x59, 0xaa, 0xd1,
658 0x63, 0x3b, 0xbc, 0xcb, 0x94, 0x58, 0x38, 0x24,
659 0xfc, 0x65, 0x25, 0xc5, 0xa6, 0x51, 0xa2, 0x2e,
660 0xf1, 0x5e, 0xf5, 0xc1, 0xf5, 0x46, 0xf7, 0xbd,
661 0xc7, 0x62, 0xa8, 0xe2, 0x27, 0xd6, 0x94, 0x5b,
662 0xd3, 0xa2, 0xb5, 0x76, 0x42, 0x67, 0x6b, 0x86,
663 0x91, 0x97, 0x4d, 0x07, 0x92, 0x00, 0x4a, 0xdf,
664 0x0b, 0x65, 0x64, 0x05, 0x03, 0x48, 0x27, 0xeb,
665 0xce, 0x9a, 0x49, 0x7f, 0x3e, 0x10, 0xe0, 0x01
668 static uchar_t modulus[128] = {
669 0x94, 0x32, 0xb9, 0x12, 0x1d, 0x68, 0x2c, 0xda,
670 0x2b, 0xe0, 0xe4, 0x97, 0x1b, 0x4d, 0xdc, 0x43,
671 0xdf, 0x38, 0x6e, 0x7b, 0x9f, 0x07, 0x58, 0xae,
672 0x9d, 0x82, 0x1e, 0xc7, 0xbc, 0x92, 0xbf, 0xd3,
673 0xce, 0x00, 0xbb, 0x91, 0xc9, 0x79, 0x06, 0x03,
674 0x1f, 0xbc, 0x9f, 0x94, 0x75, 0x29, 0x5f, 0xd7,
675 0xc5, 0xf3, 0x73, 0x8a, 0xa4, 0x35, 0x43, 0x7a,
676 0x00, 0x32, 0x97, 0x3e, 0x86, 0xef, 0x70, 0x6f,
677 0x18, 0x56, 0x15, 0xaa, 0x6a, 0x87, 0xe7, 0x8d,
678 0x7d, 0xdd, 0x1f, 0xa4, 0xe4, 0x31, 0xd4, 0x7a,
679 0x8c, 0x0e, 0x20, 0xd2, 0x23, 0xf5, 0x57, 0x3c,
680 0x1b, 0xa8, 0x44, 0xa4, 0x57, 0x8f, 0x33, 0x52,
681 0xad, 0x83, 0xae, 0x4a, 0x97, 0xa6, 0x1e, 0xa6,
682 0x2b, 0xfa, 0xea, 0xeb, 0x6e, 0x71, 0xb8, 0xb6,
683 0x0a, 0x36, 0xed, 0x83, 0xce, 0xb0, 0xdf, 0xc1,
684 0xd4, 0x3a, 0xe9, 0x99, 0x6f, 0xf3, 0x96, 0xb7
688 static void dprov_provider_status(crypto_provider_handle_t, uint_t *);
690 static crypto_control_ops_t dprov_control_ops = {
691 dprov_provider_status
694 #define DPROV_MANUFACTURER "SUNW "
695 #define DPROV_MODEL "dprov "
696 #define DPROV_ALLSPACES " "
698 static int dprov_digest_init(crypto_ctx_t *, crypto_mechanism_t *,
699 crypto_req_handle_t);
700 static int dprov_digest(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
701 crypto_req_handle_t);
702 static int dprov_digest_update(crypto_ctx_t *, crypto_data_t *,
703 crypto_req_handle_t);
704 static int dprov_digest_key(crypto_ctx_t *, crypto_key_t *,
705 crypto_req_handle_t);
706 static int dprov_digest_final(crypto_ctx_t *, crypto_data_t *,
707 crypto_req_handle_t);
708 static int dprov_digest_atomic(crypto_provider_handle_t, crypto_session_id_t,
709 crypto_mechanism_t *, crypto_data_t *, crypto_data_t *,
710 crypto_req_handle_t);
712 static crypto_digest_ops_t dprov_digest_ops = {
713 dprov_digest_init,
714 dprov_digest,
715 dprov_digest_update,
716 dprov_digest_key,
717 dprov_digest_final,
718 dprov_digest_atomic
721 static int dprov_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
722 crypto_spi_ctx_template_t, crypto_req_handle_t);
723 static int dprov_mac(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
724 crypto_req_handle_t);
725 static int dprov_mac_update(crypto_ctx_t *, crypto_data_t *,
726 crypto_req_handle_t);
727 static int dprov_mac_final(crypto_ctx_t *, crypto_data_t *,
728 crypto_req_handle_t);
729 static int dprov_mac_atomic(crypto_provider_handle_t, crypto_session_id_t,
730 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
731 crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
732 static int dprov_mac_verify_atomic(crypto_provider_handle_t,
733 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
734 crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
736 static crypto_mac_ops_t dprov_mac_ops = {
737 dprov_mac_init,
738 dprov_mac,
739 dprov_mac_update,
740 dprov_mac_final,
741 dprov_mac_atomic,
742 dprov_mac_verify_atomic
745 static int dprov_encrypt_init(crypto_ctx_t *, crypto_mechanism_t *,
746 crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
747 static int dprov_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
748 crypto_req_handle_t);
749 static int dprov_encrypt_update(crypto_ctx_t *, crypto_data_t *,
750 crypto_data_t *, crypto_req_handle_t);
751 static int dprov_encrypt_final(crypto_ctx_t *, crypto_data_t *,
752 crypto_req_handle_t);
753 static int dprov_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
754 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
755 crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
757 static int dprov_decrypt_init(crypto_ctx_t *, crypto_mechanism_t *,
758 crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
759 static int dprov_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
760 crypto_req_handle_t);
761 static int dprov_decrypt_update(crypto_ctx_t *, crypto_data_t *,
762 crypto_data_t *, crypto_req_handle_t);
763 static int dprov_decrypt_final(crypto_ctx_t *, crypto_data_t *,
764 crypto_req_handle_t);
765 static int dprov_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
766 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
767 crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
769 static crypto_cipher_ops_t dprov_cipher_ops = {
770 dprov_encrypt_init,
771 dprov_encrypt,
772 dprov_encrypt_update,
773 dprov_encrypt_final,
774 dprov_encrypt_atomic,
775 dprov_decrypt_init,
776 dprov_decrypt,
777 dprov_decrypt_update,
778 dprov_decrypt_final,
779 dprov_decrypt_atomic
782 static int dprov_sign_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
783 crypto_spi_ctx_template_t, crypto_req_handle_t);
784 static int dprov_sign(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
785 crypto_req_handle_t);
786 static int dprov_sign_update(crypto_ctx_t *, crypto_data_t *,
787 crypto_req_handle_t);
788 static int dprov_sign_final(crypto_ctx_t *, crypto_data_t *,
789 crypto_req_handle_t);
790 static int dprov_sign_atomic(crypto_provider_handle_t, crypto_session_id_t,
791 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
792 crypto_spi_ctx_template_t, crypto_req_handle_t);
793 static int dprov_sign_recover_init(crypto_ctx_t *, crypto_mechanism_t *,
794 crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
795 static int dprov_sign_recover(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
796 crypto_req_handle_t);
797 static int dprov_sign_recover_atomic(crypto_provider_handle_t,
798 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
799 crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
800 crypto_req_handle_t);
802 static crypto_sign_ops_t dprov_sign_ops = {
803 dprov_sign_init,
804 dprov_sign,
805 dprov_sign_update,
806 dprov_sign_final,
807 dprov_sign_atomic,
808 dprov_sign_recover_init,
809 dprov_sign_recover,
810 dprov_sign_recover_atomic
813 static int dprov_verify_init(crypto_ctx_t *, crypto_mechanism_t *,
814 crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
815 static int dprov_verify(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
816 crypto_req_handle_t);
817 static int dprov_verify_update(crypto_ctx_t *, crypto_data_t *,
818 crypto_req_handle_t);
819 static int dprov_verify_final(crypto_ctx_t *, crypto_data_t *,
820 crypto_req_handle_t);
821 static int dprov_verify_atomic(crypto_provider_handle_t, crypto_session_id_t,
822 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
823 crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
824 static int dprov_verify_recover_init(crypto_ctx_t *, crypto_mechanism_t *,
825 crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
826 static int dprov_verify_recover(crypto_ctx_t *, crypto_data_t *,
827 crypto_data_t *, crypto_req_handle_t);
828 static int dprov_verify_recover_atomic(crypto_provider_handle_t,
829 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
830 crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
831 crypto_req_handle_t);
833 static crypto_verify_ops_t dprov_verify_ops = {
834 dprov_verify_init,
835 dprov_verify,
836 dprov_verify_update,
837 dprov_verify_final,
838 dprov_verify_atomic,
839 dprov_verify_recover_init,
840 dprov_verify_recover,
841 dprov_verify_recover_atomic
844 static int dprov_digest_encrypt_update(crypto_ctx_t *, crypto_ctx_t *,
845 crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
846 static int dprov_decrypt_digest_update(crypto_ctx_t *, crypto_ctx_t *,
847 crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
848 static int dprov_sign_encrypt_update(crypto_ctx_t *, crypto_ctx_t *,
849 crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
850 static int dprov_decrypt_verify_update(crypto_ctx_t *, crypto_ctx_t *,
851 crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
853 static crypto_dual_ops_t dprov_dual_ops = {
854 dprov_digest_encrypt_update,
855 dprov_decrypt_digest_update,
856 dprov_sign_encrypt_update,
857 dprov_decrypt_verify_update
860 static int dprov_encrypt_mac_init(crypto_ctx_t *,
861 crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *,
862 crypto_key_t *, crypto_spi_ctx_template_t,
863 crypto_spi_ctx_template_t, crypto_req_handle_t);
864 static int dprov_encrypt_mac(crypto_ctx_t *,
865 crypto_data_t *, crypto_dual_data_t *, crypto_data_t *,
866 crypto_req_handle_t);
867 static int dprov_encrypt_mac_update(crypto_ctx_t *,
868 crypto_data_t *, crypto_dual_data_t *, crypto_req_handle_t);
869 static int dprov_encrypt_mac_final(crypto_ctx_t *,
870 crypto_dual_data_t *, crypto_data_t *, crypto_req_handle_t);
871 static int dprov_encrypt_mac_atomic(crypto_provider_handle_t,
872 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
873 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
874 crypto_dual_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
875 crypto_spi_ctx_template_t, crypto_req_handle_t);
877 static int dprov_mac_decrypt_init(crypto_ctx_t *,
878 crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *,
879 crypto_key_t *, crypto_spi_ctx_template_t,
880 crypto_spi_ctx_template_t, crypto_req_handle_t);
881 static int dprov_mac_decrypt(crypto_ctx_t *,
882 crypto_dual_data_t *, crypto_data_t *, crypto_data_t *,
883 crypto_req_handle_t);
884 static int dprov_mac_decrypt_update(crypto_ctx_t *,
885 crypto_dual_data_t *, crypto_data_t *, crypto_req_handle_t);
886 static int dprov_mac_decrypt_final(crypto_ctx_t *,
887 crypto_data_t *, crypto_data_t *, crypto_req_handle_t);
888 static int dprov_mac_decrypt_atomic(crypto_provider_handle_t,
889 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
890 crypto_mechanism_t *, crypto_key_t *, crypto_dual_data_t *,
891 crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
892 crypto_spi_ctx_template_t, crypto_req_handle_t);
893 static int dprov_mac_verify_decrypt_atomic(crypto_provider_handle_t,
894 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
895 crypto_mechanism_t *, crypto_key_t *, crypto_dual_data_t *,
896 crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
897 crypto_spi_ctx_template_t, crypto_req_handle_t);
899 static crypto_dual_cipher_mac_ops_t dprov_cipher_mac_ops = {
900 dprov_encrypt_mac_init,
901 dprov_encrypt_mac,
902 dprov_encrypt_mac_update,
903 dprov_encrypt_mac_final,
904 dprov_encrypt_mac_atomic,
905 dprov_mac_decrypt_init,
906 dprov_mac_decrypt,
907 dprov_mac_decrypt_update,
908 dprov_mac_decrypt_final,
909 dprov_mac_decrypt_atomic,
910 dprov_mac_verify_decrypt_atomic
913 static int dprov_seed_random(crypto_provider_handle_t, crypto_session_id_t,
914 uchar_t *, size_t, uint_t, uint32_t, crypto_req_handle_t);
915 static int dprov_generate_random(crypto_provider_handle_t, crypto_session_id_t,
916 uchar_t *, size_t, crypto_req_handle_t);
918 static crypto_random_number_ops_t dprov_random_number_ops = {
919 dprov_seed_random,
920 dprov_generate_random
923 static int dprov_session_open(crypto_provider_handle_t, crypto_session_id_t *,
924 crypto_req_handle_t);
925 static int dprov_session_close(crypto_provider_handle_t, crypto_session_id_t,
926 crypto_req_handle_t);
927 static int dprov_session_login(crypto_provider_handle_t, crypto_session_id_t,
928 crypto_user_type_t, char *, size_t, crypto_req_handle_t);
929 static int dprov_session_logout(crypto_provider_handle_t, crypto_session_id_t,
930 crypto_req_handle_t);
932 static crypto_session_ops_t dprov_session_ops = {
933 dprov_session_open,
934 dprov_session_close,
935 dprov_session_login,
936 dprov_session_logout
939 static int dprov_object_create(crypto_provider_handle_t, crypto_session_id_t,
940 crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
941 crypto_req_handle_t);
942 static int dprov_object_copy(crypto_provider_handle_t, crypto_session_id_t,
943 crypto_object_id_t, crypto_object_attribute_t *, uint_t,
944 crypto_object_id_t *, crypto_req_handle_t);
945 static int dprov_object_destroy(crypto_provider_handle_t, crypto_session_id_t,
946 crypto_object_id_t, crypto_req_handle_t);
947 static int dprov_object_get_size(crypto_provider_handle_t, crypto_session_id_t,
948 crypto_object_id_t, size_t *, crypto_req_handle_t);
949 static int dprov_object_get_attribute_value(crypto_provider_handle_t,
950 crypto_session_id_t, crypto_object_id_t,
951 crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
952 static int dprov_object_set_attribute_value(crypto_provider_handle_t,
953 crypto_session_id_t, crypto_object_id_t,
954 crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
955 static int dprov_object_find_init(crypto_provider_handle_t, crypto_session_id_t,
956 crypto_object_attribute_t *, uint_t, void **,
957 crypto_req_handle_t);
958 static int dprov_object_find(crypto_provider_handle_t, void *,
959 crypto_object_id_t *, uint_t, uint_t *, crypto_req_handle_t);
960 static int dprov_object_find_final(crypto_provider_handle_t, void *,
961 crypto_req_handle_t);
963 static crypto_object_ops_t dprov_object_ops = {
964 dprov_object_create,
965 dprov_object_copy,
966 dprov_object_destroy,
967 dprov_object_get_size,
968 dprov_object_get_attribute_value,
969 dprov_object_set_attribute_value,
970 dprov_object_find_init,
971 dprov_object_find,
972 dprov_object_find_final
975 static int dprov_key_generate(crypto_provider_handle_t, crypto_session_id_t,
976 crypto_mechanism_t *, crypto_object_attribute_t *, uint_t,
977 crypto_object_id_t *, crypto_req_handle_t);
978 static int dprov_key_generate_pair(crypto_provider_handle_t,
979 crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *,
980 uint_t, crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
981 crypto_object_id_t *, crypto_req_handle_t);
982 static int dprov_key_wrap(crypto_provider_handle_t, crypto_session_id_t,
983 crypto_mechanism_t *, crypto_key_t *, crypto_object_id_t *,
984 uchar_t *, size_t *, crypto_req_handle_t);
985 static int dprov_key_unwrap(crypto_provider_handle_t, crypto_session_id_t,
986 crypto_mechanism_t *, crypto_key_t *, uchar_t *, size_t *,
987 crypto_object_attribute_t *, uint_t,
988 crypto_object_id_t *, crypto_req_handle_t);
989 static int dprov_key_derive(crypto_provider_handle_t, crypto_session_id_t,
990 crypto_mechanism_t *, crypto_key_t *, crypto_object_attribute_t *,
991 uint_t, crypto_object_id_t *, crypto_req_handle_t);
993 static crypto_key_ops_t dprov_key_ops = {
994 dprov_key_generate,
995 dprov_key_generate_pair,
996 dprov_key_wrap,
997 dprov_key_unwrap,
998 dprov_key_derive
1001 static int dprov_ext_info(crypto_provider_handle_t,
1002 crypto_provider_ext_info_t *, crypto_req_handle_t);
1003 static int dprov_init_token(crypto_provider_handle_t, char *, size_t,
1004 char *, crypto_req_handle_t);
1005 static int dprov_init_pin(crypto_provider_handle_t, crypto_session_id_t,
1006 char *, size_t, crypto_req_handle_t);
1007 static int dprov_set_pin(crypto_provider_handle_t, crypto_session_id_t,
1008 char *, size_t, char *, size_t, crypto_req_handle_t);
1010 static crypto_provider_management_ops_t dprov_management_ops = {
1011 dprov_ext_info,
1012 dprov_init_token,
1013 dprov_init_pin,
1014 dprov_set_pin
1017 static int dprov_free_context(crypto_ctx_t *);
1018 static int dprov_copyin_mechanism(crypto_provider_handle_t,
1019 crypto_mechanism_t *, crypto_mechanism_t *, int *error, int);
1020 static int dprov_copyout_mechanism(crypto_provider_handle_t,
1021 crypto_mechanism_t *, crypto_mechanism_t *, int *error, int);
1022 static int dprov_free_mechanism(crypto_provider_handle_t,
1023 crypto_mechanism_t *);
1025 static crypto_ctx_ops_t dprov_ctx_ops = {
1026 NULL,
1027 dprov_free_context
1030 static crypto_mech_ops_t dprov_mech_ops = {
1031 dprov_copyin_mechanism,
1032 dprov_copyout_mechanism,
1033 dprov_free_mechanism
1036 static int dprov_nostore_key_generate(crypto_provider_handle_t,
1037 crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *,
1038 uint_t, crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
1039 static int dprov_nostore_key_generate_pair(crypto_provider_handle_t,
1040 crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *,
1041 uint_t, crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *,
1042 uint_t, crypto_object_attribute_t *, uint_t, crypto_req_handle_t);
1043 static int dprov_nostore_key_derive(crypto_provider_handle_t,
1044 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
1045 crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *,
1046 uint_t, crypto_req_handle_t);
1048 static crypto_nostore_key_ops_t dprov_nostore_key_ops = {
1049 dprov_nostore_key_generate,
1050 dprov_nostore_key_generate_pair,
1051 dprov_nostore_key_derive
1054 static crypto_ops_t dprov_crypto_ops = {
1055 &dprov_control_ops,
1056 &dprov_digest_ops,
1057 &dprov_cipher_ops,
1058 &dprov_mac_ops,
1059 &dprov_sign_ops,
1060 &dprov_verify_ops,
1061 &dprov_dual_ops,
1062 &dprov_cipher_mac_ops,
1063 &dprov_random_number_ops,
1064 &dprov_session_ops,
1065 &dprov_object_ops,
1066 &dprov_key_ops,
1067 &dprov_management_ops,
1068 &dprov_ctx_ops,
1069 &dprov_mech_ops
1073 /* maximum SO and user PIN lengths */
1074 #define DPROV_MAX_PIN_LEN 128
1077 * Objects: each session is associated with an array of objects.
1078 * Unlike PKCS#11, the objects cannot be shared between sessions.
1079 * The ioctl driver multiplexes PKCS#11 sessions to providers
1080 * sessions in order to support this semantic. This simplifies
1081 * the CSPI greatly since the provider does not have to associate
1082 * sessions with a user space process.
1083 * There is also a per-instance array of objects, which correspond
1084 * to PKCS#11 token objects. These objects can be shared by multiple
1085 * sesions.
1087 * Token objects are identified by having a CKA_TOKEN attribute B_TRUE.
1088 * Private objects are identified by having a CKA_PRIVATE attribute
1089 * set to B_TRUE.
1092 #define DPROV_MAX_OBJECTS 128 /* max # of objects */
1093 #define DPROV_MAX_ATTR 64 /* max # of attributes per object */
1095 /* object description */
1096 typedef struct dprov_object {
1097 crypto_object_attribute_t do_attr[DPROV_MAX_ATTR]; /* attributes */
1098 uint_t do_token_idx; /* index in per-instance table */
1099 /* for token objects. */
1100 boolean_t do_destroyed; /* object has been destroyed. */
1101 /* keep object around until all */
1102 /* sessions that refer to it */
1103 /* are closed, but mark it */
1104 /* destroyed so that references */
1105 /* to the object fail. */
1106 /* used for token objects only */
1107 uint_t do_refcnt;
1108 } dprov_object_t;
1111 * If a session has a reference to a dprov_object_t,
1112 * it REFHOLD()s.
1114 #define DPROV_OBJECT_REFHOLD(object) { \
1115 atomic_inc_32(&(object)->do_refcnt); \
1116 ASSERT((object)->do_refcnt != 0); \
1120 * Releases a reference to an object. When the last
1121 * reference is released, the object is freed.
1123 #define DPROV_OBJECT_REFRELE(object) { \
1124 ASSERT((object)->do_refcnt != 0); \
1125 membar_exit(); \
1126 if (atomic_dec_32_nv(&(object)->do_refcnt) == 0) \
1127 dprov_free_object(object); \
1131 * Object attributes are passed to the provider using crypto_object_attribute
1132 * structures, which contain the type of the attribute, a pointer to
1133 * it's value, and the length of its value. The attribute types values
1134 * are defined by the PKCS#11 specification. This provider only cares
1135 * about a subset of these attributes. In order to avoid having to
1136 * include the PKCS#11 header files, we define here the attributes values
1137 * which are used by the provider.
1140 #define DPROV_CKA_CLASS 0x00000000
1141 #define DPROV_CKA_TOKEN 0x00000001
1142 #define DPROV_CKA_PRIVATE 0x00000002
1143 #define DPROV_CKA_VALUE 0x00000011
1144 #define DPROV_CKA_CERTIFICATE_TYPE 0x00000080
1145 #define DPROV_CKA_KEY_TYPE 0x00000100
1146 #define DPROV_CKA_SENSITIVE 0x00000103
1147 #define DPROV_CKA_ENCRYPT 0x00000104
1148 #define DPROV_CKA_DECRYPT 0x00000105
1149 #define DPROV_CKA_WRAP 0x00000106
1150 #define DPROV_CKA_UNWRAP 0x00000107
1151 #define DPROV_CKA_SIGN 0x00000108
1152 #define DPROV_CKA_SIGN_RECOVER 0x00000109
1153 #define DPROV_CKA_VERIFY 0x0000010A
1154 #define DPROV_CKA_VERIFY_RECOVER 0x0000010B
1155 #define DPROV_CKA_DERIVE 0x0000010C
1156 #define DPROV_CKA_MODULUS 0x00000120
1157 #define DPROV_CKA_MODULUS_BITS 0x00000121
1158 #define DPROV_CKA_PUBLIC_EXPONENT 0x00000122
1159 #define DPROV_CKA_PRIVATE_EXPONENT 0x00000123
1160 #define DPROV_CKA_PRIME 0x00000130
1161 #define DPROV_CKA_BASE 0x00000132
1162 #define DPROV_CKA_VALUE_BITS 0x00000160
1163 #define DPROV_CKA_VALUE_LEN 0x00000161
1164 #define DPROV_CKA_EXTRACTABLE 0x00000162
1165 #define DPROV_CKA_EC_PARAMS 0x00000180
1166 #define DPROV_CKA_EC_POINT 0x00000181
1167 #define DPROV_HW_FEATURE_TYPE 0x00000300
1170 * Object classes from PKCS#11
1172 #define DPROV_CKO_DATA 0x00000000
1173 #define DPROV_CKO_CERTIFICATE 0x00000001
1174 #define DPROV_CKO_PUBLIC_KEY 0x00000002
1175 #define DPROV_CKO_PRIVATE_KEY 0x00000003
1176 #define DPROV_CKO_SECRET_KEY 0x00000004
1177 #define DPROV_CKO_HW_FEATURE 0x00000005
1178 #define DPROV_CKO_DOMAIN_PARAMETERS 0x00000006
1179 #define DPROV_CKO_VENDOR_DEFINED 0x80000000
1182 * A few key types from PKCS#11
1184 #define DPROV_CKK_RSA 0x00000000
1185 #define DPROV_CKK_GENERIC_SECRET 0x00000010
1186 #define DPROV_CKK_RC4 0x00000012
1187 #define DPROV_CKK_DES 0x00000013
1188 #define DPROV_CKK_DES3 0x00000015
1189 #define DPROV_CKK_AES 0x0000001F
1190 #define DPROV_CKK_BLOWFISH 0x00000020
1193 * Find object context. Allows the find object init/find/final
1194 * to store data persistent across calls.
1196 typedef struct dprov_find_ctx {
1197 crypto_object_id_t fc_ids[DPROV_MAX_OBJECTS]; /* object ids */
1198 uint_t fc_nids; /* number of ids in fc_ids */
1199 uint_t fc_next; /* next id to return */
1200 } dprov_find_ctx_t;
1203 * Session management: each instance is associated with an array
1204 * of sessions. KEF providers sessions are always R/W the library and
1205 * the ioctl maintain the PKCS#11 R/W attributes for the session.
1208 #define DPROV_MIN_SESSIONS 32 /* # of sessions to start with */
1210 typedef enum dprov_session_state {
1211 DPROV_SESSION_STATE_PUBLIC, /* public (default) */
1212 DPROV_SESSION_STATE_SO, /* SO logged in */
1213 DPROV_SESSION_STATE_USER /* user logged in */
1214 } dprov_session_state_t;
1216 /* session description */
1217 typedef struct dprov_session {
1218 dprov_session_state_t ds_state; /* session state */
1219 dprov_object_t *ds_objects[DPROV_MAX_OBJECTS]; /* session objects */
1220 } dprov_session_t;
1223 static crypto_provider_info_t dprov_prov_info = {
1224 CRYPTO_SPI_VERSION_2,
1225 "Dummy Pseudo HW Provider",
1226 CRYPTO_HW_PROVIDER,
1227 NULL, /* pi_provider_dev */
1228 NULL, /* pi_provider_handle */
1229 &dprov_crypto_ops,
1230 sizeof (dprov_mech_info_tab)/sizeof (crypto_mech_info_t),
1231 dprov_mech_info_tab,
1232 0, /* pi_logical_provider_count */
1233 NULL, /* pi_logical_providers */
1234 0 /* pi_flags */
1238 * Per-instance info.
1240 typedef struct dprov_state {
1241 kmutex_t ds_lock; /* per-instance lock */
1242 dev_info_t *ds_dip; /* device info */
1243 crypto_kcf_provider_handle_t ds_prov_handle; /* framework handle */
1244 taskq_t *ds_taskq; /* taskq for async behavior */
1245 char ds_user_pin[DPROV_MAX_PIN_LEN]; /* normal user PIN */
1246 uint_t ds_user_pin_len;
1247 char ds_so_pin[DPROV_MAX_PIN_LEN]; /* SO PIN */
1248 uint_t ds_so_pin_len;
1249 dprov_session_t **ds_sessions; /* sessions for this instance */
1250 uint_t ds_sessions_slots; /* number of session slots */
1251 uint_t ds_sessions_count; /* number of open sessions */
1252 boolean_t ds_token_initialized; /* provider initialized? */
1253 boolean_t ds_user_pin_set; /* user pin set? */
1254 char ds_label[CRYPTO_EXT_SIZE_LABEL]; /* "token" label */
1255 dprov_object_t *ds_objects[DPROV_MAX_OBJECTS]; /* "token" objects */
1256 } dprov_state_t;
1260 * A taskq is associated with each instance of the pseudo driver in order
1261 * to simulate the asynchronous execution of requests.
1262 * The following defines the taskq request structures.
1265 /* request types */
1266 typedef enum dprov_req_type {
1267 /* digest requests */
1268 DPROV_REQ_DIGEST_INIT = 1,
1269 DPROV_REQ_DIGEST,
1270 DPROV_REQ_DIGEST_UPDATE,
1271 DPROV_REQ_DIGEST_KEY,
1272 DPROV_REQ_DIGEST_FINAL,
1273 DPROV_REQ_DIGEST_ATOMIC,
1274 /* cipher requests */
1275 DPROV_REQ_ENCRYPT_INIT,
1276 DPROV_REQ_ENCRYPT,
1277 DPROV_REQ_ENCRYPT_UPDATE,
1278 DPROV_REQ_ENCRYPT_FINAL,
1279 DPROV_REQ_ENCRYPT_ATOMIC,
1280 DPROV_REQ_DECRYPT_INIT,
1281 DPROV_REQ_DECRYPT,
1282 DPROV_REQ_DECRYPT_UPDATE,
1283 DPROV_REQ_DECRYPT_FINAL,
1284 DPROV_REQ_DECRYPT_ATOMIC,
1285 /* mac requests */
1286 DPROV_REQ_MAC_INIT,
1287 DPROV_REQ_MAC,
1288 DPROV_REQ_MAC_UPDATE,
1289 DPROV_REQ_MAC_FINAL,
1290 DPROV_REQ_MAC_ATOMIC,
1291 DPROV_REQ_MAC_VERIFY_ATOMIC,
1292 /* sign requests */
1293 DPROV_REQ_SIGN_INIT,
1294 DPROV_REQ_SIGN,
1295 DPROV_REQ_SIGN_UPDATE,
1296 DPROV_REQ_SIGN_FINAL,
1297 DPROV_REQ_SIGN_ATOMIC,
1298 DPROV_REQ_SIGN_RECOVER_INIT,
1299 DPROV_REQ_SIGN_RECOVER,
1300 DPROV_REQ_SIGN_RECOVER_ATOMIC,
1301 /* verify requests */
1302 DPROV_REQ_VERIFY_INIT,
1303 DPROV_REQ_VERIFY,
1304 DPROV_REQ_VERIFY_UPDATE,
1305 DPROV_REQ_VERIFY_FINAL,
1306 DPROV_REQ_VERIFY_ATOMIC,
1307 DPROV_REQ_VERIFY_RECOVER_INIT,
1308 DPROV_REQ_VERIFY_RECOVER,
1309 DPROV_REQ_VERIFY_RECOVER_ATOMIC,
1310 /* dual ops requests */
1311 DPROV_REQ_DIGEST_ENCRYPT_UPDATE,
1312 DPROV_REQ_DECRYPT_DIGEST_UPDATE,
1313 DPROV_REQ_SIGN_ENCRYPT_UPDATE,
1314 DPROV_REQ_DECRYPT_VERIFY_UPDATE,
1315 /* dual cipher/mac requests */
1316 DPROV_REQ_ENCRYPT_MAC_INIT,
1317 DPROV_REQ_ENCRYPT_MAC,
1318 DPROV_REQ_ENCRYPT_MAC_UPDATE,
1319 DPROV_REQ_ENCRYPT_MAC_FINAL,
1320 DPROV_REQ_ENCRYPT_MAC_ATOMIC,
1321 DPROV_REQ_MAC_DECRYPT_INIT,
1322 DPROV_REQ_MAC_DECRYPT,
1323 DPROV_REQ_MAC_DECRYPT_UPDATE,
1324 DPROV_REQ_MAC_DECRYPT_FINAL,
1325 DPROV_REQ_MAC_DECRYPT_ATOMIC,
1326 DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC,
1327 /* random number ops */
1328 DPROV_REQ_RANDOM_SEED,
1329 DPROV_REQ_RANDOM_GENERATE,
1330 /* session management requests */
1331 DPROV_REQ_SESSION_OPEN,
1332 DPROV_REQ_SESSION_CLOSE,
1333 DPROV_REQ_SESSION_LOGIN,
1334 DPROV_REQ_SESSION_LOGOUT,
1335 /* object management requests */
1336 DPROV_REQ_OBJECT_CREATE,
1337 DPROV_REQ_OBJECT_COPY,
1338 DPROV_REQ_OBJECT_DESTROY,
1339 DPROV_REQ_OBJECT_GET_SIZE,
1340 DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE,
1341 DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE,
1342 DPROV_REQ_OBJECT_FIND_INIT,
1343 DPROV_REQ_OBJECT_FIND,
1344 DPROV_REQ_OBJECT_FIND_FINAL,
1345 /* key management requests */
1346 DPROV_REQ_KEY_GENERATE,
1347 DPROV_REQ_KEY_GENERATE_PAIR,
1348 DPROV_REQ_KEY_WRAP,
1349 DPROV_REQ_KEY_UNWRAP,
1350 DPROV_REQ_KEY_DERIVE,
1351 /* provider management requests */
1352 DPROV_REQ_MGMT_EXTINFO,
1353 DPROV_REQ_MGMT_INITTOKEN,
1354 DPROV_REQ_MGMT_INITPIN,
1355 DPROV_REQ_MGMT_SETPIN,
1356 /* no (key)store key management requests */
1357 DPROV_REQ_NOSTORE_KEY_GENERATE,
1358 DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR,
1359 DPROV_REQ_NOSTORE_KEY_DERIVE
1360 } dprov_req_type_t;
1362 /* for DPROV_REQ_DIGEST requests */
1363 typedef struct dprov_digest_req {
1364 crypto_mechanism_t *dr_mechanism;
1365 crypto_ctx_t *dr_ctx;
1366 crypto_data_t *dr_data;
1367 crypto_key_t *dr_key;
1368 crypto_data_t *dr_digest;
1369 } dprov_digest_req_t;
1371 /* for DPROV_REQ_MAC requests */
1372 typedef struct dprov_mac_req {
1373 crypto_mechanism_t *dr_mechanism;
1374 crypto_ctx_t *dr_ctx;
1375 crypto_key_t *dr_key;
1376 crypto_data_t *dr_data;
1377 crypto_data_t *dr_mac;
1378 crypto_session_id_t dr_session_id;
1379 } dprov_mac_req_t;
1381 /* for DPROV_REQ_ENCRYPT and DPROV_REQ_DECRYPT requests */
1382 typedef struct dprov_cipher_req {
1383 crypto_mechanism_t *dr_mechanism;
1384 crypto_ctx_t *dr_ctx;
1385 crypto_key_t *dr_key;
1386 crypto_data_t *dr_plaintext;
1387 crypto_data_t *dr_ciphertext;
1388 crypto_session_id_t dr_session_id;
1389 } dprov_cipher_req_t;
1391 /* for DPROV_REQ_SIGN requests */
1392 typedef struct dprov_sign_req {
1393 crypto_mechanism_t *sr_mechanism;
1394 crypto_ctx_t *sr_ctx;
1395 crypto_key_t *sr_key;
1396 crypto_data_t *sr_data;
1397 crypto_data_t *sr_signature;
1398 crypto_session_id_t sr_session_id;
1399 } dprov_sign_req_t;
1401 /* for DPROV_REQ_VERIFY requests */
1402 typedef struct dprov_verify_req {
1403 crypto_mechanism_t *vr_mechanism;
1404 crypto_ctx_t *vr_ctx;
1405 crypto_key_t *vr_key;
1406 crypto_data_t *vr_data;
1407 crypto_data_t *vr_signature;
1408 crypto_session_id_t vr_session_id;
1409 } dprov_verify_req_t;
1411 /* for dual ops requests */
1412 typedef struct dprov_dual_req {
1413 crypto_ctx_t *dr_signverify_ctx;
1414 crypto_ctx_t *dr_cipher_ctx;
1415 crypto_data_t *dr_plaintext;
1416 crypto_data_t *dr_ciphertext;
1417 } dprov_dual_req_t;
1419 /* for cipher/mac dual ops requests */
1420 typedef struct dprov_cipher_mac_req {
1421 crypto_session_id_t mr_session_id;
1422 crypto_ctx_t *mr_ctx;
1423 crypto_mechanism_t *mr_cipher_mech;
1424 crypto_key_t *mr_cipher_key;
1425 crypto_mechanism_t *mr_mac_mech;
1426 crypto_key_t *mr_mac_key;
1427 crypto_dual_data_t *mr_dual_data;
1428 crypto_data_t *mr_data;
1429 crypto_data_t *mr_mac;
1430 } dprov_cipher_mac_req_t;
1432 /* for DPROV_REQ_RANDOM requests */
1433 typedef struct dprov_random_req {
1434 uchar_t *rr_buf;
1435 size_t rr_len;
1436 crypto_session_id_t rr_session_id;
1437 uint_t rr_entropy_est;
1438 uint32_t rr_flags;
1439 } dprov_random_req_t;
1441 /* for DPROV_REQ_SESSION requests */
1442 typedef struct dprov_session_req {
1443 crypto_session_id_t *sr_session_id_ptr;
1444 crypto_session_id_t sr_session_id;
1445 crypto_user_type_t sr_user_type;
1446 char *sr_pin;
1447 size_t sr_pin_len;
1448 } dprov_session_req_t;
1450 /* for DPROV_REQ_OBJECT requests */
1451 typedef struct dprov_object_req {
1452 crypto_session_id_t or_session_id;
1453 crypto_object_id_t or_object_id;
1454 crypto_object_attribute_t *or_template;
1455 uint_t or_attribute_count;
1456 crypto_object_id_t *or_object_id_ptr;
1457 size_t *or_object_size;
1458 void **or_find_pp;
1459 void *or_find_p;
1460 uint_t or_max_object_count;
1461 uint_t *or_object_count_ptr;
1462 } dprov_object_req_t;
1464 /* for DPROV_REQ_KEY requests */
1465 typedef struct dprov_key_req {
1466 crypto_session_id_t kr_session_id;
1467 crypto_mechanism_t *kr_mechanism;
1468 crypto_object_attribute_t *kr_template;
1469 uint_t kr_attribute_count;
1470 crypto_object_id_t *kr_object_id_ptr;
1471 crypto_object_attribute_t *kr_private_key_template;
1472 uint_t kr_private_key_attribute_count;
1473 crypto_object_id_t *kr_private_key_object_id_ptr;
1474 crypto_key_t *kr_key;
1475 uchar_t *kr_wrapped_key;
1476 size_t *kr_wrapped_key_len_ptr;
1477 crypto_object_attribute_t *kr_out_template1;
1478 crypto_object_attribute_t *kr_out_template2;
1479 uint_t kr_out_attribute_count1;
1480 uint_t kr_out_attribute_count2;
1481 } dprov_key_req_t;
1483 /* for DPROV_REQ_MGMT requests */
1484 typedef struct dprov_mgmt_req {
1485 crypto_session_id_t mr_session_id;
1486 char *mr_pin;
1487 size_t mr_pin_len;
1488 char *mr_old_pin;
1489 size_t mr_old_pin_len;
1490 char *mr_label;
1491 crypto_provider_ext_info_t *mr_ext_info;
1492 } dprov_mgmt_req_t;
1494 /* request, as queued on taskq */
1495 typedef struct dprov_req {
1496 dprov_req_type_t dr_type;
1497 dprov_state_t *dr_softc;
1498 crypto_req_handle_t dr_kcf_req;
1499 union {
1500 dprov_digest_req_t dru_digest_req;
1501 dprov_mac_req_t dru_mac_req;
1502 dprov_cipher_req_t dru_cipher_req;
1503 dprov_sign_req_t dru_sign_req;
1504 dprov_verify_req_t dru_verify_req;
1505 dprov_dual_req_t dru_dual_req;
1506 dprov_cipher_mac_req_t dru_cipher_mac_req;
1507 dprov_random_req_t dru_random_req;
1508 dprov_session_req_t dru_session_req;
1509 dprov_object_req_t dru_object_req;
1510 dprov_key_req_t dru_key_req;
1511 dprov_mgmt_req_t dru_mgmt_req;
1512 } dr_req;
1513 } dprov_req_t;
1515 /* shortcuts for union fields */
1516 #define dr_digest_req dr_req.dru_digest_req
1517 #define dr_mac_req dr_req.dru_mac_req
1518 #define dr_cipher_req dr_req.dru_cipher_req
1519 #define dr_sign_req dr_req.dru_sign_req
1520 #define dr_verify_req dr_req.dru_verify_req
1521 #define dr_dual_req dr_req.dru_dual_req
1522 #define dr_cipher_mac_req dr_req.dru_cipher_mac_req
1523 #define dr_random_req dr_req.dru_random_req
1524 #define dr_session_req dr_req.dru_session_req
1525 #define dr_object_req dr_req.dru_object_req
1526 #define dr_key_req dr_req.dru_key_req
1527 #define dr_mgmt_req dr_req.dru_mgmt_req
1529 /* prototypes for the tasq dispatcher functions */
1530 static void dprov_digest_task(dprov_req_t *);
1531 static void dprov_mac_task(dprov_req_t *);
1532 static void dprov_sign_task(dprov_req_t *);
1533 static void dprov_verify_task(dprov_req_t *);
1534 static void dprov_dual_task(dprov_req_t *);
1535 static void dprov_cipher_task(dprov_req_t *);
1536 static void dprov_cipher_mac_task(dprov_req_t *);
1537 static void dprov_random_task(dprov_req_t *);
1538 static void dprov_session_task(dprov_req_t *);
1539 static void dprov_object_task(dprov_req_t *);
1540 static void dprov_key_task(dprov_req_t *);
1541 static void dprov_mgmt_task(dprov_req_t *);
1543 /* helper functions */
1544 static int dprov_digest_submit_req(dprov_req_type_t, dprov_state_t *,
1545 crypto_req_handle_t, crypto_mechanism_t *, crypto_data_t *, crypto_key_t *,
1546 crypto_data_t *, crypto_ctx_t *, int);
1547 static int dprov_cipher_submit_req(dprov_req_type_t, dprov_state_t *,
1548 crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
1549 crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
1550 static int dprov_mac_submit_req(dprov_req_type_t, dprov_state_t *,
1551 crypto_req_handle_t, crypto_mechanism_t *, crypto_data_t *,
1552 crypto_key_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
1553 static int dprov_sign_submit_req(dprov_req_type_t, dprov_state_t *,
1554 crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *,
1555 crypto_data_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
1556 static int dprov_verify_submit_req(dprov_req_type_t, dprov_state_t *,
1557 crypto_req_handle_t, crypto_mechanism_t *, crypto_key_t *,
1558 crypto_data_t *, crypto_data_t *, crypto_ctx_t *, crypto_session_id_t, int);
1559 static int dprov_dual_submit_req(dprov_req_type_t, dprov_state_t *,
1560 crypto_req_handle_t, crypto_ctx_t *, crypto_ctx_t *, crypto_data_t *,
1561 crypto_data_t *);
1562 static int dprov_cipher_mac_submit_req(dprov_req_type_t, dprov_state_t *,
1563 crypto_req_handle_t, crypto_ctx_t *, crypto_session_id_t,
1564 crypto_mechanism_t *, crypto_key_t *, crypto_mechanism_t *, crypto_key_t *,
1565 crypto_dual_data_t *, crypto_data_t *, crypto_data_t *, int);
1566 static int dprov_random_submit_req(dprov_req_type_t, dprov_state_t *,
1567 crypto_req_handle_t, uchar_t *, size_t, crypto_session_id_t, uint_t,
1568 uint32_t);
1569 static int dprov_session_submit_req(dprov_req_type_t, dprov_state_t *,
1570 crypto_req_handle_t, crypto_session_id_t *, crypto_session_id_t,
1571 crypto_user_type_t, char *, size_t);
1572 static int dprov_object_submit_req(dprov_req_type_t, dprov_state_t *,
1573 crypto_req_handle_t, crypto_session_id_t, crypto_object_id_t,
1574 crypto_object_attribute_t *, uint_t, crypto_object_id_t *, size_t *,
1575 void **, void *, uint_t, uint_t *, int);
1576 static int dprov_key_submit_req(dprov_req_type_t, dprov_state_t *,
1577 crypto_req_handle_t, crypto_session_id_t, crypto_mechanism_t *,
1578 crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
1579 crypto_object_attribute_t *, uint_t, crypto_object_id_t *,
1580 crypto_key_t *, uchar_t *, size_t *, crypto_object_attribute_t *,
1581 uint_t, crypto_object_attribute_t *, uint_t);
1582 static int dprov_mgmt_submit_req(dprov_req_type_t, dprov_state_t *,
1583 crypto_req_handle_t, crypto_session_id_t, char *, size_t, char *, size_t,
1584 char *, crypto_provider_ext_info_t *);
1585 static int dprov_get_sw_prov(crypto_mechanism_t *, kcf_provider_desc_t **,
1586 crypto_mech_type_t *);
1588 /* object management helper functions */
1589 static void dprov_free_object(dprov_object_t *);
1590 static void dprov_release_session_objects(dprov_session_t *);
1591 static void dprov_adjust_attrs(crypto_object_attribute_t *, int);
1592 static boolean_t dprov_object_is_private(dprov_object_t *);
1593 static boolean_t dprov_object_is_token(dprov_object_t *);
1594 static int dprov_key_value_secret(dprov_state_t *, crypto_session_id_t,
1595 dprov_req_type_t, crypto_key_t *, crypto_key_t *);
1596 static int dprov_key_attr_asymmetric(dprov_state_t *, crypto_session_id_t,
1597 dprov_req_type_t, crypto_key_t *, crypto_key_t *);
1598 static int dprov_get_object_attr_boolean(dprov_object_t *, uint64_t,
1599 boolean_t *);
1600 static int dprov_get_object_attr_ulong(dprov_object_t *, uint64_t, ulong_t *);
1601 static int dprov_get_object_attr_array(dprov_object_t *, uint64_t, void **,
1602 size_t *);
1603 static int dprov_get_key_attr_ulong(crypto_key_t *, uint64_t, ulong_t *);
1604 static int dprov_get_key_attr_array(crypto_key_t *, uint64_t, void **,
1605 size_t *);
1606 static int dprov_create_object_from_template(dprov_state_t *, dprov_session_t *,
1607 crypto_object_attribute_t *, uint_t, crypto_object_id_t *, boolean_t,
1608 boolean_t);
1609 static int dprov_get_template_attr_scalar_common(crypto_object_attribute_t *,
1610 uint_t, uint64_t, void *, size_t);
1611 static int dprov_get_template_attr_boolean(crypto_object_attribute_t *,
1612 uint_t, uint64_t, boolean_t *);
1613 static int dprov_get_template_attr_ulong(crypto_object_attribute_t *, uint_t,
1614 uint64_t, ulong_t *);
1615 static int dprov_template_attr_present(crypto_object_attribute_t *, uint_t,
1616 uint64_t);
1617 static int dprov_get_template_attr_array(crypto_object_attribute_t *, uint_t,
1618 uint64_t, void **, size_t *);
1619 static int dprov_destroy_object(dprov_state_t *, dprov_session_t *,
1620 crypto_object_id_t);
1621 static int dprov_object_set_attr(dprov_session_t *, crypto_object_id_t,
1622 crypto_object_attribute_t *, uint_t, boolean_t);
1623 static int dprov_find_attr(crypto_object_attribute_t *, uint_t, uint64_t);
1624 static boolean_t dprov_attributes_match(dprov_object_t *,
1625 crypto_object_attribute_t *, uint_t);
1627 /* retrieve the softc and instance number from a SPI crypto context */
1628 #define DPROV_SOFTC_FROM_CTX(ctx, softc, instance) { \
1629 (softc) = (dprov_state_t *)(ctx)->cc_provider; \
1630 (instance) = ddi_get_instance((softc)->ds_dip); \
1633 /* retrieve the softc and instance number from a taskq request */
1634 #define DPROV_SOFTC_FROM_REQ(req, softc, instance) { \
1635 (softc) = (req)->dr_softc; \
1636 (instance) = ddi_get_instance((softc)->ds_dip); \
1640 * The dprov private context most of the time contains a pointer to the
1641 * crypto_context_t that was allocated when calling a KCF function.
1642 * Dual cipher/mac operations however require the dprov driver
1643 * to maintain the contexts associated with the separate cipher
1644 * and mac operations. These two types of dprov contexts are
1645 * defined below.
1647 typedef enum dprov_ctx_type {
1648 DPROV_CTX_SINGLE,
1649 DPROV_CTX_DUAL
1650 } dprov_ctx_type_t;
1653 * When the context refers to a single KCF context, the
1654 * cc_provider field of a crypto_ctx_t points to a structure of
1655 * type dprov_ctx_single.
1657 typedef struct dprov_ctx_single {
1658 dprov_ctx_type_t dc_type;
1659 crypto_context_t dc_ctx;
1660 boolean_t dc_svrfy_to_mac;
1661 } dprov_ctx_single_t;
1664 * When the context is used for cipher/mac operations, it contains
1665 * pointers to to KCF contexts, one for the cipher operation, the
1666 * other for the mac operation.
1668 typedef struct dprov_ctx_dual {
1669 dprov_ctx_type_t cd_type;
1670 crypto_context_t cd_cipher_ctx;
1671 crypto_context_t cd_mac_ctx;
1672 } dprov_ctx_dual_t;
1675 * Helper macros for context accessors. These macros return the
1676 * k-API context corresponding to the given SPI context for
1677 * single and dual cipher/mac operations.
1680 #define DPROV_CTX_P(_ctx) \
1681 ((dprov_ctx_single_t *)(_ctx)->cc_provider_private)
1683 #define DPROV_CTX_SINGLE(_ctx) ((DPROV_CTX_P(_ctx))->dc_ctx)
1685 #define DPROV_CTX_DUAL_CIPHER(_ctx) \
1686 (((dprov_ctx_dual_t *)(_ctx)->cc_provider_private)->cd_cipher_ctx)
1688 #define DPROV_CTX_DUAL_MAC(_ctx) \
1689 (((dprov_ctx_dual_t *)(_ctx)->cc_provider_private)->cd_mac_ctx)
1691 static int dprov_alloc_context(dprov_req_type_t, crypto_ctx_t *);
1695 static void *statep; /* state pointer */
1698 * DDI entry points.
1701 _init(void)
1703 int error;
1705 DPROV_DEBUG(D_INIT, ("dprov: in _init\n"));
1707 if ((error = ddi_soft_state_init(&statep, sizeof (dprov_state_t),
1708 0)) != 0)
1709 return (error);
1711 return (mod_install(&modlinkage));
1715 _fini(void)
1717 int error;
1719 DPROV_DEBUG(D_INIT, ("dprov: in _fini\n"));
1721 if ((error = mod_remove(&modlinkage)) != 0)
1722 return (error);
1724 ddi_soft_state_fini(&statep);
1726 return (0);
1730 _info(struct modinfo *modinfop)
1732 DPROV_DEBUG(D_INIT, ("dprov: in _info\n"));
1734 return (mod_info(&modlinkage, modinfop));
1737 /* ARGSUSED */
1738 static int
1739 dprov_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
1741 int instance = getminor((dev_t)arg);
1742 dprov_state_t *softc;
1744 DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_getinfo() for %d\n",
1745 instance));
1747 switch (cmd) {
1748 case DDI_INFO_DEVT2DEVINFO:
1749 softc = ddi_get_soft_state(statep, instance);
1750 *result = softc->ds_dip;
1751 return (DDI_SUCCESS);
1753 case DDI_INFO_DEVT2INSTANCE:
1754 *result = (void *)(uintptr_t)instance;
1755 return (DDI_SUCCESS);
1757 return (DDI_FAILURE);
1760 static int
1761 dprov_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1763 int instance = ddi_get_instance(dip);
1764 dprov_state_t *softc;
1765 char devname[256];
1766 int ret;
1768 DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_attach() for %d\n",
1769 instance));
1771 if (cmd != DDI_ATTACH) {
1772 return (DDI_FAILURE);
1775 /* get new softc and initialize it */
1776 if (ddi_soft_state_zalloc(statep, instance) != DDI_SUCCESS)
1777 return (DDI_FAILURE);
1779 softc = ddi_get_soft_state(statep, instance);
1780 mutex_init(&softc->ds_lock, NULL, MUTEX_DRIVER, NULL);
1781 softc->ds_dip = dip;
1782 softc->ds_prov_handle = 0;
1784 /* create minor node */
1785 (void) sprintf(devname, "dprov%d", instance);
1786 if (ddi_create_minor_node(dip, devname, S_IFCHR, instance,
1787 DDI_PSEUDO, 0) != DDI_SUCCESS) {
1788 cmn_err(CE_WARN, "attach: failed creating minor node");
1789 mutex_destroy(&softc->ds_lock);
1790 ddi_soft_state_free(statep, instance);
1791 return (DDI_FAILURE);
1794 nostore_key_gen = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1795 DDI_PROP_DONTPASS, "nostore_key_gen", 0);
1796 if (nostore_key_gen != 0) {
1797 dprov_prov_info.pi_interface_version = CRYPTO_SPI_VERSION_3;
1798 dprov_crypto_ops.co_object_ops = NULL;
1799 dprov_crypto_ops.co_nostore_key_ops = &dprov_nostore_key_ops;
1802 dprov_max_digestsz = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1803 DDI_PROP_DONTPASS, "max_digest_sz", INT_MAX);
1804 if (dprov_max_digestsz != INT_MAX && dprov_max_digestsz != 0 &&
1805 dprov_max_digestsz != DDI_PROP_NOT_FOUND) {
1806 dprov_no_multipart = B_TRUE;
1807 dprov_prov_info.pi_flags |=
1808 (CRYPTO_HASH_NO_UPDATE | CRYPTO_HMAC_NO_UPDATE);
1811 /* create taskq */
1812 softc->ds_taskq = taskq_create(devname, 1, minclsyspri,
1813 crypto_taskq_minalloc, crypto_taskq_maxalloc, TASKQ_PREPOPULATE);
1815 /* initialize table of sessions */
1816 softc->ds_sessions = kmem_zalloc(DPROV_MIN_SESSIONS *
1817 sizeof (dprov_session_t *), KM_SLEEP);
1818 softc->ds_sessions_slots = DPROV_MIN_SESSIONS;
1819 softc->ds_sessions_count = 0;
1821 /* initialized done by init_token entry point */
1822 softc->ds_token_initialized = B_TRUE;
1824 (void) memset(softc->ds_label, ' ', CRYPTO_EXT_SIZE_LABEL);
1825 bcopy("Dummy Pseudo HW Provider", softc->ds_label, 24);
1827 bcopy("changeme", softc->ds_user_pin, 8);
1828 softc->ds_user_pin_len = 8;
1829 softc->ds_user_pin_set = B_TRUE;
1831 /* register with the crypto framework */
1832 dprov_prov_info.pi_provider_dev.pd_hw = dip;
1833 dprov_prov_info.pi_provider_handle = softc;
1835 if (dprov_no_multipart) { /* Export only single part */
1836 dprov_digest_ops.digest_update = NULL;
1837 dprov_digest_ops.digest_key = NULL;
1838 dprov_digest_ops.digest_final = NULL;
1839 dprov_object_ops.object_create = NULL;
1842 if ((ret = crypto_register_provider(&dprov_prov_info,
1843 &softc->ds_prov_handle)) != CRYPTO_SUCCESS) {
1844 cmn_err(CE_WARN,
1845 "dprov crypto_register_provider() failed (0x%x)", ret);
1846 taskq_destroy(softc->ds_taskq);
1847 kmem_free(softc->ds_sessions, softc->ds_sessions_slots *
1848 sizeof (dprov_session_t *));
1849 mutex_destroy(&softc->ds_lock);
1850 ddi_soft_state_free(statep, instance);
1851 ddi_remove_minor_node(dip, NULL);
1852 return (DDI_FAILURE);
1856 * This call is for testing only; it is not required by the SPI.
1858 crypto_provider_notification(softc->ds_prov_handle,
1859 CRYPTO_PROVIDER_READY);
1861 return (DDI_SUCCESS);
1864 static int
1865 dprov_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1867 int instance = ddi_get_instance(dip);
1868 dprov_state_t *softc = ddi_get_soft_state(statep, instance);
1869 dprov_session_t *session;
1870 int i, ret;
1872 DPROV_DEBUG(D_ATTACH, ("dprov: in dprov_detach() for %d\n",
1873 instance));
1875 if (cmd != DDI_DETACH)
1876 return (DDI_FAILURE);
1878 /* unregister from the crypto framework */
1879 if (softc->ds_prov_handle != 0)
1880 if ((ret = crypto_unregister_provider(
1881 softc->ds_prov_handle)) != CRYPTO_SUCCESS) {
1882 cmn_err(CE_WARN, "dprov_detach: "
1883 "crypto_unregister_provider() "
1884 "failed (0x%x)", ret);
1885 return (DDI_FAILURE);
1889 taskq_destroy(softc->ds_taskq);
1891 for (i = 0; i < softc->ds_sessions_slots; i++) {
1892 if ((session = softc->ds_sessions[i]) == NULL)
1893 continue;
1895 dprov_release_session_objects(session);
1897 kmem_free(session, sizeof (dprov_session_t));
1898 softc->ds_sessions_count--;
1902 kmem_free(softc->ds_sessions, softc->ds_sessions_slots *
1903 sizeof (dprov_session_t *));
1904 /* free token objects */
1905 for (i = 0; i < DPROV_MAX_OBJECTS; i++)
1906 if (softc->ds_objects[i] != NULL)
1907 dprov_free_object(softc->ds_objects[i]);
1909 mutex_destroy(&softc->ds_lock);
1910 ddi_soft_state_free(statep, instance);
1912 ddi_remove_minor_node(dip, NULL);
1914 return (DDI_SUCCESS);
1918 * Control entry points.
1920 static void
1921 dprov_provider_status(crypto_provider_handle_t provider, uint_t *status)
1923 _NOTE(ARGUNUSED(provider))
1925 *status = CRYPTO_PROVIDER_READY;
1929 * Digest entry points.
1932 static int
1933 dprov_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
1934 crypto_req_handle_t req)
1936 int error = CRYPTO_FAILED;
1937 dprov_state_t *softc;
1938 /* LINTED E_FUNC_SET_NOT_USED */
1939 int instance;
1941 /* extract softc and instance number from context */
1942 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
1943 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_init: started\n", instance));
1945 /* check mechanism */
1946 if (mechanism->cm_type != MD4_MECH_INFO_TYPE &&
1947 mechanism->cm_type != MD5_MECH_INFO_TYPE &&
1948 mechanism->cm_type != SHA1_MECH_INFO_TYPE &&
1949 mechanism->cm_type != SHA256_MECH_INFO_TYPE &&
1950 mechanism->cm_type != SHA384_MECH_INFO_TYPE &&
1951 mechanism->cm_type != SHA512_MECH_INFO_TYPE) {
1952 cmn_err(CE_WARN, "dprov_digest_init: unexpected mech type "
1953 "0x%llx\n", (unsigned long long)mechanism->cm_type);
1954 return (CRYPTO_MECHANISM_INVALID);
1957 /* submit request to the taskq */
1958 error = dprov_digest_submit_req(DPROV_REQ_DIGEST_INIT, softc, req,
1959 mechanism, NULL, NULL, NULL, ctx, KM_SLEEP);
1961 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_init: done err = 0x%x\n",
1962 instance, error));
1964 return (error);
1967 static int
1968 dprov_digest(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *digest,
1969 crypto_req_handle_t req)
1971 int error = CRYPTO_FAILED;
1972 dprov_state_t *softc;
1973 /* LINTED E_FUNC_SET_NOT_USED */
1974 int instance;
1976 if (dprov_no_multipart && data->cd_length > dprov_max_digestsz)
1977 return (CRYPTO_BUFFER_TOO_BIG);
1979 /* extract softc and instance number from context */
1980 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
1981 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest: started\n", instance));
1983 /* submit request to the taskq */
1984 error = dprov_digest_submit_req(DPROV_REQ_DIGEST, softc, req,
1985 NULL, data, NULL, digest, ctx, KM_NOSLEEP);
1987 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest: done, err = 0x%x\n",
1988 instance, error));
1990 return (error);
1993 static int
1994 dprov_digest_update(crypto_ctx_t *ctx, crypto_data_t *data,
1995 crypto_req_handle_t req)
1997 int error = CRYPTO_FAILED;
1998 dprov_state_t *softc;
1999 /* LINTED E_FUNC_SET_NOT_USED */
2000 int instance;
2002 /* extract softc and instance number from context */
2003 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2004 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_update: started\n",
2005 instance));
2007 /* submit request to the taskq */
2008 error = dprov_digest_submit_req(DPROV_REQ_DIGEST_UPDATE, softc,
2009 req, NULL, data, NULL, NULL, ctx, KM_NOSLEEP);
2011 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_update: done err = 0x0%x\n",
2012 instance, error));
2014 return (error);
2017 static int
2018 dprov_digest_key(crypto_ctx_t *ctx, crypto_key_t *key, crypto_req_handle_t req)
2020 int error = CRYPTO_FAILED;
2021 dprov_state_t *softc;
2022 /* LINTED E_FUNC_SET_NOT_USED */
2023 int instance;
2025 /* extract softc and instance number from context */
2026 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2027 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_key: started\n", instance));
2029 /* submit request to the taskq */
2030 error = dprov_digest_submit_req(DPROV_REQ_DIGEST_KEY, softc, req, NULL,
2031 NULL, key, NULL, ctx, KM_NOSLEEP);
2033 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_key: done err = 0x0%x\n",
2034 instance, error));
2036 return (error);
2039 static int
2040 dprov_digest_final(crypto_ctx_t *ctx, crypto_data_t *digest,
2041 crypto_req_handle_t req)
2043 int error = CRYPTO_FAILED;
2044 dprov_state_t *softc;
2045 /* LINTED E_FUNC_SET_NOT_USED */
2046 int instance;
2048 /* extract softc and instance number from context */
2049 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2050 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_final: started\n", instance));
2052 /* submit request to the taskq */
2053 error = dprov_digest_submit_req(DPROV_REQ_DIGEST_FINAL, softc, req,
2054 NULL, NULL, NULL, digest, ctx, KM_NOSLEEP);
2056 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_final: done err = 0x0%x\n",
2057 instance, error));
2059 return (error);
2062 /* ARGSUSED */
2063 static int
2064 dprov_digest_atomic(crypto_provider_handle_t provider,
2065 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
2066 crypto_data_t *data, crypto_data_t *digest,
2067 crypto_req_handle_t req)
2069 int error = CRYPTO_FAILED;
2070 dprov_state_t *softc = (dprov_state_t *)provider;
2071 /* LINTED E_FUNC_SET_NOT_USED */
2072 int instance;
2074 if (dprov_no_multipart && data->cd_length > dprov_max_digestsz)
2075 return (CRYPTO_BUFFER_TOO_BIG);
2077 instance = ddi_get_instance(softc->ds_dip);
2078 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_atomic: started\n",
2079 instance));
2081 /* check mechanism */
2082 if (mechanism->cm_type != MD4_MECH_INFO_TYPE &&
2083 mechanism->cm_type != MD5_MECH_INFO_TYPE &&
2084 mechanism->cm_type != SHA1_MECH_INFO_TYPE &&
2085 mechanism->cm_type != SHA256_MECH_INFO_TYPE &&
2086 mechanism->cm_type != SHA384_MECH_INFO_TYPE &&
2087 mechanism->cm_type != SHA512_MECH_INFO_TYPE) {
2088 cmn_err(CE_WARN, "dprov_digest_atomic: unexpected mech type "
2089 "0x%llx\n", (unsigned long long)mechanism->cm_type);
2090 return (CRYPTO_MECHANISM_INVALID);
2093 /* submit request to the taskq */
2094 error = dprov_digest_submit_req(DPROV_REQ_DIGEST_ATOMIC, softc, req,
2095 mechanism, data, NULL, digest, NULL, KM_SLEEP);
2097 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_atomic: done err = 0x0%x\n",
2098 instance, error));
2100 return (error);
2104 * MAC entry points.
2108 * Checks whether the specified mech_type is supported by mac
2109 * entry points.
2111 static boolean_t
2112 dprov_valid_mac_mech(crypto_mech_type_t mech_type)
2114 return (mech_type == MD5_HMAC_MECH_INFO_TYPE ||
2115 mech_type == MD5_HMAC_GEN_MECH_INFO_TYPE ||
2116 mech_type == SHA1_HMAC_MECH_INFO_TYPE ||
2117 mech_type == SHA1_HMAC_GEN_MECH_INFO_TYPE ||
2118 mech_type == SHA256_HMAC_MECH_INFO_TYPE ||
2119 mech_type == SHA256_HMAC_GEN_MECH_INFO_TYPE ||
2120 mech_type == SHA384_HMAC_MECH_INFO_TYPE ||
2121 mech_type == SHA384_HMAC_GEN_MECH_INFO_TYPE ||
2122 mech_type == SHA512_HMAC_MECH_INFO_TYPE ||
2123 mech_type == SHA512_HMAC_GEN_MECH_INFO_TYPE ||
2124 mech_type == AES_GMAC_MECH_INFO_TYPE ||
2125 mech_type == AES_CMAC_MECH_INFO_TYPE);
2128 static int
2129 dprov_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
2130 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
2131 crypto_req_handle_t req)
2133 int error = CRYPTO_FAILED;
2134 dprov_state_t *softc;
2135 /* LINTED E_FUNC_SET_NOT_USED */
2136 int instance;
2138 /* extract softc and instance number from context */
2139 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2140 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_init: started\n", instance));
2142 /* check mechanism */
2143 if (!dprov_valid_mac_mech(mechanism->cm_type)) {
2144 cmn_err(CE_WARN, "dprov_mac_init: unexpected mech type "
2145 "0x%llx\n", (unsigned long long)mechanism->cm_type);
2146 return (CRYPTO_MECHANISM_INVALID);
2149 if (ctx_template != NULL)
2150 return (CRYPTO_ARGUMENTS_BAD);
2152 /* submit request to the taskq */
2153 error = dprov_mac_submit_req(DPROV_REQ_MAC_INIT, softc, req,
2154 mechanism, NULL, key, NULL, ctx, 0, KM_SLEEP);
2156 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_init: done err = 0x%x\n",
2157 instance, error));
2159 return (error);
2162 static int
2163 dprov_mac(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *mac,
2164 crypto_req_handle_t req)
2166 int error = CRYPTO_FAILED;
2167 dprov_state_t *softc;
2168 /* LINTED E_FUNC_SET_NOT_USED */
2169 int instance;
2171 /* extract softc and instance number from context */
2172 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2173 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac: started\n", instance));
2175 /* submit request to the taskq */
2176 error = dprov_mac_submit_req(DPROV_REQ_MAC, softc, req,
2177 NULL, data, NULL, mac, ctx, 0, KM_NOSLEEP);
2179 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac: done, err = 0x%x\n", instance,
2180 error));
2182 return (error);
2185 static int
2186 dprov_mac_update(crypto_ctx_t *ctx, crypto_data_t *data,
2187 crypto_req_handle_t req)
2189 int error = CRYPTO_FAILED;
2190 dprov_state_t *softc;
2191 /* LINTED E_FUNC_SET_NOT_USED */
2192 int instance;
2194 /* extract softc and instance number from context */
2195 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2196 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_update: started\n", instance));
2198 /* submit request to the taskq */
2199 error = dprov_mac_submit_req(DPROV_REQ_MAC_UPDATE, softc,
2200 req, NULL, data, NULL, NULL, ctx, 0, KM_NOSLEEP);
2202 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_update: done err = 0x0%x\n",
2203 instance, error));
2205 return (error);
2208 static int
2209 dprov_mac_final(crypto_ctx_t *ctx, crypto_data_t *mac, crypto_req_handle_t req)
2211 int error = CRYPTO_FAILED;
2212 dprov_state_t *softc;
2213 /* LINTED E_FUNC_SET_NOT_USED */
2214 int instance;
2216 /* extract softc and instance number from context */
2217 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2218 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_final: started\n", instance));
2220 /* submit request to the taskq */
2221 error = dprov_mac_submit_req(DPROV_REQ_MAC_FINAL, softc, req,
2222 NULL, NULL, NULL, mac, ctx, 0, KM_NOSLEEP);
2224 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_final: done err = 0x0%x\n",
2225 instance, error));
2227 return (error);
2230 static int
2231 dprov_mac_atomic(crypto_provider_handle_t provider,
2232 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
2233 crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
2234 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
2236 int error = CRYPTO_FAILED;
2237 dprov_state_t *softc = (dprov_state_t *)provider;
2238 /* LINTED E_FUNC_SET_NOT_USED */
2239 int instance;
2241 instance = ddi_get_instance(softc->ds_dip);
2242 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_atomic: started\n", instance));
2244 if (ctx_template != NULL)
2245 return (CRYPTO_ARGUMENTS_BAD);
2247 /* check mechanism */
2248 if (!dprov_valid_mac_mech(mechanism->cm_type)) {
2249 cmn_err(CE_WARN, "dprov_mac_atomic: unexpected mech type "
2250 "0x%llx\n", (unsigned long long)mechanism->cm_type);
2251 return (CRYPTO_MECHANISM_INVALID);
2254 /* submit request to the taskq */
2255 error = dprov_mac_submit_req(DPROV_REQ_MAC_ATOMIC, softc, req,
2256 mechanism, data, key, mac, NULL, session_id, KM_SLEEP);
2258 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_atomic: done err = 0x0%x\n",
2259 instance, error));
2261 return (error);
2264 static int
2265 dprov_mac_verify_atomic(crypto_provider_handle_t provider,
2266 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
2267 crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
2268 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
2270 int error = CRYPTO_FAILED;
2271 dprov_state_t *softc = (dprov_state_t *)provider;
2272 /* LINTED E_FUNC_SET_NOT_USED */
2273 int instance;
2275 instance = ddi_get_instance(softc->ds_dip);
2276 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_verify_atomic: started\n",
2277 instance));
2279 if (ctx_template != NULL)
2280 return (CRYPTO_ARGUMENTS_BAD);
2282 /* check mechanism */
2283 if (!dprov_valid_mac_mech(mechanism->cm_type)) {
2284 cmn_err(CE_WARN, "dprov_mac_verify_atomic: unexpected mech "
2285 "type 0x%llx\n", (unsigned long long)mechanism->cm_type);
2286 return (CRYPTO_MECHANISM_INVALID);
2289 /* submit request to the taskq */
2290 error = dprov_mac_submit_req(DPROV_REQ_MAC_VERIFY_ATOMIC, softc, req,
2291 mechanism, data, key, mac, NULL, session_id, KM_SLEEP);
2293 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_verify_atomic: done err = 0x0%x\n",
2294 instance, error));
2296 return (error);
2300 * Cipher (encrypt/decrypt) entry points.
2304 * Checks whether the specified mech_type is supported by cipher entry
2305 * points.
2307 static boolean_t
2308 dprov_valid_cipher_mech(crypto_mech_type_t mech_type)
2310 return (mech_type == DES_CBC_MECH_INFO_TYPE ||
2311 mech_type == DES3_CBC_MECH_INFO_TYPE ||
2312 mech_type == DES_ECB_MECH_INFO_TYPE ||
2313 mech_type == DES3_ECB_MECH_INFO_TYPE ||
2314 mech_type == BLOWFISH_CBC_MECH_INFO_TYPE ||
2315 mech_type == BLOWFISH_ECB_MECH_INFO_TYPE ||
2316 mech_type == AES_CBC_MECH_INFO_TYPE ||
2317 mech_type == AES_CMAC_MECH_INFO_TYPE ||
2318 mech_type == AES_ECB_MECH_INFO_TYPE ||
2319 mech_type == AES_CTR_MECH_INFO_TYPE ||
2320 mech_type == AES_CCM_MECH_INFO_TYPE ||
2321 mech_type == AES_GCM_MECH_INFO_TYPE ||
2322 mech_type == AES_GMAC_MECH_INFO_TYPE ||
2323 mech_type == RC4_MECH_INFO_TYPE ||
2324 mech_type == RSA_PKCS_MECH_INFO_TYPE ||
2325 mech_type == RSA_X_509_MECH_INFO_TYPE ||
2326 mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE ||
2327 mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE ||
2328 mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE ||
2329 mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE ||
2330 mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE);
2333 static boolean_t
2334 is_publickey_mech(crypto_mech_type_t mech_type)
2336 return (mech_type == RSA_PKCS_MECH_INFO_TYPE ||
2337 mech_type == RSA_X_509_MECH_INFO_TYPE ||
2338 mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE ||
2339 mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE ||
2340 mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE ||
2341 mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE ||
2342 mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE ||
2343 mech_type == ECDSA_SHA1_MECH_INFO_TYPE ||
2344 mech_type == ECDSA_MECH_INFO_TYPE);
2348 /* ARGSUSED */
2349 static int
2350 dprov_encrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
2351 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
2352 crypto_req_handle_t req)
2354 int error = CRYPTO_FAILED;
2355 dprov_state_t *softc;
2356 /* LINTED E_FUNC_SET_NOT_USED */
2357 int instance;
2359 /* extract softc and instance number from context */
2360 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2361 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_init: started\n",
2362 instance));
2364 /* check mechanism */
2365 if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
2366 cmn_err(CE_WARN, "dprov_encrypt_init: unexpected mech type "
2367 "0x%llx\n", (unsigned long long)mechanism->cm_type);
2368 return (CRYPTO_MECHANISM_INVALID);
2371 /* submit request to the taskq */
2372 error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_INIT, softc,
2373 req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
2375 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_init: done err = 0x0%x\n",
2376 instance, error));
2378 return (error);
2381 /* ARGSUSED */
2382 static int
2383 dprov_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
2384 crypto_data_t *ciphertext, crypto_req_handle_t req)
2386 int error = CRYPTO_FAILED;
2387 dprov_state_t *softc;
2388 /* LINTED E_FUNC_SET_NOT_USED */
2389 int instance;
2391 /* extract softc and instance number from context */
2392 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2393 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt: started\n", instance));
2395 /* submit request to the taskq */
2396 error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT, softc,
2397 req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
2399 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt: done err = 0x0%x\n",
2400 instance, error));
2402 return (error);
2405 /* ARGSUSED */
2406 static int
2407 dprov_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
2408 crypto_data_t *ciphertext, crypto_req_handle_t req)
2410 int error = CRYPTO_FAILED;
2411 dprov_state_t *softc;
2412 /* LINTED E_FUNC_SET_NOT_USED */
2413 int instance;
2415 /* extract softc and instance number from context */
2416 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2417 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_update: started\n",
2418 instance));
2420 /* submit request to the taskq */
2421 error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_UPDATE, softc,
2422 req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
2424 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_update: done err = 0x0%x\n",
2425 instance, error));
2427 return (error);
2430 /* ARGSUSED */
2431 static int
2432 dprov_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
2433 crypto_req_handle_t req)
2435 int error = CRYPTO_FAILED;
2436 dprov_state_t *softc;
2437 /* LINTED E_FUNC_SET_NOT_USED */
2438 int instance;
2440 /* extract softc and instance number from context */
2441 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2442 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_final: started\n",
2443 instance));
2445 /* submit request to the taskq */
2446 error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_FINAL, softc,
2447 req, NULL, NULL, NULL, ciphertext, ctx, 0, KM_NOSLEEP);
2449 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_encrypt_final: done err = 0x0%x\n",
2450 instance, error));
2452 return (error);
2455 static int
2456 dprov_encrypt_atomic(crypto_provider_handle_t provider,
2457 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
2458 crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext,
2459 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
2461 int error = CRYPTO_FAILED;
2462 dprov_state_t *softc = (dprov_state_t *)provider;
2463 /* LINTED E_FUNC_SET_NOT_USED */
2464 int instance;
2466 instance = ddi_get_instance(softc->ds_dip);
2467 DPROV_DEBUG(D_MAC, ("(%d) dprov_encrypt_atomic: started\n", instance));
2469 if (ctx_template != NULL)
2470 return (CRYPTO_ARGUMENTS_BAD);
2472 /* check mechanism */
2473 if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
2474 cmn_err(CE_WARN, "dprov_encrypt_atomic: unexpected mech type "
2475 "0x%llx\n", (unsigned long long)mechanism->cm_type);
2476 return (CRYPTO_MECHANISM_INVALID);
2479 error = dprov_cipher_submit_req(DPROV_REQ_ENCRYPT_ATOMIC, softc,
2480 req, mechanism, key, plaintext, ciphertext, NULL, session_id,
2481 KM_SLEEP);
2483 DPROV_DEBUG(D_MAC, ("(%d) dprov_encrypt_atomic: done err = 0x0%x\n",
2484 instance, error));
2486 return (error);
2489 /* ARGSUSED */
2490 static int
2491 dprov_decrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
2492 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
2493 crypto_req_handle_t req)
2495 int error = CRYPTO_FAILED;
2496 dprov_state_t *softc;
2497 /* LINTED E_FUNC_SET_NOT_USED */
2498 int instance;
2500 /* extract softc and instance number from context */
2501 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2502 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_init: started\n",
2503 instance));
2505 /* check mechanism */
2506 if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
2507 cmn_err(CE_WARN, "dprov_decrypt_init: unexpected mech type "
2508 "0x%llx\n", (unsigned long long)mechanism->cm_type);
2509 return (CRYPTO_MECHANISM_INVALID);
2512 /* submit request to the taskq */
2513 error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_INIT, softc,
2514 req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
2516 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_init: done err = 0x0%x\n",
2517 instance, error));
2519 return (error);
2522 /* ARGSUSED */
2523 static int
2524 dprov_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
2525 crypto_data_t *plaintext, crypto_req_handle_t req)
2527 int error = CRYPTO_FAILED;
2529 dprov_state_t *softc;
2530 /* LINTED E_FUNC_SET_NOT_USED */
2531 int instance;
2533 /* extract softc and instance number from context */
2534 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2535 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt: started\n", instance));
2537 /* submit request to the taskq */
2538 error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT, softc,
2539 req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
2541 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt: done err = 0x0%x\n",
2542 instance, error));
2544 return (error);
2547 /* ARGSUSED */
2548 static int
2549 dprov_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
2550 crypto_data_t *plaintext, crypto_req_handle_t req)
2552 int error = CRYPTO_FAILED;
2553 dprov_state_t *softc;
2554 /* LINTED E_FUNC_SET_NOT_USED */
2555 int instance;
2557 /* extract softc and instance number from context */
2558 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2559 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_update: started\n",
2560 instance));
2562 /* submit request to the taskq */
2563 error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_UPDATE, softc,
2564 req, NULL, NULL, plaintext, ciphertext, ctx, 0, KM_NOSLEEP);
2566 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_update: done err = 0x0%x\n",
2567 instance, error));
2569 return (error);
2572 /* ARGSUSED */
2573 static int
2574 dprov_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *plaintext,
2575 crypto_req_handle_t req)
2577 int error = CRYPTO_FAILED;
2578 dprov_state_t *softc;
2579 /* LINTED E_FUNC_SET_NOT_USED */
2580 int instance;
2582 /* extract softc and instance number from context */
2583 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2584 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_final: started\n",
2585 instance));
2587 /* submit request to the taskq */
2588 error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_FINAL, softc,
2589 req, NULL, NULL, plaintext, NULL, ctx, 0, KM_NOSLEEP);
2591 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_decrypt_final: done err = 0x0%x\n",
2592 instance, error));
2594 return (error);
2597 static int
2598 dprov_decrypt_atomic(crypto_provider_handle_t provider,
2599 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
2600 crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext,
2601 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
2603 int error = CRYPTO_FAILED;
2604 dprov_state_t *softc = (dprov_state_t *)provider;
2605 /* LINTED E_FUNC_SET_NOT_USED */
2606 int instance;
2608 instance = ddi_get_instance(softc->ds_dip);
2609 DPROV_DEBUG(D_MAC, ("(%d) dprov_decrypt_atomic: started\n", instance));
2611 if (ctx_template != NULL)
2612 return (CRYPTO_ARGUMENTS_BAD);
2614 /* check mechanism */
2615 if (!dprov_valid_cipher_mech(mechanism->cm_type)) {
2616 cmn_err(CE_WARN, "dprov_atomic_init: unexpected mech type "
2617 "0x%llx\n", (unsigned long long)mechanism->cm_type);
2618 return (CRYPTO_MECHANISM_INVALID);
2621 error = dprov_cipher_submit_req(DPROV_REQ_DECRYPT_ATOMIC, softc,
2622 req, mechanism, key, plaintext, ciphertext, NULL, session_id,
2623 KM_SLEEP);
2625 DPROV_DEBUG(D_MAC, ("(%d) dprov_decrypt_atomic: done err = 0x0%x\n",
2626 instance, error));
2628 return (error);
2632 * Sign entry points.
2636 * Checks whether the specified mech_type is supported by sign/verify
2637 * entry points.
2639 static boolean_t
2640 dprov_valid_sign_verif_mech(crypto_mech_type_t mech_type)
2642 return (mech_type == MD5_HMAC_MECH_INFO_TYPE ||
2643 mech_type == MD5_HMAC_GEN_MECH_INFO_TYPE ||
2644 mech_type == SHA1_HMAC_MECH_INFO_TYPE ||
2645 mech_type == SHA1_HMAC_GEN_MECH_INFO_TYPE ||
2646 mech_type == SHA256_HMAC_MECH_INFO_TYPE ||
2647 mech_type == SHA256_HMAC_GEN_MECH_INFO_TYPE ||
2648 mech_type == SHA384_HMAC_MECH_INFO_TYPE ||
2649 mech_type == SHA384_HMAC_GEN_MECH_INFO_TYPE ||
2650 mech_type == SHA512_HMAC_MECH_INFO_TYPE ||
2651 mech_type == SHA512_HMAC_GEN_MECH_INFO_TYPE ||
2652 mech_type == RSA_PKCS_MECH_INFO_TYPE ||
2653 mech_type == RSA_X_509_MECH_INFO_TYPE ||
2654 mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE ||
2655 mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE ||
2656 mech_type == SHA256_RSA_PKCS_MECH_INFO_TYPE ||
2657 mech_type == SHA384_RSA_PKCS_MECH_INFO_TYPE ||
2658 mech_type == SHA512_RSA_PKCS_MECH_INFO_TYPE ||
2659 mech_type == ECDSA_SHA1_MECH_INFO_TYPE ||
2660 mech_type == ECDSA_MECH_INFO_TYPE ||
2661 mech_type == AES_CMAC_MECH_INFO_TYPE);
2664 static int
2665 dprov_sign_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
2666 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
2667 crypto_req_handle_t req)
2669 int error = CRYPTO_FAILED;
2670 dprov_state_t *softc;
2671 /* LINTED E_FUNC_SET_NOT_USED */
2672 int instance;
2674 /* extract softc and instance number from context */
2675 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2676 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_init: started\n", instance));
2678 /* check mechanism */
2679 if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
2680 cmn_err(CE_WARN, "dprov_sign_init: unexpected mech type "
2681 "0x%llx\n", (unsigned long long)mechanism->cm_type);
2682 return (CRYPTO_MECHANISM_INVALID);
2685 if (ctx_template != NULL)
2686 return (CRYPTO_ARGUMENTS_BAD);
2688 /* submit request to the taskq */
2689 error = dprov_sign_submit_req(DPROV_REQ_SIGN_INIT, softc, req,
2690 mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
2692 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_init: done err = 0x%x\n",
2693 instance, error));
2695 return (error);
2698 static int
2699 dprov_sign(crypto_ctx_t *ctx, crypto_data_t *data,
2700 crypto_data_t *signature, crypto_req_handle_t req)
2702 int error = CRYPTO_FAILED;
2703 dprov_state_t *softc;
2704 /* LINTED E_FUNC_SET_NOT_USED */
2705 int instance;
2707 /* extract softc and instance number from context */
2708 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2709 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign: started\n", instance));
2711 /* submit request to the taskq */
2712 error = dprov_sign_submit_req(DPROV_REQ_SIGN, softc, req,
2713 NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
2715 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign: done err = 0x%x\n",
2716 instance, error));
2718 return (error);
2721 static int
2722 dprov_sign_update(crypto_ctx_t *ctx, crypto_data_t *data,
2723 crypto_req_handle_t req)
2725 int error = CRYPTO_FAILED;
2726 dprov_state_t *softc;
2727 /* LINTED E_FUNC_SET_NOT_USED */
2728 int instance;
2730 /* extract softc and instance number from context */
2731 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2732 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_update: started\n", instance));
2734 /* submit request to the taskq */
2735 error = dprov_sign_submit_req(DPROV_REQ_SIGN_UPDATE, softc, req,
2736 NULL, NULL, data, NULL, ctx, 0, KM_NOSLEEP);
2738 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_update: done err = 0x%x\n",
2739 instance, error));
2741 return (error);
2744 static int
2745 dprov_sign_final(crypto_ctx_t *ctx, crypto_data_t *signature,
2746 crypto_req_handle_t req)
2748 int error = CRYPTO_FAILED;
2749 dprov_state_t *softc;
2750 /* LINTED E_FUNC_SET_NOT_USED */
2751 int instance;
2753 /* extract softc and instance number from context */
2754 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2755 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_final: started\n", instance));
2757 /* submit request to the taskq */
2758 error = dprov_sign_submit_req(DPROV_REQ_SIGN_FINAL, softc, req,
2759 NULL, NULL, NULL, signature, ctx, 0, KM_NOSLEEP);
2761 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_final: done err = 0x%x\n",
2762 instance, error));
2764 return (error);
2767 static int
2768 dprov_sign_atomic(crypto_provider_handle_t provider,
2769 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
2770 crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature,
2771 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
2773 int error = CRYPTO_FAILED;
2774 dprov_state_t *softc = (dprov_state_t *)provider;
2775 /* LINTED E_FUNC_SET_NOT_USED */
2776 int instance;
2778 instance = ddi_get_instance(softc->ds_dip);
2779 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_atomic: started\n", instance));
2781 /* check mechanism */
2782 if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
2783 cmn_err(CE_WARN, "dprov_sign_atomic: unexpected mech type "
2784 "0x%llx\n", (unsigned long long)mechanism->cm_type);
2785 return (CRYPTO_MECHANISM_INVALID);
2788 if (ctx_template != NULL)
2789 return (CRYPTO_ARGUMENTS_BAD);
2791 /* submit request to the taskq */
2792 error = dprov_sign_submit_req(DPROV_REQ_SIGN_ATOMIC, softc, req,
2793 mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
2795 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_atomic: done err = 0x%x\n",
2796 instance, error));
2798 return (error);
2801 static int
2802 dprov_sign_recover_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
2803 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
2804 crypto_req_handle_t req)
2806 int error = CRYPTO_FAILED;
2807 dprov_state_t *softc;
2808 /* LINTED E_FUNC_SET_NOT_USED */
2809 int instance;
2811 /* extract softc and instance number from context */
2812 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2813 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_init: started\n",
2814 instance));
2816 if (ctx_template != NULL)
2817 return (CRYPTO_ARGUMENTS_BAD);
2819 /* submit request to the taskq */
2820 error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER_INIT, softc, req,
2821 mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
2823 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_init: done err = 0x%x\n",
2824 instance, error));
2826 return (error);
2829 static int
2830 dprov_sign_recover(crypto_ctx_t *ctx, crypto_data_t *data,
2831 crypto_data_t *signature, crypto_req_handle_t req)
2833 int error = CRYPTO_FAILED;
2834 dprov_state_t *softc;
2835 /* LINTED E_FUNC_SET_NOT_USED */
2836 int instance;
2838 /* extract softc and instance number from context */
2839 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2840 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover: started\n", instance));
2842 /* submit request to the taskq */
2843 error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER, softc, req,
2844 NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
2846 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover: done err = 0x%x\n",
2847 instance, error));
2849 return (error);
2852 static int
2853 dprov_sign_recover_atomic(crypto_provider_handle_t provider,
2854 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
2855 crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature,
2856 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
2858 int error = CRYPTO_FAILED;
2859 dprov_state_t *softc = (dprov_state_t *)provider;
2860 /* LINTED E_FUNC_SET_NOT_USED */
2861 int instance;
2863 instance = ddi_get_instance(softc->ds_dip);
2864 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_atomic: started\n",
2865 instance));
2867 if (ctx_template != NULL)
2868 return (CRYPTO_ARGUMENTS_BAD);
2870 /* submit request to the taskq */
2871 error = dprov_sign_submit_req(DPROV_REQ_SIGN_RECOVER_ATOMIC, softc, req,
2872 mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
2874 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_recover_atomic: done "
2875 "err = 0x%x\n", instance, error));
2877 return (error);
2881 * Verify entry points.
2884 static int
2885 dprov_verify_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
2886 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
2887 crypto_req_handle_t req)
2889 int error = CRYPTO_FAILED;
2890 dprov_state_t *softc;
2891 /* LINTED E_FUNC_SET_NOT_USED */
2892 int instance;
2894 /* extract softc and instance number from context */
2895 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2896 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_init: started\n", instance));
2898 /* check mechanism */
2899 if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
2900 cmn_err(CE_WARN, "dprov_verify_init: unexpected mech type "
2901 "0x%llx\n", (unsigned long long)mechanism->cm_type);
2902 return (CRYPTO_MECHANISM_INVALID);
2905 if (ctx_template != NULL)
2906 return (CRYPTO_ARGUMENTS_BAD);
2908 error = dprov_verify_submit_req(DPROV_REQ_VERIFY_INIT, softc, req,
2909 mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
2911 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_init: done err = 0x%x\n",
2912 instance, error));
2914 return (error);
2917 static int
2918 dprov_verify(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature,
2919 crypto_req_handle_t req)
2921 int error = CRYPTO_FAILED;
2922 dprov_state_t *softc;
2923 /* LINTED E_FUNC_SET_NOT_USED */
2924 int instance;
2926 /* extract softc and instance number from context */
2927 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2928 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify: started\n", instance));
2930 /* submit request to the taskq */
2931 error = dprov_verify_submit_req(DPROV_REQ_VERIFY, softc, req,
2932 NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
2934 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify: done err = 0x%x\n",
2935 instance, error));
2937 return (error);
2940 static int
2941 dprov_verify_update(crypto_ctx_t *ctx, crypto_data_t *data,
2942 crypto_req_handle_t req)
2944 int error = CRYPTO_FAILED;
2945 dprov_state_t *softc;
2946 /* LINTED E_FUNC_SET_NOT_USED */
2947 int instance;
2949 /* extract softc and instance number from context */
2950 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2951 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_update: started\n",
2952 instance));
2954 /* submit request to the taskq */
2955 error = dprov_verify_submit_req(DPROV_REQ_VERIFY_UPDATE, softc, req,
2956 NULL, NULL, data, NULL, ctx, 0, KM_NOSLEEP);
2958 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_update: done err = 0x%x\n",
2959 instance, error));
2961 return (error);
2964 static int
2965 dprov_verify_final(crypto_ctx_t *ctx, crypto_data_t *signature,
2966 crypto_req_handle_t req)
2968 int error = CRYPTO_FAILED;
2969 dprov_state_t *softc;
2970 /* LINTED E_FUNC_SET_NOT_USED */
2971 int instance;
2973 /* extract softc and instance number from context */
2974 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
2975 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_final: started\n", instance));
2977 /* submit request to the taskq */
2978 error = dprov_verify_submit_req(DPROV_REQ_VERIFY_FINAL, softc, req,
2979 NULL, NULL, NULL, signature, ctx, 0, KM_NOSLEEP);
2981 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_final: done err = 0x%x\n",
2982 instance, error));
2984 return (error);
2987 static int
2988 dprov_verify_atomic(crypto_provider_handle_t provider,
2989 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
2990 crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature,
2991 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
2993 int error = CRYPTO_FAILED;
2994 dprov_state_t *softc = (dprov_state_t *)provider;
2995 /* LINTED E_FUNC_SET_NOT_USED */
2996 int instance;
2998 instance = ddi_get_instance(softc->ds_dip);
2999 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_atomic: started\n",
3000 instance));
3002 /* check mechanism */
3003 if (!dprov_valid_sign_verif_mech(mechanism->cm_type)) {
3004 cmn_err(CE_WARN, "dprov_verify_atomic: unexpected mech type "
3005 "0x%llx\n", (unsigned long long)mechanism->cm_type);
3006 return (CRYPTO_MECHANISM_INVALID);
3009 if (ctx_template != NULL)
3010 return (CRYPTO_ARGUMENTS_BAD);
3012 /* submit request to the taskq */
3013 error = dprov_verify_submit_req(DPROV_REQ_VERIFY_ATOMIC, softc, req,
3014 mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
3016 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_atomic: done err = 0x%x\n",
3017 instance, error));
3019 return (error);
3022 static int
3023 dprov_verify_recover_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
3024 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
3025 crypto_req_handle_t req)
3027 int error = CRYPTO_FAILED;
3028 dprov_state_t *softc;
3029 /* LINTED E_FUNC_SET_NOT_USED */
3030 int instance;
3032 /* extract softc and instance number from context */
3033 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
3034 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_init: started\n",
3035 instance));
3037 if (ctx_template != NULL)
3038 return (CRYPTO_ARGUMENTS_BAD);
3040 /* submit request to the taskq */
3041 error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER_INIT, softc,
3042 req, mechanism, key, NULL, NULL, ctx, 0, KM_SLEEP);
3044 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_init: done "
3045 "err = 0x%x\n", instance, error));
3047 return (error);
3050 static int
3051 dprov_verify_recover(crypto_ctx_t *ctx, crypto_data_t *signature,
3052 crypto_data_t *data, crypto_req_handle_t req)
3054 int error = CRYPTO_FAILED;
3055 dprov_state_t *softc;
3056 /* LINTED E_FUNC_SET_NOT_USED */
3057 int instance;
3059 /* extract softc and instance number from context */
3060 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
3061 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover: started\n",
3062 instance));
3064 /* submit request to the taskq */
3065 error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER, softc, req,
3066 NULL, NULL, data, signature, ctx, 0, KM_NOSLEEP);
3068 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover: done err = 0x%x\n",
3069 instance, error));
3071 return (error);
3074 static int
3075 dprov_verify_recover_atomic(crypto_provider_handle_t provider,
3076 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
3077 crypto_key_t *key, crypto_data_t *signature, crypto_data_t *data,
3078 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
3080 int error = CRYPTO_FAILED;
3081 dprov_state_t *softc = (dprov_state_t *)provider;
3082 /* LINTED E_FUNC_SET_NOT_USED */
3083 int instance;
3085 instance = ddi_get_instance(softc->ds_dip);
3086 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_atomic: started\n",
3087 instance));
3089 if (ctx_template != NULL)
3090 return (CRYPTO_ARGUMENTS_BAD);
3092 /* submit request to the taskq */
3093 error = dprov_verify_submit_req(DPROV_REQ_VERIFY_RECOVER_ATOMIC, softc,
3094 req, mechanism, key, data, signature, NULL, session_id, KM_SLEEP);
3096 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_recover_atomic: done "
3097 "err = 0x%x\n", instance, error));
3099 return (error);
3103 * Dual operations entry points.
3106 static int
3107 dprov_digest_encrypt_update(crypto_ctx_t *digest_ctx,
3108 crypto_ctx_t *encrypt_ctx, crypto_data_t *plaintext,
3109 crypto_data_t *ciphertext, crypto_req_handle_t req)
3111 int error = CRYPTO_FAILED;
3112 dprov_state_t *softc;
3113 /* LINTED E_FUNC_SET_NOT_USED */
3114 int instance;
3116 /* extract softc and instance number from context */
3117 DPROV_SOFTC_FROM_CTX(digest_ctx, softc, instance);
3118 DPROV_DEBUG(D_DUAL, ("(%d) dprov_digest_encrypt_update: started\n",
3119 instance));
3121 if (digest_ctx->cc_provider != encrypt_ctx->cc_provider)
3122 return (CRYPTO_INVALID_CONTEXT);
3124 /* submit request to the taskq */
3125 error = dprov_dual_submit_req(DPROV_REQ_DIGEST_ENCRYPT_UPDATE,
3126 softc, req, digest_ctx, encrypt_ctx, plaintext, ciphertext);
3128 DPROV_DEBUG(D_DUAL, ("(%d) dprov_digest_encrypt_update: done "
3129 "err = 0x%x\n", instance, error));
3131 return (error);
3134 static int
3135 dprov_decrypt_digest_update(crypto_ctx_t *decrypt_ctx, crypto_ctx_t *digest_ctx,
3136 crypto_data_t *ciphertext, crypto_data_t *plaintext,
3137 crypto_req_handle_t req)
3139 int error = CRYPTO_FAILED;
3140 dprov_state_t *softc;
3141 /* LINTED E_FUNC_SET_NOT_USED */
3142 int instance;
3144 /* extract softc and instance number from context */
3145 DPROV_SOFTC_FROM_CTX(decrypt_ctx, softc, instance);
3146 DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_digest_update: started\n",
3147 instance));
3149 if (decrypt_ctx->cc_provider != digest_ctx->cc_provider)
3150 return (CRYPTO_INVALID_CONTEXT);
3152 /* submit request to the taskq */
3153 error = dprov_dual_submit_req(DPROV_REQ_DECRYPT_DIGEST_UPDATE,
3154 softc, req, digest_ctx, decrypt_ctx, plaintext, ciphertext);
3156 DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_digest_update: done "
3157 "err = 0x%x\n", instance, error));
3159 return (error);
3162 static int
3163 dprov_sign_encrypt_update(crypto_ctx_t *sign_ctx, crypto_ctx_t *encrypt_ctx,
3164 crypto_data_t *plaintext, crypto_data_t *ciphertext,
3165 crypto_req_handle_t req)
3167 int error = CRYPTO_FAILED;
3168 dprov_state_t *softc;
3169 /* LINTED E_FUNC_SET_NOT_USED */
3170 int instance;
3172 /* extract softc and instance number from context */
3173 DPROV_SOFTC_FROM_CTX(sign_ctx, softc, instance);
3174 DPROV_DEBUG(D_DUAL, ("(%d) dprov_sign_encrypt_update: started\n",
3175 instance));
3177 if (sign_ctx->cc_provider != encrypt_ctx->cc_provider)
3178 return (CRYPTO_INVALID_CONTEXT);
3180 /* submit request to the taskq */
3181 error = dprov_dual_submit_req(DPROV_REQ_SIGN_ENCRYPT_UPDATE,
3182 softc, req, sign_ctx, encrypt_ctx, plaintext, ciphertext);
3184 DPROV_DEBUG(D_DUAL, ("(%d) dprov_sign_encrypt_update: done "
3185 "err = 0x%x\n", instance, error));
3187 return (error);
3190 static int
3191 dprov_decrypt_verify_update(crypto_ctx_t *decrypt_ctx, crypto_ctx_t *verify_ctx,
3192 crypto_data_t *ciphertext, crypto_data_t *plaintext,
3193 crypto_req_handle_t req)
3195 int error = CRYPTO_FAILED;
3196 dprov_state_t *softc;
3197 /* LINTED E_FUNC_SET_NOT_USED */
3198 int instance;
3200 /* extract softc and instance number from context */
3201 DPROV_SOFTC_FROM_CTX(decrypt_ctx, softc, instance);
3202 DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_verify_update: started\n",
3203 instance));
3205 if (decrypt_ctx->cc_provider != verify_ctx->cc_provider)
3206 return (CRYPTO_INVALID_CONTEXT);
3208 /* submit request to the taskq */
3209 error = dprov_dual_submit_req(DPROV_REQ_DECRYPT_VERIFY_UPDATE,
3210 softc, req, verify_ctx, decrypt_ctx, plaintext, ciphertext);
3212 DPROV_DEBUG(D_DUAL, ("(%d) dprov_decrypt_verify_update: done "
3213 "err = 0x%x\n", instance, error));
3215 return (error);
3219 * Dual cipher-mac entry points.
3222 static int
3223 dprov_encrypt_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *encrypt_mech,
3224 crypto_key_t *encrypt_key, crypto_mechanism_t *mac_mech,
3225 crypto_key_t *mac_key, crypto_spi_ctx_template_t encr_ctx_template,
3226 crypto_spi_ctx_template_t mac_ctx_template,
3227 crypto_req_handle_t req)
3229 int error = CRYPTO_FAILED;
3230 dprov_state_t *softc;
3231 /* LINTED E_FUNC_SET_NOT_USED */
3232 int instance;
3234 /* extract softc and instance number from context */
3235 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
3236 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_init: started\n",
3237 instance));
3239 /* check mechanisms */
3240 if (!dprov_valid_cipher_mech(encrypt_mech->cm_type)) {
3241 cmn_err(CE_WARN, "dprov_encrypt_mac_init: unexpected encrypt "
3242 "mech type 0x%llx\n",
3243 (unsigned long long)encrypt_mech->cm_type);
3244 return (CRYPTO_MECHANISM_INVALID);
3246 if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
3247 cmn_err(CE_WARN, "dprov_encrypt_mac_init: unexpected mac "
3248 "mech type 0x%llx\n",
3249 (unsigned long long)mac_mech->cm_type);
3250 return (CRYPTO_MECHANISM_INVALID);
3253 if (encr_ctx_template != NULL || mac_ctx_template != NULL)
3254 return (CRYPTO_ARGUMENTS_BAD);
3256 /* submit request to the taskq */
3257 error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_INIT,
3258 softc, req, ctx, 0, encrypt_mech, encrypt_key, mac_mech, mac_key,
3259 NULL, NULL, NULL, KM_SLEEP);
3261 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_init: done "
3262 "err = 0x%x\n", instance, error));
3264 return (error);
3267 static int
3268 dprov_encrypt_mac(crypto_ctx_t *ctx, crypto_data_t *plaintext,
3269 crypto_dual_data_t *ciphertext, crypto_data_t *mac, crypto_req_handle_t req)
3271 int error = CRYPTO_FAILED;
3272 dprov_state_t *softc;
3273 /* LINTED E_FUNC_SET_NOT_USED */
3274 int instance;
3276 /* extract softc and instance number from context */
3277 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
3278 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac: started\n",
3279 instance));
3282 * submit request to the taskq
3283 * Careful! cihertext/plaintext order inversion
3285 error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC,
3286 softc, req, ctx, 0, NULL, NULL, NULL, NULL,
3287 ciphertext, plaintext, mac, KM_NOSLEEP);
3289 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac: done "
3290 "err = 0x%x\n", instance, error));
3292 return (error);
3295 static int
3296 dprov_encrypt_mac_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
3297 crypto_dual_data_t *ciphertext, crypto_req_handle_t req)
3299 int error = CRYPTO_FAILED;
3300 dprov_state_t *softc;
3301 /* LINTED E_FUNC_SET_NOT_USED */
3302 int instance;
3304 /* extract softc and instance number from context */
3305 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
3306 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_update: started\n",
3307 instance));
3309 /* submit request to the taskq */
3310 error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_UPDATE,
3311 softc, req, ctx, 0, NULL, NULL, NULL, NULL,
3312 ciphertext, plaintext, NULL, KM_NOSLEEP);
3314 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_update: done "
3315 "err = 0x%x\n", instance, error));
3317 return (error);
3320 static int
3321 dprov_encrypt_mac_final(crypto_ctx_t *ctx,
3322 crypto_dual_data_t *ciphertext, crypto_data_t *mac,
3323 crypto_req_handle_t req)
3325 int error = CRYPTO_FAILED;
3326 dprov_state_t *softc;
3327 /* LINTED E_FUNC_SET_NOT_USED */
3328 int instance;
3330 /* extract softc and instance number from context */
3331 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
3332 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_final: started\n",
3333 instance));
3335 /* submit request to the taskq */
3336 error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_FINAL,
3337 softc, req, ctx, 0, NULL, NULL, NULL, NULL,
3338 ciphertext, NULL, mac, KM_NOSLEEP);
3340 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_final: done "
3341 "err = 0x%x\n", instance, error));
3343 return (error);
3346 static int
3347 dprov_encrypt_mac_atomic(crypto_provider_handle_t provider,
3348 crypto_session_id_t session_id, crypto_mechanism_t *encrypt_mech,
3349 crypto_key_t *encrypt_key, crypto_mechanism_t *mac_mech,
3350 crypto_key_t *mac_key, crypto_data_t *plaintext,
3351 crypto_dual_data_t *ciphertext, crypto_data_t *mac,
3352 crypto_spi_ctx_template_t encr_ctx_template,
3353 crypto_spi_ctx_template_t mac_ctx_template,
3354 crypto_req_handle_t req)
3356 int error = CRYPTO_FAILED;
3357 dprov_state_t *softc = (dprov_state_t *)provider;
3358 /* LINTED E_FUNC_SET_NOT_USED */
3359 int instance;
3361 instance = ddi_get_instance(softc->ds_dip);
3362 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_atomic: started\n",
3363 instance));
3365 /* check mechanisms */
3366 if (!dprov_valid_cipher_mech(encrypt_mech->cm_type)) {
3367 cmn_err(CE_WARN, "dprov_encrypt_mac_atomic: unexpected encrypt "
3368 "mech type 0x%llx\n",
3369 (unsigned long long)encrypt_mech->cm_type);
3370 return (CRYPTO_MECHANISM_INVALID);
3372 if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
3373 cmn_err(CE_WARN, "dprov_encrypt_mac_atomic: unexpected mac "
3374 "mech type 0x%llx\n",
3375 (unsigned long long)mac_mech->cm_type);
3376 return (CRYPTO_MECHANISM_INVALID);
3379 if (encr_ctx_template != NULL || mac_ctx_template != NULL)
3380 return (CRYPTO_ARGUMENTS_BAD);
3382 /* submit request to the taskq */
3383 error = dprov_cipher_mac_submit_req(DPROV_REQ_ENCRYPT_MAC_ATOMIC,
3384 softc, req, NULL, session_id, encrypt_mech, encrypt_key, mac_mech,
3385 mac_key, ciphertext, plaintext, mac, KM_SLEEP);
3387 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_encrypt_mac_atomic: done "
3388 "err = 0x%x\n", instance, error));
3390 return (error);
3393 static int
3394 dprov_mac_decrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mac_mech,
3395 crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech,
3396 crypto_key_t *decrypt_key, crypto_spi_ctx_template_t mac_ctx_template,
3397 crypto_spi_ctx_template_t decr_ctx_template,
3398 crypto_req_handle_t req)
3400 int error = CRYPTO_FAILED;
3401 dprov_state_t *softc;
3402 /* LINTED E_FUNC_SET_NOT_USED */
3403 int instance;
3405 /* extract softc and instance number from context */
3406 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
3407 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_init: started\n",
3408 instance));
3410 /* check mechanisms */
3411 if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) {
3412 cmn_err(CE_WARN, "dprov_mac_decrypt_init: unexpected decrypt "
3413 "mech type 0x%llx\n",
3414 (unsigned long long)decrypt_mech->cm_type);
3415 return (CRYPTO_MECHANISM_INVALID);
3417 if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
3418 cmn_err(CE_WARN, "dprov_mac_decrypt_init: unexpected mac "
3419 "mech type 0x%llx\n",
3420 (unsigned long long)mac_mech->cm_type);
3421 return (CRYPTO_MECHANISM_INVALID);
3424 if (decr_ctx_template != NULL || mac_ctx_template != NULL)
3425 return (CRYPTO_ARGUMENTS_BAD);
3427 /* submit request to the taskq */
3428 error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_INIT,
3429 softc, req, ctx, 0, decrypt_mech, decrypt_key, mac_mech, mac_key,
3430 NULL, NULL, NULL, KM_SLEEP);
3432 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_init: done "
3433 "err = 0x%x\n", instance, error));
3435 return (error);
3438 static int
3439 dprov_mac_decrypt(crypto_ctx_t *ctx, crypto_dual_data_t *ciphertext,
3440 crypto_data_t *mac, crypto_data_t *plaintext, crypto_req_handle_t req)
3442 int error = CRYPTO_FAILED;
3443 dprov_state_t *softc;
3444 /* LINTED E_FUNC_SET_NOT_USED */
3445 int instance;
3447 /* extract softc and instance number from context */
3448 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
3449 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt: started\n",
3450 instance));
3452 /* submit request to the taskq */
3453 error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT,
3454 softc, req, ctx, 0, NULL, NULL, NULL, NULL,
3455 ciphertext, plaintext, mac, KM_NOSLEEP);
3457 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt: done "
3458 "err = 0x%x\n", instance, error));
3460 return (error);
3463 static int
3464 dprov_mac_decrypt_update(crypto_ctx_t *ctx, crypto_dual_data_t *ciphertext,
3465 crypto_data_t *plaintext, crypto_req_handle_t req)
3467 int error = CRYPTO_FAILED;
3468 dprov_state_t *softc;
3469 /* LINTED E_FUNC_SET_NOT_USED */
3470 int instance;
3472 /* extract softc and instance number from context */
3473 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
3474 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_update: started\n",
3475 instance));
3477 /* submit request to the taskq */
3478 error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_UPDATE,
3479 softc, req, ctx, 0, NULL, NULL, NULL, NULL,
3480 ciphertext, plaintext, NULL, KM_NOSLEEP);
3482 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_update: done "
3483 "err = 0x%x\n", instance, error));
3485 return (error);
3488 static int
3489 dprov_mac_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *mac,
3490 crypto_data_t *plaintext, crypto_req_handle_t req)
3492 int error = CRYPTO_FAILED;
3493 dprov_state_t *softc;
3494 /* LINTED E_FUNC_SET_NOT_USED */
3495 int instance;
3497 /* extract softc and instance number from context */
3498 DPROV_SOFTC_FROM_CTX(ctx, softc, instance);
3499 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_final: started\n",
3500 instance));
3502 /* submit request to the taskq */
3503 error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_FINAL,
3504 softc, req, ctx, 0, NULL, NULL, NULL, NULL,
3505 NULL, plaintext, mac, KM_NOSLEEP);
3507 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_final: done "
3508 "err = 0x%x\n", instance, error));
3510 return (error);
3513 static int
3514 dprov_mac_decrypt_atomic(crypto_provider_handle_t provider,
3515 crypto_session_id_t session_id, crypto_mechanism_t *mac_mech,
3516 crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech,
3517 crypto_key_t *decrypt_key, crypto_dual_data_t *ciphertext,
3518 crypto_data_t *mac, crypto_data_t *plaintext,
3519 crypto_spi_ctx_template_t mac_ctx_template,
3520 crypto_spi_ctx_template_t decr_ctx_template,
3521 crypto_req_handle_t req)
3523 int error = CRYPTO_FAILED;
3524 dprov_state_t *softc = (dprov_state_t *)provider;
3525 /* LINTED E_FUNC_SET_NOT_USED */
3526 int instance;
3528 instance = ddi_get_instance(softc->ds_dip);
3529 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_atomic: started\n",
3530 instance));
3532 /* check mechanisms */
3533 if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) {
3534 cmn_err(CE_WARN, "dprov_mac_decrypt_atomic: unexpected encrypt "
3535 "mech type 0x%llx\n",
3536 (unsigned long long)decrypt_mech->cm_type);
3537 return (CRYPTO_MECHANISM_INVALID);
3539 if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
3540 cmn_err(CE_WARN, "dprov_mac_decrypt_atomic: unexpected mac "
3541 "mech type 0x%llx\n",
3542 (unsigned long long)mac_mech->cm_type);
3543 return (CRYPTO_MECHANISM_INVALID);
3546 if (decr_ctx_template != NULL || mac_ctx_template != NULL)
3547 return (CRYPTO_ARGUMENTS_BAD);
3549 /* submit request to the taskq */
3550 error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_DECRYPT_ATOMIC,
3551 softc, req, NULL, session_id, decrypt_mech, decrypt_key, mac_mech,
3552 mac_key, ciphertext, plaintext, mac, KM_SLEEP);
3554 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_decrypt_atomic: done "
3555 "err = 0x%x\n", instance, error));
3557 return (error);
3560 static int
3561 dprov_mac_verify_decrypt_atomic(crypto_provider_handle_t provider,
3562 crypto_session_id_t session_id, crypto_mechanism_t *mac_mech,
3563 crypto_key_t *mac_key, crypto_mechanism_t *decrypt_mech,
3564 crypto_key_t *decrypt_key, crypto_dual_data_t *ciphertext,
3565 crypto_data_t *mac, crypto_data_t *plaintext,
3566 crypto_spi_ctx_template_t mac_ctx_template,
3567 crypto_spi_ctx_template_t decr_ctx_template,
3568 crypto_req_handle_t req)
3570 int error = CRYPTO_FAILED;
3571 dprov_state_t *softc = (dprov_state_t *)provider;
3572 /* LINTED E_FUNC_SET_NOT_USED */
3573 int instance;
3575 instance = ddi_get_instance(softc->ds_dip);
3576 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_verify_decrypt_atomic:"
3577 "started\n", instance));
3579 /* check mechanisms */
3580 if (!dprov_valid_cipher_mech(decrypt_mech->cm_type)) {
3581 cmn_err(CE_WARN, "dprov_mac_verify_decrypt_atomic: "
3582 "unexpected encrypt mech type 0x%llx\n",
3583 (unsigned long long)decrypt_mech->cm_type);
3584 return (CRYPTO_MECHANISM_INVALID);
3586 if (!dprov_valid_mac_mech(mac_mech->cm_type)) {
3587 cmn_err(CE_WARN, "dprov_mac_verify_decrypt_atomic: "
3588 "unexpected mac mech type 0x%llx\n",
3589 (unsigned long long)mac_mech->cm_type);
3590 return (CRYPTO_MECHANISM_INVALID);
3593 if (decr_ctx_template != NULL || mac_ctx_template != NULL)
3594 return (CRYPTO_ARGUMENTS_BAD);
3596 /* submit request to the taskq */
3597 error = dprov_cipher_mac_submit_req(DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC,
3598 softc, req, NULL, session_id, decrypt_mech, decrypt_key, mac_mech,
3599 mac_key, ciphertext, plaintext, mac, KM_SLEEP);
3601 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_mac_verify_decrypt_atomic: done "
3602 "err = 0x%x\n", instance, error));
3604 return (error);
3608 * Random number entry points.
3611 static int
3612 dprov_seed_random(crypto_provider_handle_t provider, crypto_session_id_t sid,
3613 uchar_t *buf, size_t len, uint_t entropy_est, uint32_t flags,
3614 crypto_req_handle_t req)
3616 int error = CRYPTO_FAILED;
3617 dprov_state_t *softc = (dprov_state_t *)provider;
3618 /* LINTED E_FUNC_SET_NOT_USED */
3619 int instance;
3621 instance = ddi_get_instance(softc->ds_dip);
3622 DPROV_DEBUG(D_RANDOM, ("(%d) dprov_seed_random: started\n",
3623 instance));
3625 error = dprov_random_submit_req(DPROV_REQ_RANDOM_SEED, softc,
3626 req, buf, len, sid, entropy_est, flags);
3628 DPROV_DEBUG(D_RANDOM, ("(%d) dprov_seed_random: done err = 0x0%x\n",
3629 instance, error));
3631 return (error);
3634 static int
3635 dprov_generate_random(crypto_provider_handle_t provider,
3636 crypto_session_id_t sid, uchar_t *buf, size_t len, crypto_req_handle_t req)
3638 int error = CRYPTO_FAILED;
3639 dprov_state_t *softc = (dprov_state_t *)provider;
3640 /* LINTED E_FUNC_SET_NOT_USED */
3641 int instance;
3643 instance = ddi_get_instance(softc->ds_dip);
3644 DPROV_DEBUG(D_RANDOM, ("(%d) dprov_generate_random: started\n",
3645 instance));
3647 error = dprov_random_submit_req(DPROV_REQ_RANDOM_GENERATE, softc,
3648 req, buf, len, sid, 0, 0);
3650 DPROV_DEBUG(D_RANDOM, ("(%d) dprov_generate_random: done "
3651 "err = 0x0%x\n", instance, error));
3653 return (error);
3657 * Session Management entry points.
3660 static int
3661 dprov_session_open(crypto_provider_handle_t provider,
3662 crypto_session_id_t *session_id, crypto_req_handle_t req)
3664 int error = CRYPTO_FAILED;
3665 dprov_state_t *softc = (dprov_state_t *)provider;
3666 /* LINTED E_FUNC_SET_NOT_USED */
3667 int instance;
3669 instance = ddi_get_instance(softc->ds_dip);
3670 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_open: started\n",
3671 instance));
3673 error = dprov_session_submit_req(DPROV_REQ_SESSION_OPEN, softc,
3674 req, session_id, 0, 0, NULL, 0);
3676 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_open: done err = 0x0%x\n",
3677 instance, error));
3679 return (error);
3682 static int
3683 dprov_session_close(crypto_provider_handle_t provider,
3684 crypto_session_id_t session_id, crypto_req_handle_t req)
3686 int error = CRYPTO_FAILED;
3687 dprov_state_t *softc = (dprov_state_t *)provider;
3688 /* LINTED E_FUNC_SET_NOT_USED */
3689 int instance;
3691 instance = ddi_get_instance(softc->ds_dip);
3692 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_close: started\n",
3693 instance));
3695 error = dprov_session_submit_req(DPROV_REQ_SESSION_CLOSE, softc,
3696 req, 0, session_id, 0, NULL, 0);
3698 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_close: done err = 0x0%x\n",
3699 instance, error));
3701 return (error);
3704 static int
3705 dprov_session_login(crypto_provider_handle_t provider,
3706 crypto_session_id_t session_id, crypto_user_type_t user_type,
3707 char *pin, size_t pin_len, crypto_req_handle_t req)
3709 int error = CRYPTO_FAILED;
3710 dprov_state_t *softc = (dprov_state_t *)provider;
3711 /* LINTED E_FUNC_SET_NOT_USED */
3712 int instance;
3714 instance = ddi_get_instance(softc->ds_dip);
3715 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_login: started\n",
3716 instance));
3718 error = dprov_session_submit_req(DPROV_REQ_SESSION_LOGIN, softc,
3719 req, 0, session_id, user_type, pin, pin_len);
3721 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_login: done err = 0x0%x\n",
3722 instance, error));
3724 return (error);
3727 static int
3728 dprov_session_logout(crypto_provider_handle_t provider,
3729 crypto_session_id_t session_id, crypto_req_handle_t req)
3731 int error = CRYPTO_FAILED;
3732 dprov_state_t *softc = (dprov_state_t *)provider;
3733 /* LINTED E_FUNC_SET_NOT_USED */
3734 int instance;
3736 instance = ddi_get_instance(softc->ds_dip);
3737 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_logout: started\n",
3738 instance));
3740 error = dprov_session_submit_req(DPROV_REQ_SESSION_LOGOUT, softc,
3741 req, 0, session_id, 0, NULL, 0);
3743 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_logout: done err = 0x0%x\n",
3744 instance, error));
3746 return (error);
3750 * Object management entry points.
3753 static int
3754 dprov_object_create(crypto_provider_handle_t provider,
3755 crypto_session_id_t session_id, crypto_object_attribute_t *template,
3756 uint_t attribute_count, crypto_object_id_t *object,
3757 crypto_req_handle_t req)
3759 int error = CRYPTO_FAILED;
3760 dprov_state_t *softc = (dprov_state_t *)provider;
3761 /* LINTED E_FUNC_SET_NOT_USED */
3762 int instance;
3764 instance = ddi_get_instance(softc->ds_dip);
3765 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_create: started\n",
3766 instance));
3768 /* submit request to the taskq */
3769 error = dprov_object_submit_req(DPROV_REQ_OBJECT_CREATE, softc, req,
3770 session_id, 0, template, attribute_count, object, NULL, NULL,
3771 NULL, 0, NULL, KM_NOSLEEP);
3773 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_create: done err = 0x0%x\n",
3774 instance, error));
3776 return (error);
3779 static int
3780 dprov_object_copy(crypto_provider_handle_t provider,
3781 crypto_session_id_t session_id, crypto_object_id_t object,
3782 crypto_object_attribute_t *template, uint_t attribute_count,
3783 crypto_object_id_t *new_object, crypto_req_handle_t req)
3785 int error = CRYPTO_FAILED;
3786 dprov_state_t *softc = (dprov_state_t *)provider;
3787 /* LINTED E_FUNC_SET_NOT_USED */
3788 int instance;
3790 instance = ddi_get_instance(softc->ds_dip);
3791 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_copy: started\n",
3792 instance));
3794 /* submit request to the taskq */
3795 error = dprov_object_submit_req(DPROV_REQ_OBJECT_COPY, softc, req,
3796 session_id, object, template, attribute_count, new_object,
3797 NULL, NULL, NULL, 0, NULL, KM_NOSLEEP);
3799 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_copy: done err = 0x0%x\n",
3800 instance, error));
3802 return (error);
3805 static int
3806 dprov_object_destroy(crypto_provider_handle_t provider,
3807 crypto_session_id_t session_id, crypto_object_id_t object,
3808 crypto_req_handle_t req)
3810 int error = CRYPTO_FAILED;
3811 dprov_state_t *softc = (dprov_state_t *)provider;
3812 /* LINTED E_FUNC_SET_NOT_USED */
3813 int instance;
3815 instance = ddi_get_instance(softc->ds_dip);
3816 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_destroy: started\n",
3817 instance));
3819 /* submit request to the taskq */
3820 error = dprov_object_submit_req(DPROV_REQ_OBJECT_DESTROY, softc, req,
3821 session_id, object, NULL, 0, NULL, NULL, NULL, NULL, 0, NULL,
3822 KM_NOSLEEP);
3824 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_destroy: done err = 0x0%x\n",
3825 instance, error));
3827 return (error);
3830 static int
3831 dprov_object_get_size(crypto_provider_handle_t provider,
3832 crypto_session_id_t session_id, crypto_object_id_t object,
3833 size_t *size, crypto_req_handle_t req)
3835 int error = CRYPTO_FAILED;
3836 dprov_state_t *softc = (dprov_state_t *)provider;
3837 /* LINTED E_FUNC_SET_NOT_USED */
3838 int instance;
3840 instance = ddi_get_instance(softc->ds_dip);
3841 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_size: started\n",
3842 instance));
3844 /* submit request to the taskq */
3845 error = dprov_object_submit_req(DPROV_REQ_OBJECT_GET_SIZE, softc, req,
3846 session_id, object, NULL, 0, NULL, size, NULL, NULL, 0, NULL,
3847 KM_NOSLEEP);
3849 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_size: done err = 0x0%x\n",
3850 instance, error));
3852 return (error);
3855 static int
3856 dprov_object_get_attribute_value(crypto_provider_handle_t provider,
3857 crypto_session_id_t session_id, crypto_object_id_t object,
3858 crypto_object_attribute_t *template, uint_t attribute_count,
3859 crypto_req_handle_t req)
3861 int error = CRYPTO_FAILED;
3862 dprov_state_t *softc = (dprov_state_t *)provider;
3863 /* LINTED E_FUNC_SET_NOT_USED */
3864 int instance;
3866 instance = ddi_get_instance(softc->ds_dip);
3867 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_attribute_value: "
3868 "started\n", instance));
3870 /* submit request to the taskq */
3871 error = dprov_object_submit_req(DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE,
3872 softc, req, session_id, object, template, attribute_count,
3873 NULL, NULL, NULL, NULL, 0, NULL, KM_NOSLEEP);
3875 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_get_attribute_value: "
3876 "done err = 0x0%x\n", instance, error));
3878 return (error);
3881 static int
3882 dprov_object_set_attribute_value(crypto_provider_handle_t provider,
3883 crypto_session_id_t session_id, crypto_object_id_t object,
3884 crypto_object_attribute_t *template, uint_t attribute_count,
3885 crypto_req_handle_t req)
3887 int error = CRYPTO_FAILED;
3888 dprov_state_t *softc = (dprov_state_t *)provider;
3889 /* LINTED E_FUNC_SET_NOT_USED */
3890 int instance;
3892 instance = ddi_get_instance(softc->ds_dip);
3893 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_set_attribute_value: "
3894 "started\n", instance));
3896 /* submit request to the taskq */
3897 error = dprov_object_submit_req(DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE,
3898 softc, req, session_id, object, template, attribute_count,
3899 NULL, NULL, NULL, NULL, 0, NULL, KM_NOSLEEP);
3901 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_set_attribute_value: "
3902 "done err = 0x0%x\n", instance, error));
3904 return (error);
3907 static int
3908 dprov_object_find_init(crypto_provider_handle_t provider,
3909 crypto_session_id_t session_id, crypto_object_attribute_t *template,
3910 uint_t attribute_count, void **provider_private,
3911 crypto_req_handle_t req)
3913 int error = CRYPTO_FAILED;
3914 dprov_state_t *softc = (dprov_state_t *)provider;
3915 /* LINTED E_FUNC_SET_NOT_USED */
3916 int instance;
3918 instance = ddi_get_instance(softc->ds_dip);
3919 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_init: started\n",
3920 instance));
3922 /* submit request to the taskq */
3923 error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND_INIT, softc, req,
3924 session_id, 0, template, attribute_count, NULL, NULL,
3925 provider_private, NULL, 0, NULL, KM_SLEEP);
3927 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_init: done "
3928 "err = 0x0%x\n", instance, error));
3930 return (error);
3933 static int
3934 dprov_object_find(crypto_provider_handle_t provider, void *provider_private,
3935 crypto_object_id_t *objects, uint_t max_object_count,
3936 uint_t *object_count, crypto_req_handle_t req)
3938 int error = CRYPTO_FAILED;
3939 dprov_state_t *softc = (dprov_state_t *)provider;
3940 /* LINTED E_FUNC_SET_NOT_USED */
3941 int instance;
3943 instance = ddi_get_instance(softc->ds_dip);
3944 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find: started\n",
3945 instance));
3947 /* submit request to the taskq */
3948 error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND, softc, req,
3949 0, 0, NULL, 0, objects, NULL, NULL, provider_private,
3950 max_object_count, object_count, KM_NOSLEEP);
3953 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find: done err = 0x0%x\n",
3954 instance, error));
3956 return (error);
3959 static int
3960 dprov_object_find_final(crypto_provider_handle_t provider,
3961 void *provider_private, crypto_req_handle_t req)
3963 int error = CRYPTO_FAILED;
3964 dprov_state_t *softc = (dprov_state_t *)provider;
3965 /* LINTED E_FUNC_SET_NOT_USED */
3966 int instance;
3968 instance = ddi_get_instance(softc->ds_dip);
3969 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_final: started\n",
3970 instance));
3972 /* submit request to the taskq */
3973 error = dprov_object_submit_req(DPROV_REQ_OBJECT_FIND_FINAL, softc, req,
3974 0, 0, NULL, 0, NULL, NULL, NULL, provider_private,
3975 0, NULL, KM_NOSLEEP);
3977 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_find_final: done "
3978 "err = 0x0%x\n", instance, error));
3980 return (error);
3984 * Key management entry points.
3987 static int
3988 dprov_key_generate(crypto_provider_handle_t provider,
3989 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
3990 crypto_object_attribute_t *template, uint_t attribute_count,
3991 crypto_object_id_t *object, crypto_req_handle_t req)
3993 int error = CRYPTO_FAILED;
3994 dprov_state_t *softc = (dprov_state_t *)provider;
3995 /* LINTED E_FUNC_SET_NOT_USED */
3996 int instance;
3998 instance = ddi_get_instance(softc->ds_dip);
3999 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate: started\n",
4000 instance));
4002 /* submit request to the taskq */
4003 error = dprov_key_submit_req(DPROV_REQ_KEY_GENERATE, softc, req,
4004 session_id, mechanism, template, attribute_count, object, NULL,
4005 0, NULL, NULL, NULL, 0, NULL, 0, NULL, 0);
4007 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate: done err = 0x0%x\n",
4008 instance, error));
4010 return (error);
4013 static int
4014 dprov_key_generate_pair(crypto_provider_handle_t provider,
4015 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
4016 crypto_object_attribute_t *public_key_template,
4017 uint_t public_key_attribute_count,
4018 crypto_object_attribute_t *private_key_template,
4019 uint_t private_key_attribute_count,
4020 crypto_object_id_t *public_key, crypto_object_id_t *private_key,
4021 crypto_req_handle_t req)
4023 int error = CRYPTO_FAILED;
4024 dprov_state_t *softc = (dprov_state_t *)provider;
4025 /* LINTED E_FUNC_SET_NOT_USED */
4026 int instance;
4028 instance = ddi_get_instance(softc->ds_dip);
4029 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate_pair: started\n",
4030 instance));
4032 /* submit request to the taskq */
4033 error = dprov_key_submit_req(DPROV_REQ_KEY_GENERATE_PAIR, softc, req,
4034 session_id, mechanism, public_key_template,
4035 public_key_attribute_count, public_key, private_key_template,
4036 private_key_attribute_count, private_key, NULL, NULL, 0, NULL, 0,
4037 NULL, 0);
4039 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_generate_pair: done err = 0x0%x\n",
4040 instance, error));
4042 return (error);
4045 static int
4046 dprov_key_wrap(crypto_provider_handle_t provider,
4047 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
4048 crypto_key_t *wrapping_key, crypto_object_id_t *key,
4049 uchar_t *wrapped_key, size_t *wrapped_key_len_ptr, crypto_req_handle_t req)
4051 int error = CRYPTO_FAILED;
4052 dprov_state_t *softc = (dprov_state_t *)provider;
4053 /* LINTED E_FUNC_SET_NOT_USED */
4054 int instance;
4056 instance = ddi_get_instance(softc->ds_dip);
4057 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_wrap: started\n",
4058 instance));
4060 /* submit request to the taskq */
4061 error = dprov_key_submit_req(DPROV_REQ_KEY_WRAP, softc, req,
4062 session_id, mechanism, NULL, 0, key, NULL,
4063 0, NULL, wrapping_key, wrapped_key, wrapped_key_len_ptr,
4064 NULL, 0, NULL, 0);
4066 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_wrap: done err = 0x0%x\n",
4067 instance, error));
4069 return (error);
4072 static int
4073 dprov_key_unwrap(crypto_provider_handle_t provider,
4074 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
4075 crypto_key_t *unwrapping_key, uchar_t *wrapped_key,
4076 size_t *wrapped_key_len_ptr, crypto_object_attribute_t *template,
4077 uint_t attribute_count, crypto_object_id_t *key, crypto_req_handle_t req)
4079 int error = CRYPTO_FAILED;
4080 dprov_state_t *softc = (dprov_state_t *)provider;
4081 /* LINTED E_FUNC_SET_NOT_USED */
4082 int instance;
4084 instance = ddi_get_instance(softc->ds_dip);
4085 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_unwrap: started\n",
4086 instance));
4088 /* submit request to the taskq */
4089 error = dprov_key_submit_req(DPROV_REQ_KEY_UNWRAP, softc, req,
4090 session_id, mechanism, template, attribute_count, key, NULL,
4091 0, NULL, unwrapping_key, wrapped_key, wrapped_key_len_ptr,
4092 NULL, 0, NULL, 0);
4094 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_unwrap: done err = 0x0%x\n",
4095 instance, error));
4097 return (error);
4100 static int
4101 dprov_key_derive(crypto_provider_handle_t provider,
4102 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
4103 crypto_key_t *base_key, crypto_object_attribute_t *template,
4104 uint_t attribute_count, crypto_object_id_t *key, crypto_req_handle_t req)
4106 int error = CRYPTO_FAILED;
4107 dprov_state_t *softc = (dprov_state_t *)provider;
4108 /* LINTED E_FUNC_SET_NOT_USED */
4109 int instance;
4111 instance = ddi_get_instance(softc->ds_dip);
4112 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_derive: started\n",
4113 instance));
4115 /* submit request to the taskq */
4116 error = dprov_key_submit_req(DPROV_REQ_KEY_DERIVE, softc, req,
4117 session_id, mechanism, template, attribute_count, key, NULL,
4118 0, NULL, base_key, NULL, 0, NULL, 0, NULL, 0);
4120 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_derive: done err = 0x0%x\n",
4121 instance, error));
4123 return (error);
4127 * Provider management entry points.
4130 static int
4131 dprov_ext_info(crypto_provider_handle_t provider,
4132 crypto_provider_ext_info_t *ext_info, crypto_req_handle_t req)
4134 int error = CRYPTO_FAILED;
4135 dprov_state_t *softc = (dprov_state_t *)provider;
4136 /* LINTED E_FUNC_SET_NOT_USED */
4137 int instance;
4139 instance = ddi_get_instance(softc->ds_dip);
4140 DPROV_DEBUG(D_MGMT, ("(%d) dprov_ext_info: started\n",
4141 instance));
4143 error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_EXTINFO, softc, req,
4144 0, NULL, 0, NULL, 0, NULL, ext_info);
4146 DPROV_DEBUG(D_MGMT, ("(%d) dprov_ext_info: done err = 0x0%x\n",
4147 instance, error));
4149 return (error);
4152 static int
4153 dprov_init_token(crypto_provider_handle_t provider, char *pin, size_t pin_len,
4154 char *label, crypto_req_handle_t req)
4156 int error = CRYPTO_FAILED;
4157 dprov_state_t *softc = (dprov_state_t *)provider;
4158 /* LINTED E_FUNC_SET_NOT_USED */
4159 int instance;
4161 instance = ddi_get_instance(softc->ds_dip);
4162 DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_token: started\n",
4163 instance));
4165 error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_INITTOKEN, softc, req,
4166 0, pin, pin_len, NULL, 0, label, NULL);
4168 DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_token: done err = 0x0%x\n",
4169 instance, error));
4171 return (error);
4174 static int
4175 dprov_init_pin(crypto_provider_handle_t provider,
4176 crypto_session_id_t session_id, char *pin, size_t pin_len,
4177 crypto_req_handle_t req)
4179 int error = CRYPTO_FAILED;
4180 dprov_state_t *softc = (dprov_state_t *)provider;
4181 /* LINTED E_FUNC_SET_NOT_USED */
4182 int instance;
4184 instance = ddi_get_instance(softc->ds_dip);
4185 DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_pin: started\n",
4186 instance));
4188 error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_INITPIN, softc, req,
4189 session_id, pin, pin_len, NULL, 0, NULL, NULL);
4191 DPROV_DEBUG(D_MGMT, ("(%d) dprov_init_pin: done err = 0x0%x\n",
4192 instance, error));
4194 return (error);
4197 static int
4198 dprov_set_pin(crypto_provider_handle_t provider, crypto_session_id_t session_id,
4199 char *old_pin, size_t old_pin_len, char *new_pin, size_t new_pin_len,
4200 crypto_req_handle_t req)
4202 int error = CRYPTO_FAILED;
4203 dprov_state_t *softc = (dprov_state_t *)provider;
4204 /* LINTED E_FUNC_SET_NOT_USED */
4205 int instance;
4207 instance = ddi_get_instance(softc->ds_dip);
4208 DPROV_DEBUG(D_MGMT, ("(%d) dprov_set_pin: started\n",
4209 instance));
4211 error = dprov_mgmt_submit_req(DPROV_REQ_MGMT_SETPIN, softc, req,
4212 session_id, new_pin, new_pin_len, old_pin, old_pin_len, NULL, NULL);
4214 DPROV_DEBUG(D_MGMT, ("(%d) dprov_set_pin: done err = 0x0%x\n",
4215 instance, error));
4217 return (error);
4222 * Context management entry points.
4226 * Allocate a dprov-private context based on the specified dprov request.
4227 * For dual cipher/mac requests, the allocated context will
4228 * contain a structure dprov_ctx_dual_t, for other request types,
4229 * it will contain a dprov_ctx_single.
4230 * Returns one of the CRYPTO_ status codes.
4232 static int
4233 dprov_alloc_context(dprov_req_type_t req_type, crypto_ctx_t *spi_ctx)
4235 dprov_ctx_single_t *dprov_private;
4237 switch (req_type) {
4238 case DPROV_REQ_ENCRYPT_MAC_INIT:
4239 case DPROV_REQ_MAC_DECRYPT_INIT:
4240 dprov_private = kmem_zalloc(sizeof (dprov_ctx_dual_t),
4241 KM_NOSLEEP);
4242 if (dprov_private == NULL)
4243 return (CRYPTO_HOST_MEMORY);
4244 dprov_private->dc_type = DPROV_CTX_DUAL;
4245 break;
4246 default:
4247 dprov_private = kmem_zalloc(sizeof (dprov_ctx_single_t),
4248 KM_NOSLEEP);
4249 if (dprov_private == NULL)
4250 return (CRYPTO_HOST_MEMORY);
4251 dprov_private->dc_type = DPROV_CTX_SINGLE;
4252 dprov_private->dc_svrfy_to_mac = B_FALSE;
4253 break;
4256 spi_ctx->cc_provider_private = (void *)dprov_private;
4258 return (CRYPTO_SUCCESS);
4261 static int
4262 dprov_free_context(crypto_ctx_t *ctx)
4264 if (ctx->cc_provider_private == NULL)
4265 return (CRYPTO_SUCCESS);
4267 DPROV_DEBUG(D_CONTEXT, ("dprov_free_context\n"));
4271 * The dprov private context could contain either
4272 * a dprov_ctx_single_t or a dprov_ctx_dual_t. Free
4273 * the context based on its type. The k-API contexts
4274 * that were attached to the dprov private context
4275 * are freed by the framework.
4277 dprov_ctx_single_t *ctx_single =
4278 (dprov_ctx_single_t *)(ctx->cc_provider_private);
4280 if (ctx_single->dc_type == DPROV_CTX_SINGLE) {
4281 crypto_context_t context = DPROV_CTX_SINGLE(ctx);
4284 * This case happens for the crypto_cancel_ctx() case.
4285 * We have to cancel the SW provider context also.
4287 if (context != NULL)
4288 crypto_cancel_ctx(context);
4290 kmem_free(ctx_single, sizeof (dprov_ctx_single_t));
4291 } else {
4292 crypto_context_t cipher_context =
4293 DPROV_CTX_DUAL_CIPHER(ctx);
4294 crypto_context_t mac_context = DPROV_CTX_DUAL_MAC(ctx);
4296 /* See comments above. */
4297 if (cipher_context != NULL)
4298 crypto_cancel_ctx(cipher_context);
4299 if (mac_context != NULL)
4300 crypto_cancel_ctx(mac_context);
4302 ASSERT(ctx_single->dc_type == DPROV_CTX_DUAL);
4303 kmem_free(ctx_single, sizeof (dprov_ctx_dual_t));
4305 ctx->cc_provider_private = NULL;
4308 return (CRYPTO_SUCCESS);
4312 * Resource control checks don't need to be done. Why? Because this routine
4313 * knows the size of the structure, and it can't be overridden by a user.
4314 * This is different from the crypto module, which has no knowledge of
4315 * specific mechanisms, and therefore has to trust specified size of the
4316 * parameter. This trust, or lack of trust, is why the size of the
4317 * parameter has to be charged against the project resource control.
4319 static int
4320 copyin_aes_ccm_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
4321 int *out_error, int mode)
4323 STRUCT_DECL(crypto_mechanism, mech);
4324 STRUCT_DECL(CK_AES_CCM_PARAMS, params);
4325 CK_AES_CCM_PARAMS *aes_ccm_params;
4326 caddr_t pp;
4327 size_t param_len;
4328 int error = 0;
4329 int rv = 0;
4331 STRUCT_INIT(mech, mode);
4332 STRUCT_INIT(params, mode);
4333 bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4334 pp = STRUCT_FGETP(mech, cm_param);
4335 param_len = STRUCT_FGET(mech, cm_param_len);
4337 if (param_len != STRUCT_SIZE(params)) {
4338 rv = CRYPTO_ARGUMENTS_BAD;
4339 goto out;
4342 out_mech->cm_type = STRUCT_FGET(mech, cm_type);
4343 out_mech->cm_param = NULL;
4344 out_mech->cm_param_len = 0;
4345 if (pp != NULL) {
4346 size_t nonce_len, auth_data_len, total_param_len;
4348 if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
4349 out_mech->cm_param = NULL;
4350 error = EFAULT;
4351 goto out;
4354 nonce_len = STRUCT_FGET(params, ulNonceSize);
4355 auth_data_len = STRUCT_FGET(params, ulAuthDataSize);
4357 /* allocate param structure */
4358 total_param_len =
4359 sizeof (CK_AES_CCM_PARAMS) + nonce_len + auth_data_len;
4360 aes_ccm_params = kmem_alloc(total_param_len, KM_NOSLEEP);
4361 if (aes_ccm_params == NULL) {
4362 rv = CRYPTO_HOST_MEMORY;
4363 goto out;
4365 aes_ccm_params->ulMACSize = STRUCT_FGET(params, ulMACSize);
4366 aes_ccm_params->ulNonceSize = nonce_len;
4367 aes_ccm_params->ulAuthDataSize = auth_data_len;
4368 aes_ccm_params->ulDataSize
4369 = STRUCT_FGET(params, ulDataSize);
4370 aes_ccm_params->nonce
4371 = (uchar_t *)aes_ccm_params + sizeof (CK_AES_CCM_PARAMS);
4372 aes_ccm_params->authData
4373 = aes_ccm_params->nonce + nonce_len;
4375 if (copyin((char *)STRUCT_FGETP(params, nonce),
4376 aes_ccm_params->nonce, nonce_len) != 0) {
4377 kmem_free(aes_ccm_params, total_param_len);
4378 out_mech->cm_param = NULL;
4379 error = EFAULT;
4380 goto out;
4382 if (copyin((char *)STRUCT_FGETP(params, authData),
4383 aes_ccm_params->authData, auth_data_len) != 0) {
4384 kmem_free(aes_ccm_params, total_param_len);
4385 out_mech->cm_param = NULL;
4386 error = EFAULT;
4387 goto out;
4389 out_mech->cm_param = (char *)aes_ccm_params;
4390 out_mech->cm_param_len = sizeof (CK_AES_CCM_PARAMS);
4392 out:
4393 *out_error = error;
4394 return (rv);
4398 * Resource control checks don't need to be done. Why? Because this routine
4399 * knows the size of the structure, and it can't be overridden by a user.
4400 * This is different from the crypto module, which has no knowledge of
4401 * specific mechanisms, and therefore has to trust specified size of the
4402 * parameter. This trust, or lack of trust, is why the size of the
4403 * parameter has to be charged against the project resource control.
4405 static int
4406 copyin_aes_gcm_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
4407 int *out_error, int mode)
4409 STRUCT_DECL(crypto_mechanism, mech);
4410 STRUCT_DECL(CK_AES_GCM_PARAMS, params);
4411 CK_AES_GCM_PARAMS *aes_gcm_params;
4412 caddr_t pp;
4413 size_t param_len;
4414 int error = 0;
4415 int rv = 0;
4417 STRUCT_INIT(mech, mode);
4418 STRUCT_INIT(params, mode);
4419 bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4420 pp = STRUCT_FGETP(mech, cm_param);
4421 param_len = STRUCT_FGET(mech, cm_param_len);
4423 if (param_len != STRUCT_SIZE(params)) {
4424 rv = CRYPTO_ARGUMENTS_BAD;
4425 goto out;
4428 out_mech->cm_type = STRUCT_FGET(mech, cm_type);
4429 out_mech->cm_param = NULL;
4430 out_mech->cm_param_len = 0;
4431 if (pp != NULL) {
4432 size_t nonce_len, auth_data_len, total_param_len;
4434 if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
4435 out_mech->cm_param = NULL;
4436 error = EFAULT;
4437 goto out;
4440 nonce_len = STRUCT_FGET(params, ulIvLen);
4441 auth_data_len = STRUCT_FGET(params, ulAADLen);
4443 /* allocate param structure */
4444 total_param_len =
4445 sizeof (CK_AES_GCM_PARAMS) + nonce_len + auth_data_len;
4446 aes_gcm_params = kmem_alloc(total_param_len, KM_NOSLEEP);
4447 if (aes_gcm_params == NULL) {
4448 rv = CRYPTO_HOST_MEMORY;
4449 goto out;
4451 aes_gcm_params->ulTagBits = STRUCT_FGET(params, ulTagBits);
4452 aes_gcm_params->ulIvLen = nonce_len;
4453 aes_gcm_params->ulAADLen = auth_data_len;
4454 aes_gcm_params->pIv
4455 = (uchar_t *)aes_gcm_params + sizeof (CK_AES_GCM_PARAMS);
4456 aes_gcm_params->pAAD = aes_gcm_params->pIv + nonce_len;
4458 if (copyin((char *)STRUCT_FGETP(params, pIv),
4459 aes_gcm_params->pIv, nonce_len) != 0) {
4460 kmem_free(aes_gcm_params, total_param_len);
4461 out_mech->cm_param = NULL;
4462 error = EFAULT;
4463 goto out;
4465 if (copyin((char *)STRUCT_FGETP(params, pAAD),
4466 aes_gcm_params->pAAD, auth_data_len) != 0) {
4467 kmem_free(aes_gcm_params, total_param_len);
4468 out_mech->cm_param = NULL;
4469 error = EFAULT;
4470 goto out;
4472 out_mech->cm_param = (char *)aes_gcm_params;
4473 out_mech->cm_param_len = sizeof (CK_AES_GCM_PARAMS);
4475 out:
4476 *out_error = error;
4477 return (rv);
4480 static int
4481 copyin_aes_gmac_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
4482 int *out_error, int mode)
4484 STRUCT_DECL(crypto_mechanism, mech);
4485 STRUCT_DECL(CK_AES_GMAC_PARAMS, params);
4486 CK_AES_GMAC_PARAMS *aes_gmac_params;
4487 caddr_t pp;
4488 size_t param_len;
4489 int error = 0;
4490 int rv = 0;
4492 STRUCT_INIT(mech, mode);
4493 STRUCT_INIT(params, mode);
4494 bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4495 pp = STRUCT_FGETP(mech, cm_param);
4496 param_len = STRUCT_FGET(mech, cm_param_len);
4498 if (param_len != STRUCT_SIZE(params)) {
4499 rv = CRYPTO_ARGUMENTS_BAD;
4500 goto out;
4503 out_mech->cm_type = STRUCT_FGET(mech, cm_type);
4504 out_mech->cm_param = NULL;
4505 out_mech->cm_param_len = 0;
4506 if (pp != NULL) {
4507 size_t auth_data_len, total_param_len;
4509 if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
4510 out_mech->cm_param = NULL;
4511 error = EFAULT;
4512 goto out;
4515 auth_data_len = STRUCT_FGET(params, ulAADLen);
4517 /* allocate param structure */
4518 total_param_len = sizeof (CK_AES_GMAC_PARAMS) +
4519 AES_GMAC_IV_LEN + auth_data_len;
4520 aes_gmac_params = kmem_alloc(total_param_len, KM_NOSLEEP);
4521 if (aes_gmac_params == NULL) {
4522 rv = CRYPTO_HOST_MEMORY;
4523 goto out;
4525 aes_gmac_params->ulAADLen = auth_data_len;
4526 aes_gmac_params->pIv
4527 = (uchar_t *)aes_gmac_params + sizeof (CK_AES_GMAC_PARAMS);
4528 aes_gmac_params->pAAD = aes_gmac_params->pIv + AES_GMAC_IV_LEN;
4530 if (copyin((char *)STRUCT_FGETP(params, pIv),
4531 aes_gmac_params->pIv, AES_GMAC_IV_LEN) != 0) {
4532 kmem_free(aes_gmac_params, total_param_len);
4533 out_mech->cm_param = NULL;
4534 error = EFAULT;
4535 goto out;
4537 if (copyin((char *)STRUCT_FGETP(params, pAAD),
4538 aes_gmac_params->pAAD, auth_data_len) != 0) {
4539 kmem_free(aes_gmac_params, total_param_len);
4540 out_mech->cm_param = NULL;
4541 error = EFAULT;
4542 goto out;
4544 out_mech->cm_param = (char *)aes_gmac_params;
4545 out_mech->cm_param_len = sizeof (CK_AES_GMAC_PARAMS);
4547 out:
4548 *out_error = error;
4549 return (rv);
4553 * Resource control checks don't need to be done. Why? Because this routine
4554 * knows the size of the structure, and it can't be overridden by a user.
4555 * This is different from the crypto module, which has no knowledge of
4556 * specific mechanisms, and therefore has to trust specified size of the
4557 * parameter. This trust, or lack of trust, is why the size of the
4558 * parameter has to be charged against the project resource control.
4560 static int
4561 copyin_aes_ctr_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
4562 int *out_error, int mode)
4564 STRUCT_DECL(crypto_mechanism, mech);
4565 STRUCT_DECL(CK_AES_CTR_PARAMS, params);
4566 CK_AES_CTR_PARAMS *aes_ctr_params;
4567 caddr_t pp;
4568 size_t param_len;
4569 int error = 0;
4570 int rv = 0;
4572 STRUCT_INIT(mech, mode);
4573 STRUCT_INIT(params, mode);
4574 bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4575 pp = STRUCT_FGETP(mech, cm_param);
4576 param_len = STRUCT_FGET(mech, cm_param_len);
4578 if (param_len != STRUCT_SIZE(params)) {
4579 rv = CRYPTO_ARGUMENTS_BAD;
4580 goto out;
4583 out_mech->cm_type = STRUCT_FGET(mech, cm_type);
4584 out_mech->cm_param = NULL;
4585 out_mech->cm_param_len = 0;
4586 if (pp != NULL) {
4587 if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
4588 out_mech->cm_param = NULL;
4589 error = EFAULT;
4590 goto out;
4592 /* allocate param structure and counter block */
4593 aes_ctr_params = kmem_alloc(sizeof (CK_AES_CTR_PARAMS),
4594 KM_NOSLEEP);
4595 if (aes_ctr_params == NULL) {
4596 rv = CRYPTO_HOST_MEMORY;
4597 goto out;
4599 aes_ctr_params->ulCounterBits = STRUCT_FGET(params,
4600 ulCounterBits);
4601 bcopy(STRUCT_FGETP(params, cb), aes_ctr_params->cb, 16);
4602 out_mech->cm_param = (char *)aes_ctr_params;
4603 out_mech->cm_param_len = sizeof (CK_AES_CTR_PARAMS);
4605 out:
4606 *out_error = error;
4607 return (rv);
4610 static int
4611 copyin_ecc_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
4612 int *out_error, int mode)
4614 STRUCT_DECL(crypto_mechanism, mech);
4615 STRUCT_DECL(CK_ECDH1_DERIVE_PARAMS, params);
4616 CK_ECDH1_DERIVE_PARAMS *ecc_params;
4617 caddr_t pp;
4618 size_t param_len, shared_data_len, public_data_len;
4619 int error = 0;
4620 int rv = 0;
4622 STRUCT_INIT(mech, mode);
4623 STRUCT_INIT(params, mode);
4624 bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4625 pp = STRUCT_FGETP(mech, cm_param);
4626 param_len = STRUCT_FGET(mech, cm_param_len);
4628 if (param_len != STRUCT_SIZE(params)) {
4629 rv = CRYPTO_ARGUMENTS_BAD;
4630 goto out;
4633 out_mech->cm_type = STRUCT_FGET(mech, cm_type);
4634 out_mech->cm_param = NULL;
4635 out_mech->cm_param_len = 0;
4636 if (pp != NULL) {
4637 if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
4638 out_mech->cm_param = NULL;
4639 error = EFAULT;
4640 goto out;
4642 shared_data_len = STRUCT_FGET(params, ulSharedDataLen);
4643 public_data_len = STRUCT_FGET(params, ulPublicDataLen);
4644 /* allocate param structure and buffers */
4645 ecc_params = kmem_alloc(sizeof (CK_ECDH1_DERIVE_PARAMS) +
4646 roundup(shared_data_len, sizeof (caddr_t)) +
4647 roundup(public_data_len, sizeof (caddr_t)), KM_NOSLEEP);
4648 if (ecc_params == NULL) {
4649 rv = CRYPTO_HOST_MEMORY;
4650 goto out;
4652 ecc_params->pSharedData = (uchar_t *)ecc_params +
4653 sizeof (CK_ECDH1_DERIVE_PARAMS);
4654 ecc_params->pPublicData = (uchar_t *)ecc_params->pSharedData +
4655 roundup(shared_data_len, sizeof (caddr_t));
4656 if (copyin((char *)STRUCT_FGETP(params, pSharedData),
4657 ecc_params->pSharedData, shared_data_len) != 0) {
4658 kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) +
4659 roundup(shared_data_len, sizeof (caddr_t)) +
4660 roundup(public_data_len, sizeof (caddr_t)));
4661 out_mech->cm_param = NULL;
4662 error = EFAULT;
4663 goto out;
4665 ecc_params->ulSharedDataLen = shared_data_len;
4667 if (copyin((char *)STRUCT_FGETP(params, pPublicData),
4668 ecc_params->pPublicData, public_data_len) != 0) {
4669 kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) +
4670 roundup(shared_data_len, sizeof (caddr_t)) +
4671 roundup(public_data_len, sizeof (caddr_t)));
4672 out_mech->cm_param = NULL;
4673 error = EFAULT;
4674 goto out;
4676 ecc_params->ulPublicDataLen = public_data_len;
4677 ecc_params->kdf = STRUCT_FGET(params, kdf);
4678 out_mech->cm_param = (char *)ecc_params;
4679 out_mech->cm_param_len = sizeof (CK_ECDH1_DERIVE_PARAMS);
4681 out:
4682 *out_error = error;
4683 return (rv);
4686 /* ARGSUSED */
4687 static int
4688 copyout_aes_ctr_mech(crypto_mechanism_t *in_mech, crypto_mechanism_t *out_mech,
4689 int *out_error, int mode)
4691 STRUCT_DECL(crypto_mechanism, mech);
4692 STRUCT_DECL(CK_AES_CTR_PARAMS, params);
4693 caddr_t pp;
4694 size_t param_len;
4695 int error = 0;
4696 int rv = 0;
4698 STRUCT_INIT(mech, mode);
4699 STRUCT_INIT(params, mode);
4700 bcopy(out_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4701 pp = STRUCT_FGETP(mech, cm_param);
4702 param_len = STRUCT_FGET(mech, cm_param_len);
4703 if (param_len != STRUCT_SIZE(params)) {
4704 rv = CRYPTO_ARGUMENTS_BAD;
4705 goto out;
4708 if (copyin((char *)pp, STRUCT_BUF(params), param_len) != 0) {
4709 error = EFAULT;
4710 goto out;
4713 /* for testing, overwrite the iv with 16 X 'A' */
4714 (void) memset(STRUCT_FGETP(params, cb), 'A', 16);
4715 if (copyout((char *)pp, STRUCT_BUF(params), param_len) != 0) {
4716 error = EFAULT;
4717 goto out;
4719 out:
4720 *out_error = error;
4721 return (rv);
4724 /* ARGSUSED */
4725 static int
4726 dprov_copyin_mechanism(crypto_provider_handle_t provider,
4727 crypto_mechanism_t *umech, crypto_mechanism_t *kmech,
4728 int *out_error, int mode)
4730 STRUCT_DECL(crypto_mechanism, mech);
4731 size_t param_len, expected_param_len;
4732 caddr_t pp;
4733 char *param;
4734 int rv;
4735 int error = 0;
4737 ASSERT(!servicing_interrupt());
4739 STRUCT_INIT(mech, mode);
4740 bcopy(umech, STRUCT_BUF(mech), STRUCT_SIZE(mech));
4741 pp = STRUCT_FGETP(mech, cm_param);
4742 param_len = STRUCT_FGET(mech, cm_param_len);
4744 kmech->cm_param = NULL;
4745 kmech->cm_param_len = 0;
4747 switch (kmech->cm_type) {
4748 case DES_CBC_MECH_INFO_TYPE:
4749 case DES3_CBC_MECH_INFO_TYPE:
4750 expected_param_len = DES_BLOCK_LEN;
4751 break;
4753 case BLOWFISH_CBC_MECH_INFO_TYPE:
4754 expected_param_len = BLOWFISH_BLOCK_LEN;
4755 break;
4757 case AES_CBC_MECH_INFO_TYPE:
4758 expected_param_len = AES_BLOCK_LEN;
4759 break;
4761 case AES_CTR_MECH_INFO_TYPE:
4762 case SHA1_KEY_DERIVATION_MECH_INFO_TYPE: /* for testing only */
4763 rv = copyin_aes_ctr_mech(umech, kmech, &error, mode);
4764 goto out;
4766 case ECDH1_DERIVE_MECH_INFO_TYPE:
4767 rv = copyin_ecc_mech(umech, kmech, &error, mode);
4768 goto out;
4770 case AES_CCM_MECH_INFO_TYPE:
4771 rv = copyin_aes_ccm_mech(umech, kmech, &error, mode);
4772 goto out;
4774 case AES_GCM_MECH_INFO_TYPE:
4775 rv = copyin_aes_gcm_mech(umech, kmech, &error, mode);
4776 goto out;
4778 case AES_GMAC_MECH_INFO_TYPE:
4779 rv = copyin_aes_gmac_mech(umech, kmech, &error, mode);
4780 goto out;
4782 case DH_PKCS_DERIVE_MECH_INFO_TYPE:
4783 expected_param_len = param_len;
4784 break;
4786 default:
4787 /* nothing to do - mechanism has no parameters */
4788 rv = CRYPTO_SUCCESS;
4789 goto out;
4792 if (param_len != expected_param_len) {
4793 rv = CRYPTO_MECHANISM_PARAM_INVALID;
4794 goto out;
4796 if (pp == NULL) {
4797 rv = CRYPTO_MECHANISM_PARAM_INVALID;
4798 goto out;
4800 if ((param = kmem_alloc(param_len, KM_NOSLEEP)) == NULL) {
4801 rv = CRYPTO_HOST_MEMORY;
4802 goto out;
4804 if (copyin((char *)pp, param, param_len) != 0) {
4805 kmem_free(param, param_len);
4806 error = EFAULT;
4807 rv = CRYPTO_FAILED;
4808 goto out;
4810 kmech->cm_param = (char *)param;
4811 kmech->cm_param_len = param_len;
4812 rv = CRYPTO_SUCCESS;
4813 out:
4814 *out_error = error;
4815 return (rv);
4818 /* ARGSUSED */
4819 static int
4820 dprov_copyout_mechanism(crypto_provider_handle_t provider,
4821 crypto_mechanism_t *kmech, crypto_mechanism_t *umech,
4822 int *out_error, int mode)
4824 ASSERT(!servicing_interrupt());
4826 switch (kmech->cm_type) {
4827 case AES_CTR_MECH_INFO_TYPE:
4828 case SHA1_KEY_DERIVATION_MECH_INFO_TYPE: /* for testing only */
4829 return (copyout_aes_ctr_mech(kmech, umech, out_error, mode));
4830 case ECDH1_DERIVE_MECH_INFO_TYPE:
4831 return (CRYPTO_SUCCESS);
4832 default:
4833 return (CRYPTO_MECHANISM_INVALID);
4838 * Free mechanism parameter that was allocated by the provider.
4840 /* ARGSUSED */
4841 static int
4842 dprov_free_mechanism(crypto_provider_handle_t provider,
4843 crypto_mechanism_t *mech)
4845 size_t len;
4847 if (mech->cm_param == NULL || mech->cm_param_len == 0)
4848 return (CRYPTO_SUCCESS);
4850 switch (mech->cm_type) {
4851 case AES_CTR_MECH_INFO_TYPE:
4852 case SHA1_KEY_DERIVATION_MECH_INFO_TYPE:
4853 len = sizeof (CK_AES_CTR_PARAMS);
4854 break;
4855 case ECDH1_DERIVE_MECH_INFO_TYPE: {
4856 CK_ECDH1_DERIVE_PARAMS *ecc_params;
4858 /* LINTED: pointer alignment */
4859 ecc_params = (CK_ECDH1_DERIVE_PARAMS *)mech->cm_param;
4860 kmem_free(ecc_params, sizeof (CK_ECDH1_DERIVE_PARAMS) +
4861 roundup(ecc_params->ulSharedDataLen, sizeof (caddr_t)) +
4862 roundup(ecc_params->ulPublicDataLen, sizeof (caddr_t)));
4863 return (CRYPTO_SUCCESS);
4865 case AES_CCM_MECH_INFO_TYPE: {
4866 CK_AES_CCM_PARAMS *params;
4867 size_t total_param_len;
4869 if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) {
4870 /* LINTED: pointer alignment */
4871 params = (CK_AES_CCM_PARAMS *)mech->cm_param;
4872 total_param_len = mech->cm_param_len +
4873 params->ulNonceSize + params->ulAuthDataSize;
4874 kmem_free(params, total_param_len);
4875 mech->cm_param = NULL;
4876 mech->cm_param_len = 0;
4878 return (CRYPTO_SUCCESS);
4880 case AES_GMAC_MECH_INFO_TYPE: {
4881 CK_AES_GMAC_PARAMS *params;
4882 size_t total_param_len;
4884 if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) {
4885 /* LINTED: pointer alignment */
4886 params = (CK_AES_GMAC_PARAMS *)mech->cm_param;
4887 total_param_len = mech->cm_param_len +
4888 AES_GMAC_IV_LEN + params->ulAADLen;
4889 kmem_free(params, total_param_len);
4890 mech->cm_param = NULL;
4891 mech->cm_param_len = 0;
4893 return (CRYPTO_SUCCESS);
4895 case AES_GCM_MECH_INFO_TYPE: {
4896 CK_AES_GCM_PARAMS *params;
4897 size_t total_param_len;
4899 if ((mech->cm_param != NULL) && (mech->cm_param_len != 0)) {
4900 /* LINTED: pointer alignment */
4901 params = (CK_AES_GCM_PARAMS *)mech->cm_param;
4902 total_param_len = mech->cm_param_len +
4903 params->ulIvLen + params->ulAADLen;
4904 kmem_free(params, total_param_len);
4905 mech->cm_param = NULL;
4906 mech->cm_param_len = 0;
4908 return (CRYPTO_SUCCESS);
4911 default:
4912 len = mech->cm_param_len;
4914 kmem_free(mech->cm_param, len);
4915 return (CRYPTO_SUCCESS);
4919 * No (Key)Store Key management entry point.
4921 static int
4922 dprov_nostore_key_generate(crypto_provider_handle_t provider,
4923 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
4924 crypto_object_attribute_t *template, uint_t attribute_count,
4925 crypto_object_attribute_t *out_template, uint_t out_attribute_count,
4926 crypto_req_handle_t req)
4928 int error = CRYPTO_FAILED;
4929 dprov_state_t *softc = (dprov_state_t *)provider;
4930 /* LINTED E_FUNC_SET_NOT_USED */
4931 int instance;
4933 instance = ddi_get_instance(softc->ds_dip);
4934 DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate: started\n",
4935 instance));
4937 /* submit request to the taskq */
4938 error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_GENERATE,
4939 softc, req, session_id, mechanism, template, attribute_count,
4940 NULL, NULL, 0, NULL, NULL, NULL, 0, out_template,
4941 out_attribute_count, NULL, 0);
4943 DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate: "
4944 "done err = 0x0%x\n", instance, error));
4946 return (error);
4949 static int
4950 dprov_nostore_key_generate_pair(crypto_provider_handle_t provider,
4951 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
4952 crypto_object_attribute_t *public_key_template,
4953 uint_t public_key_attribute_count,
4954 crypto_object_attribute_t *private_key_template,
4955 uint_t private_key_attribute_count,
4956 crypto_object_attribute_t *out_public_key_template,
4957 uint_t out_public_key_attribute_count,
4958 crypto_object_attribute_t *out_private_key_template,
4959 uint_t out_private_key_attribute_count,
4960 crypto_req_handle_t req)
4962 int error = CRYPTO_FAILED;
4963 dprov_state_t *softc = (dprov_state_t *)provider;
4964 /* LINTED E_FUNC_SET_NOT_USED */
4965 int instance;
4967 instance = ddi_get_instance(softc->ds_dip);
4968 DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate_pair: started\n",
4969 instance));
4971 /* submit request to the taskq */
4972 error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR,
4973 softc, req, session_id, mechanism, public_key_template,
4974 public_key_attribute_count, NULL, private_key_template,
4975 private_key_attribute_count, NULL, NULL, NULL, 0,
4976 out_public_key_template, out_public_key_attribute_count,
4977 out_private_key_template, out_private_key_attribute_count);
4979 DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_generate_pair: "
4980 "done err = 0x0%x\n", instance, error));
4982 return (error);
4985 static int
4986 dprov_nostore_key_derive(crypto_provider_handle_t provider,
4987 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
4988 crypto_key_t *base_key, crypto_object_attribute_t *template,
4989 uint_t attribute_count, crypto_object_attribute_t *out_template,
4990 uint_t out_attribute_count, crypto_req_handle_t req)
4992 int error = CRYPTO_FAILED;
4993 dprov_state_t *softc = (dprov_state_t *)provider;
4994 /* LINTED E_FUNC_SET_NOT_USED */
4995 int instance;
4997 instance = ddi_get_instance(softc->ds_dip);
4998 DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_derive: started\n",
4999 instance));
5001 /* submit request to the taskq */
5002 error = dprov_key_submit_req(DPROV_REQ_NOSTORE_KEY_DERIVE, softc, req,
5003 session_id, mechanism, template, attribute_count, NULL, NULL,
5004 0, NULL, base_key, NULL, 0, out_template, out_attribute_count,
5005 NULL, 0);
5007 DPROV_DEBUG(D_KEY, ("(%d) dprov_nostore_key_derive: "
5008 "done err = 0x0%x\n", instance, error));
5010 return (error);
5014 * Allocate a dprov taskq request and initialize the common fields.
5015 * Return NULL if the memory allocation failed.
5017 static dprov_req_t *
5018 dprov_alloc_req(dprov_req_type_t req_type, dprov_state_t *softc,
5019 crypto_req_handle_t kcf_req, int kmflag)
5021 dprov_req_t *taskq_req;
5023 if ((taskq_req = kmem_alloc(sizeof (dprov_req_t), kmflag)) == NULL)
5024 return (NULL);
5026 taskq_req->dr_type = req_type;
5027 taskq_req->dr_softc = softc;
5028 taskq_req->dr_kcf_req = kcf_req;
5030 return (taskq_req);
5034 * Dispatch a dprov request on the taskq associated with a softc.
5035 * Returns CRYPTO_HOST_MEMORY if the request cannot be queued,
5036 * CRYPTO_QUEUED on success.
5038 static int
5039 dprov_taskq_dispatch(dprov_state_t *softc, dprov_req_t *taskq_req,
5040 task_func_t *func, int kmflag)
5042 if (taskq_dispatch(softc->ds_taskq, func, taskq_req,
5043 kmflag == KM_NOSLEEP ? TQ_NOSLEEP : TQ_SLEEP) == (taskqid_t)0) {
5044 kmem_free(taskq_req, sizeof (dprov_req_t));
5045 return (CRYPTO_HOST_MEMORY);
5046 } else
5047 return (CRYPTO_QUEUED);
5051 * Helper function to submit digest operations to the taskq.
5052 * Returns one of the CRYPTO_ errors.
5054 static int
5055 dprov_digest_submit_req(dprov_req_type_t req_type,
5056 dprov_state_t *softc, crypto_req_handle_t req,
5057 crypto_mechanism_t *mechanism, crypto_data_t *data, crypto_key_t *key,
5058 crypto_data_t *digest, crypto_ctx_t *ctx, int kmflag)
5060 dprov_req_t *taskq_req;
5062 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
5063 return (CRYPTO_HOST_MEMORY);
5065 taskq_req->dr_digest_req.dr_mechanism = mechanism;
5066 taskq_req->dr_digest_req.dr_ctx = ctx;
5067 taskq_req->dr_digest_req.dr_data = data;
5068 taskq_req->dr_digest_req.dr_key = key;
5069 taskq_req->dr_digest_req.dr_digest = digest;
5071 return (dprov_taskq_dispatch(softc, taskq_req,
5072 (task_func_t *)dprov_digest_task, kmflag));
5076 * Helper function to submit mac operations to the taskq.
5077 * Returns one of the CRYPTO_ errors.
5079 static int
5080 dprov_mac_submit_req(dprov_req_type_t req_type,
5081 dprov_state_t *softc, crypto_req_handle_t req,
5082 crypto_mechanism_t *mechanism, crypto_data_t *data, crypto_key_t *key,
5083 crypto_data_t *mac, crypto_ctx_t *ctx, crypto_session_id_t sid, int kmflag)
5085 dprov_req_t *taskq_req;
5087 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
5088 return (CRYPTO_HOST_MEMORY);
5090 taskq_req->dr_mac_req.dr_mechanism = mechanism;
5091 taskq_req->dr_mac_req.dr_ctx = ctx;
5092 taskq_req->dr_mac_req.dr_data = data;
5093 taskq_req->dr_mac_req.dr_key = key;
5094 taskq_req->dr_mac_req.dr_mac = mac;
5095 taskq_req->dr_mac_req.dr_session_id = sid;
5097 return (dprov_taskq_dispatch(softc, taskq_req,
5098 (task_func_t *)dprov_mac_task, kmflag));
5102 * Helper function to submit sign operations to the taskq.
5103 * Returns one of the CRYPTO_ errors.
5105 static int
5106 dprov_sign_submit_req(dprov_req_type_t req_type,
5107 dprov_state_t *softc, crypto_req_handle_t req,
5108 crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data,
5109 crypto_data_t *signature, crypto_ctx_t *ctx, crypto_session_id_t sid,
5110 int kmflag)
5112 dprov_req_t *taskq_req;
5114 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
5115 return (CRYPTO_HOST_MEMORY);
5117 taskq_req->dr_sign_req.sr_mechanism = mechanism;
5118 taskq_req->dr_sign_req.sr_ctx = ctx;
5119 taskq_req->dr_sign_req.sr_key = key;
5120 taskq_req->dr_sign_req.sr_data = data;
5121 taskq_req->dr_sign_req.sr_signature = signature;
5122 taskq_req->dr_sign_req.sr_session_id = sid;
5124 return (dprov_taskq_dispatch(softc, taskq_req,
5125 (task_func_t *)dprov_sign_task, kmflag));
5129 * Helper function to submit verify operations to the taskq.
5130 * Returns one of the CRYPTO_ errors.
5132 static int
5133 dprov_verify_submit_req(dprov_req_type_t req_type,
5134 dprov_state_t *softc, crypto_req_handle_t req,
5135 crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data,
5136 crypto_data_t *signature, crypto_ctx_t *ctx, crypto_session_id_t sid,
5137 int kmflag)
5139 dprov_req_t *taskq_req;
5141 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
5142 return (CRYPTO_HOST_MEMORY);
5144 taskq_req->dr_verify_req.vr_mechanism = mechanism;
5145 taskq_req->dr_verify_req.vr_ctx = ctx;
5146 taskq_req->dr_verify_req.vr_key = key;
5147 taskq_req->dr_verify_req.vr_data = data;
5148 taskq_req->dr_verify_req.vr_signature = signature;
5149 taskq_req->dr_verify_req.vr_session_id = sid;
5151 return (dprov_taskq_dispatch(softc, taskq_req,
5152 (task_func_t *)dprov_verify_task, kmflag));
5156 * Helper function to submit dual operations to the taskq.
5157 * Returns one of the CRYPTO_ errors.
5159 static int
5160 dprov_dual_submit_req(dprov_req_type_t req_type, dprov_state_t *softc,
5161 crypto_req_handle_t req, crypto_ctx_t *signverify_ctx,
5162 crypto_ctx_t *cipher_ctx, crypto_data_t *plaintext,
5163 crypto_data_t *ciphertext)
5165 dprov_req_t *taskq_req;
5167 if ((taskq_req = dprov_alloc_req(req_type, softc, req,
5168 KM_NOSLEEP)) == NULL)
5169 return (CRYPTO_HOST_MEMORY);
5171 taskq_req->dr_dual_req.dr_signverify_ctx = signverify_ctx;
5172 taskq_req->dr_dual_req.dr_cipher_ctx = cipher_ctx;
5173 taskq_req->dr_dual_req.dr_plaintext = plaintext;
5174 taskq_req->dr_dual_req.dr_ciphertext = ciphertext;
5176 return (dprov_taskq_dispatch(softc, taskq_req,
5177 (task_func_t *)dprov_dual_task, KM_NOSLEEP));
5181 * Helper function to submit dual cipher/mac operations to the taskq.
5182 * Returns one of the CRYPTO_ errors.
5184 static int
5185 dprov_cipher_mac_submit_req(dprov_req_type_t req_type,
5186 dprov_state_t *softc, crypto_req_handle_t req, crypto_ctx_t *ctx,
5187 crypto_session_id_t sid, crypto_mechanism_t *cipher_mech,
5188 crypto_key_t *cipher_key, crypto_mechanism_t *mac_mech,
5189 crypto_key_t *mac_key, crypto_dual_data_t *dual_data,
5190 crypto_data_t *data, crypto_data_t *mac, int kmflag)
5192 dprov_req_t *taskq_req;
5194 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
5195 return (CRYPTO_HOST_MEMORY);
5197 taskq_req->dr_cipher_mac_req.mr_session_id = sid;
5198 taskq_req->dr_cipher_mac_req.mr_ctx = ctx;
5199 taskq_req->dr_cipher_mac_req.mr_cipher_mech = cipher_mech;
5200 taskq_req->dr_cipher_mac_req.mr_cipher_key = cipher_key;
5201 taskq_req->dr_cipher_mac_req.mr_mac_mech = mac_mech;
5202 taskq_req->dr_cipher_mac_req.mr_mac_key = mac_key;
5203 taskq_req->dr_cipher_mac_req.mr_dual_data = dual_data;
5204 taskq_req->dr_cipher_mac_req.mr_data = data;
5205 taskq_req->dr_cipher_mac_req.mr_mac = mac;
5207 return (dprov_taskq_dispatch(softc, taskq_req,
5208 (task_func_t *)dprov_cipher_mac_task, kmflag));
5212 * Helper function to submit cipher operations to the taskq.
5213 * Returns one of the CRYPTO_ errors.
5215 static int
5216 dprov_cipher_submit_req(dprov_req_type_t req_type,
5217 dprov_state_t *softc, crypto_req_handle_t req,
5218 crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *plaintext,
5219 crypto_data_t *ciphertext, crypto_ctx_t *ctx, crypto_session_id_t sid,
5220 int kmflag)
5222 dprov_req_t *taskq_req;
5224 if ((taskq_req = dprov_alloc_req(req_type, softc, req, kmflag)) == NULL)
5225 return (CRYPTO_HOST_MEMORY);
5227 taskq_req->dr_cipher_req.dr_mechanism = mechanism;
5228 taskq_req->dr_cipher_req.dr_ctx = ctx;
5229 taskq_req->dr_cipher_req.dr_key = key;
5230 taskq_req->dr_cipher_req.dr_plaintext = plaintext;
5231 taskq_req->dr_cipher_req.dr_ciphertext = ciphertext;
5232 taskq_req->dr_cipher_req.dr_session_id = sid;
5234 return (dprov_taskq_dispatch(softc, taskq_req,
5235 (task_func_t *)dprov_cipher_task, kmflag));
5239 * Helper function to submit random number operations to the taskq.
5240 * Returns one of the CRYPTO_ errors.
5242 static int
5243 dprov_random_submit_req(dprov_req_type_t req_type,
5244 dprov_state_t *softc, crypto_req_handle_t req, uchar_t *buf, size_t len,
5245 crypto_session_id_t sid, uint_t entropy_est, uint32_t flags)
5247 dprov_req_t *taskq_req;
5249 if ((taskq_req = dprov_alloc_req(req_type, softc, req,
5250 KM_NOSLEEP)) == NULL)
5251 return (CRYPTO_HOST_MEMORY);
5253 taskq_req->dr_random_req.rr_buf = buf;
5254 taskq_req->dr_random_req.rr_len = len;
5255 taskq_req->dr_random_req.rr_session_id = sid;
5256 taskq_req->dr_random_req.rr_entropy_est = entropy_est;
5257 taskq_req->dr_random_req.rr_flags = flags;
5259 return (dprov_taskq_dispatch(softc, taskq_req,
5260 (task_func_t *)dprov_random_task, KM_NOSLEEP));
5265 * Helper function to submit session management operations to the taskq.
5266 * Returns one of the CRYPTO_ errors.
5268 static int
5269 dprov_session_submit_req(dprov_req_type_t req_type,
5270 dprov_state_t *softc, crypto_req_handle_t req,
5271 crypto_session_id_t *session_id_ptr, crypto_session_id_t session_id,
5272 crypto_user_type_t user_type, char *pin, size_t pin_len)
5274 dprov_req_t *taskq_req;
5276 if ((taskq_req = dprov_alloc_req(req_type, softc, req,
5277 KM_NOSLEEP)) == NULL)
5278 return (CRYPTO_HOST_MEMORY);
5280 taskq_req->dr_session_req.sr_session_id_ptr = session_id_ptr;
5281 taskq_req->dr_session_req.sr_session_id = session_id;
5282 taskq_req->dr_session_req.sr_user_type = user_type;
5283 taskq_req->dr_session_req.sr_pin = pin;
5284 taskq_req->dr_session_req.sr_pin_len = pin_len;
5286 return (dprov_taskq_dispatch(softc, taskq_req,
5287 (task_func_t *)dprov_session_task, KM_NOSLEEP));
5291 * Helper function to submit object management operations to the taskq.
5292 * Returns one of the CRYPTO_ errors.
5294 static int
5295 dprov_object_submit_req(dprov_req_type_t req_type,
5296 dprov_state_t *softc, crypto_req_handle_t req,
5297 crypto_session_id_t session_id, crypto_object_id_t object_id,
5298 crypto_object_attribute_t *template, uint_t attribute_count,
5299 crypto_object_id_t *object_id_ptr, size_t *object_size,
5300 void **find_pp, void *find_p, uint_t max_object_count,
5301 uint_t *object_count_ptr, int kmflag)
5303 dprov_req_t *taskq_req;
5305 if ((taskq_req = dprov_alloc_req(req_type, softc, req,
5306 kmflag)) == NULL)
5307 return (CRYPTO_HOST_MEMORY);
5309 taskq_req->dr_object_req.or_session_id = session_id;
5310 taskq_req->dr_object_req.or_object_id = object_id;
5311 taskq_req->dr_object_req.or_template = template;
5312 taskq_req->dr_object_req.or_attribute_count = attribute_count;
5313 taskq_req->dr_object_req.or_object_id_ptr = object_id_ptr;
5314 taskq_req->dr_object_req.or_object_size = object_size;
5315 taskq_req->dr_object_req.or_find_pp = find_pp;
5316 taskq_req->dr_object_req.or_find_p = find_p;
5317 taskq_req->dr_object_req.or_max_object_count = max_object_count;
5318 taskq_req->dr_object_req.or_object_count_ptr = object_count_ptr;
5320 return (dprov_taskq_dispatch(softc, taskq_req,
5321 (task_func_t *)dprov_object_task, KM_NOSLEEP));
5325 * Helper function to submit key management operations to the taskq.
5326 * Returns one of the CRYPTO_ errors.
5328 static int
5329 dprov_key_submit_req(dprov_req_type_t req_type,
5330 dprov_state_t *softc, crypto_req_handle_t req,
5331 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
5332 crypto_object_attribute_t *template, uint_t attribute_count,
5333 crypto_object_id_t *object_id_ptr,
5334 crypto_object_attribute_t *private_key_template,
5335 uint_t private_key_attribute_count,
5336 crypto_object_id_t *private_key_object_id_ptr, crypto_key_t *key,
5337 uchar_t *wrapped_key, size_t *wrapped_key_len_ptr,
5338 crypto_object_attribute_t *out_template1, uint_t out_attribute_count1,
5339 crypto_object_attribute_t *out_template2, uint_t out_attribute_count2)
5341 dprov_req_t *taskq_req;
5343 if ((taskq_req = dprov_alloc_req(req_type, softc, req,
5344 KM_NOSLEEP)) == NULL)
5345 return (CRYPTO_HOST_MEMORY);
5347 taskq_req->dr_key_req.kr_session_id = session_id;
5348 taskq_req->dr_key_req.kr_mechanism = mechanism;
5349 taskq_req->dr_key_req.kr_template = template;
5350 taskq_req->dr_key_req.kr_attribute_count = attribute_count;
5351 taskq_req->dr_key_req.kr_object_id_ptr = object_id_ptr;
5352 taskq_req->dr_key_req.kr_private_key_template = private_key_template;
5353 taskq_req->dr_key_req.kr_private_key_attribute_count =
5354 private_key_attribute_count;
5355 taskq_req->dr_key_req.kr_private_key_object_id_ptr =
5356 private_key_object_id_ptr;
5357 taskq_req->dr_key_req.kr_key = key;
5358 taskq_req->dr_key_req.kr_wrapped_key = wrapped_key;
5359 taskq_req->dr_key_req.kr_wrapped_key_len_ptr = wrapped_key_len_ptr;
5360 taskq_req->dr_key_req.kr_out_template1 = out_template1;
5361 taskq_req->dr_key_req.kr_out_attribute_count1 = out_attribute_count1;
5362 taskq_req->dr_key_req.kr_out_template2 = out_template2;
5363 taskq_req->dr_key_req.kr_out_attribute_count2 = out_attribute_count2;
5365 return (dprov_taskq_dispatch(softc, taskq_req,
5366 (task_func_t *)dprov_key_task, KM_NOSLEEP));
5370 * Helper function to submit provider management operations to the taskq.
5371 * Returns one of the CRYPTO_ errors.
5373 static int
5374 dprov_mgmt_submit_req(dprov_req_type_t req_type,
5375 dprov_state_t *softc, crypto_req_handle_t req,
5376 crypto_session_id_t session_id, char *pin, size_t pin_len,
5377 char *old_pin, size_t old_pin_len, char *label,
5378 crypto_provider_ext_info_t *ext_info)
5380 dprov_req_t *taskq_req;
5382 if ((taskq_req = dprov_alloc_req(req_type, softc, req,
5383 KM_NOSLEEP)) == NULL)
5384 return (CRYPTO_HOST_MEMORY);
5386 taskq_req->dr_mgmt_req.mr_session_id = session_id;
5387 taskq_req->dr_mgmt_req.mr_pin = pin;
5388 taskq_req->dr_mgmt_req.mr_pin_len = pin_len;
5389 taskq_req->dr_mgmt_req.mr_old_pin = old_pin;
5390 taskq_req->dr_mgmt_req.mr_old_pin_len = old_pin_len;
5391 taskq_req->dr_mgmt_req.mr_label = label;
5392 taskq_req->dr_mgmt_req.mr_ext_info = ext_info;
5394 return (dprov_taskq_dispatch(softc, taskq_req,
5395 (task_func_t *)dprov_mgmt_task, KM_NOSLEEP));
5399 * Helper function for taskq dispatcher routines. Notify the framework
5400 * that the operation corresponding to the specified request is done,
5401 * and pass it the error code. Finally, free the taskq_req.
5403 static void
5404 dprov_op_done(dprov_req_t *taskq_req, int error)
5406 /* notify framework that request is completed */
5407 crypto_op_notification(taskq_req->dr_kcf_req, error);
5409 /* free taskq request structure */
5410 kmem_free(taskq_req, sizeof (dprov_req_t));
5414 * taskq dispatcher function for digest operations.
5416 static void
5417 dprov_digest_task(dprov_req_t *taskq_req)
5419 kcf_provider_desc_t *pd;
5420 dprov_state_t *softc;
5421 /* LINTED E_FUNC_SET_NOT_USED */
5422 int instance;
5423 int error = CRYPTO_NOT_SUPPORTED;
5424 crypto_ctx_t *ctx = taskq_req->dr_digest_req.dr_ctx;
5425 crypto_mechanism_t mech;
5427 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
5428 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_task: started\n", instance));
5430 switch (taskq_req->dr_type) {
5432 case DPROV_REQ_DIGEST_INIT:
5433 /* allocate a dprov-private context */
5434 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
5435 CRYPTO_SUCCESS)
5436 break;
5438 /* structure assignment */
5439 mech = *taskq_req->dr_digest_req.dr_mechanism;
5441 /* get the software provider for this mechanism */
5442 if ((error = dprov_get_sw_prov(
5443 taskq_req->dr_digest_req.dr_mechanism, &pd,
5444 &mech.cm_type)) != CRYPTO_SUCCESS)
5445 break;
5447 /* Use a session id of zero since we use a software provider */
5448 error = crypto_digest_init_prov(pd, 0, &mech,
5449 &DPROV_CTX_SINGLE(ctx), NULL);
5451 /* release provider reference */
5452 KCF_PROV_REFRELE(pd);
5453 break;
5455 case DPROV_REQ_DIGEST:
5456 error = crypto_digest_single(DPROV_CTX_SINGLE(ctx),
5457 taskq_req->dr_digest_req.dr_data,
5458 taskq_req->dr_digest_req.dr_digest, NULL);
5460 if (error != CRYPTO_BUFFER_TOO_SMALL) {
5461 DPROV_CTX_SINGLE(ctx) = NULL;
5462 (void) dprov_free_context(ctx);
5464 break;
5466 case DPROV_REQ_DIGEST_UPDATE:
5467 error = crypto_digest_update(DPROV_CTX_SINGLE(ctx),
5468 taskq_req->dr_digest_req.dr_data, NULL);
5469 break;
5471 case DPROV_REQ_DIGEST_KEY: {
5472 crypto_data_t data;
5473 crypto_key_t key;
5474 size_t len;
5476 mutex_enter(&softc->ds_lock);
5477 error = dprov_key_value_secret(softc, ctx->cc_session,
5478 taskq_req->dr_type, taskq_req->dr_digest_req.dr_key, &key);
5479 mutex_exit(&softc->ds_lock);
5480 if (error != CRYPTO_SUCCESS)
5481 break;
5483 /* key lengths are specified in bits */
5484 len = CRYPTO_BITS2BYTES(key.ck_length);
5485 data.cd_format = CRYPTO_DATA_RAW;
5486 data.cd_offset = 0;
5487 data.cd_length = len;
5488 data.cd_raw.iov_base = key.ck_data;
5489 data.cd_raw.iov_len = len;
5490 error = crypto_digest_update(DPROV_CTX_SINGLE(ctx),
5491 &data, NULL);
5492 break;
5495 case DPROV_REQ_DIGEST_FINAL:
5496 error = crypto_digest_final(DPROV_CTX_SINGLE(ctx),
5497 taskq_req->dr_digest_req.dr_digest, NULL);
5498 if (error != CRYPTO_BUFFER_TOO_SMALL) {
5499 DPROV_CTX_SINGLE(ctx) = NULL;
5500 (void) dprov_free_context(ctx);
5502 break;
5504 case DPROV_REQ_DIGEST_ATOMIC:
5505 /* structure assignment */
5506 mech = *taskq_req->dr_digest_req.dr_mechanism;
5508 /* get the software provider for this mechanism */
5509 if ((error = dprov_get_sw_prov(
5510 taskq_req->dr_digest_req.dr_mechanism, &pd,
5511 &mech.cm_type)) != CRYPTO_SUCCESS)
5512 break;
5514 /* use a session id of zero since we use a software provider */
5515 error = crypto_digest_prov(pd, 0, &mech,
5516 taskq_req->dr_digest_req.dr_data,
5517 taskq_req->dr_digest_req.dr_digest, NULL);
5519 /* release provider reference */
5520 KCF_PROV_REFRELE(pd);
5522 break;
5525 dprov_op_done(taskq_req, error);
5526 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_digest_task: end\n", instance));
5530 * taskq dispatcher function for mac operations.
5532 static void
5533 dprov_mac_task(dprov_req_t *taskq_req)
5535 kcf_provider_desc_t *pd;
5536 dprov_state_t *softc;
5537 /* LINTED E_FUNC_SET_NOT_USED */
5538 int instance;
5539 int error = CRYPTO_NOT_SUPPORTED;
5540 crypto_ctx_t *ctx = taskq_req->dr_mac_req.dr_ctx;
5541 crypto_key_t key;
5542 crypto_mechanism_t mech;
5544 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
5545 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: started\n", instance));
5547 switch (taskq_req->dr_type) {
5549 case DPROV_REQ_MAC_INIT:
5550 /* allocate a dprov-private context */
5551 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
5552 CRYPTO_SUCCESS)
5553 break;
5555 /* get key value */
5556 mutex_enter(&softc->ds_lock);
5557 error = dprov_key_value_secret(softc, ctx->cc_session,
5558 taskq_req->dr_type, taskq_req->dr_mac_req.dr_key, &key);
5559 mutex_exit(&softc->ds_lock);
5560 if (error != CRYPTO_SUCCESS)
5561 break;
5563 /* structure assignment */
5564 mech = *taskq_req->dr_mac_req.dr_mechanism;
5566 /* get the software provider for this mechanism */
5567 if ((error = dprov_get_sw_prov(
5568 taskq_req->dr_mac_req.dr_mechanism, &pd,
5569 &mech.cm_type)) != CRYPTO_SUCCESS)
5570 break;
5572 /* Use a session id of zero since we use a software provider */
5573 error = crypto_mac_init_prov(pd, 0, &mech, &key, NULL,
5574 &DPROV_CTX_SINGLE(ctx), NULL);
5576 /* release provider reference */
5577 KCF_PROV_REFRELE(pd);
5578 break;
5580 case DPROV_REQ_MAC:
5581 error = crypto_mac_single(DPROV_CTX_SINGLE(ctx),
5582 taskq_req->dr_mac_req.dr_data,
5583 taskq_req->dr_mac_req.dr_mac, NULL);
5585 if (error != CRYPTO_BUFFER_TOO_SMALL) {
5586 DPROV_CTX_SINGLE(ctx) = NULL;
5587 (void) dprov_free_context(ctx);
5589 break;
5591 case DPROV_REQ_MAC_UPDATE:
5592 error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
5593 taskq_req->dr_mac_req.dr_data, NULL);
5594 break;
5596 case DPROV_REQ_MAC_FINAL:
5597 error = crypto_mac_final(DPROV_CTX_SINGLE(ctx),
5598 taskq_req->dr_mac_req.dr_mac, NULL);
5599 if (error != CRYPTO_BUFFER_TOO_SMALL) {
5600 DPROV_CTX_SINGLE(ctx) = NULL;
5601 (void) dprov_free_context(ctx);
5603 break;
5605 case DPROV_REQ_MAC_ATOMIC:
5606 case DPROV_REQ_MAC_VERIFY_ATOMIC:
5607 /* get key value */
5608 mutex_enter(&softc->ds_lock);
5609 error = dprov_key_value_secret(softc,
5610 taskq_req->dr_mac_req.dr_session_id,
5611 taskq_req->dr_type, taskq_req->dr_mac_req.dr_key, &key);
5612 mutex_exit(&softc->ds_lock);
5613 if (error != CRYPTO_SUCCESS)
5614 break;
5616 /* structure assignment */
5617 mech = *taskq_req->dr_mac_req.dr_mechanism;
5619 /* get the software provider for this mechanism */
5620 if ((error = dprov_get_sw_prov(
5621 taskq_req->dr_mac_req.dr_mechanism, &pd,
5622 &mech.cm_type)) != CRYPTO_SUCCESS)
5623 break;
5625 /* use a session id of zero since we use a software provider */
5626 if (taskq_req->dr_type == DPROV_REQ_MAC_ATOMIC)
5627 error = crypto_mac_prov(pd, 0, &mech,
5628 taskq_req->dr_mac_req.dr_data,
5629 &key, NULL, taskq_req->dr_mac_req.dr_mac, NULL);
5630 else
5631 error = crypto_mac_verify_prov(pd, 0, &mech,
5632 taskq_req->dr_mac_req.dr_data,
5633 &key, NULL, taskq_req->dr_mac_req.dr_mac, NULL);
5635 /* release provider reference */
5636 KCF_PROV_REFRELE(pd);
5638 break;
5641 dprov_op_done(taskq_req, error);
5642 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: end\n", instance));
5646 * taskq dispatcher function for sign operations.
5648 static void
5649 dprov_sign_task(dprov_req_t *taskq_req)
5651 kcf_provider_desc_t *pd;
5652 dprov_state_t *softc;
5653 /* LINTED E_FUNC_SET_NOT_USED */
5654 int instance;
5655 int error = CRYPTO_NOT_SUPPORTED;
5656 crypto_ctx_t *ctx = taskq_req->dr_sign_req.sr_ctx;
5657 crypto_key_t key, *keyp;
5658 crypto_mechanism_t mech;
5660 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
5661 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_task: started\n", instance));
5663 switch (taskq_req->dr_type) {
5665 case DPROV_REQ_SIGN_INIT:
5666 case DPROV_REQ_SIGN_RECOVER_INIT:
5667 /* allocate a dprov-private context */
5668 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
5669 CRYPTO_SUCCESS)
5670 break;
5672 /* structure assignment */
5673 mech = *taskq_req->dr_sign_req.sr_mechanism;
5674 if (dprov_valid_mac_mech(mech.cm_type)) {
5675 DPROV_CTX_P(ctx)->dc_svrfy_to_mac = B_TRUE;
5678 mutex_enter(&softc->ds_lock);
5679 if (is_publickey_mech(mech.cm_type)) {
5680 if ((error = dprov_key_attr_asymmetric(softc,
5681 ctx->cc_session, taskq_req->dr_type,
5682 taskq_req->dr_sign_req.sr_key, &key))
5683 != CRYPTO_SUCCESS) {
5684 mutex_exit(&softc->ds_lock);
5685 break;
5687 keyp = &key;
5688 } else {
5689 if ((error = dprov_key_value_secret(softc,
5690 ctx->cc_session, taskq_req->dr_type,
5691 taskq_req->dr_sign_req.sr_key, &key))
5692 != CRYPTO_SUCCESS) {
5693 mutex_exit(&softc->ds_lock);
5694 break;
5696 keyp = &key;
5698 mutex_exit(&softc->ds_lock);
5700 /* get the software provider for this mechanism */
5701 if ((error = dprov_get_sw_prov(
5702 taskq_req->dr_sign_req.sr_mechanism, &pd,
5703 &mech.cm_type)) != CRYPTO_SUCCESS)
5704 break;
5706 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5707 error = crypto_mac_init_prov(pd, 0, &mech, keyp, NULL,
5708 &DPROV_CTX_SINGLE(ctx), NULL);
5710 /* release provider reference */
5711 KCF_PROV_REFRELE(pd);
5712 break;
5715 /* Use a session id of zero since we use a software provider */
5716 if (taskq_req->dr_type == DPROV_REQ_SIGN_INIT)
5717 error = crypto_sign_init_prov(pd, 0, &mech, keyp,
5718 NULL, &DPROV_CTX_SINGLE(ctx), NULL);
5719 else
5720 error = crypto_sign_recover_init_prov(pd, 0, &mech,
5721 keyp, NULL, &DPROV_CTX_SINGLE(ctx), NULL);
5723 /* release provider reference */
5724 KCF_PROV_REFRELE(pd);
5726 break;
5728 case DPROV_REQ_SIGN:
5729 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5730 /* Emulate using update and final */
5731 error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
5732 taskq_req->dr_mac_req.dr_data, NULL);
5733 if (error == CRYPTO_SUCCESS) {
5734 error = crypto_mac_final(DPROV_CTX_SINGLE(ctx),
5735 taskq_req->dr_mac_req.dr_mac, NULL);
5737 } else {
5738 error = crypto_sign_single(DPROV_CTX_SINGLE(ctx),
5739 taskq_req->dr_sign_req.sr_data,
5740 taskq_req->dr_sign_req.sr_signature, NULL);
5743 if (error != CRYPTO_BUFFER_TOO_SMALL) {
5744 DPROV_CTX_SINGLE(ctx) = NULL;
5745 (void) dprov_free_context(ctx);
5747 break;
5749 case DPROV_REQ_SIGN_UPDATE:
5750 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5751 error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
5752 taskq_req->dr_mac_req.dr_data, NULL);
5753 } else {
5754 error = crypto_sign_update(DPROV_CTX_SINGLE(ctx),
5755 taskq_req->dr_sign_req.sr_data, NULL);
5757 break;
5759 case DPROV_REQ_SIGN_FINAL:
5760 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5761 error = crypto_mac_final(DPROV_CTX_SINGLE(ctx),
5762 taskq_req->dr_mac_req.dr_mac, NULL);
5763 } else {
5764 error = crypto_sign_final(DPROV_CTX_SINGLE(ctx),
5765 taskq_req->dr_sign_req.sr_signature, NULL);
5768 if (error != CRYPTO_BUFFER_TOO_SMALL) {
5769 DPROV_CTX_SINGLE(ctx) = NULL;
5770 (void) dprov_free_context(ctx);
5772 break;
5774 case DPROV_REQ_SIGN_ATOMIC:
5775 case DPROV_REQ_SIGN_RECOVER_ATOMIC:
5776 /* structure assignment */
5777 mech = *taskq_req->dr_sign_req.sr_mechanism;
5779 mutex_enter(&softc->ds_lock);
5780 /* get key value for secret key algorithms */
5781 if (is_publickey_mech(mech.cm_type)) {
5782 if ((error = dprov_key_attr_asymmetric(softc,
5783 taskq_req->dr_sign_req.sr_session_id,
5784 taskq_req->dr_type,
5785 taskq_req->dr_sign_req.sr_key, &key))
5786 != CRYPTO_SUCCESS) {
5787 mutex_exit(&softc->ds_lock);
5788 break;
5790 keyp = &key;
5791 } else {
5792 if ((error = dprov_key_value_secret(softc,
5793 taskq_req->dr_sign_req.sr_session_id,
5794 taskq_req->dr_type,
5795 taskq_req->dr_sign_req.sr_key, &key))
5796 != CRYPTO_SUCCESS) {
5797 mutex_exit(&softc->ds_lock);
5798 break;
5800 keyp = &key;
5802 mutex_exit(&softc->ds_lock);
5804 /* get the software provider for this mechanism */
5805 if ((error = dprov_get_sw_prov(
5806 taskq_req->dr_sign_req.sr_mechanism, &pd,
5807 &mech.cm_type)) != CRYPTO_SUCCESS)
5808 break;
5810 /* Use a session id of zero since we use a software provider */
5811 if (taskq_req->dr_type == DPROV_REQ_SIGN_ATOMIC)
5812 error = crypto_sign_prov(pd, 0, &mech, keyp,
5813 taskq_req->dr_sign_req.sr_data,
5814 NULL, taskq_req->dr_sign_req.sr_signature, NULL);
5815 else
5816 error = crypto_sign_recover_prov(pd, 0, &mech, keyp,
5817 taskq_req->dr_sign_req.sr_data,
5818 NULL, taskq_req->dr_sign_req.sr_signature, NULL);
5820 /* release provider reference */
5821 KCF_PROV_REFRELE(pd);
5822 break;
5824 case DPROV_REQ_SIGN_RECOVER:
5825 error = crypto_sign_recover_single(DPROV_CTX_SINGLE(ctx),
5826 taskq_req->dr_sign_req.sr_data,
5827 taskq_req->dr_sign_req.sr_signature, NULL);
5829 if (error != CRYPTO_BUFFER_TOO_SMALL) {
5830 DPROV_CTX_SINGLE(ctx) = NULL;
5831 (void) dprov_free_context(ctx);
5833 break;
5836 dprov_op_done(taskq_req, error);
5837 DPROV_DEBUG(D_SIGN, ("(%d) dprov_sign_task: end\n", instance));
5840 static int
5841 emulate_verify_with_mac(crypto_ctx_t *ctx, crypto_data_t *in_mac)
5843 int error;
5844 crypto_data_t tmpd;
5845 crypto_data_t *out_mac;
5846 char digest[SHA512_DIGEST_LENGTH];
5848 bzero(&tmpd, sizeof (crypto_data_t));
5849 tmpd.cd_format = CRYPTO_DATA_RAW;
5850 tmpd.cd_length = SHA512_DIGEST_LENGTH;
5851 tmpd.cd_raw.iov_base = digest;
5852 tmpd.cd_raw.iov_len = SHA512_DIGEST_LENGTH;
5853 out_mac = &tmpd;
5855 error = crypto_mac_final(DPROV_CTX_SINGLE(ctx), out_mac, NULL);
5856 if (in_mac->cd_length != out_mac->cd_length ||
5857 (bcmp(digest, (unsigned char *)in_mac->cd_raw.iov_base +
5858 in_mac->cd_offset, out_mac->cd_length) != 0)) {
5859 error = CRYPTO_INVALID_MAC;
5862 return (error);
5866 * taskq dispatcher function for verify operations.
5868 static void
5869 dprov_verify_task(dprov_req_t *taskq_req)
5871 kcf_provider_desc_t *pd;
5872 dprov_state_t *softc;
5873 /* LINTED E_FUNC_SET_NOT_USED */
5874 int instance;
5875 int error = CRYPTO_NOT_SUPPORTED;
5876 crypto_ctx_t *ctx = taskq_req->dr_verify_req.vr_ctx;
5877 crypto_key_t key, *keyp;
5878 crypto_mechanism_t mech;
5880 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
5881 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_task: started\n", instance));
5883 switch (taskq_req->dr_type) {
5885 case DPROV_REQ_VERIFY_INIT:
5886 case DPROV_REQ_VERIFY_RECOVER_INIT:
5887 /* allocate a dprov-private context */
5888 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
5889 CRYPTO_SUCCESS)
5890 break;
5892 /* structure assignment */
5893 mech = *taskq_req->dr_verify_req.vr_mechanism;
5894 if (dprov_valid_mac_mech(mech.cm_type)) {
5895 DPROV_CTX_P(ctx)->dc_svrfy_to_mac = B_TRUE;
5898 mutex_enter(&softc->ds_lock);
5899 /* get key value for secret key algorithms */
5900 if (is_publickey_mech(mech.cm_type)) {
5901 if ((error = dprov_key_attr_asymmetric(softc,
5902 ctx->cc_session, taskq_req->dr_type,
5903 taskq_req->dr_verify_req.vr_key, &key))
5904 != CRYPTO_SUCCESS) {
5905 mutex_exit(&softc->ds_lock);
5906 break;
5908 keyp = &key;
5909 } else {
5910 if ((error = dprov_key_value_secret(softc,
5911 ctx->cc_session, taskq_req->dr_type,
5912 taskq_req->dr_verify_req.vr_key, &key))
5913 != CRYPTO_SUCCESS) {
5914 mutex_exit(&softc->ds_lock);
5915 break;
5917 keyp = &key;
5919 mutex_exit(&softc->ds_lock);
5921 /* get the software provider for this mechanism */
5922 if ((error = dprov_get_sw_prov(
5923 taskq_req->dr_verify_req.vr_mechanism, &pd,
5924 &mech.cm_type)) != CRYPTO_SUCCESS)
5925 break;
5928 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5929 error = crypto_mac_init_prov(pd, 0, &mech, keyp, NULL,
5930 &DPROV_CTX_SINGLE(ctx), NULL);
5932 /* release provider reference */
5933 KCF_PROV_REFRELE(pd);
5934 break;
5937 /* Use a session id of zero since we use a software provider */
5938 if (taskq_req->dr_type == DPROV_REQ_VERIFY_INIT)
5939 error = crypto_verify_init_prov(pd, 0, &mech, keyp,
5940 NULL, &DPROV_CTX_SINGLE(ctx), NULL);
5941 else
5942 error = crypto_verify_recover_init_prov(pd, 0, &mech,
5943 keyp, NULL, &DPROV_CTX_SINGLE(ctx), NULL);
5945 /* release provider reference */
5946 KCF_PROV_REFRELE(pd);
5948 break;
5950 case DPROV_REQ_VERIFY:
5951 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5952 /* Emulate using update and final */
5953 error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
5954 taskq_req->dr_mac_req.dr_data, NULL);
5955 if (error == CRYPTO_SUCCESS) {
5956 error = emulate_verify_with_mac(ctx,
5957 taskq_req->dr_mac_req.dr_mac);
5959 } else {
5960 error = crypto_verify_single(DPROV_CTX_SINGLE(ctx),
5961 taskq_req->dr_verify_req.vr_data,
5962 taskq_req->dr_verify_req.vr_signature, NULL);
5965 ASSERT(error != CRYPTO_BUFFER_TOO_SMALL);
5966 DPROV_CTX_SINGLE(ctx) = NULL;
5967 (void) dprov_free_context(ctx);
5968 break;
5970 case DPROV_REQ_VERIFY_UPDATE:
5971 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5972 error = crypto_mac_update(DPROV_CTX_SINGLE(ctx),
5973 taskq_req->dr_mac_req.dr_data, NULL);
5974 } else {
5975 error = crypto_verify_update(DPROV_CTX_SINGLE(ctx),
5976 taskq_req->dr_verify_req.vr_data, NULL);
5978 break;
5980 case DPROV_REQ_VERIFY_FINAL:
5981 if (DPROV_CTX_P(ctx)->dc_svrfy_to_mac) {
5982 error = emulate_verify_with_mac(ctx,
5983 taskq_req->dr_mac_req.dr_mac);
5984 } else {
5985 error = crypto_verify_final(DPROV_CTX_SINGLE(ctx),
5986 taskq_req->dr_verify_req.vr_signature, NULL);
5989 ASSERT(error != CRYPTO_BUFFER_TOO_SMALL);
5990 DPROV_CTX_SINGLE(ctx) = NULL;
5991 (void) dprov_free_context(ctx);
5992 break;
5994 case DPROV_REQ_VERIFY_ATOMIC:
5995 case DPROV_REQ_VERIFY_RECOVER_ATOMIC:
5996 /* structure assignment */
5997 mech = *taskq_req->dr_verify_req.vr_mechanism;
5999 mutex_enter(&softc->ds_lock);
6000 /* get key value for secret key algorithms */
6001 if (is_publickey_mech(mech.cm_type)) {
6002 if ((error = dprov_key_attr_asymmetric(softc,
6003 taskq_req->dr_verify_req.vr_session_id,
6004 taskq_req->dr_type,
6005 taskq_req->dr_verify_req.vr_key, &key))
6006 != CRYPTO_SUCCESS) {
6007 mutex_exit(&softc->ds_lock);
6008 break;
6010 keyp = &key;
6011 } else {
6012 if ((error = dprov_key_value_secret(softc,
6013 taskq_req->dr_verify_req.vr_session_id,
6014 taskq_req->dr_type,
6015 taskq_req->dr_verify_req.vr_key, &key))
6016 != CRYPTO_SUCCESS) {
6017 mutex_exit(&softc->ds_lock);
6018 break;
6020 keyp = &key;
6022 mutex_exit(&softc->ds_lock);
6024 /* get the software provider for this mechanism */
6025 if ((error = dprov_get_sw_prov(
6026 taskq_req->dr_verify_req.vr_mechanism, &pd,
6027 &mech.cm_type)) != CRYPTO_SUCCESS)
6028 break;
6030 /* Use a session id of zero since we use a software provider */
6031 if (taskq_req->dr_type == DPROV_REQ_VERIFY_ATOMIC)
6032 error = crypto_verify_prov(pd, 0, &mech, keyp,
6033 taskq_req->dr_verify_req.vr_data,
6034 NULL, taskq_req->dr_verify_req.vr_signature, NULL);
6035 else
6037 * crypto_verify_recover_prov() has different argument
6038 * order than crypto_verify_prov().
6040 error = crypto_verify_recover_prov(pd, 0, &mech, keyp,
6041 taskq_req->dr_verify_req.vr_signature,
6042 NULL, taskq_req->dr_verify_req.vr_data, NULL);
6044 /* release provider reference */
6045 KCF_PROV_REFRELE(pd);
6046 break;
6048 case DPROV_REQ_VERIFY_RECOVER:
6050 * crypto_verify_recover_single() has different argument
6051 * order than crypto_verify_single().
6053 error = crypto_verify_recover_single(DPROV_CTX_SINGLE(ctx),
6054 taskq_req->dr_verify_req.vr_signature,
6055 taskq_req->dr_verify_req.vr_data, NULL);
6057 if (error != CRYPTO_BUFFER_TOO_SMALL) {
6058 DPROV_CTX_SINGLE(ctx) = NULL;
6059 (void) dprov_free_context(ctx);
6061 break;
6064 dprov_op_done(taskq_req, error);
6065 DPROV_DEBUG(D_VERIFY, ("(%d) dprov_verify_task: end\n", instance));
6069 * taskq dispatcher function for dual operations.
6071 static void
6072 dprov_dual_task(dprov_req_t *taskq_req)
6074 dprov_state_t *softc;
6075 /* LINTED E_FUNC_SET_NOT_USED */
6076 int instance;
6077 int error = CRYPTO_NOT_SUPPORTED;
6078 crypto_ctx_t *signverify_ctx = taskq_req->dr_dual_req.dr_signverify_ctx;
6079 crypto_ctx_t *cipher_ctx = taskq_req->dr_dual_req.dr_cipher_ctx;
6081 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
6082 DPROV_DEBUG(D_DUAL, ("(%d) dprov_dual_task: started\n", instance));
6084 switch (taskq_req->dr_type) {
6086 case DPROV_REQ_DIGEST_ENCRYPT_UPDATE:
6087 error = crypto_digest_encrypt_update(
6088 DPROV_CTX_SINGLE(signverify_ctx),
6089 DPROV_CTX_SINGLE(cipher_ctx),
6090 taskq_req->dr_dual_req.dr_plaintext,
6091 taskq_req->dr_dual_req.dr_ciphertext, NULL);
6092 break;
6094 case DPROV_REQ_DECRYPT_DIGEST_UPDATE:
6095 error = crypto_decrypt_digest_update(
6096 DPROV_CTX_SINGLE(cipher_ctx),
6097 DPROV_CTX_SINGLE(signverify_ctx),
6098 taskq_req->dr_dual_req.dr_ciphertext,
6099 taskq_req->dr_dual_req.dr_plaintext, NULL);
6100 break;
6102 case DPROV_REQ_SIGN_ENCRYPT_UPDATE:
6103 error = crypto_sign_encrypt_update(
6104 DPROV_CTX_SINGLE(signverify_ctx),
6105 DPROV_CTX_SINGLE(cipher_ctx),
6106 taskq_req->dr_dual_req.dr_plaintext,
6107 taskq_req->dr_dual_req.dr_ciphertext, NULL);
6108 break;
6110 case DPROV_REQ_DECRYPT_VERIFY_UPDATE:
6111 error = crypto_decrypt_verify_update(
6112 DPROV_CTX_SINGLE(cipher_ctx),
6113 DPROV_CTX_SINGLE(signverify_ctx),
6114 taskq_req->dr_dual_req.dr_ciphertext,
6115 taskq_req->dr_dual_req.dr_plaintext, NULL);
6116 break;
6119 dprov_op_done(taskq_req, error);
6120 DPROV_DEBUG(D_DUAL, ("(%d) dprov_dual_task: end\n", instance));
6124 * taskq dispatcher function for cipher operations.
6126 static void
6127 dprov_cipher_task(dprov_req_t *taskq_req)
6129 kcf_provider_desc_t *pd;
6130 dprov_state_t *softc;
6131 /* LINTED E_FUNC_SET_NOT_USED */
6132 int instance;
6133 int error = CRYPTO_NOT_SUPPORTED;
6134 crypto_ctx_t *ctx = taskq_req->dr_cipher_req.dr_ctx;
6135 crypto_key_t key, *keyp;
6136 crypto_mechanism_t mech;
6138 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
6139 DPROV_DEBUG(D_CIPHER, ("(%d) dprov_cipher_task: started\n", instance));
6141 switch (taskq_req->dr_type) {
6143 case DPROV_REQ_ENCRYPT_INIT:
6144 case DPROV_REQ_DECRYPT_INIT:
6145 /* allocate a dprov-private context */
6146 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
6147 CRYPTO_SUCCESS)
6148 break;
6150 /* structure assignment */
6151 mech = *taskq_req->dr_cipher_req.dr_mechanism;
6153 mutex_enter(&softc->ds_lock);
6154 /* get key value for secret key algorithms */
6155 if (is_publickey_mech(mech.cm_type)) {
6156 if ((error = dprov_key_attr_asymmetric(softc,
6157 ctx->cc_session, taskq_req->dr_type,
6158 taskq_req->dr_cipher_req.dr_key, &key))
6159 != CRYPTO_SUCCESS) {
6160 mutex_exit(&softc->ds_lock);
6161 break;
6163 keyp = &key;
6164 } else {
6165 if ((error = dprov_key_value_secret(softc,
6166 ctx->cc_session, taskq_req->dr_type,
6167 taskq_req->dr_cipher_req.dr_key, &key))
6168 != CRYPTO_SUCCESS) {
6169 mutex_exit(&softc->ds_lock);
6170 break;
6172 keyp = &key;
6174 mutex_exit(&softc->ds_lock);
6176 /* get the software provider for this mechanism */
6177 if ((error = dprov_get_sw_prov(
6178 taskq_req->dr_cipher_req.dr_mechanism, &pd,
6179 &mech.cm_type)) != CRYPTO_SUCCESS)
6180 break;
6182 /* Use a session id of zero since we use a software provider */
6183 if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_INIT)
6184 error = crypto_encrypt_init_prov(pd, 0, &mech, keyp,
6185 NULL, &DPROV_CTX_SINGLE(ctx), NULL);
6186 else
6187 error = crypto_decrypt_init_prov(pd, 0, &mech, keyp,
6188 NULL, &DPROV_CTX_SINGLE(ctx), NULL);
6190 if (ctx->cc_flags & CRYPTO_INIT_OPSTATE) {
6191 crypto_ctx_t *lctx =
6192 (crypto_ctx_t *)(DPROV_CTX_SINGLE(ctx));
6194 ctx->cc_opstate = lctx->cc_provider_private;
6195 ctx->cc_flags |= CRYPTO_USE_OPSTATE;
6198 /* release provider reference */
6199 KCF_PROV_REFRELE(pd);
6200 break;
6202 case DPROV_REQ_ENCRYPT:
6203 error = crypto_encrypt_single(DPROV_CTX_SINGLE(ctx),
6204 taskq_req->dr_cipher_req.dr_plaintext,
6205 taskq_req->dr_cipher_req.dr_ciphertext, NULL);
6207 if (error != CRYPTO_BUFFER_TOO_SMALL) {
6208 DPROV_CTX_SINGLE(ctx) = NULL;
6209 (void) dprov_free_context(ctx);
6211 break;
6213 case DPROV_REQ_DECRYPT:
6214 error = crypto_decrypt_single(DPROV_CTX_SINGLE(ctx),
6215 taskq_req->dr_cipher_req.dr_ciphertext,
6216 taskq_req->dr_cipher_req.dr_plaintext, NULL);
6218 if (error != CRYPTO_BUFFER_TOO_SMALL) {
6219 DPROV_CTX_SINGLE(ctx) = NULL;
6220 (void) dprov_free_context(ctx);
6222 break;
6224 case DPROV_REQ_ENCRYPT_UPDATE:
6225 ASSERT(!(ctx->cc_flags & CRYPTO_INIT_OPSTATE) ||
6226 (ctx->cc_flags & CRYPTO_USE_OPSTATE));
6227 error = crypto_encrypt_update(DPROV_CTX_SINGLE(ctx),
6228 taskq_req->dr_cipher_req.dr_plaintext,
6229 taskq_req->dr_cipher_req.dr_ciphertext, NULL);
6230 break;
6232 case DPROV_REQ_DECRYPT_UPDATE:
6233 ASSERT(!(ctx->cc_flags & CRYPTO_INIT_OPSTATE) ||
6234 (ctx->cc_flags & CRYPTO_USE_OPSTATE));
6235 error = crypto_decrypt_update(DPROV_CTX_SINGLE(ctx),
6236 taskq_req->dr_cipher_req.dr_ciphertext,
6237 taskq_req->dr_cipher_req.dr_plaintext, NULL);
6238 break;
6240 case DPROV_REQ_ENCRYPT_FINAL:
6241 error = crypto_encrypt_final(DPROV_CTX_SINGLE(ctx),
6242 taskq_req->dr_cipher_req.dr_ciphertext, NULL);
6243 if (error != CRYPTO_BUFFER_TOO_SMALL) {
6244 DPROV_CTX_SINGLE(ctx) = NULL;
6245 (void) dprov_free_context(ctx);
6247 break;
6249 case DPROV_REQ_DECRYPT_FINAL:
6250 error = crypto_decrypt_final(DPROV_CTX_SINGLE(ctx),
6251 taskq_req->dr_cipher_req.dr_plaintext, NULL);
6252 if (error != CRYPTO_BUFFER_TOO_SMALL) {
6253 DPROV_CTX_SINGLE(ctx) = NULL;
6254 (void) dprov_free_context(ctx);
6256 break;
6258 case DPROV_REQ_ENCRYPT_ATOMIC:
6259 case DPROV_REQ_DECRYPT_ATOMIC:
6260 /* structure assignment */
6261 mech = *taskq_req->dr_cipher_req.dr_mechanism;
6263 mutex_enter(&softc->ds_lock);
6264 /* get key value for secret key algorithms */
6265 if (is_publickey_mech(mech.cm_type)) {
6266 if ((error = dprov_key_attr_asymmetric(softc,
6267 taskq_req->dr_cipher_req.dr_session_id,
6268 taskq_req->dr_type,
6269 taskq_req->dr_cipher_req.dr_key,
6270 &key)) != CRYPTO_SUCCESS) {
6271 mutex_exit(&softc->ds_lock);
6272 break;
6274 keyp = &key;
6275 } else {
6276 if ((error = dprov_key_value_secret(softc,
6277 taskq_req->dr_cipher_req.dr_session_id,
6278 taskq_req->dr_type, taskq_req->dr_cipher_req.dr_key,
6279 &key))
6280 != CRYPTO_SUCCESS) {
6281 mutex_exit(&softc->ds_lock);
6282 break;
6284 keyp = &key;
6286 mutex_exit(&softc->ds_lock);
6288 /* get the software provider for this mechanism */
6289 if ((error = dprov_get_sw_prov(
6290 taskq_req->dr_cipher_req.dr_mechanism, &pd,
6291 &mech.cm_type)) != CRYPTO_SUCCESS)
6292 break;
6294 /* use a session id of zero since we use a software provider */
6295 if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_ATOMIC)
6296 error = crypto_encrypt_prov(pd, 0, &mech,
6297 taskq_req->dr_cipher_req.dr_plaintext,
6298 keyp, NULL,
6299 taskq_req->dr_cipher_req.dr_ciphertext, NULL);
6300 else
6301 error = crypto_decrypt_prov(pd, 0, &mech,
6302 taskq_req->dr_cipher_req.dr_ciphertext,
6303 keyp, NULL,
6304 taskq_req->dr_cipher_req.dr_plaintext, NULL);
6306 /* release provider reference */
6307 KCF_PROV_REFRELE(pd);
6309 break;
6312 dprov_op_done(taskq_req, error);
6313 DPROV_DEBUG(D_MAC, ("(%d) dprov_mac_task: end\n", instance));
6317 * Helper function for the cipher/mac dual operation taskq dispatch
6318 * function. Initialize the cipher and mac key values and find the
6319 * providers that can process the request for the specified mechanisms.
6321 static int
6322 dprov_cipher_mac_key_pd(dprov_state_t *softc, crypto_session_id_t sid,
6323 dprov_req_t *taskq_req, crypto_key_t *cipher_key, crypto_key_t *mac_key,
6324 kcf_provider_desc_t **cipher_pd, kcf_provider_desc_t **mac_pd,
6325 crypto_mech_type_t *cipher_mech_type, crypto_mech_type_t *mac_mech_type)
6327 int error;
6329 /* get the cipher key value */
6330 mutex_enter(&softc->ds_lock);
6331 error = dprov_key_value_secret(softc, sid, DPROV_REQ_ENCRYPT_ATOMIC,
6332 taskq_req->dr_cipher_mac_req.mr_cipher_key, cipher_key);
6333 if (error != CRYPTO_SUCCESS) {
6334 mutex_exit(&softc->ds_lock);
6335 return (error);
6338 /* get the mac key value */
6339 error = dprov_key_value_secret(softc, sid, DPROV_REQ_MAC_ATOMIC,
6340 taskq_req->dr_cipher_mac_req.mr_mac_key, mac_key);
6341 mutex_exit(&softc->ds_lock);
6342 if (error != CRYPTO_SUCCESS)
6343 return (error);
6345 /* get the SW provider to perform the cipher operation */
6346 if ((error = dprov_get_sw_prov(
6347 taskq_req->dr_cipher_mac_req.mr_cipher_mech, cipher_pd,
6348 cipher_mech_type)) != CRYPTO_SUCCESS)
6349 return (error);
6351 /* get the SW provider to perform the mac operation */
6352 error = dprov_get_sw_prov(taskq_req->dr_cipher_mac_req.mr_mac_mech,
6353 mac_pd, mac_mech_type);
6355 return (error);
6359 * taskq dispatcher function for cipher/mac dual operations.
6361 static void
6362 dprov_cipher_mac_task(dprov_req_t *taskq_req)
6364 dprov_state_t *softc;
6365 /* LINTED E_FUNC_SET_NOT_USED */
6366 int instance;
6367 int error = CRYPTO_NOT_SUPPORTED;
6368 crypto_ctx_t *ctx = taskq_req->dr_cipher_mac_req.mr_ctx;
6369 kcf_provider_desc_t *cipher_pd;
6370 kcf_provider_desc_t *mac_pd;
6371 crypto_key_t cipher_key;
6372 crypto_key_t mac_key;
6373 crypto_dual_data_t *dual_data =
6374 taskq_req->dr_cipher_mac_req.mr_dual_data;
6375 crypto_data_t cipher_data;
6376 crypto_data_t mac_data;
6377 crypto_mechanism_t cipher_mech, mac_mech;
6378 crypto_session_id_t session_id;
6380 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
6381 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_cipher_mac_task: started\n",
6382 instance));
6384 switch (taskq_req->dr_type) {
6385 case DPROV_REQ_ENCRYPT_MAC_INIT:
6386 case DPROV_REQ_MAC_DECRYPT_INIT:
6387 /* structure assignment */
6388 cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech;
6389 mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech;
6391 /* get the keys values and providers to use for operations */
6392 if ((error = dprov_cipher_mac_key_pd(softc, ctx->cc_session,
6393 taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd,
6394 &cipher_mech.cm_type, &mac_mech.cm_type)) != CRYPTO_SUCCESS)
6395 break;
6397 /* allocate a dprov-private context */
6398 if ((error = dprov_alloc_context(taskq_req->dr_type, ctx)) !=
6399 CRYPTO_SUCCESS)
6400 break;
6402 if (taskq_req->dr_type == DPROV_REQ_ENCRYPT_MAC_INIT)
6403 /* do the encryption initialization */
6404 error = crypto_encrypt_init_prov(cipher_pd, 0,
6405 &cipher_mech, &cipher_key, NULL,
6406 &DPROV_CTX_DUAL_CIPHER(ctx), NULL);
6407 else
6408 /* do the decryption initialization */
6409 error = crypto_decrypt_init_prov(cipher_pd, 0,
6410 &cipher_mech, &cipher_key, NULL,
6411 &DPROV_CTX_DUAL_CIPHER(ctx), NULL);
6412 if (error != CRYPTO_SUCCESS)
6413 break;
6415 /* do the mac initialization */
6416 if ((error = crypto_mac_init_prov(mac_pd, 0,
6417 &mac_mech, &mac_key, NULL, &DPROV_CTX_DUAL_MAC(ctx),
6418 NULL)) != CRYPTO_SUCCESS)
6419 break;
6421 /* release references to providers */
6422 KCF_PROV_REFRELE(cipher_pd);
6423 KCF_PROV_REFRELE(mac_pd);
6425 break;
6427 case DPROV_REQ_ENCRYPT_MAC: {
6428 size_t encrypted;
6429 boolean_t inplace;
6431 crypto_data_t *plaintext_tmp, *ciphertext_tmp;
6433 cipher_data = *((crypto_data_t *)dual_data);
6435 /* do an encrypt update */
6436 inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL);
6437 if (inplace) {
6438 plaintext_tmp = &cipher_data;
6439 ciphertext_tmp = NULL;
6440 } else {
6441 plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data;
6442 ciphertext_tmp = &cipher_data;
6444 if ((error = crypto_encrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
6445 plaintext_tmp, ciphertext_tmp, NULL)) != CRYPTO_SUCCESS)
6446 break;
6448 /* do an encrypt final */
6449 encrypted = cipher_data.cd_length;
6451 cipher_data.cd_offset += encrypted;
6452 cipher_data.cd_length = dual_data->dd_len1 - encrypted;
6454 if ((error = crypto_encrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
6455 &cipher_data, NULL)) != CRYPTO_SUCCESS)
6456 break;
6459 * Do a mac update on the resulting ciphertext, but with no
6460 * more bytes than specified by dual_data, and starting at
6461 * offset specified by dual_data. For in-place operations,
6462 * we use the length specified by the dual_data.
6464 mac_data = cipher_data;
6465 mac_data.cd_offset = dual_data->dd_offset2;
6466 mac_data.cd_length = dual_data->dd_len2;
6467 if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
6468 &mac_data, NULL)) != CRYPTO_SUCCESS)
6469 break;
6471 /* do a mac final */
6472 error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
6473 taskq_req->dr_cipher_mac_req.mr_mac, NULL);
6475 /* Set the total size of the ciphertext, when successful */
6476 if (error == CRYPTO_SUCCESS)
6477 dual_data->dd_len1 = encrypted + cipher_data.cd_length;
6479 if (error != CRYPTO_BUFFER_TOO_SMALL) {
6480 DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
6481 DPROV_CTX_DUAL_MAC(ctx) = NULL;
6482 (void) dprov_free_context(ctx);
6484 break;
6487 case DPROV_REQ_ENCRYPT_MAC_UPDATE: {
6488 crypto_data_t *plaintext_tmp, *ciphertext_tmp;
6489 size_t encrypted;
6490 ssize_t maclen;
6491 boolean_t inplace;
6493 cipher_data = *((crypto_data_t *)dual_data);
6495 /* do an encrypt update */
6496 inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL);
6497 if (inplace) {
6498 plaintext_tmp = &cipher_data;
6499 ciphertext_tmp = NULL;
6500 } else {
6501 plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data;
6502 ciphertext_tmp = &cipher_data;
6504 if ((error = crypto_encrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
6505 plaintext_tmp, ciphertext_tmp, NULL)) != CRYPTO_SUCCESS)
6506 break;
6508 encrypted = cipher_data.cd_length;
6511 * Do a mac update on the resulting ciphertext, but with no
6512 * more bytes than specified by dual_data, and starting at
6513 * offset specified by dual_data. For in-place operations,
6514 * we use the length specified by the dual_data.
6515 * There is an edge case, when the encryption step produced
6516 * zero bytes in the ciphertext. Only the portion between
6517 * offset2 and offset1 is then thrown in the MAC mix.
6519 maclen = dual_data->dd_offset1 - dual_data->dd_offset2 +
6520 encrypted;
6521 if (maclen > 0) {
6522 mac_data = cipher_data;
6523 mac_data.cd_offset = dual_data->dd_offset2;
6524 mac_data.cd_length = min(dual_data->dd_len2, maclen);
6525 if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
6526 &mac_data, NULL)) != CRYPTO_SUCCESS)
6527 break;
6529 /* Set the total size of the ciphertext, when successful */
6530 if (error == CRYPTO_SUCCESS)
6531 dual_data->dd_len1 = encrypted;
6533 break;
6536 case DPROV_REQ_ENCRYPT_MAC_FINAL:
6537 cipher_data = *((crypto_data_t *)dual_data);
6539 /* do an encrypt final */
6540 if ((error = crypto_encrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
6541 taskq_req->dr_cipher_mac_req.mr_data == NULL ?
6542 &cipher_data : taskq_req->dr_cipher_mac_req.mr_data,
6543 NULL)) != CRYPTO_SUCCESS)
6544 break;
6547 * If ciphertext length is different from zero, do a mac
6548 * update on it. This does not apply to in-place since we
6549 * do not allow partial updates, hence no final residual.
6551 if (taskq_req->dr_cipher_mac_req.mr_data != NULL &&
6552 taskq_req->dr_cipher_mac_req.mr_data->cd_length > 0)
6553 if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
6554 taskq_req->dr_cipher_mac_req.mr_data, NULL)) !=
6555 CRYPTO_SUCCESS)
6556 break;
6558 /* do a mac final */
6559 error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
6560 taskq_req->dr_cipher_mac_req.mr_mac, NULL);
6562 if (error != CRYPTO_BUFFER_TOO_SMALL) {
6563 DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
6564 DPROV_CTX_DUAL_MAC(ctx) = NULL;
6565 (void) dprov_free_context(ctx);
6567 break;
6569 case DPROV_REQ_ENCRYPT_MAC_ATOMIC: {
6570 crypto_data_t *plaintext_tmp, *ciphertext_tmp;
6571 boolean_t inplace;
6573 cipher_data = *((crypto_data_t *)dual_data);
6575 /* do an encrypt atomic */
6576 inplace = (taskq_req->dr_cipher_mac_req.mr_data == NULL);
6577 if (inplace) {
6578 plaintext_tmp = &cipher_data;
6579 ciphertext_tmp = NULL;
6580 } else {
6581 plaintext_tmp = taskq_req->dr_cipher_mac_req.mr_data;
6582 ciphertext_tmp = &cipher_data;
6585 /* structure assignment */
6586 cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech;
6587 mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech;
6588 session_id = taskq_req->dr_cipher_mac_req.mr_session_id;
6590 /* get the keys values and providers to use for operations */
6591 if ((error = dprov_cipher_mac_key_pd(softc, session_id,
6592 taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd,
6593 &cipher_mech.cm_type, &mac_mech.cm_type)) !=
6594 CRYPTO_SUCCESS)
6595 break;
6597 /* do the atomic encrypt */
6598 if ((error = crypto_encrypt_prov(cipher_pd, 0,
6599 &cipher_mech, plaintext_tmp, &cipher_key, NULL,
6600 ciphertext_tmp, NULL)) != CRYPTO_SUCCESS)
6601 break;
6603 /* do the atomic mac */
6604 mac_data = cipher_data;
6605 mac_data.cd_length = dual_data->dd_len2;
6606 mac_data.cd_offset = dual_data->dd_offset2;
6607 error = crypto_mac_prov(mac_pd, 0, &mac_mech, &mac_data,
6608 &mac_key, NULL, taskq_req->dr_cipher_mac_req.mr_mac, NULL);
6610 dual_data->dd_len1 = cipher_data.cd_length;
6612 break;
6615 case DPROV_REQ_MAC_DECRYPT: {
6616 uint_t decrypted;
6617 crypto_data_t plaintext_tmp;
6619 cipher_data = *((crypto_data_t *)dual_data);
6621 /* do a mac update and final on the ciphertext */
6622 if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
6623 &mac_data, NULL)) != CRYPTO_SUCCESS)
6624 break;
6626 /* do a mac final */
6627 if ((error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
6628 taskq_req->dr_cipher_mac_req.mr_mac, NULL)) !=
6629 CRYPTO_SUCCESS)
6630 break;
6632 /* do an decrypt update */
6633 cipher_data = mac_data;
6634 cipher_data.cd_length = dual_data->dd_len2;
6635 cipher_data.cd_offset = dual_data->dd_offset2;
6636 if (taskq_req->dr_cipher_mac_req.mr_data == NULL)
6637 /* in-place */
6638 plaintext_tmp = cipher_data;
6639 else
6640 plaintext_tmp = *taskq_req->dr_cipher_mac_req.mr_data;
6642 if ((error = crypto_decrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
6643 &cipher_data, taskq_req->dr_cipher_mac_req.mr_data,
6644 NULL)) != CRYPTO_SUCCESS)
6645 break;
6647 /* do an decrypt final */
6648 if (taskq_req->dr_cipher_mac_req.mr_data == NULL)
6649 /* in-place, everything must have been decrypted */
6650 decrypted = cipher_data.cd_length;
6651 else
6652 decrypted =
6653 taskq_req->dr_cipher_mac_req.mr_data->cd_length;
6654 plaintext_tmp.cd_offset += decrypted;
6655 plaintext_tmp.cd_length -= decrypted;
6657 error = crypto_decrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
6658 &plaintext_tmp, NULL);
6659 if (taskq_req->dr_cipher_mac_req.mr_data != NULL)
6660 taskq_req->dr_cipher_mac_req.mr_data->cd_length +=
6661 plaintext_tmp.cd_length;
6663 if (error != CRYPTO_BUFFER_TOO_SMALL) {
6664 DPROV_CTX_DUAL_MAC(ctx) = NULL;
6665 DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
6666 (void) dprov_free_context(ctx);
6668 break;
6671 case DPROV_REQ_MAC_DECRYPT_UPDATE:
6672 cipher_data = *((crypto_data_t *)dual_data);
6674 /* do mac update */
6675 if ((error = crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx),
6676 &cipher_data, NULL)) != CRYPTO_SUCCESS)
6677 break;
6679 /* do a decrypt update */
6680 cipher_data.cd_length = dual_data->dd_len2;
6681 cipher_data.cd_offset = dual_data->dd_offset2;
6682 error = crypto_decrypt_update(DPROV_CTX_DUAL_CIPHER(ctx),
6683 &cipher_data, taskq_req->dr_cipher_mac_req.mr_data, NULL);
6685 break;
6687 case DPROV_REQ_MAC_DECRYPT_FINAL:
6688 /* do a mac final */
6689 if ((error = crypto_mac_final(DPROV_CTX_DUAL_MAC(ctx),
6690 taskq_req->dr_cipher_mac_req.mr_mac, NULL)) !=
6691 CRYPTO_SUCCESS)
6692 break;
6694 /* do a decrypt final */
6695 error = crypto_decrypt_final(DPROV_CTX_DUAL_CIPHER(ctx),
6696 taskq_req->dr_cipher_mac_req.mr_data, NULL);
6698 if (error != CRYPTO_BUFFER_TOO_SMALL) {
6699 DPROV_CTX_DUAL_MAC(ctx) = NULL;
6700 DPROV_CTX_DUAL_CIPHER(ctx) = NULL;
6701 (void) dprov_free_context(ctx);
6703 break;
6705 case DPROV_REQ_MAC_DECRYPT_ATOMIC:
6706 case DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC:
6707 cipher_data = *((crypto_data_t *)dual_data);
6709 /* structure assignment */
6710 cipher_mech = *taskq_req->dr_cipher_mac_req.mr_cipher_mech;
6711 mac_mech = *taskq_req->dr_cipher_mac_req.mr_mac_mech;
6712 session_id = taskq_req->dr_cipher_mac_req.mr_session_id;
6714 /* get the keys values and providers to use for operations */
6715 if ((error = dprov_cipher_mac_key_pd(softc, session_id,
6716 taskq_req, &cipher_key, &mac_key, &cipher_pd, &mac_pd,
6717 &cipher_mech.cm_type, &mac_mech.cm_type)) != CRYPTO_SUCCESS)
6718 break;
6720 /* do the atomic mac */
6721 if (taskq_req->dr_type == DPROV_REQ_MAC_DECRYPT_ATOMIC)
6722 error = crypto_mac_prov(mac_pd, 0, &mac_mech,
6723 &cipher_data, &mac_key, NULL,
6724 taskq_req->dr_cipher_mac_req.mr_mac, NULL);
6725 else
6726 /* DPROV_REQ_MAC_VERIFY_DECRYPT_ATOMIC */
6727 error = crypto_mac_verify_prov(mac_pd, 0, &mac_mech,
6728 &cipher_data, &mac_key, NULL,
6729 taskq_req->dr_cipher_mac_req.mr_mac, NULL);
6731 if (error != CRYPTO_SUCCESS)
6732 break;
6734 /* do the atomic decrypt */
6735 cipher_data.cd_length = dual_data->dd_len2;
6736 cipher_data.cd_offset = dual_data->dd_offset2;
6737 error = crypto_decrypt_prov(cipher_pd, 0, &cipher_mech,
6738 &cipher_data, &cipher_key, NULL,
6739 taskq_req->dr_cipher_mac_req.mr_data, NULL);
6741 break;
6744 dprov_op_done(taskq_req, error);
6745 DPROV_DEBUG(D_CIPHER_MAC, ("(%d) dprov_cipher_mac_task: end\n",
6746 instance));
6750 * taskq dispatcher function for random number generation.
6752 static void
6753 dprov_random_task(dprov_req_t *taskq_req)
6755 dprov_state_t *softc;
6756 /* LINTED E_FUNC_SET_NOT_USED */
6757 int instance;
6758 int error = CRYPTO_SUCCESS;
6760 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
6761 DPROV_DEBUG(D_RANDOM, ("(%d) dprov_random_task: started\n", instance));
6763 mutex_enter(&softc->ds_lock);
6765 switch (taskq_req->dr_type) {
6767 DPROV_REQ_RANDOM_SEED:
6769 * Since we don't really generate random numbers
6770 * nothing to do.
6772 break;
6774 case DPROV_REQ_RANDOM_GENERATE: {
6775 uint_t i;
6776 uchar_t c = 0;
6779 * We don't generate random numbers so that the result
6780 * of the operation can be checked during testing.
6783 for (i = 0; i < taskq_req->dr_random_req.rr_len; i++)
6784 taskq_req->dr_random_req.rr_buf[i] = c++;
6786 break;
6790 mutex_exit(&softc->ds_lock);
6791 dprov_op_done(taskq_req, error);
6792 DPROV_DEBUG(D_RANDOM, ("(%d) dprov_random_task: end\n", instance));
6797 * taskq dispatcher function for session management operations.
6799 static void
6800 dprov_session_task(dprov_req_t *taskq_req)
6802 dprov_state_t *softc;
6803 /* LINTED E_FUNC_SET_NOT_USED */
6804 int instance;
6805 int error = CRYPTO_NOT_SUPPORTED;
6806 crypto_session_id_t session_id =
6807 taskq_req->dr_session_req.sr_session_id;
6808 dprov_session_t *session;
6809 dprov_object_t *object;
6810 int i;
6812 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
6813 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_task: started\n",
6814 instance));
6816 mutex_enter(&softc->ds_lock);
6818 if (taskq_req->dr_type != DPROV_REQ_SESSION_OPEN)
6819 /* validate session id and get ptr to session */
6820 if ((session = softc->ds_sessions[session_id]) == NULL) {
6821 mutex_exit(&softc->ds_lock);
6822 dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID);
6823 return;
6826 switch (taskq_req->dr_type) {
6828 case DPROV_REQ_SESSION_OPEN: {
6829 dprov_session_t **new_sessions;
6831 if (softc->ds_token_initialized == B_FALSE) {
6832 error = CRYPTO_OPERATION_NOT_INITIALIZED;
6833 break;
6836 /* search for available session slot */
6837 for (i = 0; i < softc->ds_sessions_slots; i++)
6838 if (softc->ds_sessions[i] == NULL)
6839 break;
6841 if (i == softc->ds_sessions_slots) {
6842 /* ran out of slots, grow sessions array */
6843 new_sessions = kmem_zalloc(
6844 2 * softc->ds_sessions_slots *
6845 sizeof (dprov_session_t *), KM_NOSLEEP);
6846 if (new_sessions == NULL) {
6847 error = CRYPTO_SESSION_COUNT;
6848 break;
6850 bcopy(softc->ds_sessions, new_sessions,
6851 softc->ds_sessions_slots *
6852 sizeof (dprov_session_t *));
6853 kmem_free(softc->ds_sessions, softc->ds_sessions_slots *
6854 sizeof (dprov_session_t *));
6855 softc->ds_sessions = new_sessions;
6856 softc->ds_sessions_slots *= 2;
6859 /* allocate and initialize new session */
6860 softc->ds_sessions[i] = kmem_zalloc(
6861 sizeof (dprov_session_t), KM_NOSLEEP);
6862 if (softc->ds_sessions[i] == NULL) {
6863 error = CRYPTO_HOST_MEMORY;
6864 break;
6866 softc->ds_sessions_count++;
6868 /* initialize session state */
6869 softc->ds_sessions[i]->ds_state = DPROV_SESSION_STATE_PUBLIC;
6871 /* return new session id to caller */
6872 *(taskq_req->dr_session_req.sr_session_id_ptr) = i;
6874 error = CRYPTO_SUCCESS;
6875 break;
6878 case DPROV_REQ_SESSION_CLOSE:
6879 softc->ds_sessions[session_id] = NULL;
6881 if (softc->ds_token_initialized == B_FALSE) {
6882 error = CRYPTO_OPERATION_NOT_INITIALIZED;
6883 break;
6886 dprov_release_session_objects(session);
6888 /* free session state and corresponding slot */
6889 kmem_free(session, sizeof (dprov_session_t));
6890 softc->ds_sessions_count--;
6892 error = CRYPTO_SUCCESS;
6893 break;
6895 case DPROV_REQ_SESSION_LOGIN: {
6896 char *pin = taskq_req->dr_session_req.sr_pin;
6897 size_t pin_len = taskq_req->dr_session_req.sr_pin_len;
6898 crypto_user_type_t user_type =
6899 taskq_req->dr_session_req.sr_user_type;
6901 /* check user type */
6902 if (user_type != CRYPTO_SO && user_type != CRYPTO_USER) {
6903 error = CRYPTO_USER_TYPE_INVALID;
6904 break;
6907 /* check pin length */
6908 if (pin_len > DPROV_MAX_PIN_LEN) {
6909 error = CRYPTO_PIN_LEN_RANGE;
6910 break;
6913 /* check pin */
6914 if (pin == NULL) {
6915 error = CRYPTO_PIN_INVALID;
6916 break;
6919 /* validate PIN state */
6920 if ((user_type == CRYPTO_SO) && !softc->ds_token_initialized ||
6921 (user_type == CRYPTO_USER) && !softc->ds_user_pin_set) {
6922 error = CRYPTO_USER_PIN_NOT_INITIALIZED;
6923 break;
6926 if ((user_type == CRYPTO_SO &&
6927 softc->ds_sessions[session_id]->ds_state ==
6928 DPROV_SESSION_STATE_SO) ||
6929 (user_type == CRYPTO_USER &&
6930 softc->ds_sessions[session_id]->ds_state ==
6931 DPROV_SESSION_STATE_USER)) {
6932 /* SO or user already logged in */
6933 error = CRYPTO_USER_ALREADY_LOGGED_IN;
6934 break;
6937 if (softc->ds_sessions[session_id]->ds_state !=
6938 DPROV_SESSION_STATE_PUBLIC) {
6939 /* another user already logged in */
6940 error = CRYPTO_USER_ANOTHER_ALREADY_LOGGED_IN;
6941 break;
6944 /* everything's fine, update session */
6945 softc->ds_sessions[session_id]->ds_state =
6946 user_type == CRYPTO_SO ?
6947 DPROV_SESSION_STATE_SO : DPROV_SESSION_STATE_USER;
6949 error = CRYPTO_SUCCESS;
6950 break;
6953 case DPROV_REQ_SESSION_LOGOUT:
6954 /* fail if not logged in */
6955 if (softc->ds_sessions[session_id]->ds_state ==
6956 DPROV_SESSION_STATE_PUBLIC) {
6957 error = CRYPTO_USER_NOT_LOGGED_IN;
6958 break;
6962 * Destroy all private session objects.
6963 * Invalidate handles to all private objects.
6965 for (i = 0; i < DPROV_MAX_OBJECTS; i++) {
6966 object = softc->ds_sessions[session_id]->ds_objects[i];
6967 if (object != NULL && dprov_object_is_private(object)) {
6968 if (!dprov_object_is_token(object))
6969 /* It's a session object, free it */
6970 DPROV_OBJECT_REFRELE(object);
6971 softc->ds_sessions[session_id]->ds_objects[i] =
6972 NULL;
6976 /* update session state */
6977 softc->ds_sessions[session_id]->ds_state =
6978 DPROV_SESSION_STATE_PUBLIC;
6980 error = CRYPTO_SUCCESS;
6981 break;
6984 mutex_exit(&softc->ds_lock);
6985 dprov_op_done(taskq_req, error);
6986 DPROV_DEBUG(D_SESSION, ("(%d) dprov_session_task: end\n", instance));
6989 /* return true if attribute is defined to be a PKCS#11 long */
6990 static boolean_t
6991 fixed_size_attribute(crypto_attr_type_t type)
6993 return (type == DPROV_CKA_CLASS ||
6994 type == DPROV_CKA_CERTIFICATE_TYPE ||
6995 type == DPROV_CKA_KEY_TYPE ||
6996 type == DPROV_HW_FEATURE_TYPE);
7000 * Attributes defined to be a PKCS#11 long causes problems for dprov
7001 * because 32-bit applications set the size to 4 and 64-bit applications
7002 * set the size to 8. dprov always stores these fixed-size attributes
7003 * as uint32_t.
7005 static ssize_t
7006 attribute_size(crypto_attr_type_t type, ssize_t len)
7008 if (fixed_size_attribute(type))
7009 return (sizeof (uint32_t));
7011 return (len);
7015 * taskq dispatcher function for object management operations.
7017 static void
7018 dprov_object_task(dprov_req_t *taskq_req)
7020 dprov_state_t *softc;
7021 /* LINTED E_FUNC_SET_NOT_USED */
7022 int instance;
7023 int error = CRYPTO_NOT_SUPPORTED;
7024 crypto_object_id_t object_id = taskq_req->dr_object_req.or_object_id;
7025 crypto_session_id_t session_id = taskq_req->dr_object_req.or_session_id;
7026 crypto_object_attribute_t *template =
7027 taskq_req->dr_object_req.or_template;
7028 uint_t attr_count = taskq_req->dr_object_req.or_attribute_count;
7029 dprov_object_t *object;
7030 dprov_session_t *session;
7032 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
7033 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_task: started\n", instance));
7035 mutex_enter(&softc->ds_lock);
7037 /* validate session id and get ptr to session */
7038 if ((session = softc->ds_sessions[session_id]) == NULL) {
7039 mutex_exit(&softc->ds_lock);
7040 dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID);
7041 return;
7044 switch (taskq_req->dr_type) {
7046 case DPROV_REQ_OBJECT_CREATE:
7047 /* create the object from the specified template */
7048 if ((error = dprov_create_object_from_template(softc, session,
7049 template, attr_count,
7050 taskq_req->dr_object_req.or_object_id_ptr, B_TRUE,
7051 B_FALSE)) != CRYPTO_SUCCESS)
7052 break;
7054 break;
7056 case DPROV_REQ_OBJECT_COPY:
7057 /* check object id */
7058 if (object_id >= DPROV_MAX_OBJECTS ||
7059 (object = session->ds_objects[object_id]) == NULL) {
7060 error = CRYPTO_OBJECT_HANDLE_INVALID;
7061 break;
7065 * Create a new object from the object passed as
7066 * argument.
7068 if ((error = dprov_create_object_from_template(softc, session,
7069 object->do_attr, DPROV_MAX_ATTR,
7070 taskq_req->dr_object_req.or_object_id_ptr, B_TRUE,
7071 B_FALSE)) != CRYPTO_SUCCESS)
7072 break;
7075 * Add the attributes specified by the template to the
7076 * newly created object, replacing existing ones if needed.
7078 error = dprov_object_set_attr(session,
7079 *taskq_req->dr_object_req.or_object_id_ptr,
7080 taskq_req->dr_object_req.or_template,
7081 taskq_req->dr_object_req.or_attribute_count, B_TRUE);
7083 break;
7085 case DPROV_REQ_OBJECT_DESTROY:
7086 /* destroy the object */
7087 error = dprov_destroy_object(softc, session,
7088 taskq_req->dr_object_req.or_object_id);
7090 break;
7092 case DPROV_REQ_OBJECT_GET_SIZE:
7093 /* get ptr to object */
7094 if (object_id >= DPROV_MAX_OBJECTS ||
7095 session->ds_objects[object_id] == NULL) {
7096 error = CRYPTO_OBJECT_HANDLE_INVALID;
7097 break;
7101 * The PKCS11 specification does not specifies what
7102 * the object size really is, here we just return
7103 * the number of possible attributes of the object.
7105 *taskq_req->dr_object_req.or_object_size = DPROV_MAX_ATTR;
7107 error = CRYPTO_SUCCESS;
7108 break;
7110 case DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE: {
7111 crypto_attr_type_t type;
7112 size_t olen, tlen;
7113 offset_t offset;
7114 int tmpl_idx;
7115 int object_idx;
7116 ulong_t class = DPROV_CKO_DATA;
7117 boolean_t extractable = B_TRUE;
7119 error = CRYPTO_SUCCESS;
7121 /* get ptr to object */
7122 if (object_id >= DPROV_MAX_OBJECTS ||
7123 (object = session->ds_objects[object_id]) == NULL) {
7124 error = CRYPTO_OBJECT_HANDLE_INVALID;
7125 break;
7128 (void) dprov_get_object_attr_boolean(object,
7129 DPROV_CKA_EXTRACTABLE, &extractable);
7131 (void) dprov_get_object_attr_ulong(object,
7132 DPROV_CKA_CLASS, &class);
7134 /* return the specified attributes, when possible */
7135 for (tmpl_idx = 0; tmpl_idx < attr_count; tmpl_idx++) {
7137 * Attribute can't be revealed if the CKA_EXTRACTABLE
7138 * attribute is set to false.
7140 type = template[tmpl_idx].oa_type;
7141 if (!extractable && class == DPROV_CKO_SECRET_KEY) {
7142 if (type == DPROV_CKA_VALUE) {
7143 template[tmpl_idx].oa_value_len = -1;
7144 error = CRYPTO_ATTRIBUTE_SENSITIVE;
7145 continue;
7148 if (!extractable && class == DPROV_CKO_PRIVATE_KEY) {
7149 if (type == DPROV_CKA_PRIVATE_EXPONENT) {
7150 template[tmpl_idx].oa_value_len = -1;
7151 error = CRYPTO_ATTRIBUTE_SENSITIVE;
7152 continue;
7156 object_idx = dprov_find_attr(object->do_attr,
7157 DPROV_MAX_ATTR, type);
7158 if (object_idx == -1) {
7159 /* attribute not found in object */
7160 template[tmpl_idx].oa_value_len = -1;
7161 error = CRYPTO_ATTRIBUTE_TYPE_INVALID;
7162 continue;
7165 tlen = template[tmpl_idx].oa_value_len;
7166 olen = object->do_attr[object_idx].oa_value_len;
7167 /* return attribute length */
7168 if (template[tmpl_idx].oa_value == NULL) {
7170 * The size of the attribute is set by the
7171 * library according to the data model of the
7172 * application, so don't overwrite it with
7173 * dprov's size.
7175 if (!fixed_size_attribute(type))
7176 template[tmpl_idx].oa_value_len = olen;
7177 continue;
7180 if (tlen < olen) {
7181 template[tmpl_idx].oa_value_len = -1;
7182 error = CRYPTO_BUFFER_TOO_SMALL;
7183 continue;
7186 /* copy attribute value */
7187 bzero(template[tmpl_idx].oa_value, tlen);
7189 offset = 0;
7190 #ifdef _BIG_ENDIAN
7191 if (fixed_size_attribute(type)) {
7192 offset = tlen - olen;
7194 #endif
7195 bcopy(object->do_attr[object_idx].oa_value,
7196 &template[tmpl_idx].oa_value[offset], olen);
7198 /* don't update length for fixed-size attributes */
7199 if (!fixed_size_attribute(type))
7200 template[tmpl_idx].oa_value_len = olen;
7203 break;
7206 case DPROV_REQ_OBJECT_SET_ATTRIBUTE_VALUE:
7208 * Add the attributes specified by the template to the
7209 * newly created object, replacing existing ones if needed.
7211 error = dprov_object_set_attr(session,
7212 taskq_req->dr_object_req.or_object_id,
7213 taskq_req->dr_object_req.or_template,
7214 taskq_req->dr_object_req.or_attribute_count, B_TRUE);
7216 break;
7218 case DPROV_REQ_OBJECT_FIND_INIT: {
7219 dprov_find_ctx_t *find_ctx;
7220 int so_idx; /* session object index */
7221 int to_idx; /* token object index */
7223 error = CRYPTO_SUCCESS;
7224 /* allocate find context */
7225 find_ctx = kmem_zalloc(sizeof (dprov_find_ctx_t), KM_SLEEP);
7226 *taskq_req->dr_object_req.or_find_pp = find_ctx;
7228 /* first go through the existing session objects */
7229 for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++) {
7230 if ((object = session->ds_objects[so_idx]) == NULL)
7231 continue;
7233 /* setting count to zero means find all objects */
7234 if (attr_count > 0) {
7235 if (!dprov_attributes_match(object, template,
7236 attr_count))
7237 continue;
7240 /* session object attributes matches template */
7241 find_ctx->fc_ids[find_ctx->fc_nids] = so_idx;
7242 find_ctx->fc_nids++;
7246 * Go through the token object. For each token object
7247 * that can be accessed:
7248 * If there was already an session object id assigned
7249 * to that token object, skip it, since it was returned
7250 * during the check of session objects, else,
7251 * assign a new object id for that token object and
7252 * add it to the array of matching objects.
7254 for (to_idx = 0; to_idx < DPROV_MAX_OBJECTS &&
7255 error == CRYPTO_SUCCESS; to_idx++) {
7256 if ((object = softc->ds_objects[to_idx]) == NULL)
7257 continue;
7259 /* setting count to zero means find all objects */
7260 if (attr_count > 0) {
7261 if (!dprov_attributes_match(object, template,
7262 attr_count))
7263 continue;
7266 /* if the the object has been destroyed, skip it */
7267 if (object->do_destroyed)
7268 continue;
7270 /* skip object if it cannot be accessed from session */
7271 if (dprov_object_is_private(object) &&
7272 session->ds_state != DPROV_SESSION_STATE_USER)
7273 continue;
7276 * Is there already a session object id for this
7277 * token object?
7279 for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++)
7280 if (session->ds_objects[so_idx] != NULL &&
7281 session->ds_objects[so_idx]->do_token_idx ==
7282 to_idx)
7283 break;
7284 if (so_idx < DPROV_MAX_OBJECTS)
7285 /* object found in session table, skip it */
7286 continue;
7288 /* find free session slot for this object */
7289 for (so_idx = 0; so_idx < DPROV_MAX_OBJECTS; so_idx++)
7290 if (session->ds_objects[so_idx] == NULL)
7291 break;
7292 if (so_idx == DPROV_MAX_OBJECTS) {
7293 /* ran out of session objects slots */
7294 kmem_free(find_ctx, sizeof (dprov_find_ctx_t));
7295 error = CRYPTO_HOST_MEMORY;
7296 break;
7299 /* add object to session objects table */
7300 session->ds_objects[so_idx] = object;
7301 DPROV_OBJECT_REFHOLD(object);
7303 /* add object to list of objects to return */
7304 find_ctx->fc_ids[find_ctx->fc_nids] = so_idx;
7305 find_ctx->fc_nids++;
7308 break;
7311 case DPROV_REQ_OBJECT_FIND: {
7312 crypto_object_id_t *object_ids =
7313 taskq_req->dr_object_req.or_object_id_ptr;
7314 uint_t max_object_count =
7315 taskq_req->dr_object_req.or_max_object_count;
7316 dprov_find_ctx_t *find_ctx =
7317 taskq_req->dr_object_req.or_find_p;
7318 uint_t ret_oid_idx;
7320 /* return the desired number of object ids */
7321 for (ret_oid_idx = 0; ret_oid_idx < max_object_count &&
7322 find_ctx->fc_next < find_ctx->fc_nids; ret_oid_idx++)
7323 object_ids[ret_oid_idx] =
7324 find_ctx->fc_ids[find_ctx->fc_next++];
7326 *taskq_req->dr_object_req.or_object_count_ptr = ret_oid_idx;
7328 error = CRYPTO_SUCCESS;
7329 break;
7332 case DPROV_REQ_OBJECT_FIND_FINAL:
7333 kmem_free(taskq_req->dr_object_req.or_find_p,
7334 sizeof (dprov_find_ctx_t));
7336 error = CRYPTO_SUCCESS;
7337 break;
7340 mutex_exit(&softc->ds_lock);
7341 dprov_op_done(taskq_req, error);
7342 DPROV_DEBUG(D_OBJECT, ("(%d) dprov_object_task: end\n", instance));
7346 * Copy attribute values into a template. RSA values are precomputed.
7348 static int
7349 nostore_copy_attribute(crypto_object_attribute_t *template, uint_t count,
7350 uint64_t attr_type)
7352 void *value, *dprov_attribute_value;
7353 size_t dprov_attribute_size;
7354 size_t value_len = 0;
7355 int error;
7357 switch (attr_type) {
7358 case DPROV_CKA_VALUE:
7359 dprov_attribute_size = sizeof (dh_value);
7360 dprov_attribute_value = dh_value;
7361 break;
7363 case DPROV_CKA_MODULUS:
7364 dprov_attribute_size = sizeof (modulus);
7365 dprov_attribute_value = modulus;
7366 break;
7368 case DPROV_CKA_PUBLIC_EXPONENT:
7369 dprov_attribute_size = sizeof (public_exponent);
7370 dprov_attribute_value = public_exponent;
7371 break;
7373 case DPROV_CKA_PRIVATE_EXPONENT:
7374 dprov_attribute_size = sizeof (private_exponent);
7375 dprov_attribute_value = private_exponent;
7376 break;
7378 default:
7379 return (CRYPTO_ATTRIBUTE_TYPE_INVALID);
7382 error = dprov_get_template_attr_array(template, count, attr_type,
7383 &value, &value_len);
7384 if (error != CRYPTO_SUCCESS)
7385 return (error);
7387 if (value_len < dprov_attribute_size)
7388 return (CRYPTO_BUFFER_TOO_SMALL);
7391 * The updated template will be returned to libpkcs11.
7393 bcopy(dprov_attribute_value, value, dprov_attribute_size);
7395 return (CRYPTO_SUCCESS);
7398 static void
7399 fill_dh(void *value, size_t len)
7401 int i = 0;
7402 char *p = value;
7403 while (i < len) {
7404 p[i++] = 'D';
7405 if (i >= len)
7406 break;
7407 p[i++] = 'H';
7412 * taskq dispatcher function for key management operations.
7414 static void
7415 dprov_key_task(dprov_req_t *taskq_req)
7417 dprov_state_t *softc;
7418 /* LINTED E_FUNC_SET_NOT_USED */
7419 int instance;
7420 int error = CRYPTO_NOT_SUPPORTED;
7421 kcf_provider_desc_t *pd;
7422 crypto_session_id_t session_id = taskq_req->dr_key_req.kr_session_id;
7423 dprov_session_t *session;
7425 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
7426 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_task: started\n", instance));
7428 mutex_enter(&softc->ds_lock);
7430 /* validate session id and get ptr to session */
7431 if ((session = softc->ds_sessions[session_id]) == NULL) {
7432 mutex_exit(&softc->ds_lock);
7433 dprov_op_done(taskq_req, CRYPTO_SESSION_HANDLE_INVALID);
7434 return;
7437 switch (taskq_req->dr_type) {
7438 case DPROV_REQ_KEY_GENERATE: {
7439 crypto_mechanism_t *mechp;
7440 crypto_object_id_t *object_id_ptr;
7441 crypto_object_attribute_t *template;
7442 crypto_object_attribute_t attribute;
7443 uint_t attribute_count;
7444 ulong_t key_type = ~0UL, class = ~0UL;
7445 ulong_t value_len;
7446 size_t key_len = 0;
7448 error = CRYPTO_SUCCESS;
7450 template = taskq_req->dr_key_req.kr_template;
7451 attribute_count = taskq_req->dr_key_req.kr_attribute_count;
7452 object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr;
7453 mechp = taskq_req->dr_key_req.kr_mechanism;
7455 /* optional */
7456 (void) dprov_get_template_attr_ulong(template, attribute_count,
7457 DPROV_CKA_CLASS, &class);
7459 /* optional */
7460 (void) dprov_get_template_attr_ulong(template, attribute_count,
7461 DPROV_CKA_KEY_TYPE, &key_type);
7463 if (class != ~0UL && class != DPROV_CKO_SECRET_KEY) {
7464 error = CRYPTO_TEMPLATE_INCONSISTENT;
7465 break;
7468 switch (mechp->cm_type) {
7469 case DES_KEY_GEN_MECH_INFO_TYPE:
7470 if (key_type != ~0UL && key_type != DPROV_CKK_DES) {
7471 error = CRYPTO_TEMPLATE_INCONSISTENT;
7472 break;
7474 key_len = DES_KEY_LEN;
7475 key_type = DPROV_CKK_DES;
7476 break;
7478 case DES3_KEY_GEN_MECH_INFO_TYPE:
7479 if (key_type != ~0UL && key_type != DPROV_CKK_DES3) {
7480 error = CRYPTO_TEMPLATE_INCONSISTENT;
7481 break;
7483 key_len = DES3_KEY_LEN;
7484 key_type = DPROV_CKK_DES3;
7485 break;
7487 case AES_KEY_GEN_MECH_INFO_TYPE:
7488 if (key_type != ~0UL && key_type != DPROV_CKK_AES) {
7489 error = CRYPTO_TEMPLATE_INCONSISTENT;
7490 break;
7492 if (dprov_get_template_attr_ulong(template,
7493 attribute_count, DPROV_CKA_VALUE_LEN,
7494 &value_len) != CRYPTO_SUCCESS) {
7495 error = CRYPTO_TEMPLATE_INCOMPLETE;
7496 break;
7498 if (value_len >= AES_MAX_KEY_LEN) {
7499 error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
7500 break;
7502 key_len = value_len;
7503 key_type = DPROV_CKK_AES;
7504 break;
7506 case BLOWFISH_KEY_GEN_MECH_INFO_TYPE:
7507 if (key_type != ~0UL &&
7508 key_type != DPROV_CKK_BLOWFISH) {
7509 error = CRYPTO_TEMPLATE_INCONSISTENT;
7510 break;
7512 if (dprov_get_template_attr_ulong(template,
7513 attribute_count, DPROV_CKA_VALUE_LEN,
7514 &value_len) != CRYPTO_SUCCESS) {
7515 error = CRYPTO_TEMPLATE_INCOMPLETE;
7516 break;
7518 if (value_len >= BLOWFISH_MAX_KEY_LEN) {
7519 error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
7520 break;
7522 key_len = value_len;
7523 key_type = DPROV_CKK_BLOWFISH;
7524 break;
7526 case RC4_KEY_GEN_MECH_INFO_TYPE:
7527 if (key_type != ~0UL && key_type != DPROV_CKK_RC4) {
7528 error = CRYPTO_TEMPLATE_INCONSISTENT;
7529 break;
7531 if (dprov_get_template_attr_ulong(template,
7532 attribute_count, DPROV_CKA_VALUE_LEN,
7533 &value_len) != CRYPTO_SUCCESS) {
7534 error = CRYPTO_TEMPLATE_INCOMPLETE;
7535 break;
7537 if (value_len >=
7538 CRYPTO_BITS2BYTES(ARCFOUR_MAX_KEY_BITS)) {
7539 error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
7540 break;
7542 key_len = value_len;
7543 key_type = DPROV_CKK_RC4;
7544 break;
7546 default:
7547 error = CRYPTO_MECHANISM_INVALID;
7550 if (error != CRYPTO_SUCCESS)
7551 break;
7553 error = dprov_create_object_from_template(softc, session,
7554 template, attribute_count, object_id_ptr, B_FALSE, B_TRUE);
7556 if (error != CRYPTO_SUCCESS)
7557 break;
7559 /* make sure class is set */
7560 attribute.oa_type = DPROV_CKA_CLASS;
7561 attribute.oa_value = (char *)&class;
7562 attribute.oa_value_len = sizeof (ulong_t);
7563 error = dprov_object_set_attr(session, *object_id_ptr,
7564 &attribute, 1, B_FALSE);
7566 if (error != CRYPTO_SUCCESS) {
7567 goto destroy_object;
7570 /* make sure key_type is set */
7571 attribute.oa_type = DPROV_CKA_KEY_TYPE;
7572 attribute.oa_value = (char *)&key_type;
7573 attribute.oa_value_len = sizeof (ulong_t);
7574 error = dprov_object_set_attr(session, *object_id_ptr,
7575 &attribute, 1, B_FALSE);
7577 if (error != CRYPTO_SUCCESS) {
7578 goto destroy_object;
7581 attribute.oa_type = DPROV_CKA_VALUE;
7582 attribute.oa_value = kmem_alloc(key_len, KM_SLEEP);
7583 attribute.oa_value_len = key_len;
7585 if (random_get_pseudo_bytes((uchar_t *)attribute.oa_value,
7586 key_len) != 0) {
7587 bzero(attribute.oa_value, key_len);
7588 kmem_free(attribute.oa_value, key_len);
7589 goto destroy_object;
7591 error = dprov_object_set_attr(session, *object_id_ptr,
7592 &attribute, 1, B_FALSE);
7594 bzero(attribute.oa_value, key_len);
7595 kmem_free(attribute.oa_value, key_len);
7597 if (error != CRYPTO_SUCCESS) {
7598 goto destroy_object;
7600 break;
7602 destroy_object:
7603 (void) dprov_destroy_object(softc, session, *object_id_ptr);
7604 break;
7607 case DPROV_REQ_KEY_GENERATE_PAIR: {
7608 crypto_mechanism_t *mechp;
7609 crypto_object_id_t *pub_object_id_ptr;
7610 crypto_object_id_t *pri_object_id_ptr;
7611 crypto_object_attribute_t *pub_template;
7612 crypto_object_attribute_t *pri_template;
7613 crypto_object_attribute_t attribute;
7614 uint_t pub_attribute_count;
7615 uint_t pri_attribute_count;
7616 ulong_t pub_key_type = ~0UL, pub_class = ~0UL;
7617 ulong_t pri_key_type = ~0UL, pri_class = ~0UL;
7619 pub_template = taskq_req->dr_key_req.kr_template;
7620 pub_attribute_count = taskq_req->dr_key_req.kr_attribute_count;
7621 pub_object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr;
7622 pri_template = taskq_req->dr_key_req.kr_private_key_template;
7623 pri_attribute_count =
7624 taskq_req->dr_key_req.kr_private_key_attribute_count;
7625 pri_object_id_ptr =
7626 taskq_req->dr_key_req.kr_private_key_object_id_ptr;
7627 mechp = taskq_req->dr_key_req.kr_mechanism;
7629 error = CRYPTO_SUCCESS;
7631 /* optional */
7632 (void) dprov_get_template_attr_ulong(pub_template,
7633 pub_attribute_count, DPROV_CKA_CLASS, &pub_class);
7635 /* optional */
7636 (void) dprov_get_template_attr_ulong(pri_template,
7637 pri_attribute_count, DPROV_CKA_CLASS, &pri_class);
7639 /* optional */
7640 (void) dprov_get_template_attr_ulong(pub_template,
7641 pub_attribute_count, DPROV_CKA_KEY_TYPE, &pub_key_type);
7643 /* optional */
7644 (void) dprov_get_template_attr_ulong(pri_template,
7645 pri_attribute_count, DPROV_CKA_KEY_TYPE, &pri_key_type);
7647 if (pub_class != ~0UL && pub_class != DPROV_CKO_PUBLIC_KEY) {
7648 error = CRYPTO_TEMPLATE_INCONSISTENT;
7649 break;
7652 if (pri_class != ~0UL && pri_class != DPROV_CKO_PRIVATE_KEY) {
7653 error = CRYPTO_TEMPLATE_INCONSISTENT;
7654 break;
7657 switch (mechp->cm_type) {
7658 case RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE:
7659 if (pub_key_type != ~0UL &&
7660 pub_key_type != DPROV_CKK_RSA) {
7661 error = CRYPTO_TEMPLATE_INCONSISTENT;
7662 break;
7664 pub_key_type = DPROV_CKK_RSA;
7666 if (pri_key_type != ~0UL &&
7667 pri_key_type != DPROV_CKK_RSA) {
7668 error = CRYPTO_TEMPLATE_INCONSISTENT;
7669 break;
7671 pri_key_type = DPROV_CKK_RSA;
7673 if (pub_class != ~0UL &&
7674 pub_class != DPROV_CKO_PUBLIC_KEY) {
7675 error = CRYPTO_TEMPLATE_INCONSISTENT;
7676 break;
7678 pub_class = DPROV_CKO_PUBLIC_KEY;
7680 if (pri_class != ~0UL &&
7681 pri_class != DPROV_CKO_PRIVATE_KEY) {
7682 error = CRYPTO_TEMPLATE_INCONSISTENT;
7683 break;
7685 pri_class = DPROV_CKO_PRIVATE_KEY;
7686 break;
7688 default:
7689 error = CRYPTO_MECHANISM_INVALID;
7692 if (error != CRYPTO_SUCCESS)
7693 break;
7695 error = dprov_create_object_from_template(softc, session,
7696 pub_template, pub_attribute_count, pub_object_id_ptr,
7697 B_FALSE, B_TRUE);
7699 if (error != CRYPTO_SUCCESS)
7700 break;
7702 /* make sure class is set */
7703 attribute.oa_type = DPROV_CKA_CLASS;
7704 attribute.oa_value = (char *)&pub_class;
7705 attribute.oa_value_len = sizeof (ulong_t);
7706 error = dprov_object_set_attr(session, *pub_object_id_ptr,
7707 &attribute, 1, B_FALSE);
7709 if (error != CRYPTO_SUCCESS) {
7710 goto destroy_public_object;
7713 /* make sure key_type is set */
7714 attribute.oa_type = DPROV_CKA_KEY_TYPE;
7715 attribute.oa_value = (char *)&pub_key_type;
7716 attribute.oa_value_len = sizeof (ulong_t);
7717 error = dprov_object_set_attr(session, *pub_object_id_ptr,
7718 &attribute, 1, B_FALSE);
7720 if (error != CRYPTO_SUCCESS) {
7721 goto destroy_public_object;
7724 attribute.oa_type = DPROV_CKA_MODULUS;
7725 attribute.oa_value = (char *)modulus;
7726 attribute.oa_value_len = sizeof (modulus);
7727 error = dprov_object_set_attr(session, *pub_object_id_ptr,
7728 &attribute, 1, B_FALSE);
7730 if (error != CRYPTO_SUCCESS) {
7731 goto destroy_public_object;
7734 attribute.oa_type = DPROV_CKA_PUBLIC_EXPONENT;
7735 attribute.oa_value = public_exponent;
7736 attribute.oa_value_len = sizeof (public_exponent);
7737 error = dprov_object_set_attr(session, *pub_object_id_ptr,
7738 &attribute, 1, B_FALSE);
7740 if (error != CRYPTO_SUCCESS) {
7741 goto destroy_public_object;
7744 error = dprov_create_object_from_template(softc, session,
7745 pri_template, pri_attribute_count, pri_object_id_ptr,
7746 B_FALSE, B_TRUE);
7748 if (error != CRYPTO_SUCCESS)
7749 break;
7751 /* make sure class is set */
7752 attribute.oa_type = DPROV_CKA_CLASS;
7753 attribute.oa_value = (char *)&pri_class;
7754 attribute.oa_value_len = sizeof (ulong_t);
7755 error = dprov_object_set_attr(session, *pri_object_id_ptr,
7756 &attribute, 1, B_FALSE);
7758 if (error != CRYPTO_SUCCESS) {
7759 goto destroy_private_object;
7762 /* make sure key_type is set */
7763 attribute.oa_type = DPROV_CKA_KEY_TYPE;
7764 attribute.oa_value = (char *)&pri_key_type;
7765 attribute.oa_value_len = sizeof (ulong_t);
7766 error = dprov_object_set_attr(session, *pri_object_id_ptr,
7767 &attribute, 1, B_FALSE);
7769 if (error != CRYPTO_SUCCESS) {
7770 goto destroy_private_object;
7773 attribute.oa_type = DPROV_CKA_MODULUS;
7774 attribute.oa_value = (char *)modulus;
7775 attribute.oa_value_len = sizeof (modulus);
7776 error = dprov_object_set_attr(session, *pri_object_id_ptr,
7777 &attribute, 1, B_FALSE);
7779 if (error != CRYPTO_SUCCESS) {
7780 goto destroy_private_object;
7783 attribute.oa_type = DPROV_CKA_PRIVATE_EXPONENT;
7784 attribute.oa_value = (char *)private_exponent;
7785 attribute.oa_value_len = sizeof (private_exponent);
7786 error = dprov_object_set_attr(session, *pri_object_id_ptr,
7787 &attribute, 1, B_FALSE);
7789 if (error != CRYPTO_SUCCESS) {
7790 goto destroy_private_object;
7792 break;
7794 destroy_private_object:
7795 (void) dprov_destroy_object(softc, session,
7796 *pri_object_id_ptr);
7797 destroy_public_object:
7798 (void) dprov_destroy_object(softc, session,
7799 *pub_object_id_ptr);
7801 break;
7804 case DPROV_REQ_KEY_WRAP: {
7805 crypto_mechanism_t mech, *mechp;
7806 crypto_key_t key, *keyp;
7807 crypto_object_id_t object_id;
7808 ulong_t class = DPROV_CKO_DATA;
7809 boolean_t extractable = B_TRUE;
7810 dprov_object_t *object;
7811 int object_idx;
7812 char *plaintext_key;
7813 size_t plaintext_key_len;
7814 crypto_data_t plaintext;
7815 crypto_data_t ciphertext;
7816 size_t *lenp;
7818 mechp = taskq_req->dr_key_req.kr_mechanism;
7819 /* structure assignment */
7820 mech = *mechp;
7822 /* get wrapping key value */
7823 if (is_publickey_mech(mech.cm_type)) {
7824 if ((error = dprov_key_attr_asymmetric(softc,
7825 session_id, taskq_req->dr_type,
7826 taskq_req->dr_key_req.kr_key,
7827 &key)) != CRYPTO_SUCCESS)
7828 break;
7829 keyp = &key;
7830 } else {
7831 if ((error = dprov_key_value_secret(softc,
7832 session_id, taskq_req->dr_type,
7833 taskq_req->dr_key_req.kr_key,
7834 &key)) != CRYPTO_SUCCESS)
7835 break;
7836 keyp = &key;
7839 /* get the software provider for this mechanism */
7840 if ((error = dprov_get_sw_prov(mechp, &pd,
7841 &mech.cm_type)) != CRYPTO_SUCCESS)
7842 break;
7844 object_id = *taskq_req->dr_key_req.kr_object_id_ptr;
7845 if (object_id >= DPROV_MAX_OBJECTS) {
7846 error = CRYPTO_KEY_HANDLE_INVALID;
7847 break;
7850 /* get ptr to object */
7851 if ((object = session->ds_objects[object_id]) == NULL) {
7852 error = CRYPTO_OBJECT_HANDLE_INVALID;
7853 break;
7856 (void) dprov_get_object_attr_boolean(object,
7857 DPROV_CKA_EXTRACTABLE, &extractable);
7859 if (!extractable) {
7860 error = CRYPTO_ATTRIBUTE_SENSITIVE;
7861 break;
7864 (void) dprov_get_object_attr_ulong(object,
7865 DPROV_CKA_CLASS, &class);
7867 switch (class) {
7868 case DPROV_CKO_SECRET_KEY:
7869 object_idx = dprov_find_attr(object->do_attr,
7870 DPROV_MAX_ATTR, DPROV_CKA_VALUE);
7871 if (object_idx == -1) {
7872 error = CRYPTO_ATTRIBUTE_TYPE_INVALID;
7873 break;
7875 break;
7877 case DPROV_CKO_PRIVATE_KEY:
7879 * PKCS#11 says that ASN.1 should be used to encode
7880 * specific attributes before encrypting the blob.
7881 * We only encrypt the private exponent for the
7882 * purpose of testing.
7884 object_idx = dprov_find_attr(object->do_attr,
7885 DPROV_MAX_ATTR, DPROV_CKA_PRIVATE_EXPONENT);
7886 if (object_idx == -1) {
7887 error = CRYPTO_ATTRIBUTE_TYPE_INVALID;
7888 break;
7890 break;
7891 default:
7892 error = CRYPTO_KEY_NOT_WRAPPABLE;
7893 break;
7895 if (error != CRYPTO_SUCCESS)
7896 break;
7898 plaintext_key = object->do_attr[object_idx].oa_value;
7899 plaintext_key_len = object->do_attr[object_idx].oa_value_len;
7900 lenp = taskq_req->dr_key_req.kr_wrapped_key_len_ptr;
7902 /* session id is 0 for software provider */
7903 plaintext.cd_format = CRYPTO_DATA_RAW;
7904 plaintext.cd_offset = 0;
7905 plaintext.cd_length = plaintext_key_len;
7906 plaintext.cd_raw.iov_base = plaintext_key;
7907 plaintext.cd_raw.iov_len = plaintext_key_len;
7908 plaintext.cd_miscdata = NULL;
7910 ciphertext.cd_format = CRYPTO_DATA_RAW;
7911 ciphertext.cd_offset = 0;
7912 ciphertext.cd_length = *lenp;
7913 ciphertext.cd_raw.iov_base =
7914 (char *)taskq_req->dr_key_req.kr_wrapped_key;
7915 ciphertext.cd_raw.iov_len = ciphertext.cd_length;
7916 ciphertext.cd_miscdata = NULL;
7918 error = crypto_encrypt_prov(pd, 0, &mech, &plaintext, keyp,
7919 NULL, &ciphertext, NULL);
7921 KCF_PROV_REFRELE(pd);
7922 if (error == CRYPTO_SUCCESS ||
7923 error == CRYPTO_BUFFER_TOO_SMALL) {
7924 *lenp = ciphertext.cd_length;
7926 break;
7929 case DPROV_REQ_KEY_UNWRAP: {
7930 crypto_mechanism_t mech, *mechp;
7931 crypto_key_t key, *keyp;
7932 crypto_object_id_t *object_id_ptr;
7933 ulong_t class = DPROV_CKO_DATA;
7934 uchar_t *wrapped_key;
7935 char *plaintext_buf;
7936 size_t wrapped_key_len;
7937 crypto_data_t plaintext;
7938 crypto_data_t ciphertext;
7939 crypto_object_attribute_t unwrapped_key;
7940 crypto_object_attribute_t *template;
7941 uint_t attribute_count;
7943 template = taskq_req->dr_key_req.kr_template;
7944 attribute_count = taskq_req->dr_key_req.kr_attribute_count;
7945 object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr;
7947 /* all objects must have an object class attribute */
7948 if (dprov_get_template_attr_ulong(template, attribute_count,
7949 DPROV_CKA_CLASS, &class) != CRYPTO_SUCCESS) {
7950 error = CRYPTO_TEMPLATE_INCOMPLETE;
7951 break;
7954 mechp = taskq_req->dr_key_req.kr_mechanism;
7955 /* structure assignment */
7956 mech = *mechp;
7958 /* get unwrapping key value */
7959 if (is_publickey_mech(mech.cm_type)) {
7960 if ((error = dprov_key_attr_asymmetric(softc,
7961 session_id, taskq_req->dr_type,
7962 taskq_req->dr_key_req.kr_key,
7963 &key)) != CRYPTO_SUCCESS)
7964 break;
7965 keyp = &key;
7966 } else {
7967 if ((error = dprov_key_value_secret(softc,
7968 session_id, taskq_req->dr_type,
7969 taskq_req->dr_key_req.kr_key,
7970 &key)) != CRYPTO_SUCCESS)
7971 break;
7972 keyp = &key;
7975 /* get the software provider for this mechanism */
7976 if ((error = dprov_get_sw_prov(mechp, &pd,
7977 &mech.cm_type)) != CRYPTO_SUCCESS)
7978 break;
7980 wrapped_key = taskq_req->dr_key_req.kr_wrapped_key;
7981 wrapped_key_len = *taskq_req->dr_key_req.kr_wrapped_key_len_ptr;
7982 ciphertext.cd_format = CRYPTO_DATA_RAW;
7983 ciphertext.cd_offset = 0;
7984 ciphertext.cd_length = wrapped_key_len;
7985 ciphertext.cd_raw.iov_base = (char *)wrapped_key;
7986 ciphertext.cd_raw.iov_len = wrapped_key_len;
7987 ciphertext.cd_miscdata = NULL;
7990 * Plaintext length is less than or equal to
7991 * the length of the ciphertext.
7993 plaintext_buf = kmem_alloc(wrapped_key_len, KM_SLEEP);
7994 plaintext.cd_format = CRYPTO_DATA_RAW;
7995 plaintext.cd_offset = 0;
7996 plaintext.cd_length = wrapped_key_len;
7997 plaintext.cd_raw.iov_base = plaintext_buf;
7998 plaintext.cd_raw.iov_len = wrapped_key_len;
7999 plaintext.cd_miscdata = NULL;
8001 error = crypto_decrypt_prov(pd, 0, &mech, &ciphertext, keyp,
8002 NULL, &plaintext, NULL);
8004 KCF_PROV_REFRELE(pd);
8006 if (error != CRYPTO_SUCCESS)
8007 goto free_unwrapped_key;
8009 error = dprov_create_object_from_template(softc, session,
8010 template, attribute_count, object_id_ptr, B_FALSE, B_FALSE);
8012 if (error != CRYPTO_SUCCESS)
8013 goto free_unwrapped_key;
8015 switch (class) {
8016 case DPROV_CKO_SECRET_KEY:
8017 unwrapped_key.oa_type = DPROV_CKA_VALUE;
8018 unwrapped_key.oa_value_len = plaintext.cd_length;
8019 unwrapped_key.oa_value = plaintext_buf;
8020 break;
8021 case DPROV_CKO_PRIVATE_KEY:
8023 * PKCS#11 says that ASN.1 should be used to encode
8024 * specific attributes before encrypting the blob.
8025 * We only encrypt the private exponent for the
8026 * purpose of testing.
8028 unwrapped_key.oa_type = DPROV_CKA_PRIVATE_EXPONENT;
8029 unwrapped_key.oa_value_len = plaintext.cd_length;
8030 unwrapped_key.oa_value = plaintext_buf;
8031 break;
8032 default:
8033 error = CRYPTO_TEMPLATE_INCONSISTENT;
8034 goto free_unwrapped_key;
8037 if ((error = dprov_object_set_attr(session, *object_id_ptr,
8038 &unwrapped_key, 1, B_FALSE)) == CRYPTO_SUCCESS)
8039 break; /* don't free the unwrapped key */
8041 /* failure */
8042 (void) dprov_destroy_object(softc, session, *object_id_ptr);
8043 break;
8045 free_unwrapped_key:
8046 bzero(plaintext_buf, wrapped_key_len);
8047 kmem_free(plaintext_buf, wrapped_key_len);
8048 break;
8051 case DPROV_REQ_KEY_DERIVE: {
8052 crypto_mechanism_t digest_mech, *mechp;
8053 crypto_key_t key, *base_keyp;
8054 crypto_object_id_t *object_id_ptr;
8055 crypto_data_t data;
8056 crypto_data_t digest;
8057 size_t hash_size;
8058 char *digest_buf;
8059 crypto_object_attribute_t derived_key;
8060 crypto_object_attribute_t *template;
8061 uint_t attribute_count;
8062 ulong_t key_type;
8063 void *value;
8064 size_t value_len = 0;
8066 error = CRYPTO_SUCCESS;
8068 template = taskq_req->dr_key_req.kr_template;
8069 attribute_count = taskq_req->dr_key_req.kr_attribute_count;
8070 object_id_ptr = taskq_req->dr_key_req.kr_object_id_ptr;
8072 /* required */
8073 if (dprov_get_template_attr_ulong(template, attribute_count,
8074 DPROV_CKA_KEY_TYPE, &key_type) != CRYPTO_SUCCESS) {
8075 error = CRYPTO_TEMPLATE_INCOMPLETE;
8076 break;
8079 mechp = taskq_req->dr_key_req.kr_mechanism;
8080 /* structure assignment */
8081 digest_mech = *mechp;
8083 switch (digest_mech.cm_type) {
8084 case SHA1_KEY_DERIVATION_MECH_INFO_TYPE:
8085 hash_size = SHA1_DIGEST_LEN;
8086 digest_mech.cm_type = SHA1_MECH_INFO_TYPE;
8087 break;
8089 case SHA256_KEY_DERIVATION_MECH_INFO_TYPE:
8090 hash_size = SHA256_DIGEST_LENGTH;
8091 digest_mech.cm_type = SHA256_MECH_INFO_TYPE;
8092 break;
8094 case SHA384_KEY_DERIVATION_MECH_INFO_TYPE:
8095 hash_size = SHA384_DIGEST_LENGTH;
8096 digest_mech.cm_type = SHA384_MECH_INFO_TYPE;
8097 break;
8099 case SHA512_KEY_DERIVATION_MECH_INFO_TYPE:
8100 hash_size = SHA512_DIGEST_LENGTH;
8101 digest_mech.cm_type = SHA512_MECH_INFO_TYPE;
8102 break;
8104 case MD5_KEY_DERIVATION_MECH_INFO_TYPE:
8105 hash_size = MD5_DIGEST_LEN;
8106 digest_mech.cm_type = MD5_MECH_INFO_TYPE;
8107 break;
8109 default:
8110 error = CRYPTO_MECHANISM_INVALID;
8113 if (error != CRYPTO_SUCCESS)
8114 break;
8116 /* CKA_VALUE is optional */
8117 (void) dprov_get_template_attr_array(template, attribute_count,
8118 DPROV_CKA_VALUE, &value, &value_len);
8120 /* check for inconsistent value length */
8121 switch (key_type) {
8122 case DPROV_CKK_GENERIC_SECRET:
8123 if (value_len > 0) {
8124 if (value_len > hash_size)
8125 error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
8126 } else {
8127 value_len = hash_size;
8129 break;
8131 case DPROV_CKK_RC4:
8132 case DPROV_CKK_AES:
8133 if (value_len == 0 ||
8134 value_len > hash_size) {
8135 error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
8137 break;
8139 case DPROV_CKK_DES:
8140 if (value_len > 0 &&
8141 value_len != DES_KEY_LEN) {
8142 error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
8144 value_len = DES_KEY_LEN;
8145 break;
8147 case DPROV_CKK_DES3:
8148 if (value_len > 0 &&
8149 value_len != DES3_KEY_LEN) {
8150 error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
8152 value_len = DES3_KEY_LEN;
8153 break;
8155 default:
8156 error = CRYPTO_ATTRIBUTE_VALUE_INVALID;
8157 break;
8160 if (error != CRYPTO_SUCCESS)
8161 break;
8163 /* get the software provider for this mechanism */
8164 if ((error = dprov_get_sw_prov(&digest_mech, &pd,
8165 &digest_mech.cm_type)) != CRYPTO_SUCCESS)
8166 break;
8168 /* get the base key */
8169 error = dprov_key_value_secret(softc, session_id,
8170 taskq_req->dr_type, taskq_req->dr_key_req.kr_key, &key);
8171 if (error != CRYPTO_SUCCESS)
8172 break;
8174 base_keyp = &key;
8176 data.cd_format = CRYPTO_DATA_RAW;
8177 data.cd_offset = 0;
8178 data.cd_length = CRYPTO_BITS2BYTES(base_keyp->ck_length);
8179 data.cd_raw.iov_base = base_keyp->ck_data;
8180 data.cd_raw.iov_len = data.cd_length;
8182 digest_buf = kmem_alloc(hash_size, KM_SLEEP);
8183 digest.cd_format = CRYPTO_DATA_RAW;
8184 digest.cd_offset = 0;
8185 digest.cd_length = hash_size;
8186 digest.cd_raw.iov_base = digest_buf;
8187 digest.cd_raw.iov_len = hash_size;
8189 error = crypto_digest_prov(pd, 0, &digest_mech, &data,
8190 &digest, NULL);
8192 KCF_PROV_REFRELE(pd);
8194 if (error != CRYPTO_SUCCESS)
8195 goto free_derived_key;
8197 error = dprov_create_object_from_template(softc, session,
8198 template, attribute_count, object_id_ptr, B_FALSE, B_FALSE);
8200 if (error != CRYPTO_SUCCESS)
8201 goto free_derived_key;
8203 derived_key.oa_type = DPROV_CKA_VALUE;
8204 derived_key.oa_value = digest_buf;
8205 derived_key.oa_value_len = value_len;
8207 error = dprov_object_set_attr(session, *object_id_ptr,
8208 &derived_key, 1, B_FALSE);
8210 if (error != CRYPTO_SUCCESS) {
8211 (void) dprov_destroy_object(softc, session,
8212 *object_id_ptr);
8215 free_derived_key:
8216 bzero(digest_buf, hash_size);
8217 kmem_free(digest_buf, hash_size);
8218 break;
8221 case DPROV_REQ_NOSTORE_KEY_GENERATE: {
8222 crypto_object_attribute_t *out_template;
8223 uint_t out_attribute_count;
8224 void *value;
8225 size_t value_len = 0;
8227 out_template = taskq_req->dr_key_req.kr_out_template1;
8228 out_attribute_count =
8229 taskq_req->dr_key_req.kr_out_attribute_count1;
8231 error = dprov_get_template_attr_array(out_template,
8232 out_attribute_count, DPROV_CKA_VALUE, &value, &value_len);
8233 if (error != CRYPTO_SUCCESS)
8234 break;
8236 /* fill the entire array with pattern */
8238 int i = 0;
8239 char *p = value;
8240 while (i < value_len) {
8241 p[i++] = 'A';
8242 if (i >= value_len)
8243 break;
8244 p[i++] = 'B';
8245 if (i >= value_len)
8246 break;
8247 p[i++] = 'C';
8251 error = CRYPTO_SUCCESS;
8252 break;
8255 case DPROV_REQ_NOSTORE_KEY_GENERATE_PAIR: {
8256 crypto_mechanism_t *mechp;
8257 crypto_object_attribute_t *pub_template;
8258 crypto_object_attribute_t *pri_template;
8259 uint_t pub_attribute_count;
8260 uint_t pri_attribute_count;
8261 crypto_object_attribute_t *out_pub_template;
8262 crypto_object_attribute_t *out_pri_template;
8263 uint_t out_pub_attribute_count;
8264 uint_t out_pri_attribute_count;
8266 mechp = taskq_req->dr_key_req.kr_mechanism;
8267 pub_template = taskq_req->dr_key_req.kr_template;
8268 pub_attribute_count = taskq_req->dr_key_req.kr_attribute_count;
8269 pri_template = taskq_req->dr_key_req.kr_private_key_template;
8270 pri_attribute_count =
8271 taskq_req->dr_key_req.kr_private_key_attribute_count;
8272 out_pub_template = taskq_req->dr_key_req.kr_out_template1;
8273 out_pub_attribute_count =
8274 taskq_req->dr_key_req.kr_out_attribute_count1;
8275 out_pri_template = taskq_req->dr_key_req.kr_out_template2;
8276 out_pri_attribute_count =
8277 taskq_req->dr_key_req.kr_out_attribute_count2;
8279 switch (mechp->cm_type) {
8280 case RSA_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE:
8281 error = nostore_copy_attribute(out_pub_template,
8282 out_pub_attribute_count, DPROV_CKA_MODULUS);
8283 if (error != CRYPTO_SUCCESS)
8284 break;
8286 error = nostore_copy_attribute(out_pub_template,
8287 out_pub_attribute_count, DPROV_CKA_PUBLIC_EXPONENT);
8288 if (error == CRYPTO_ARGUMENTS_BAD) {
8289 size_t tmp_len = 0;
8290 void *tmp;
8292 /* public exponent must be here */
8293 error = dprov_get_template_attr_array(
8294 pub_template, pub_attribute_count,
8295 DPROV_CKA_PUBLIC_EXPONENT, &tmp, &tmp_len);
8296 if (error != CRYPTO_SUCCESS)
8297 break;
8299 error = nostore_copy_attribute(out_pri_template,
8300 out_pri_attribute_count, DPROV_CKA_MODULUS);
8301 if (error != CRYPTO_SUCCESS)
8302 break;
8304 error = nostore_copy_attribute(out_pri_template,
8305 out_pri_attribute_count,
8306 DPROV_CKA_PRIVATE_EXPONENT);
8307 break;
8309 case DH_PKCS_KEY_PAIR_GEN_MECH_INFO_TYPE:
8311 * There is no software provider for DH mechanism;
8312 * Just return pre-defined values.
8314 error = nostore_copy_attribute(out_pub_template,
8315 out_pub_attribute_count, DPROV_CKA_VALUE);
8316 error = nostore_copy_attribute(out_pri_template,
8317 out_pri_attribute_count, DPROV_CKA_VALUE);
8318 break;
8320 case EC_KEY_PAIR_GEN_MECH_INFO_TYPE: {
8321 crypto_mechanism_t mech, *mechp;
8322 kcf_req_params_t params;
8323 crypto_object_attribute_t *pub_template;
8324 uint_t pub_attribute_count;
8325 crypto_object_attribute_t *out_pub_template;
8326 crypto_object_attribute_t *out_pri_template;
8327 uint_t out_pub_attribute_count;
8328 uint_t out_pri_attribute_count;
8330 mechp = taskq_req->dr_key_req.kr_mechanism;
8331 pub_template = taskq_req->dr_key_req.kr_template;
8332 pub_attribute_count =
8333 taskq_req->dr_key_req.kr_attribute_count;
8334 out_pub_template =
8335 taskq_req->dr_key_req.kr_out_template1;
8336 out_pub_attribute_count =
8337 taskq_req->dr_key_req.kr_out_attribute_count1;
8338 out_pri_template =
8339 taskq_req->dr_key_req.kr_out_template2;
8340 out_pri_attribute_count =
8341 taskq_req->dr_key_req.kr_out_attribute_count2;
8343 /* get the software provider for this mechanism */
8344 mech = *mechp;
8345 if ((error = dprov_get_sw_prov(mechp, &pd,
8346 &mech.cm_type)) != CRYPTO_SUCCESS)
8347 break;
8349 * Turn 32-bit values into 64-bit values for certain
8350 * attributes like CKA_CLASS.
8352 dprov_adjust_attrs(pub_template, pub_attribute_count);
8353 dprov_adjust_attrs(pri_template, pri_attribute_count);
8355 /* bypass the kernel API for now */
8356 KCF_WRAP_NOSTORE_KEY_OPS_PARAMS(&params,
8357 KCF_OP_KEY_GENERATE_PAIR,
8358 0, /* session 0 for sw provider */
8359 &mech, pub_template, pub_attribute_count,
8360 pri_template, pri_attribute_count, NULL,
8361 out_pub_template, out_pub_attribute_count,
8362 out_pri_template, out_pri_attribute_count);
8364 error = kcf_submit_request(pd, NULL, NULL, &params,
8365 B_FALSE);
8367 KCF_PROV_REFRELE(pd);
8368 break;
8370 default:
8371 error = CRYPTO_MECHANISM_INVALID;
8373 break;
8376 case DPROV_REQ_NOSTORE_KEY_DERIVE: {
8377 crypto_mechanism_t *mechp;
8378 crypto_object_attribute_t *in_template, *out_template;
8379 crypto_key_t *base_key;
8380 uint_t in_attribute_count, out_attribute_count;
8381 ulong_t key_type;
8382 void *value;
8383 size_t value_len = 0;
8384 size_t value_len_value = 0;
8386 in_template = taskq_req->dr_key_req.kr_template;
8387 out_template = taskq_req->dr_key_req.kr_out_template1;
8388 in_attribute_count = taskq_req->dr_key_req.kr_attribute_count;
8389 out_attribute_count =
8390 taskq_req->dr_key_req.kr_out_attribute_count1;
8391 mechp = taskq_req->dr_key_req.kr_mechanism;
8392 base_key = taskq_req->dr_key_req.kr_key;
8395 * CKA_VALUE must be present so the derived key can
8396 * be returned by value.
8398 if (dprov_get_template_attr_array(out_template,
8399 out_attribute_count, DPROV_CKA_VALUE, &value,
8400 &value_len) != CRYPTO_SUCCESS) {
8401 error = CRYPTO_TEMPLATE_INCOMPLETE;
8402 break;
8405 if (dprov_get_template_attr_ulong(in_template,
8406 in_attribute_count, DPROV_CKA_KEY_TYPE,
8407 &key_type) != CRYPTO_SUCCESS) {
8408 error = CRYPTO_TEMPLATE_INCOMPLETE;
8409 break;
8411 switch (mechp->cm_type) {
8412 case DH_PKCS_DERIVE_MECH_INFO_TYPE: {
8413 size_t tmp_len = 0;
8414 void *tmp;
8416 if (base_key->ck_format != CRYPTO_KEY_ATTR_LIST) {
8417 error = CRYPTO_ARGUMENTS_BAD;
8418 break;
8421 if ((dprov_get_template_attr_array(base_key->ck_attrs,
8422 base_key->ck_count, DPROV_CKA_BASE, &tmp,
8423 &tmp_len) != CRYPTO_SUCCESS) ||
8424 (dprov_get_template_attr_array(base_key->ck_attrs,
8425 base_key->ck_count, DPROV_CKA_PRIME, &tmp,
8426 &tmp_len) != CRYPTO_SUCCESS) ||
8427 (dprov_get_template_attr_array(base_key->ck_attrs,
8428 base_key->ck_count, DPROV_CKA_VALUE, &tmp,
8429 &tmp_len) != CRYPTO_SUCCESS)) {
8430 error = CRYPTO_TEMPLATE_INCOMPLETE;
8431 break;
8435 * CKA_VALUE is added to the derived key template by
8436 * the library.
8438 error = CRYPTO_SUCCESS;
8439 switch (key_type) {
8440 case DPROV_CKK_AES:
8441 if (dprov_get_template_attr_ulong(in_template,
8442 in_attribute_count, DPROV_CKA_VALUE_LEN,
8443 &value_len_value) != CRYPTO_SUCCESS) {
8444 error = CRYPTO_TEMPLATE_INCOMPLETE;
8445 break;
8447 if (value_len != value_len_value) {
8448 error = CRYPTO_TEMPLATE_INCONSISTENT;
8449 break;
8451 break;
8452 default:
8453 error = CRYPTO_MECHANISM_INVALID;
8455 if (error == CRYPTO_SUCCESS)
8456 fill_dh(value, value_len);
8457 break;
8459 case ECDH1_DERIVE_MECH_INFO_TYPE: {
8460 crypto_mechanism_t mech;
8461 kcf_req_params_t params;
8463 /* get the software provider for this mechanism */
8464 mech = *mechp;
8465 if ((error = dprov_get_sw_prov(mechp, &pd,
8466 &mech.cm_type)) != CRYPTO_SUCCESS)
8467 break;
8470 * Turn 32-bit values into 64-bit values for certain
8471 * attributes like CKA_VALUE_LEN.
8473 dprov_adjust_attrs(in_template, in_attribute_count);
8475 /* bypass the kernel API for now */
8476 KCF_WRAP_NOSTORE_KEY_OPS_PARAMS(&params,
8477 KCF_OP_KEY_DERIVE,
8478 0, /* session 0 for sw provider */
8479 &mech, in_template, in_attribute_count,
8480 NULL, 0, base_key,
8481 out_template, out_attribute_count,
8482 NULL, 0);
8484 error = kcf_submit_request(pd, NULL, NULL, &params,
8485 B_FALSE);
8487 KCF_PROV_REFRELE(pd);
8488 break;
8491 default:
8492 error = CRYPTO_MECHANISM_INVALID;
8494 break;
8495 default:
8496 error = CRYPTO_MECHANISM_INVALID;
8498 } /* end case */
8500 mutex_exit(&softc->ds_lock);
8501 dprov_op_done(taskq_req, error);
8502 DPROV_DEBUG(D_KEY, ("(%d) dprov_key_task: end\n", instance));
8506 * taskq dispatcher function for provider management operations.
8508 static void
8509 dprov_mgmt_task(dprov_req_t *taskq_req)
8511 dprov_state_t *softc;
8512 /* LINTED E_FUNC_SET_NOT_USED */
8513 int instance;
8514 int error = CRYPTO_NOT_SUPPORTED;
8516 DPROV_SOFTC_FROM_REQ(taskq_req, softc, instance);
8517 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_mgmt_task: started\n", instance));
8519 mutex_enter(&softc->ds_lock);
8521 switch (taskq_req->dr_type) {
8522 case DPROV_REQ_MGMT_EXTINFO: {
8523 crypto_provider_ext_info_t *ext_info =
8524 taskq_req->dr_mgmt_req.mr_ext_info;
8526 (void) memset(ext_info->ei_label, ' ', CRYPTO_EXT_SIZE_LABEL);
8527 if (!softc->ds_token_initialized) {
8528 bcopy("(not initialized)", ext_info->ei_label,
8529 strlen("(not initialized)"));
8530 } else {
8531 bcopy(softc->ds_label, ext_info->ei_label,
8532 CRYPTO_EXT_SIZE_LABEL);
8535 bcopy(DPROV_MANUFACTURER, ext_info->ei_manufacturerID,
8536 CRYPTO_EXT_SIZE_MANUF);
8537 bcopy(DPROV_MODEL, ext_info->ei_model, CRYPTO_EXT_SIZE_MODEL);
8539 (void) snprintf((char *)ext_info->ei_serial_number, 16, "%d%s",
8540 instance, DPROV_ALLSPACES);
8541 /* PKCS#11 blank padding */
8542 ext_info->ei_serial_number[15] = ' ';
8543 ext_info->ei_max_session_count = CRYPTO_EFFECTIVELY_INFINITE;
8544 ext_info->ei_max_pin_len = (ulong_t)DPROV_MAX_PIN_LEN;
8545 ext_info->ei_min_pin_len = 1;
8546 ext_info->ei_total_public_memory = CRYPTO_EFFECTIVELY_INFINITE;
8547 ext_info->ei_free_public_memory = CRYPTO_EFFECTIVELY_INFINITE;
8548 ext_info->ei_total_private_memory = CRYPTO_EFFECTIVELY_INFINITE;
8549 ext_info->ei_free_private_memory = CRYPTO_EFFECTIVELY_INFINITE;
8550 ext_info->ei_hardware_version.cv_major = 1;
8551 ext_info->ei_hardware_version.cv_minor = 0;
8552 ext_info->ei_firmware_version.cv_major = 1;
8553 ext_info->ei_firmware_version.cv_minor = 0;
8555 ext_info->ei_flags = CRYPTO_EXTF_RNG |
8556 CRYPTO_EXTF_LOGIN_REQUIRED |
8557 CRYPTO_EXTF_DUAL_CRYPTO_OPERATIONS;
8558 if (softc->ds_user_pin_set)
8559 ext_info->ei_flags |= CRYPTO_EXTF_USER_PIN_INITIALIZED;
8560 if (softc->ds_token_initialized)
8561 ext_info->ei_flags |= CRYPTO_EXTF_TOKEN_INITIALIZED;
8563 ext_info->ei_hash_max_input_len = dprov_max_digestsz;
8564 ext_info->ei_hmac_max_input_len = dprov_max_digestsz;
8565 error = CRYPTO_SUCCESS;
8566 break;
8568 case DPROV_REQ_MGMT_INITTOKEN: {
8569 char *pin = taskq_req->dr_mgmt_req.mr_pin;
8570 size_t pin_len = taskq_req->dr_mgmt_req.mr_pin_len;
8571 char *label = taskq_req->dr_mgmt_req.mr_label;
8573 /* cannot initialize token when a session is open */
8574 if (softc->ds_sessions_count > 0) {
8575 error = CRYPTO_SESSION_EXISTS;
8576 break;
8579 /* check PIN length */
8580 if (pin_len > DPROV_MAX_PIN_LEN) {
8581 error = CRYPTO_PIN_LEN_RANGE;
8582 break;
8585 /* check PIN */
8586 if (pin == NULL) {
8587 error = CRYPTO_PIN_INVALID;
8588 break;
8592 * If the token has already been initialized, need
8593 * to validate supplied PIN.
8595 if (softc->ds_token_initialized &&
8596 (softc->ds_so_pin_len != pin_len ||
8597 strncmp(softc->ds_so_pin, pin, pin_len) != 0)) {
8598 /* invalid SO PIN */
8599 error = CRYPTO_PIN_INCORRECT;
8600 break;
8603 /* set label */
8604 bcopy(label, softc->ds_label, CRYPTO_EXT_SIZE_LABEL);
8606 /* set new SO PIN, update state */
8607 bcopy(pin, softc->ds_so_pin, pin_len);
8608 softc->ds_so_pin_len = pin_len;
8609 softc->ds_token_initialized = B_TRUE;
8610 softc->ds_user_pin_set = B_FALSE;
8612 error = CRYPTO_SUCCESS;
8613 break;
8615 case DPROV_REQ_MGMT_INITPIN: {
8616 char *pin = taskq_req->dr_mgmt_req.mr_pin;
8617 size_t pin_len = taskq_req->dr_mgmt_req.mr_pin_len;
8618 crypto_session_id_t session_id =
8619 taskq_req->dr_mgmt_req.mr_session_id;
8621 /* check session id */
8622 if (softc->ds_sessions[session_id] == NULL) {
8623 error = CRYPTO_SESSION_HANDLE_INVALID;
8624 break;
8627 /* fail if not logged in as SO */
8628 if (softc->ds_sessions[session_id]->ds_state !=
8629 DPROV_SESSION_STATE_SO) {
8630 error = CRYPTO_USER_NOT_LOGGED_IN;
8631 break;
8634 /* check PIN length */
8635 if (pin_len > DPROV_MAX_PIN_LEN) {
8636 error = CRYPTO_PIN_LEN_RANGE;
8637 break;
8640 /* check PIN */
8641 if (pin == NULL) {
8642 error = CRYPTO_PIN_INVALID;
8643 break;
8646 /* set new normal user PIN */
8647 bcopy(pin, softc->ds_user_pin, pin_len);
8648 softc->ds_user_pin_len = pin_len;
8649 softc->ds_user_pin_set = B_TRUE;
8651 error = CRYPTO_SUCCESS;
8652 break;
8654 case DPROV_REQ_MGMT_SETPIN: {
8655 char *new_pin = taskq_req->dr_mgmt_req.mr_pin;
8656 size_t new_pin_len = taskq_req->dr_mgmt_req.mr_pin_len;
8657 char *old_pin = taskq_req->dr_mgmt_req.mr_old_pin;
8658 size_t old_pin_len = taskq_req->dr_mgmt_req.mr_old_pin_len;
8659 crypto_session_id_t session_id =
8660 taskq_req->dr_mgmt_req.mr_session_id;
8662 /* check session id */
8663 if (softc->ds_sessions[session_id] == NULL) {
8664 error = CRYPTO_SESSION_HANDLE_INVALID;
8665 break;
8668 /* check PIN length */
8669 if (old_pin_len > DPROV_MAX_PIN_LEN ||
8670 new_pin_len > DPROV_MAX_PIN_LEN) {
8671 error = CRYPTO_PIN_LEN_RANGE;
8672 break;
8675 /* check PIN */
8676 if (old_pin == NULL || new_pin == NULL) {
8677 error = CRYPTO_PIN_INVALID;
8678 break;
8681 /* check user PIN state */
8682 if (!softc->ds_user_pin_set) {
8683 error = CRYPTO_USER_PIN_NOT_INITIALIZED;
8684 break;
8688 * If the token has already been initialized, need
8689 * to validate supplied PIN.
8691 if (softc->ds_user_pin_len != old_pin_len ||
8692 strncmp(softc->ds_user_pin, old_pin, old_pin_len) != 0) {
8693 /* invalid SO PIN */
8694 error = CRYPTO_PIN_INCORRECT;
8695 break;
8698 /* set new PIN */
8699 bcopy(new_pin, softc->ds_user_pin, new_pin_len);
8700 softc->ds_user_pin_len = new_pin_len;
8702 error = CRYPTO_SUCCESS;
8703 break;
8707 mutex_exit(&softc->ds_lock);
8708 dprov_op_done(taskq_req, error);
8709 DPROV_DEBUG(D_DIGEST, ("(%d) dprov_mgmt_task: end\n", instance));
8713 * Returns in the location pointed to by pd a pointer to the descriptor
8714 * for the software provider for the specified mechanism.
8715 * The provider descriptor is returned held. Returns one of the CRYPTO_
8716 * error codes on failure, CRYPTO_SUCCESS on success.
8718 static int
8719 dprov_get_sw_prov(crypto_mechanism_t *mech, kcf_provider_desc_t **pd,
8720 crypto_mech_type_t *provider_mech_type)
8722 crypto_mech_type_t kcf_mech_type = CRYPTO_MECH_INVALID;
8723 int i, rv;
8725 /* lookup the KCF mech type associated with our mech type */
8726 for (i = 0; i < sizeof (dprov_mech_info_tab)/
8727 sizeof (crypto_mech_info_t); i++) {
8728 if (mech->cm_type == dprov_mech_info_tab[i].cm_mech_number) {
8729 kcf_mech_type = crypto_mech2id_common(
8730 dprov_mech_info_tab[i].cm_mech_name, B_TRUE);
8734 rv = kcf_get_sw_prov(kcf_mech_type, pd, NULL, B_TRUE);
8735 if (rv == CRYPTO_SUCCESS)
8736 *provider_mech_type = kcf_mech_type;
8738 return (rv);
8742 * Object management helper functions.
8746 * Given a crypto_key_t, return whether the key can be used or not
8747 * for the specified request. The attributes used here are defined
8748 * in table 42 of the PKCS#11 spec (Common secret key attributes).
8750 static int
8751 dprov_key_can_use(dprov_object_t *object, dprov_req_type_t req_type)
8753 boolean_t ret = 0;
8754 int rv = CRYPTO_SUCCESS;
8756 /* check if object is allowed for specified operation */
8757 switch (req_type) {
8758 case DPROV_REQ_ENCRYPT_INIT:
8759 case DPROV_REQ_ENCRYPT_ATOMIC:
8760 rv = dprov_get_object_attr_boolean(object,
8761 DPROV_CKA_ENCRYPT, &ret);
8762 break;
8763 case DPROV_REQ_DECRYPT_INIT:
8764 case DPROV_REQ_DECRYPT_ATOMIC:
8765 rv = dprov_get_object_attr_boolean(object,
8766 DPROV_CKA_DECRYPT, &ret);
8767 break;
8768 case DPROV_REQ_SIGN_INIT:
8769 case DPROV_REQ_SIGN_ATOMIC:
8770 case DPROV_REQ_MAC_INIT:
8771 case DPROV_REQ_MAC_ATOMIC:
8772 case DPROV_REQ_MAC_VERIFY_ATOMIC:
8773 rv = dprov_get_object_attr_boolean(object,
8774 DPROV_CKA_SIGN, &ret);
8775 break;
8776 case DPROV_REQ_SIGN_RECOVER_INIT:
8777 case DPROV_REQ_SIGN_RECOVER_ATOMIC:
8778 rv = dprov_get_object_attr_boolean(object,
8779 DPROV_CKA_SIGN_RECOVER, &ret);
8780 break;
8781 case DPROV_REQ_VERIFY_INIT:
8782 case DPROV_REQ_VERIFY_ATOMIC:
8783 rv = dprov_get_object_attr_boolean(object,
8784 DPROV_CKA_VERIFY, &ret);
8785 break;
8786 case DPROV_REQ_VERIFY_RECOVER_INIT:
8787 case DPROV_REQ_VERIFY_RECOVER_ATOMIC:
8788 rv = dprov_get_object_attr_boolean(object,
8789 DPROV_CKA_VERIFY_RECOVER, &ret);
8790 break;
8791 case DPROV_REQ_KEY_WRAP:
8792 rv = dprov_get_object_attr_boolean(object,
8793 DPROV_CKA_WRAP, &ret);
8794 break;
8795 case DPROV_REQ_KEY_UNWRAP:
8796 rv = dprov_get_object_attr_boolean(object,
8797 DPROV_CKA_UNWRAP, &ret);
8798 break;
8799 case DPROV_REQ_DIGEST_KEY:
8801 * There is no attribute to check for; therefore,
8802 * any secret key can be used.
8804 ret = B_TRUE;
8805 rv = CRYPTO_SUCCESS;
8806 break;
8807 case DPROV_REQ_KEY_DERIVE:
8808 rv = dprov_get_object_attr_boolean(object,
8809 DPROV_CKA_DERIVE, &ret);
8810 break;
8813 if (rv != CRYPTO_SUCCESS || !ret)
8814 return (CRYPTO_KEY_FUNCTION_NOT_PERMITTED);
8816 return (CRYPTO_SUCCESS);
8820 * Given a crypto_key_t corresponding to a secret key (i.e. for
8821 * use with symmetric crypto algorithms) specified in raw format, by
8822 * attribute, or by reference, initialize the ck_data and ck_length
8823 * fields of the ret_key argument so that they specify the key value
8824 * and length.
8826 * For a key by value, this function uess the ck_data and ck_length,
8827 * for a key by reference, it looks up the corresponding object and
8828 * returns the appropriate attribute. For a key by attribute, it returns
8829 * the appropriate attribute. The attributes used are CKA_VALUE to retrieve
8830 * the value of the key, and CKA_VALUE_LEN to retrieve its length in bytes.
8832 static int
8833 dprov_key_value_secret(dprov_state_t *softc, crypto_session_id_t session_id,
8834 dprov_req_type_t req_type, crypto_key_t *key, crypto_key_t *ret_key)
8836 ulong_t key_type;
8837 int ret = CRYPTO_SUCCESS;
8839 ret_key->ck_format = CRYPTO_KEY_RAW;
8841 switch (key->ck_format) {
8843 case CRYPTO_KEY_RAW:
8844 ret_key->ck_data = key->ck_data;
8845 ret_key->ck_length = key->ck_length;
8846 break;
8848 case CRYPTO_KEY_ATTR_LIST: {
8849 void *value;
8850 size_t len, value_len;
8852 if ((ret = dprov_get_key_attr_ulong(key, DPROV_CKA_KEY_TYPE,
8853 &key_type)) != CRYPTO_SUCCESS)
8854 break;
8856 if ((ret = dprov_get_key_attr_array(key, DPROV_CKA_VALUE,
8857 &value, &len)) != CRYPTO_SUCCESS)
8858 break;
8861 * The length of the array is expressed in bytes.
8862 * Convert to bits now since that's how keys are measured.
8864 len = CRYPTO_BYTES2BITS(len);
8866 /* optional */
8867 if ((dprov_get_key_attr_ulong(key, DPROV_CKA_VALUE_LEN,
8868 &value_len)) == CRYPTO_SUCCESS) {
8869 len = value_len;
8872 ret_key->ck_data = value;
8873 ret_key->ck_length = (uint_t)len;
8875 break;
8878 case CRYPTO_KEY_REFERENCE: {
8879 dprov_object_t *object;
8880 void *value;
8881 size_t len, value_len;
8883 /* check session id */
8884 if (softc->ds_sessions[session_id] == NULL) {
8885 ret = CRYPTO_SESSION_HANDLE_INVALID;
8886 break;
8889 if (key->ck_obj_id >= DPROV_MAX_OBJECTS) {
8890 ret = CRYPTO_KEY_HANDLE_INVALID;
8891 goto bail;
8894 /* check if object id specified by key is valid */
8895 object = softc->ds_sessions[session_id]->
8896 ds_objects[key->ck_obj_id];
8897 if (object == NULL) {
8898 ret = CRYPTO_KEY_HANDLE_INVALID;
8899 goto bail;
8902 /* check if object can be used for operation */
8903 if ((ret = dprov_key_can_use(object, req_type)) !=
8904 CRYPTO_SUCCESS)
8905 goto bail;
8907 if ((ret = dprov_get_object_attr_ulong(object,
8908 DPROV_CKA_KEY_TYPE, &key_type)) != CRYPTO_SUCCESS)
8909 goto bail;
8911 if ((ret = dprov_get_object_attr_array(object,
8912 DPROV_CKA_VALUE, &value, &len)) != CRYPTO_SUCCESS)
8913 goto bail;
8915 /* optional */
8916 if ((dprov_get_object_attr_ulong(object, DPROV_CKA_VALUE_LEN,
8917 &value_len)) == CRYPTO_SUCCESS) {
8918 len = value_len;
8922 * The length of attributes are in bytes.
8923 * Convert to bits now since that's how keys are measured.
8925 len = CRYPTO_BYTES2BITS(len);
8927 ret_key->ck_data = value;
8928 ret_key->ck_length = (uint_t)len;
8929 bail:
8930 break;
8933 default:
8934 ret = CRYPTO_ARGUMENTS_BAD;
8935 break;
8938 return (ret);
8942 * Get the attribute list for the specified asymmetric key.
8944 static int
8945 dprov_key_attr_asymmetric(dprov_state_t *softc, crypto_session_id_t session_id,
8946 dprov_req_type_t req_type, crypto_key_t *key, crypto_key_t *ret_key)
8948 int ret = CRYPTO_SUCCESS;
8950 ret_key->ck_format = CRYPTO_KEY_ATTR_LIST;
8952 switch (key->ck_format) {
8954 case CRYPTO_KEY_ATTR_LIST:
8955 ret_key->ck_attrs = key->ck_attrs;
8956 ret_key->ck_count = key->ck_count;
8957 break;
8959 case CRYPTO_KEY_REFERENCE: {
8960 dprov_object_t *object;
8962 /* check session id */
8963 if (softc->ds_sessions[session_id] == NULL) {
8964 ret = CRYPTO_SESSION_HANDLE_INVALID;
8965 break;
8968 /* check if object id specified by key is valid */
8969 object = softc->ds_sessions[session_id]->
8970 ds_objects[key->ck_obj_id];
8971 if (object == NULL) {
8972 ret = CRYPTO_KEY_HANDLE_INVALID;
8973 break;
8976 /* check if object can be used for operation */
8977 if ((ret = dprov_key_can_use(object, req_type)) !=
8978 CRYPTO_SUCCESS)
8979 break;
8981 ret_key->ck_attrs = object->do_attr;
8982 ret_key->ck_count = DPROV_MAX_ATTR;
8983 break;
8986 default:
8987 ret = CRYPTO_ARGUMENTS_BAD;
8990 return (ret);
8994 * Return the index of an attribute of specified type found in
8995 * the specified array of attributes. If the attribute cannot
8996 * found, return -1.
8998 static int
8999 dprov_find_attr(crypto_object_attribute_t *attr, uint_t nattr,
9000 uint64_t attr_type)
9002 int i;
9004 for (i = 0; i < nattr; i++)
9005 if (attr[i].oa_value != NULL &&
9006 attr[i].oa_type == attr_type)
9007 return (i);
9009 return (-1);
9013 * Given the given object template and session, return whether
9014 * an object can be created from that template according to the
9015 * following rules:
9016 * - private objects can be created only by a logged-in user
9018 static int
9019 dprov_template_can_create(dprov_session_t *session,
9020 crypto_object_attribute_t *template, uint_t nattr,
9021 boolean_t check_for_secret)
9023 boolean_t is_private = B_FALSE;
9024 ulong_t key_type, class;
9025 int error;
9027 /* check CKA_PRIVATE attribute value */
9028 error = dprov_get_template_attr_boolean(template, nattr,
9029 DPROV_CKA_PRIVATE, &is_private);
9030 if (error == CRYPTO_SUCCESS && is_private) {
9031 /* it's a private object */
9032 if (session->ds_state != DPROV_SESSION_STATE_USER) {
9034 * Cannot create private object with SO or public
9035 * sessions.
9037 return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
9041 /* all objects must have an object class attribute */
9042 if (dprov_get_template_attr_ulong(template, nattr, DPROV_CKA_CLASS,
9043 &class) != CRYPTO_SUCCESS) {
9044 return (CRYPTO_TEMPLATE_INCOMPLETE);
9047 /* key objects must have a key type attribute */
9048 if (class == DPROV_CKO_SECRET_KEY ||
9049 class == DPROV_CKO_PUBLIC_KEY ||
9050 class == DPROV_CKO_PRIVATE_KEY) {
9051 if (!dprov_template_attr_present(template, nattr,
9052 DPROV_CKA_KEY_TYPE)) {
9053 return (CRYPTO_TEMPLATE_INCOMPLETE);
9057 /* check for RSA public key attributes that must be present */
9058 if (class == DPROV_CKO_PUBLIC_KEY) {
9059 if (dprov_get_template_attr_ulong(template, nattr,
9060 DPROV_CKA_KEY_TYPE, &key_type) == CRYPTO_SUCCESS) {
9061 if (key_type == DPROV_CKK_RSA) {
9062 if (!dprov_template_attr_present(template,
9063 nattr, DPROV_CKA_MODULUS) ||
9064 !dprov_template_attr_present(template,
9065 nattr, DPROV_CKA_PUBLIC_EXPONENT)) {
9066 return (CRYPTO_TEMPLATE_INCOMPLETE);
9069 /* these attributes should not be present */
9070 if (dprov_template_attr_present(template, nattr,
9071 DPROV_CKA_MODULUS_BITS)) {
9072 return (CRYPTO_TEMPLATE_INCONSISTENT);
9078 /* check for RSA private key attributes that must be present */
9079 if (class == DPROV_CKO_PRIVATE_KEY) {
9080 if (dprov_get_template_attr_ulong(template, nattr,
9081 DPROV_CKA_KEY_TYPE, &key_type) == CRYPTO_SUCCESS) {
9082 if (key_type == DPROV_CKK_RSA) {
9083 if (!dprov_template_attr_present(template,
9084 nattr, DPROV_CKA_MODULUS))
9085 return (CRYPTO_TEMPLATE_INCOMPLETE);
9087 if (check_for_secret) {
9088 if (!dprov_template_attr_present(
9089 template, nattr,
9090 DPROV_CKA_PRIVATE_EXPONENT))
9091 return (
9092 CRYPTO_TEMPLATE_INCOMPLETE);
9098 /* check for secret key attributes that must be present */
9099 if (class == DPROV_CKO_SECRET_KEY) {
9100 if (check_for_secret) {
9101 if (!dprov_template_attr_present(template, nattr,
9102 DPROV_CKA_VALUE)) {
9103 return (CRYPTO_TEMPLATE_INCOMPLETE);
9107 /* these attributes should not be present */
9108 if (dprov_template_attr_present(template, nattr,
9109 DPROV_CKA_VALUE_LEN)) {
9110 return (CRYPTO_TEMPLATE_INCONSISTENT);
9114 return (CRYPTO_SUCCESS);
9118 * Create an object from the specified template. Checks whether the
9119 * object can be created according to its attributes and the state
9120 * of the session. The new session object id is returned. If the
9121 * object is a token object, it is added to the per-instance object
9122 * table as well.
9124 static int
9125 dprov_create_object_from_template(dprov_state_t *softc,
9126 dprov_session_t *session, crypto_object_attribute_t *template,
9127 uint_t nattr, crypto_object_id_t *object_id, boolean_t check_for_secret,
9128 boolean_t force)
9130 dprov_object_t *object;
9131 boolean_t is_token = B_FALSE;
9132 boolean_t extractable_attribute_present = B_FALSE;
9133 boolean_t sensitive_attribute_present = B_FALSE;
9134 boolean_t private_attribute_present = B_FALSE;
9135 boolean_t token_attribute_present = B_FALSE;
9136 uint_t i;
9137 int error;
9138 uint_t attr;
9139 uint_t oattr;
9140 crypto_attr_type_t type;
9141 size_t old_len, new_len;
9142 offset_t offset;
9144 if (nattr > DPROV_MAX_ATTR)
9145 return (CRYPTO_HOST_MEMORY);
9147 if (!force) {
9148 /* verify that object can be created */
9149 if ((error = dprov_template_can_create(session, template,
9150 nattr, check_for_secret)) != CRYPTO_SUCCESS)
9151 return (error);
9154 /* allocate new object */
9155 object = kmem_zalloc(sizeof (dprov_object_t), KM_SLEEP);
9156 if (object == NULL)
9157 return (CRYPTO_HOST_MEMORY);
9159 /* is it a token object? */
9160 /* check CKA_TOKEN attribute value */
9161 error = dprov_get_template_attr_boolean(template, nattr,
9162 DPROV_CKA_TOKEN, &is_token);
9163 if (error == CRYPTO_SUCCESS && is_token) {
9164 /* token object, add it to the per-instance object table */
9165 for (i = 0; i < DPROV_MAX_OBJECTS; i++)
9166 if (softc->ds_objects[i] == NULL)
9167 break;
9168 if (i == DPROV_MAX_OBJECTS)
9169 /* no free slot */
9170 return (CRYPTO_HOST_MEMORY);
9171 softc->ds_objects[i] = object;
9172 object->do_token_idx = i;
9173 DPROV_OBJECT_REFHOLD(object);
9176 /* add object to session object table */
9177 for (i = 0; i < DPROV_MAX_OBJECTS; i++)
9178 if (session->ds_objects[i] == NULL)
9179 break;
9180 if (i == DPROV_MAX_OBJECTS) {
9181 /* no more session object slots */
9182 DPROV_OBJECT_REFRELE(object);
9183 return (CRYPTO_HOST_MEMORY);
9185 session->ds_objects[i] = object;
9186 DPROV_OBJECT_REFHOLD(object);
9187 *object_id = i;
9189 /* initialize object from template */
9190 for (attr = 0, oattr = 0; attr < nattr; attr++) {
9191 if (template[attr].oa_value == NULL)
9192 continue;
9193 type = template[attr].oa_type;
9194 old_len = template[attr].oa_value_len;
9195 new_len = attribute_size(type, old_len);
9197 if (type == DPROV_CKA_EXTRACTABLE) {
9198 extractable_attribute_present = B_TRUE;
9199 } else if (type == DPROV_CKA_PRIVATE) {
9200 private_attribute_present = B_TRUE;
9201 } else if (type == DPROV_CKA_TOKEN) {
9202 token_attribute_present = B_TRUE;
9204 object->do_attr[oattr].oa_type = type;
9205 object->do_attr[oattr].oa_value_len = new_len;
9207 object->do_attr[oattr].oa_value = kmem_zalloc(new_len,
9208 KM_SLEEP);
9210 offset = 0;
9211 #ifdef _BIG_ENDIAN
9212 if (fixed_size_attribute(type)) {
9213 offset = old_len - new_len;
9215 #endif
9216 bcopy(&template[attr].oa_value[offset],
9217 object->do_attr[oattr].oa_value, new_len);
9218 oattr++;
9221 /* add boolean attributes that must be present */
9222 if (extractable_attribute_present == B_FALSE) {
9223 object->do_attr[oattr].oa_type = DPROV_CKA_EXTRACTABLE;
9224 object->do_attr[oattr].oa_value_len = 1;
9225 object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP);
9226 object->do_attr[oattr].oa_value[0] = B_TRUE;
9227 oattr++;
9230 if (private_attribute_present == B_FALSE) {
9231 object->do_attr[oattr].oa_type = DPROV_CKA_PRIVATE;
9232 object->do_attr[oattr].oa_value_len = 1;
9233 object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP);
9234 object->do_attr[oattr].oa_value[0] = B_FALSE;
9235 oattr++;
9238 if (token_attribute_present == B_FALSE) {
9239 object->do_attr[oattr].oa_type = DPROV_CKA_TOKEN;
9240 object->do_attr[oattr].oa_value_len = 1;
9241 object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP);
9242 object->do_attr[oattr].oa_value[0] = B_FALSE;
9243 oattr++;
9246 if (sensitive_attribute_present == B_FALSE) {
9247 object->do_attr[oattr].oa_type = DPROV_CKA_SENSITIVE;
9248 object->do_attr[oattr].oa_value_len = 1;
9249 object->do_attr[oattr].oa_value = kmem_alloc(1, KM_SLEEP);
9250 object->do_attr[oattr].oa_value[0] = B_FALSE;
9251 oattr++;
9253 return (CRYPTO_SUCCESS);
9257 * Checks whether or not the object matches the specified attributes.
9259 * PKCS#11 attributes which are longs are stored in uint32_t containers
9260 * so they can be matched by both 32 and 64-bit applications.
9262 static boolean_t
9263 dprov_attributes_match(dprov_object_t *object,
9264 crypto_object_attribute_t *template, uint_t nattr)
9266 crypto_attr_type_t type;
9267 size_t tlen, olen, diff;
9268 int ta_idx; /* template attribute index */
9269 int oa_idx; /* object attribute index */
9271 for (ta_idx = 0; ta_idx < nattr; ta_idx++) {
9272 /* no value for template attribute */
9273 if (template[ta_idx].oa_value == NULL)
9274 continue;
9276 /* find attribute in object */
9277 type = template[ta_idx].oa_type;
9278 oa_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR, type);
9280 if (oa_idx == -1)
9281 /* attribute not found in object */
9282 return (B_FALSE);
9284 tlen = template[ta_idx].oa_value_len;
9285 olen = object->do_attr[oa_idx].oa_value_len;
9286 if (tlen < olen)
9287 return (B_FALSE);
9289 diff = 0;
9290 #ifdef _BIG_ENDIAN
9291 /* application may think attribute is 8 bytes */
9292 if (fixed_size_attribute(type))
9293 diff = tlen - olen;
9294 #endif
9296 if (bcmp(&template[ta_idx].oa_value[diff],
9297 object->do_attr[oa_idx].oa_value, olen) != 0)
9298 /* value mismatch */
9299 return (B_FALSE);
9302 return (B_TRUE);
9306 * Destroy the object specified by its session and object id.
9308 static int
9309 dprov_destroy_object(dprov_state_t *softc, dprov_session_t *session,
9310 crypto_object_id_t object_id)
9312 dprov_object_t *object;
9314 if ((object = session->ds_objects[object_id]) == NULL)
9315 return (CRYPTO_OBJECT_HANDLE_INVALID);
9317 /* remove from session table */
9318 session->ds_objects[object_id] = NULL;
9320 if (dprov_object_is_token(object)) {
9321 if (!object->do_destroyed) {
9322 object->do_destroyed = B_TRUE;
9323 /* remove from per-instance token table */
9324 softc->ds_objects[object->do_token_idx] = NULL;
9325 DPROV_OBJECT_REFRELE(object);
9326 } else {
9327 DPROV_DEBUG(D_OBJECT, ("dprov_destroy_object: "
9328 "object %p already destroyed\n", (void *)object));
9332 DPROV_OBJECT_REFRELE(object);
9333 return (CRYPTO_SUCCESS);
9336 static int
9337 dprov_object_can_modify(dprov_object_t *object,
9338 crypto_object_attribute_t *template, uint_t nattr)
9340 ulong_t object_class;
9342 /* all objects should have an object class attribute */
9343 if (dprov_get_object_attr_ulong(object, DPROV_CKA_CLASS,
9344 &object_class) != CRYPTO_SUCCESS) {
9345 return (CRYPTO_SUCCESS);
9348 if (object_class == DPROV_CKO_SECRET_KEY ||
9349 object_class == DPROV_CKO_PUBLIC_KEY ||
9350 object_class == DPROV_CKO_PRIVATE_KEY) {
9351 if (dprov_template_attr_present(template, nattr,
9352 DPROV_CKA_CLASS) ||
9353 dprov_template_attr_present(template, nattr,
9354 DPROV_CKA_KEY_TYPE))
9355 return (CRYPTO_TEMPLATE_INCONSISTENT);
9358 switch (object_class) {
9359 case DPROV_CKO_SECRET_KEY:
9360 if (dprov_template_attr_present(template, nattr,
9361 DPROV_CKA_VALUE))
9362 return (CRYPTO_TEMPLATE_INCONSISTENT);
9363 break;
9365 case DPROV_CKO_PUBLIC_KEY:
9366 if (dprov_template_attr_present(template, nattr,
9367 DPROV_CKA_MODULUS) ||
9368 dprov_template_attr_present(template, nattr,
9369 DPROV_CKA_PUBLIC_EXPONENT))
9370 return (CRYPTO_TEMPLATE_INCONSISTENT);
9371 break;
9373 case DPROV_CKO_PRIVATE_KEY:
9374 if (dprov_template_attr_present(template, nattr,
9375 DPROV_CKA_MODULUS) ||
9376 dprov_template_attr_present(template, nattr,
9377 DPROV_CKA_PRIVATE_EXPONENT))
9378 return (CRYPTO_TEMPLATE_INCONSISTENT);
9379 break;
9381 default:
9382 return (CRYPTO_SUCCESS);
9385 return (CRYPTO_SUCCESS);
9389 * Set the attributes specified by the template in the specified object,
9390 * replacing existing ones if needed.
9392 static int
9393 dprov_object_set_attr(dprov_session_t *session, crypto_object_id_t object_id,
9394 crypto_object_attribute_t *template, uint_t nattr,
9395 boolean_t check_attributes)
9397 crypto_attr_type_t type;
9398 dprov_object_t *object;
9399 size_t old_len, new_len;
9400 uint_t i, j;
9401 int error;
9403 if ((object = session->ds_objects[object_id]) == NULL)
9404 return (CRYPTO_OBJECT_HANDLE_INVALID);
9406 if (check_attributes) {
9407 /* verify that attributes in the template can be modified */
9408 if ((error = dprov_object_can_modify(object, template, nattr))
9409 != CRYPTO_SUCCESS)
9410 return (error);
9413 /* go through the attributes specified in the template */
9414 for (i = 0; i < nattr; i++) {
9415 if (template[i].oa_value == NULL)
9416 continue;
9418 /* find attribute in object */
9419 type = template[i].oa_type;
9420 j = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR, type);
9422 if (j != -1) {
9423 /* attribute already exists, free old value */
9424 kmem_free(object->do_attr[j].oa_value,
9425 object->do_attr[j].oa_value_len);
9426 } else {
9427 /* attribute does not exist, create it */
9428 for (j = 0; j < DPROV_MAX_ATTR; j++)
9429 if (object->do_attr[j].oa_value == NULL)
9430 break;
9431 if (j == DPROV_MAX_ATTR)
9432 /* ran out of attribute slots */
9433 return (CRYPTO_HOST_MEMORY);
9436 old_len = template[i].oa_value_len;
9437 new_len = attribute_size(type, old_len);
9439 /* set object attribute value */
9440 object->do_attr[j].oa_value = kmem_alloc(new_len, KM_SLEEP);
9441 bcopy(&template[i].oa_value[old_len - new_len],
9442 object->do_attr[j].oa_value, new_len);
9443 object->do_attr[j].oa_value_len = new_len;
9445 /* and the type */
9446 object->do_attr[j].oa_type = type;
9449 return (CRYPTO_SUCCESS);
9454 * Free the specified object.
9456 static void
9457 dprov_free_object(dprov_object_t *object)
9459 int i;
9461 /* free the object attributes values */
9462 for (i = 0; i < DPROV_MAX_ATTR; i++)
9463 if (object->do_attr[i].oa_value != NULL)
9464 kmem_free(object->do_attr[i].oa_value,
9465 object->do_attr[i].oa_value_len);
9467 /* free the object */
9468 kmem_free(object, sizeof (dprov_object_t));
9472 * Checks whether the specified object is a private or public object.
9474 static boolean_t
9475 dprov_object_is_private(dprov_object_t *object)
9477 boolean_t ret;
9478 int err;
9480 err = dprov_get_object_attr_boolean(object, DPROV_CKA_PRIVATE, &ret);
9482 if (err != CRYPTO_SUCCESS)
9483 /* by default, CKA_PRIVATE is false */
9484 ret = B_FALSE;
9486 return (ret);
9490 * Checks whether the specified object is a token or session object.
9492 static boolean_t
9493 dprov_object_is_token(dprov_object_t *object)
9495 boolean_t ret;
9496 int err;
9498 err = dprov_get_object_attr_boolean(object, DPROV_CKA_TOKEN, &ret);
9500 if (err != CRYPTO_SUCCESS)
9501 /* by default, CKA_TOKEN is false */
9502 ret = B_FALSE;
9504 return (ret);
9508 * Common function used by the dprov_get_object_attr_*() family of
9509 * functions. Returns the value of the specified attribute of specified
9510 * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID
9511 * if the length of the attribute does not match the specified length,
9512 * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found.
9514 static int
9515 dprov_get_object_attr_scalar_common(dprov_object_t *object, uint64_t attr_type,
9516 void *value, size_t value_len)
9518 int attr_idx;
9519 size_t oa_value_len;
9520 size_t offset = 0;
9522 if ((attr_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR,
9523 attr_type)) == -1)
9524 return (CRYPTO_ARGUMENTS_BAD);
9526 oa_value_len = object->do_attr[attr_idx].oa_value_len;
9527 if (oa_value_len != value_len) {
9529 * For some attributes, it's okay to copy the value
9530 * into a larger container, e.g. copy an unsigned
9531 * 32-bit integer into a 64-bit container.
9533 if (attr_type == DPROV_CKA_VALUE_LEN ||
9534 attr_type == DPROV_CKA_KEY_TYPE ||
9535 attr_type == DPROV_CKA_CLASS) {
9536 if (oa_value_len < value_len) {
9537 #ifdef _BIG_ENDIAN
9538 offset = value_len - oa_value_len;
9539 #endif
9540 bzero(value, value_len);
9541 goto do_copy;
9544 /* incorrect attribute value length */
9545 return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
9548 do_copy:
9549 bcopy(object->do_attr[attr_idx].oa_value, (uchar_t *)value + offset,
9550 oa_value_len);
9552 return (CRYPTO_SUCCESS);
9556 * Get the value of the a boolean attribute from the specified object.
9558 static int
9559 dprov_get_object_attr_boolean(dprov_object_t *object, uint64_t attr_type,
9560 boolean_t *attr_value)
9562 uchar_t val;
9563 int ret;
9565 /* PKCS#11 defines a boolean as one byte */
9566 ret = dprov_get_object_attr_scalar_common(object, attr_type, &val, 1);
9567 if (ret == CRYPTO_SUCCESS) {
9568 *attr_value = (val == '\0') ? B_FALSE : B_TRUE;
9570 return (ret);
9574 * Get the value of a ulong_t attribute from the specified object.
9576 static int
9577 dprov_get_object_attr_ulong(dprov_object_t *object, uint64_t attr_type,
9578 ulong_t *attr_value)
9580 return (dprov_get_object_attr_scalar_common(object, attr_type,
9581 attr_value, sizeof (ulong_t)));
9585 * Find the specified byte array attribute of specified type in
9586 * the specified object. Returns CRYPTO_SUCCESS
9587 * on success or CRYPTO_ARGUMENTS_BAD if the specified
9588 * attribute cannot be found.
9590 static int
9591 dprov_get_object_attr_array(dprov_object_t *object, uint64_t attr_type,
9592 void **array, size_t *len)
9594 int attr_idx;
9596 if ((attr_idx = dprov_find_attr(object->do_attr, DPROV_MAX_ATTR,
9597 attr_type)) == -1)
9598 return (CRYPTO_ARGUMENTS_BAD);
9600 *array = object->do_attr[attr_idx].oa_value;
9601 *len = object->do_attr[attr_idx].oa_value_len;
9603 return (CRYPTO_SUCCESS);
9607 * Common function used by the dprov_get_template_attr_*() family of
9608 * functions. Returns the value of the specified attribute of specified
9609 * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID
9610 * if the length of the attribute does not match the specified length,
9611 * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found.
9613 static int
9614 dprov_get_template_attr_scalar_common(crypto_object_attribute_t *template,
9615 uint_t nattr, uint64_t attr_type, void *value, size_t value_len)
9617 size_t oa_value_len;
9618 size_t offset = 0;
9619 int attr_idx;
9621 if ((attr_idx = dprov_find_attr(template, nattr, attr_type)) == -1)
9622 return (CRYPTO_ARGUMENTS_BAD);
9624 oa_value_len = template[attr_idx].oa_value_len;
9625 if (oa_value_len != value_len) {
9627 * For some attributes, it's okay to copy the value
9628 * into a larger container, e.g. copy an unsigned
9629 * 32-bit integer into a 64-bit container.
9631 if (attr_type == DPROV_CKA_VALUE_LEN ||
9632 attr_type == DPROV_CKA_KEY_TYPE ||
9633 attr_type == DPROV_CKA_CLASS) {
9634 if (oa_value_len < value_len) {
9635 #ifdef _BIG_ENDIAN
9636 offset = value_len - oa_value_len;
9637 #endif
9638 bzero(value, value_len);
9639 goto do_copy;
9642 /* incorrect attribute value length */
9643 return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
9646 do_copy:
9647 bcopy(template[attr_idx].oa_value, (uchar_t *)value + offset,
9648 oa_value_len);
9650 return (CRYPTO_SUCCESS);
9654 * Get the value of the a boolean attribute from the specified template
9656 static int
9657 dprov_get_template_attr_boolean(crypto_object_attribute_t *template,
9658 uint_t nattr, uint64_t attr_type, boolean_t *attr_value)
9660 uchar_t val;
9661 int ret;
9663 /* PKCS#11 defines a boolean as one byte */
9664 ret = dprov_get_template_attr_scalar_common(template, nattr,
9665 attr_type, &val, 1);
9666 if (ret == CRYPTO_SUCCESS) {
9667 *attr_value = (val == '\0') ? B_FALSE : B_TRUE;
9669 return (ret);
9673 * Get the value of a ulong_t attribute from the specified template.
9675 static int
9676 dprov_get_template_attr_ulong(crypto_object_attribute_t *template,
9677 uint_t nattr, uint64_t attr_type, ulong_t *attr_value)
9679 return (dprov_get_template_attr_scalar_common(template, nattr,
9680 attr_type, attr_value, sizeof (ulong_t)));
9683 static int
9684 dprov_template_attr_present(crypto_object_attribute_t *template,
9685 uint_t nattr, uint64_t attr_type)
9687 return (dprov_find_attr(template, nattr,
9688 attr_type) == -1 ? B_FALSE : B_TRUE);
9692 * Find the specified byte array attribute of specified type in
9693 * the specified template. Returns CRYPTO_SUCCESS on success or
9694 * CRYPTO_ARGUMENTS_BAD if the specified attribute cannot be found.
9696 static int
9697 dprov_get_template_attr_array(crypto_object_attribute_t *template,
9698 uint_t nattr, uint64_t attr_type, void **array, size_t *len)
9700 int attr_idx;
9702 if ((attr_idx = dprov_find_attr(template, nattr, attr_type)) == -1)
9703 return (CRYPTO_ARGUMENTS_BAD);
9705 *array = template[attr_idx].oa_value;
9706 *len = template[attr_idx].oa_value_len;
9708 return (CRYPTO_SUCCESS);
9712 * Common function used by the dprov_get_key_attr_*() family of
9713 * functions. Returns the value of the specified attribute of specified
9714 * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID
9715 * if the length of the attribute does not match the specified length,
9716 * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found.
9718 static int
9719 dprov_get_key_attr_scalar_common(crypto_key_t *key, uint64_t attr_type,
9720 void *value, size_t value_len)
9722 int attr_idx;
9724 ASSERT(key->ck_format == CRYPTO_KEY_ATTR_LIST);
9726 if ((attr_idx = dprov_find_attr(key->ck_attrs, key->ck_count,
9727 attr_type)) == -1)
9728 return (CRYPTO_ARGUMENTS_BAD);
9730 if (key->ck_attrs[attr_idx].oa_value_len != value_len)
9731 /* incorrect attribute value length */
9732 return (CRYPTO_ATTRIBUTE_VALUE_INVALID);
9734 bcopy(key->ck_attrs[attr_idx].oa_value, value, value_len);
9736 return (CRYPTO_SUCCESS);
9740 * Get the value of a ulong_t attribute from the specified key.
9742 static int
9743 dprov_get_key_attr_ulong(crypto_key_t *key, uint64_t attr_type,
9744 ulong_t *attr_value)
9746 return (dprov_get_key_attr_scalar_common(key, attr_type,
9747 attr_value, sizeof (ulong_t)));
9751 * Find the specified byte array attribute of specified type in
9752 * the specified key by attributes. Returns CRYPTO_SUCCESS
9753 * on success or CRYPTO_ARGUMENTS_BAD if the specified
9754 * attribute cannot be found.
9756 static int
9757 dprov_get_key_attr_array(crypto_key_t *key, uint64_t attr_type,
9758 void **array, size_t *len)
9760 int attr_idx;
9762 ASSERT(key->ck_format == CRYPTO_KEY_ATTR_LIST);
9764 if ((attr_idx = dprov_find_attr(key->ck_attrs, key->ck_count,
9765 attr_type)) == -1)
9766 return (CRYPTO_ARGUMENTS_BAD);
9768 *array = key->ck_attrs[attr_idx].oa_value;
9769 *len = key->ck_attrs[attr_idx].oa_value_len;
9771 return (CRYPTO_SUCCESS);
9774 static void
9775 dprov_release_session_objects(dprov_session_t *session)
9777 dprov_object_t *object;
9778 int i;
9780 for (i = 0; i < DPROV_MAX_OBJECTS; i++) {
9781 object = session->ds_objects[i];
9782 if (object != NULL) {
9783 DPROV_OBJECT_REFRELE(object);
9789 * Adjust an attribute list by turning 32-bit values into 64-bit values
9790 * for certain attributes like CKA_CLASS. Assumes that at least 8 bytes
9791 * of storage have been allocated for all attributes.
9793 static void
9794 dprov_adjust_attrs(crypto_object_attribute_t *in, int in_count)
9796 int i;
9797 size_t offset = 0;
9798 ulong_t tmp = 0;
9800 for (i = 0; i < in_count; i++) {
9802 * For some attributes, it's okay to copy the value
9803 * into a larger container, e.g. copy an unsigned
9804 * 32-bit integer into a 64-bit container.
9806 if (in[i].oa_type == CKA_VALUE_LEN ||
9807 in[i].oa_type == CKA_KEY_TYPE ||
9808 in[i].oa_type == CKA_CLASS) {
9809 if (in[i].oa_value_len < sizeof (ulong_t)) {
9810 #ifdef _BIG_ENDIAN
9811 offset = sizeof (ulong_t) - in[i].oa_value_len;
9812 #endif
9813 bcopy(in[i].oa_value, (uchar_t *)&tmp + offset,
9814 in[i].oa_value_len);
9815 bcopy(&tmp, in[i].oa_value, sizeof (ulong_t));
9816 in[i].oa_value_len = sizeof (ulong_t);