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]
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
44 * - support for async requests
45 * - cipher entry points
48 * - verify entry points
49 * - dual operations entry points
50 * - dual cipher/mac operation entry points
51 * - session 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>
76 #include <sys/sunddi.h>
78 #include <sys/errno.h>
79 #include <sys/ksynch.h>
83 #include <sys/model.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>
92 #include <sys/sysmacros.h>
93 #include <sys/crypto/impl.h>
94 #include <sys/crypto/sched_impl.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>
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; }
128 #define DPROV_DEBUG(f, x)
129 #define DPROV_CALL(f, r, x)
132 static int nostore_key_gen
;
133 static boolean_t dprov_no_multipart
= B_FALSE
;
134 static int dprov_max_digestsz
= INT_MAX
;
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 **);
146 static struct cb_ops cbops
= {
148 nodev
, /* cb_close */
149 nodev
, /* cb_strategy */
150 nodev
, /* cb_print */
153 nodev
, /* cb_write */
154 nodev
, /* cb_ioctl */
155 nodev
, /* cb_devmap */
157 nodev
, /* cb_segmap */
158 nochpoll
, /* cb_chpoll */
159 ddi_prop_op
, /* cb_prop_op */
160 NULL
, /* cb_streamtab */
163 nodev
, /* cb_aread */
164 nodev
, /* cb_awrite */
167 static struct dev_ops devops
= {
168 DEVO_REV
, /* devo_rev */
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
= {
184 "Pseudo KCF Prov (drv)",
188 static struct modlcrypto modlcrypto
= {
190 "Pseudo KCF Prov (crypto)"
193 static struct modlinkage modlinkage
= {
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 */
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
[] = {
320 {SUN_CKM_MD4
, MD4_MECH_INFO_TYPE
,
321 CRYPTO_FG_DIGEST
| CRYPTO_FG_DIGEST_ATOMIC
, 0, 0,
322 CRYPTO_KEYSIZE_UNIT_IN_BITS
},
324 {SUN_CKM_MD5
, MD5_MECH_INFO_TYPE
,
325 CRYPTO_FG_DIGEST
| CRYPTO_FG_DIGEST_ATOMIC
, 0, 0,
326 CRYPTO_KEYSIZE_UNIT_IN_BITS
},
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
},
346 {SUN_CKM_SHA1
, SHA1_MECH_INFO_TYPE
,
347 CRYPTO_FG_DIGEST
| CRYPTO_FG_DIGEST_ATOMIC
, 0, 0,
348 CRYPTO_KEYSIZE_UNIT_IN_BITS
},
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
},
368 {SUN_CKM_SHA256
, SHA256_MECH_INFO_TYPE
,
369 CRYPTO_FG_DIGEST
| CRYPTO_FG_DIGEST_ATOMIC
, 0, 0,
370 CRYPTO_KEYSIZE_UNIT_IN_BITS
},
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
},
390 {SUN_CKM_SHA384
, SHA384_MECH_INFO_TYPE
,
391 CRYPTO_FG_DIGEST
| CRYPTO_FG_DIGEST_ATOMIC
, 0, 0,
392 CRYPTO_KEYSIZE_UNIT_IN_BITS
},
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
},
412 {SUN_CKM_SHA512
, SHA512_MECH_INFO_TYPE
,
413 CRYPTO_FG_DIGEST
| CRYPTO_FG_DIGEST_ATOMIC
, 0, 0,
414 CRYPTO_KEYSIZE_UNIT_IN_BITS
},
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
},
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
},
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
},
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
},
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
},
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
},
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
},
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
},
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
},
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
},
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
},
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
},
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
},
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
},
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
},
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
},
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
},
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
},
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
},
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
},
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
},
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
},
637 {DPROV_CKM_ECDH1_DERIVE
, ECDH1_DERIVE_MECH_INFO_TYPE
,
638 CRYPTO_FG_DERIVE
, 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS
}
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
= {
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
= {
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
= {
772 dprov_encrypt_update
,
774 dprov_encrypt_atomic
,
777 dprov_decrypt_update
,
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
= {
808 dprov_sign_recover_init
,
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
= {
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
,
902 dprov_encrypt_mac_update
,
903 dprov_encrypt_mac_final
,
904 dprov_encrypt_mac_atomic
,
905 dprov_mac_decrypt_init
,
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
= {
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
= {
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
= {
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
,
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
= {
995 dprov_key_generate_pair
,
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
= {
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
= {
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
= {
1062 &dprov_cipher_mac_ops
,
1063 &dprov_random_number_ops
,
1067 &dprov_management_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
1087 * Token objects are identified by having a CKA_TOKEN attribute B_TRUE.
1088 * Private objects are identified by having a CKA_PRIVATE attribute
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 */
1111 * If a session has a reference to a dprov_object_t,
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); \
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 */
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 */
1223 static crypto_provider_info_t dprov_prov_info
= {
1224 CRYPTO_SPI_VERSION_2
,
1225 "Dummy Pseudo HW Provider",
1227 NULL
, /* pi_provider_dev */
1228 NULL
, /* pi_provider_handle */
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 */
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 */
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.
1266 typedef enum dprov_req_type
{
1267 /* digest requests */
1268 DPROV_REQ_DIGEST_INIT
= 1,
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
,
1277 DPROV_REQ_ENCRYPT_UPDATE
,
1278 DPROV_REQ_ENCRYPT_FINAL
,
1279 DPROV_REQ_ENCRYPT_ATOMIC
,
1280 DPROV_REQ_DECRYPT_INIT
,
1282 DPROV_REQ_DECRYPT_UPDATE
,
1283 DPROV_REQ_DECRYPT_FINAL
,
1284 DPROV_REQ_DECRYPT_ATOMIC
,
1288 DPROV_REQ_MAC_UPDATE
,
1289 DPROV_REQ_MAC_FINAL
,
1290 DPROV_REQ_MAC_ATOMIC
,
1291 DPROV_REQ_MAC_VERIFY_ATOMIC
,
1293 DPROV_REQ_SIGN_INIT
,
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
,
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
,
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
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
;
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
;
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
;
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
{
1436 crypto_session_id_t rr_session_id
;
1437 uint_t rr_entropy_est
;
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
;
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
;
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
;
1483 /* for DPROV_REQ_MGMT requests */
1484 typedef struct dprov_mgmt_req
{
1485 crypto_session_id_t mr_session_id
;
1489 size_t mr_old_pin_len
;
1491 crypto_provider_ext_info_t
*mr_ext_info
;
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
;
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
;
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
*,
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
,
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,
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 **,
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 **,
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
,
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
,
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
1647 typedef enum dprov_ctx_type
{
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
;
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 */
1705 DPROV_DEBUG(D_INIT
, ("dprov: in _init\n"));
1707 if ((error
= ddi_soft_state_init(&statep
, sizeof (dprov_state_t
),
1711 return (mod_install(&modlinkage
));
1719 DPROV_DEBUG(D_INIT
, ("dprov: in _fini\n"));
1721 if ((error
= mod_remove(&modlinkage
)) != 0)
1724 ddi_soft_state_fini(&statep
);
1730 _info(struct modinfo
*modinfop
)
1732 DPROV_DEBUG(D_INIT
, ("dprov: in _info\n"));
1734 return (mod_info(&modlinkage
, modinfop
));
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",
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
);
1761 dprov_attach(dev_info_t
*dip
, ddi_attach_cmd_t cmd
)
1763 int instance
= ddi_get_instance(dip
);
1764 dprov_state_t
*softc
;
1768 DPROV_DEBUG(D_ATTACH
, ("dprov: in dprov_attach() for %d\n",
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
);
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
) {
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
);
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
;
1872 DPROV_DEBUG(D_ATTACH
, ("dprov: in dprov_detach() for %d\n",
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
)
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.
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.
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 */
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",
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 */
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",
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 */
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",
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",
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 */
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",
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 */
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",
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 */
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",
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",
2108 * Checks whether the specified mech_type is supported by mac
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
);
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 */
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",
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 */
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
,
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 */
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",
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 */
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",
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 */
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",
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 */
2275 instance
= ddi_get_instance(softc
->ds_dip
);
2276 DPROV_DEBUG(D_MAC
, ("(%d) dprov_mac_verify_atomic: started\n",
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",
2300 * Cipher (encrypt/decrypt) entry points.
2304 * Checks whether the specified mech_type is supported by cipher entry
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
);
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
);
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 */
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",
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",
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 */
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",
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 */
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",
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",
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 */
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",
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",
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 */
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
,
2483 DPROV_DEBUG(D_MAC
, ("(%d) dprov_encrypt_atomic: done err = 0x0%x\n",
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 */
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",
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",
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 */
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",
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 */
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",
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",
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 */
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",
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",
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 */
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
,
2625 DPROV_DEBUG(D_MAC
, ("(%d) dprov_decrypt_atomic: done err = 0x0%x\n",
2632 * Sign entry points.
2636 * Checks whether the specified mech_type is supported by sign/verify
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
);
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 */
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",
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 */
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",
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 */
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",
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 */
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",
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 */
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",
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 */
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",
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",
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 */
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",
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 */
2863 instance
= ddi_get_instance(softc
->ds_dip
);
2864 DPROV_DEBUG(D_SIGN
, ("(%d) dprov_sign_recover_atomic: started\n",
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
));
2881 * Verify entry points.
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 */
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",
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 */
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",
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 */
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",
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",
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 */
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",
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 */
2998 instance
= ddi_get_instance(softc
->ds_dip
);
2999 DPROV_DEBUG(D_VERIFY
, ("(%d) dprov_verify_atomic: started\n",
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",
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 */
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",
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
));
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 */
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",
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",
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 */
3085 instance
= ddi_get_instance(softc
->ds_dip
);
3086 DPROV_DEBUG(D_VERIFY
, ("(%d) dprov_verify_recover_atomic: started\n",
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
));
3103 * Dual operations entry points.
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 */
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",
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
));
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 */
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",
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
));
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 */
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",
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
));
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 */
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",
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
));
3219 * Dual cipher-mac entry points.
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 */
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",
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
));
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 */
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",
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
));
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 */
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",
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
));
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 */
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",
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
));
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 */
3361 instance
= ddi_get_instance(softc
->ds_dip
);
3362 DPROV_DEBUG(D_CIPHER_MAC
, ("(%d) dprov_encrypt_mac_atomic: started\n",
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
));
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 */
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",
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
));
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 */
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",
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
));
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 */
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",
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
));
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 */
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",
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
));
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 */
3528 instance
= ddi_get_instance(softc
->ds_dip
);
3529 DPROV_DEBUG(D_CIPHER_MAC
, ("(%d) dprov_mac_decrypt_atomic: started\n",
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
));
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 */
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
));
3608 * Random number entry points.
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 */
3621 instance
= ddi_get_instance(softc
->ds_dip
);
3622 DPROV_DEBUG(D_RANDOM
, ("(%d) dprov_seed_random: started\n",
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",
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 */
3643 instance
= ddi_get_instance(softc
->ds_dip
);
3644 DPROV_DEBUG(D_RANDOM
, ("(%d) dprov_generate_random: started\n",
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
));
3657 * Session Management entry points.
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 */
3669 instance
= ddi_get_instance(softc
->ds_dip
);
3670 DPROV_DEBUG(D_SESSION
, ("(%d) dprov_session_open: started\n",
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",
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 */
3691 instance
= ddi_get_instance(softc
->ds_dip
);
3692 DPROV_DEBUG(D_SESSION
, ("(%d) dprov_session_close: started\n",
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",
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 */
3714 instance
= ddi_get_instance(softc
->ds_dip
);
3715 DPROV_DEBUG(D_SESSION
, ("(%d) dprov_session_login: started\n",
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",
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 */
3736 instance
= ddi_get_instance(softc
->ds_dip
);
3737 DPROV_DEBUG(D_SESSION
, ("(%d) dprov_session_logout: started\n",
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",
3750 * Object management entry points.
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 */
3764 instance
= ddi_get_instance(softc
->ds_dip
);
3765 DPROV_DEBUG(D_OBJECT
, ("(%d) dprov_object_create: started\n",
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",
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 */
3790 instance
= ddi_get_instance(softc
->ds_dip
);
3791 DPROV_DEBUG(D_OBJECT
, ("(%d) dprov_object_copy: started\n",
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",
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 */
3815 instance
= ddi_get_instance(softc
->ds_dip
);
3816 DPROV_DEBUG(D_OBJECT
, ("(%d) dprov_object_destroy: started\n",
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
,
3824 DPROV_DEBUG(D_OBJECT
, ("(%d) dprov_object_destroy: done err = 0x0%x\n",
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 */
3840 instance
= ddi_get_instance(softc
->ds_dip
);
3841 DPROV_DEBUG(D_OBJECT
, ("(%d) dprov_object_get_size: started\n",
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
,
3849 DPROV_DEBUG(D_OBJECT
, ("(%d) dprov_object_get_size: done err = 0x0%x\n",
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 */
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
));
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 */
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
));
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 */
3918 instance
= ddi_get_instance(softc
->ds_dip
);
3919 DPROV_DEBUG(D_OBJECT
, ("(%d) dprov_object_find_init: started\n",
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
));
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 */
3943 instance
= ddi_get_instance(softc
->ds_dip
);
3944 DPROV_DEBUG(D_OBJECT
, ("(%d) dprov_object_find: started\n",
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",
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 */
3968 instance
= ddi_get_instance(softc
->ds_dip
);
3969 DPROV_DEBUG(D_OBJECT
, ("(%d) dprov_object_find_final: started\n",
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
));
3984 * Key management entry points.
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 */
3998 instance
= ddi_get_instance(softc
->ds_dip
);
3999 DPROV_DEBUG(D_KEY
, ("(%d) dprov_key_generate: started\n",
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",
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 */
4028 instance
= ddi_get_instance(softc
->ds_dip
);
4029 DPROV_DEBUG(D_KEY
, ("(%d) dprov_key_generate_pair: started\n",
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,
4039 DPROV_DEBUG(D_KEY
, ("(%d) dprov_key_generate_pair: done err = 0x0%x\n",
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 */
4056 instance
= ddi_get_instance(softc
->ds_dip
);
4057 DPROV_DEBUG(D_KEY
, ("(%d) dprov_key_wrap: started\n",
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
,
4066 DPROV_DEBUG(D_KEY
, ("(%d) dprov_key_wrap: done err = 0x0%x\n",
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 */
4084 instance
= ddi_get_instance(softc
->ds_dip
);
4085 DPROV_DEBUG(D_KEY
, ("(%d) dprov_key_unwrap: started\n",
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
,
4094 DPROV_DEBUG(D_KEY
, ("(%d) dprov_key_unwrap: done err = 0x0%x\n",
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 */
4111 instance
= ddi_get_instance(softc
->ds_dip
);
4112 DPROV_DEBUG(D_KEY
, ("(%d) dprov_key_derive: started\n",
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",
4127 * Provider management entry points.
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 */
4139 instance
= ddi_get_instance(softc
->ds_dip
);
4140 DPROV_DEBUG(D_MGMT
, ("(%d) dprov_ext_info: started\n",
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",
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 */
4161 instance
= ddi_get_instance(softc
->ds_dip
);
4162 DPROV_DEBUG(D_MGMT
, ("(%d) dprov_init_token: started\n",
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",
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 */
4184 instance
= ddi_get_instance(softc
->ds_dip
);
4185 DPROV_DEBUG(D_MGMT
, ("(%d) dprov_init_pin: started\n",
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",
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 */
4207 instance
= ddi_get_instance(softc
->ds_dip
);
4208 DPROV_DEBUG(D_MGMT
, ("(%d) dprov_set_pin: started\n",
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",
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.
4233 dprov_alloc_context(dprov_req_type_t req_type
, crypto_ctx_t
*spi_ctx
)
4235 dprov_ctx_single_t
*dprov_private
;
4238 case DPROV_REQ_ENCRYPT_MAC_INIT
:
4239 case DPROV_REQ_MAC_DECRYPT_INIT
:
4240 dprov_private
= kmem_zalloc(sizeof (dprov_ctx_dual_t
),
4242 if (dprov_private
== NULL
)
4243 return (CRYPTO_HOST_MEMORY
);
4244 dprov_private
->dc_type
= DPROV_CTX_DUAL
;
4247 dprov_private
= kmem_zalloc(sizeof (dprov_ctx_single_t
),
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
;
4256 spi_ctx
->cc_provider_private
= (void *)dprov_private
;
4258 return (CRYPTO_SUCCESS
);
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
));
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.
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
;
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
;
4342 out_mech
->cm_type
= STRUCT_FGET(mech
, cm_type
);
4343 out_mech
->cm_param
= NULL
;
4344 out_mech
->cm_param_len
= 0;
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
;
4354 nonce_len
= STRUCT_FGET(params
, ulNonceSize
);
4355 auth_data_len
= STRUCT_FGET(params
, ulAuthDataSize
);
4357 /* allocate param structure */
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
;
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
;
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
;
4389 out_mech
->cm_param
= (char *)aes_ccm_params
;
4390 out_mech
->cm_param_len
= sizeof (CK_AES_CCM_PARAMS
);
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.
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
;
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
;
4428 out_mech
->cm_type
= STRUCT_FGET(mech
, cm_type
);
4429 out_mech
->cm_param
= NULL
;
4430 out_mech
->cm_param_len
= 0;
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
;
4440 nonce_len
= STRUCT_FGET(params
, ulIvLen
);
4441 auth_data_len
= STRUCT_FGET(params
, ulAADLen
);
4443 /* allocate param structure */
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
;
4451 aes_gcm_params
->ulTagBits
= STRUCT_FGET(params
, ulTagBits
);
4452 aes_gcm_params
->ulIvLen
= nonce_len
;
4453 aes_gcm_params
->ulAADLen
= auth_data_len
;
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
;
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
;
4472 out_mech
->cm_param
= (char *)aes_gcm_params
;
4473 out_mech
->cm_param_len
= sizeof (CK_AES_GCM_PARAMS
);
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
;
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
;
4503 out_mech
->cm_type
= STRUCT_FGET(mech
, cm_type
);
4504 out_mech
->cm_param
= NULL
;
4505 out_mech
->cm_param_len
= 0;
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
;
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
;
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
;
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
;
4544 out_mech
->cm_param
= (char *)aes_gmac_params
;
4545 out_mech
->cm_param_len
= sizeof (CK_AES_GMAC_PARAMS
);
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.
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
;
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
;
4583 out_mech
->cm_type
= STRUCT_FGET(mech
, cm_type
);
4584 out_mech
->cm_param
= NULL
;
4585 out_mech
->cm_param_len
= 0;
4587 if (copyin((char *)pp
, STRUCT_BUF(params
), param_len
) != 0) {
4588 out_mech
->cm_param
= NULL
;
4592 /* allocate param structure and counter block */
4593 aes_ctr_params
= kmem_alloc(sizeof (CK_AES_CTR_PARAMS
),
4595 if (aes_ctr_params
== NULL
) {
4596 rv
= CRYPTO_HOST_MEMORY
;
4599 aes_ctr_params
->ulCounterBits
= STRUCT_FGET(params
,
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
);
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
;
4618 size_t param_len
, shared_data_len
, public_data_len
;
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
;
4633 out_mech
->cm_type
= STRUCT_FGET(mech
, cm_type
);
4634 out_mech
->cm_param
= NULL
;
4635 out_mech
->cm_param_len
= 0;
4637 if (copyin((char *)pp
, STRUCT_BUF(params
), param_len
) != 0) {
4638 out_mech
->cm_param
= NULL
;
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
;
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
;
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
;
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
);
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
);
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
;
4708 if (copyin((char *)pp
, STRUCT_BUF(params
), param_len
) != 0) {
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) {
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
;
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
;
4753 case BLOWFISH_CBC_MECH_INFO_TYPE
:
4754 expected_param_len
= BLOWFISH_BLOCK_LEN
;
4757 case AES_CBC_MECH_INFO_TYPE
:
4758 expected_param_len
= AES_BLOCK_LEN
;
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
);
4766 case ECDH1_DERIVE_MECH_INFO_TYPE
:
4767 rv
= copyin_ecc_mech(umech
, kmech
, &error
, mode
);
4770 case AES_CCM_MECH_INFO_TYPE
:
4771 rv
= copyin_aes_ccm_mech(umech
, kmech
, &error
, mode
);
4774 case AES_GCM_MECH_INFO_TYPE
:
4775 rv
= copyin_aes_gcm_mech(umech
, kmech
, &error
, mode
);
4778 case AES_GMAC_MECH_INFO_TYPE
:
4779 rv
= copyin_aes_gmac_mech(umech
, kmech
, &error
, mode
);
4782 case DH_PKCS_DERIVE_MECH_INFO_TYPE
:
4783 expected_param_len
= param_len
;
4787 /* nothing to do - mechanism has no parameters */
4788 rv
= CRYPTO_SUCCESS
;
4792 if (param_len
!= expected_param_len
) {
4793 rv
= CRYPTO_MECHANISM_PARAM_INVALID
;
4797 rv
= CRYPTO_MECHANISM_PARAM_INVALID
;
4800 if ((param
= kmem_alloc(param_len
, KM_NOSLEEP
)) == NULL
) {
4801 rv
= CRYPTO_HOST_MEMORY
;
4804 if (copyin((char *)pp
, param
, param_len
) != 0) {
4805 kmem_free(param
, param_len
);
4810 kmech
->cm_param
= (char *)param
;
4811 kmech
->cm_param_len
= param_len
;
4812 rv
= CRYPTO_SUCCESS
;
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
);
4833 return (CRYPTO_MECHANISM_INVALID
);
4838 * Free mechanism parameter that was allocated by the provider.
4842 dprov_free_mechanism(crypto_provider_handle_t provider
,
4843 crypto_mechanism_t
*mech
)
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
);
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
);
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.
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 */
4933 instance
= ddi_get_instance(softc
->ds_dip
);
4934 DPROV_DEBUG(D_KEY
, ("(%d) dprov_nostore_key_generate: started\n",
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
));
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 */
4967 instance
= ddi_get_instance(softc
->ds_dip
);
4968 DPROV_DEBUG(D_KEY
, ("(%d) dprov_nostore_key_generate_pair: started\n",
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
));
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 */
4997 instance
= ddi_get_instance(softc
->ds_dip
);
4998 DPROV_DEBUG(D_KEY
, ("(%d) dprov_nostore_key_derive: started\n",
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
,
5007 DPROV_DEBUG(D_KEY
, ("(%d) dprov_nostore_key_derive: "
5008 "done err = 0x0%x\n", instance
, 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
)
5026 taskq_req
->dr_type
= req_type
;
5027 taskq_req
->dr_softc
= softc
;
5028 taskq_req
->dr_kcf_req
= kcf_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.
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
);
5047 return (CRYPTO_QUEUED
);
5051 * Helper function to submit digest operations to the taskq.
5052 * Returns one of the CRYPTO_ errors.
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.
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.
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
,
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.
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
,
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.
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.
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.
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
,
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.
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.
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.
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
,
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.
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.
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.
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.
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 */
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
)) !=
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
)
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
);
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
);
5466 case DPROV_REQ_DIGEST_UPDATE
:
5467 error
= crypto_digest_update(DPROV_CTX_SINGLE(ctx
),
5468 taskq_req
->dr_digest_req
.dr_data
, NULL
);
5471 case DPROV_REQ_DIGEST_KEY
: {
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
)
5483 /* key lengths are specified in bits */
5484 len
= CRYPTO_BITS2BYTES(key
.ck_length
);
5485 data
.cd_format
= CRYPTO_DATA_RAW
;
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
),
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
);
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
)
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
);
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.
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 */
5539 int error
= CRYPTO_NOT_SUPPORTED
;
5540 crypto_ctx_t
*ctx
= taskq_req
->dr_mac_req
.dr_ctx
;
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
)) !=
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
)
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
)
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
);
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
);
5591 case DPROV_REQ_MAC_UPDATE
:
5592 error
= crypto_mac_update(DPROV_CTX_SINGLE(ctx
),
5593 taskq_req
->dr_mac_req
.dr_data
, NULL
);
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
);
5605 case DPROV_REQ_MAC_ATOMIC
:
5606 case DPROV_REQ_MAC_VERIFY_ATOMIC
:
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
)
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
)
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
);
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
);
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.
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 */
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
)) !=
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
);
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
);
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
)
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
);
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
);
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
);
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
);
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
);
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
);
5754 error
= crypto_sign_update(DPROV_CTX_SINGLE(ctx
),
5755 taskq_req
->dr_sign_req
.sr_data
, NULL
);
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
);
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
);
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
,
5785 taskq_req
->dr_sign_req
.sr_key
, &key
))
5786 != CRYPTO_SUCCESS
) {
5787 mutex_exit(&softc
->ds_lock
);
5792 if ((error
= dprov_key_value_secret(softc
,
5793 taskq_req
->dr_sign_req
.sr_session_id
,
5795 taskq_req
->dr_sign_req
.sr_key
, &key
))
5796 != CRYPTO_SUCCESS
) {
5797 mutex_exit(&softc
->ds_lock
);
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
)
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
);
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
);
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
);
5836 dprov_op_done(taskq_req
, error
);
5837 DPROV_DEBUG(D_SIGN
, ("(%d) dprov_sign_task: end\n", instance
));
5841 emulate_verify_with_mac(crypto_ctx_t
*ctx
, crypto_data_t
*in_mac
)
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
;
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
;
5866 * taskq dispatcher function for verify operations.
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 */
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
)) !=
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
);
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
);
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
)
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
);
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
);
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
);
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
);
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
);
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
);
5975 error
= crypto_verify_update(DPROV_CTX_SINGLE(ctx
),
5976 taskq_req
->dr_verify_req
.vr_data
, NULL
);
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
);
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
);
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
,
6005 taskq_req
->dr_verify_req
.vr_key
, &key
))
6006 != CRYPTO_SUCCESS
) {
6007 mutex_exit(&softc
->ds_lock
);
6012 if ((error
= dprov_key_value_secret(softc
,
6013 taskq_req
->dr_verify_req
.vr_session_id
,
6015 taskq_req
->dr_verify_req
.vr_key
, &key
))
6016 != CRYPTO_SUCCESS
) {
6017 mutex_exit(&softc
->ds_lock
);
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
)
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
);
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
);
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
);
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.
6072 dprov_dual_task(dprov_req_t
*taskq_req
)
6074 dprov_state_t
*softc
;
6075 /* LINTED E_FUNC_SET_NOT_USED */
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
);
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
);
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
);
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
);
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.
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 */
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
)) !=
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
);
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
);
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
)
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
,
6269 taskq_req
->dr_cipher_req
.dr_key
,
6270 &key
)) != CRYPTO_SUCCESS
) {
6271 mutex_exit(&softc
->ds_lock
);
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
,
6280 != CRYPTO_SUCCESS
) {
6281 mutex_exit(&softc
->ds_lock
);
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
)
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
,
6299 taskq_req
->dr_cipher_req
.dr_ciphertext
, NULL
);
6301 error
= crypto_decrypt_prov(pd
, 0, &mech
,
6302 taskq_req
->dr_cipher_req
.dr_ciphertext
,
6304 taskq_req
->dr_cipher_req
.dr_plaintext
, NULL
);
6306 /* release provider reference */
6307 KCF_PROV_REFRELE(pd
);
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.
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
)
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
);
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
)
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
)
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
);
6359 * taskq dispatcher function for cipher/mac dual operations.
6362 dprov_cipher_mac_task(dprov_req_t
*taskq_req
)
6364 dprov_state_t
*softc
;
6365 /* LINTED E_FUNC_SET_NOT_USED */
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",
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
)
6397 /* allocate a dprov-private context */
6398 if ((error
= dprov_alloc_context(taskq_req
->dr_type
, ctx
)) !=
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
);
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
)
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
)
6421 /* release references to providers */
6422 KCF_PROV_REFRELE(cipher_pd
);
6423 KCF_PROV_REFRELE(mac_pd
);
6427 case DPROV_REQ_ENCRYPT_MAC
: {
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
);
6438 plaintext_tmp
= &cipher_data
;
6439 ciphertext_tmp
= NULL
;
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
)
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
)
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
)
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
);
6487 case DPROV_REQ_ENCRYPT_MAC_UPDATE
: {
6488 crypto_data_t
*plaintext_tmp
, *ciphertext_tmp
;
6493 cipher_data
= *((crypto_data_t
*)dual_data
);
6495 /* do an encrypt update */
6496 inplace
= (taskq_req
->dr_cipher_mac_req
.mr_data
== NULL
);
6498 plaintext_tmp
= &cipher_data
;
6499 ciphertext_tmp
= NULL
;
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
)
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
+
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
)
6529 /* Set the total size of the ciphertext, when successful */
6530 if (error
== CRYPTO_SUCCESS
)
6531 dual_data
->dd_len1
= encrypted
;
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
)
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
)) !=
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
);
6569 case DPROV_REQ_ENCRYPT_MAC_ATOMIC
: {
6570 crypto_data_t
*plaintext_tmp
, *ciphertext_tmp
;
6573 cipher_data
= *((crypto_data_t
*)dual_data
);
6575 /* do an encrypt atomic */
6576 inplace
= (taskq_req
->dr_cipher_mac_req
.mr_data
== NULL
);
6578 plaintext_tmp
= &cipher_data
;
6579 ciphertext_tmp
= NULL
;
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
)) !=
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
)
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
;
6615 case DPROV_REQ_MAC_DECRYPT
: {
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
)
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
)) !=
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
)
6638 plaintext_tmp
= cipher_data
;
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
)
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
;
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
);
6671 case DPROV_REQ_MAC_DECRYPT_UPDATE
:
6672 cipher_data
= *((crypto_data_t
*)dual_data
);
6675 if ((error
= crypto_mac_update(DPROV_CTX_DUAL_MAC(ctx
),
6676 &cipher_data
, NULL
)) != CRYPTO_SUCCESS
)
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
);
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
)) !=
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
);
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
)
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
);
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
)
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
);
6744 dprov_op_done(taskq_req
, error
);
6745 DPROV_DEBUG(D_CIPHER_MAC
, ("(%d) dprov_cipher_mac_task: end\n",
6750 * taskq dispatcher function for random number generation.
6753 dprov_random_task(dprov_req_t
*taskq_req
)
6755 dprov_state_t
*softc
;
6756 /* LINTED E_FUNC_SET_NOT_USED */
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
6774 case DPROV_REQ_RANDOM_GENERATE
: {
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
++;
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.
6800 dprov_session_task(dprov_req_t
*taskq_req
)
6802 dprov_state_t
*softc
;
6803 /* LINTED E_FUNC_SET_NOT_USED */
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
;
6812 DPROV_SOFTC_FROM_REQ(taskq_req
, softc
, instance
);
6813 DPROV_DEBUG(D_SESSION
, ("(%d) dprov_session_task: started\n",
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
);
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
;
6836 /* search for available session slot */
6837 for (i
= 0; i
< softc
->ds_sessions_slots
; i
++)
6838 if (softc
->ds_sessions
[i
] == NULL
)
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
;
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
;
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
;
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
;
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
;
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
;
6907 /* check pin length */
6908 if (pin_len
> DPROV_MAX_PIN_LEN
) {
6909 error
= CRYPTO_PIN_LEN_RANGE
;
6915 error
= CRYPTO_PIN_INVALID
;
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
;
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
;
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
;
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
;
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
;
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
] =
6976 /* update session state */
6977 softc
->ds_sessions
[session_id
]->ds_state
=
6978 DPROV_SESSION_STATE_PUBLIC
;
6980 error
= CRYPTO_SUCCESS
;
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 */
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
7006 attribute_size(crypto_attr_type_t type
, ssize_t len
)
7008 if (fixed_size_attribute(type
))
7009 return (sizeof (uint32_t));
7015 * taskq dispatcher function for object management operations.
7018 dprov_object_task(dprov_req_t
*taskq_req
)
7020 dprov_state_t
*softc
;
7021 /* LINTED E_FUNC_SET_NOT_USED */
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
);
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
)
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
;
7065 * Create a new object from the object passed as
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
)
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
);
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
);
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
;
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
;
7110 case DPROV_REQ_OBJECT_GET_ATTRIBUTE_VALUE
: {
7111 crypto_attr_type_t type
;
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
;
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
;
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
;
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
;
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
7175 if (!fixed_size_attribute(type
))
7176 template[tmpl_idx
].oa_value_len
= olen
;
7181 template[tmpl_idx
].oa_value_len
= -1;
7182 error
= CRYPTO_BUFFER_TOO_SMALL
;
7186 /* copy attribute value */
7187 bzero(template[tmpl_idx
].oa_value
, tlen
);
7191 if (fixed_size_attribute(type
)) {
7192 offset
= tlen
- olen
;
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
;
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
);
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
)
7233 /* setting count to zero means find all objects */
7234 if (attr_count
> 0) {
7235 if (!dprov_attributes_match(object
, template,
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
)
7259 /* setting count to zero means find all objects */
7260 if (attr_count
> 0) {
7261 if (!dprov_attributes_match(object
, template,
7266 /* if the the object has been destroyed, skip it */
7267 if (object
->do_destroyed
)
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
)
7276 * Is there already a session object id for this
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
==
7284 if (so_idx
< DPROV_MAX_OBJECTS
)
7285 /* object found in session table, skip it */
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
)
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
;
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
++;
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
;
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
;
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
;
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.
7349 nostore_copy_attribute(crypto_object_attribute_t
*template, uint_t count
,
7352 void *value
, *dprov_attribute_value
;
7353 size_t dprov_attribute_size
;
7354 size_t value_len
= 0;
7357 switch (attr_type
) {
7358 case DPROV_CKA_VALUE
:
7359 dprov_attribute_size
= sizeof (dh_value
);
7360 dprov_attribute_value
= dh_value
;
7363 case DPROV_CKA_MODULUS
:
7364 dprov_attribute_size
= sizeof (modulus
);
7365 dprov_attribute_value
= modulus
;
7368 case DPROV_CKA_PUBLIC_EXPONENT
:
7369 dprov_attribute_size
= sizeof (public_exponent
);
7370 dprov_attribute_value
= public_exponent
;
7373 case DPROV_CKA_PRIVATE_EXPONENT
:
7374 dprov_attribute_size
= sizeof (private_exponent
);
7375 dprov_attribute_value
= private_exponent
;
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
)
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
);
7399 fill_dh(void *value
, size_t len
)
7412 * taskq dispatcher function for key management operations.
7415 dprov_key_task(dprov_req_t
*taskq_req
)
7417 dprov_state_t
*softc
;
7418 /* LINTED E_FUNC_SET_NOT_USED */
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
);
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;
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
;
7456 (void) dprov_get_template_attr_ulong(template, attribute_count
,
7457 DPROV_CKA_CLASS
, &class);
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
;
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
;
7474 key_len
= DES_KEY_LEN
;
7475 key_type
= DPROV_CKK_DES
;
7478 case DES3_KEY_GEN_MECH_INFO_TYPE
:
7479 if (key_type
!= ~0UL && key_type
!= DPROV_CKK_DES3
) {
7480 error
= CRYPTO_TEMPLATE_INCONSISTENT
;
7483 key_len
= DES3_KEY_LEN
;
7484 key_type
= DPROV_CKK_DES3
;
7487 case AES_KEY_GEN_MECH_INFO_TYPE
:
7488 if (key_type
!= ~0UL && key_type
!= DPROV_CKK_AES
) {
7489 error
= CRYPTO_TEMPLATE_INCONSISTENT
;
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
;
7498 if (value_len
>= AES_MAX_KEY_LEN
) {
7499 error
= CRYPTO_ATTRIBUTE_VALUE_INVALID
;
7502 key_len
= value_len
;
7503 key_type
= DPROV_CKK_AES
;
7506 case BLOWFISH_KEY_GEN_MECH_INFO_TYPE
:
7507 if (key_type
!= ~0UL &&
7508 key_type
!= DPROV_CKK_BLOWFISH
) {
7509 error
= CRYPTO_TEMPLATE_INCONSISTENT
;
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
;
7518 if (value_len
>= BLOWFISH_MAX_KEY_LEN
) {
7519 error
= CRYPTO_ATTRIBUTE_VALUE_INVALID
;
7522 key_len
= value_len
;
7523 key_type
= DPROV_CKK_BLOWFISH
;
7526 case RC4_KEY_GEN_MECH_INFO_TYPE
:
7527 if (key_type
!= ~0UL && key_type
!= DPROV_CKK_RC4
) {
7528 error
= CRYPTO_TEMPLATE_INCONSISTENT
;
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
;
7538 CRYPTO_BITS2BYTES(ARCFOUR_MAX_KEY_BITS
)) {
7539 error
= CRYPTO_ATTRIBUTE_VALUE_INVALID
;
7542 key_len
= value_len
;
7543 key_type
= DPROV_CKK_RC4
;
7547 error
= CRYPTO_MECHANISM_INVALID
;
7550 if (error
!= CRYPTO_SUCCESS
)
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
)
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
,
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
;
7603 (void) dprov_destroy_object(softc
, session
, *object_id_ptr
);
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
;
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
;
7632 (void) dprov_get_template_attr_ulong(pub_template
,
7633 pub_attribute_count
, DPROV_CKA_CLASS
, &pub_class
);
7636 (void) dprov_get_template_attr_ulong(pri_template
,
7637 pri_attribute_count
, DPROV_CKA_CLASS
, &pri_class
);
7640 (void) dprov_get_template_attr_ulong(pub_template
,
7641 pub_attribute_count
, DPROV_CKA_KEY_TYPE
, &pub_key_type
);
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
;
7652 if (pri_class
!= ~0UL && pri_class
!= DPROV_CKO_PRIVATE_KEY
) {
7653 error
= CRYPTO_TEMPLATE_INCONSISTENT
;
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
;
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
;
7671 pri_key_type
= DPROV_CKK_RSA
;
7673 if (pub_class
!= ~0UL &&
7674 pub_class
!= DPROV_CKO_PUBLIC_KEY
) {
7675 error
= CRYPTO_TEMPLATE_INCONSISTENT
;
7678 pub_class
= DPROV_CKO_PUBLIC_KEY
;
7680 if (pri_class
!= ~0UL &&
7681 pri_class
!= DPROV_CKO_PRIVATE_KEY
) {
7682 error
= CRYPTO_TEMPLATE_INCONSISTENT
;
7685 pri_class
= DPROV_CKO_PRIVATE_KEY
;
7689 error
= CRYPTO_MECHANISM_INVALID
;
7692 if (error
!= CRYPTO_SUCCESS
)
7695 error
= dprov_create_object_from_template(softc
, session
,
7696 pub_template
, pub_attribute_count
, pub_object_id_ptr
,
7699 if (error
!= CRYPTO_SUCCESS
)
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
,
7748 if (error
!= CRYPTO_SUCCESS
)
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
;
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
);
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
;
7812 char *plaintext_key
;
7813 size_t plaintext_key_len
;
7814 crypto_data_t plaintext
;
7815 crypto_data_t ciphertext
;
7818 mechp
= taskq_req
->dr_key_req
.kr_mechanism
;
7819 /* structure assignment */
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
)
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
)
7839 /* get the software provider for this mechanism */
7840 if ((error
= dprov_get_sw_prov(mechp
, &pd
,
7841 &mech
.cm_type
)) != CRYPTO_SUCCESS
)
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
;
7850 /* get ptr to object */
7851 if ((object
= session
->ds_objects
[object_id
]) == NULL
) {
7852 error
= CRYPTO_OBJECT_HANDLE_INVALID
;
7856 (void) dprov_get_object_attr_boolean(object
,
7857 DPROV_CKA_EXTRACTABLE
, &extractable
);
7860 error
= CRYPTO_ATTRIBUTE_SENSITIVE
;
7864 (void) dprov_get_object_attr_ulong(object
,
7865 DPROV_CKA_CLASS
, &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
;
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
;
7892 error
= CRYPTO_KEY_NOT_WRAPPABLE
;
7895 if (error
!= CRYPTO_SUCCESS
)
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
;
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
;
7954 mechp
= taskq_req
->dr_key_req
.kr_mechanism
;
7955 /* structure assignment */
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
)
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
)
7975 /* get the software provider for this mechanism */
7976 if ((error
= dprov_get_sw_prov(mechp
, &pd
,
7977 &mech
.cm_type
)) != CRYPTO_SUCCESS
)
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
;
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
;
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
;
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 */
8042 (void) dprov_destroy_object(softc
, session
, *object_id_ptr
);
8046 bzero(plaintext_buf
, wrapped_key_len
);
8047 kmem_free(plaintext_buf
, wrapped_key_len
);
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
;
8056 crypto_data_t digest
;
8059 crypto_object_attribute_t derived_key
;
8060 crypto_object_attribute_t
*template;
8061 uint_t attribute_count
;
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
;
8073 if (dprov_get_template_attr_ulong(template, attribute_count
,
8074 DPROV_CKA_KEY_TYPE
, &key_type
) != CRYPTO_SUCCESS
) {
8075 error
= CRYPTO_TEMPLATE_INCOMPLETE
;
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
;
8089 case SHA256_KEY_DERIVATION_MECH_INFO_TYPE
:
8090 hash_size
= SHA256_DIGEST_LENGTH
;
8091 digest_mech
.cm_type
= SHA256_MECH_INFO_TYPE
;
8094 case SHA384_KEY_DERIVATION_MECH_INFO_TYPE
:
8095 hash_size
= SHA384_DIGEST_LENGTH
;
8096 digest_mech
.cm_type
= SHA384_MECH_INFO_TYPE
;
8099 case SHA512_KEY_DERIVATION_MECH_INFO_TYPE
:
8100 hash_size
= SHA512_DIGEST_LENGTH
;
8101 digest_mech
.cm_type
= SHA512_MECH_INFO_TYPE
;
8104 case MD5_KEY_DERIVATION_MECH_INFO_TYPE
:
8105 hash_size
= MD5_DIGEST_LEN
;
8106 digest_mech
.cm_type
= MD5_MECH_INFO_TYPE
;
8110 error
= CRYPTO_MECHANISM_INVALID
;
8113 if (error
!= CRYPTO_SUCCESS
)
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 */
8122 case DPROV_CKK_GENERIC_SECRET
:
8123 if (value_len
> 0) {
8124 if (value_len
> hash_size
)
8125 error
= CRYPTO_ATTRIBUTE_VALUE_INVALID
;
8127 value_len
= hash_size
;
8133 if (value_len
== 0 ||
8134 value_len
> hash_size
) {
8135 error
= CRYPTO_ATTRIBUTE_VALUE_INVALID
;
8140 if (value_len
> 0 &&
8141 value_len
!= DES_KEY_LEN
) {
8142 error
= CRYPTO_ATTRIBUTE_VALUE_INVALID
;
8144 value_len
= DES_KEY_LEN
;
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
;
8156 error
= CRYPTO_ATTRIBUTE_VALUE_INVALID
;
8160 if (error
!= CRYPTO_SUCCESS
)
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
)
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
)
8176 data
.cd_format
= CRYPTO_DATA_RAW
;
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
,
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
,
8216 bzero(digest_buf
, hash_size
);
8217 kmem_free(digest_buf
, hash_size
);
8221 case DPROV_REQ_NOSTORE_KEY_GENERATE
: {
8222 crypto_object_attribute_t
*out_template
;
8223 uint_t out_attribute_count
;
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
)
8236 /* fill the entire array with pattern */
8240 while (i
< value_len
) {
8251 error
= CRYPTO_SUCCESS
;
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
)
8286 error
= nostore_copy_attribute(out_pub_template
,
8287 out_pub_attribute_count
, DPROV_CKA_PUBLIC_EXPONENT
);
8288 if (error
== CRYPTO_ARGUMENTS_BAD
) {
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
)
8299 error
= nostore_copy_attribute(out_pri_template
,
8300 out_pri_attribute_count
, DPROV_CKA_MODULUS
);
8301 if (error
!= CRYPTO_SUCCESS
)
8304 error
= nostore_copy_attribute(out_pri_template
,
8305 out_pri_attribute_count
,
8306 DPROV_CKA_PRIVATE_EXPONENT
);
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
);
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
;
8335 taskq_req
->dr_key_req
.kr_out_template1
;
8336 out_pub_attribute_count
=
8337 taskq_req
->dr_key_req
.kr_out_attribute_count1
;
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 */
8345 if ((error
= dprov_get_sw_prov(mechp
, &pd
,
8346 &mech
.cm_type
)) != CRYPTO_SUCCESS
)
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(¶ms
,
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
, ¶ms
,
8367 KCF_PROV_REFRELE(pd
);
8371 error
= CRYPTO_MECHANISM_INVALID
;
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
;
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
;
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
;
8411 switch (mechp
->cm_type
) {
8412 case DH_PKCS_DERIVE_MECH_INFO_TYPE
: {
8416 if (base_key
->ck_format
!= CRYPTO_KEY_ATTR_LIST
) {
8417 error
= CRYPTO_ARGUMENTS_BAD
;
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
;
8435 * CKA_VALUE is added to the derived key template by
8438 error
= CRYPTO_SUCCESS
;
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
;
8447 if (value_len
!= value_len_value
) {
8448 error
= CRYPTO_TEMPLATE_INCONSISTENT
;
8453 error
= CRYPTO_MECHANISM_INVALID
;
8455 if (error
== CRYPTO_SUCCESS
)
8456 fill_dh(value
, value_len
);
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 */
8465 if ((error
= dprov_get_sw_prov(mechp
, &pd
,
8466 &mech
.cm_type
)) != CRYPTO_SUCCESS
)
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(¶ms
,
8478 0, /* session 0 for sw provider */
8479 &mech
, in_template
, in_attribute_count
,
8481 out_template
, out_attribute_count
,
8484 error
= kcf_submit_request(pd
, NULL
, NULL
, ¶ms
,
8487 KCF_PROV_REFRELE(pd
);
8492 error
= CRYPTO_MECHANISM_INVALID
;
8496 error
= CRYPTO_MECHANISM_INVALID
;
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.
8509 dprov_mgmt_task(dprov_req_t
*taskq_req
)
8511 dprov_state_t
*softc
;
8512 /* LINTED E_FUNC_SET_NOT_USED */
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)"));
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
;
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
;
8579 /* check PIN length */
8580 if (pin_len
> DPROV_MAX_PIN_LEN
) {
8581 error
= CRYPTO_PIN_LEN_RANGE
;
8587 error
= CRYPTO_PIN_INVALID
;
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
;
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
;
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
;
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
;
8634 /* check PIN length */
8635 if (pin_len
> DPROV_MAX_PIN_LEN
) {
8636 error
= CRYPTO_PIN_LEN_RANGE
;
8642 error
= CRYPTO_PIN_INVALID
;
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
;
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
;
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
;
8676 if (old_pin
== NULL
|| new_pin
== NULL
) {
8677 error
= CRYPTO_PIN_INVALID
;
8681 /* check user PIN state */
8682 if (!softc
->ds_user_pin_set
) {
8683 error
= CRYPTO_USER_PIN_NOT_INITIALIZED
;
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
;
8699 bcopy(new_pin
, softc
->ds_user_pin
, new_pin_len
);
8700 softc
->ds_user_pin_len
= new_pin_len
;
8702 error
= CRYPTO_SUCCESS
;
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.
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
;
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
;
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).
8751 dprov_key_can_use(dprov_object_t
*object
, dprov_req_type_t req_type
)
8754 int rv
= CRYPTO_SUCCESS
;
8756 /* check if object is allowed for specified operation */
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
);
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
);
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
);
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
);
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
);
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
);
8791 case DPROV_REQ_KEY_WRAP
:
8792 rv
= dprov_get_object_attr_boolean(object
,
8793 DPROV_CKA_WRAP
, &ret
);
8795 case DPROV_REQ_KEY_UNWRAP
:
8796 rv
= dprov_get_object_attr_boolean(object
,
8797 DPROV_CKA_UNWRAP
, &ret
);
8799 case DPROV_REQ_DIGEST_KEY
:
8801 * There is no attribute to check for; therefore,
8802 * any secret key can be used.
8805 rv
= CRYPTO_SUCCESS
;
8807 case DPROV_REQ_KEY_DERIVE
:
8808 rv
= dprov_get_object_attr_boolean(object
,
8809 DPROV_CKA_DERIVE
, &ret
);
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
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.
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
)
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
;
8848 case CRYPTO_KEY_ATTR_LIST
: {
8850 size_t len
, value_len
;
8852 if ((ret
= dprov_get_key_attr_ulong(key
, DPROV_CKA_KEY_TYPE
,
8853 &key_type
)) != CRYPTO_SUCCESS
)
8856 if ((ret
= dprov_get_key_attr_array(key
, DPROV_CKA_VALUE
,
8857 &value
, &len
)) != CRYPTO_SUCCESS
)
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
);
8867 if ((dprov_get_key_attr_ulong(key
, DPROV_CKA_VALUE_LEN
,
8868 &value_len
)) == CRYPTO_SUCCESS
) {
8872 ret_key
->ck_data
= value
;
8873 ret_key
->ck_length
= (uint_t
)len
;
8878 case CRYPTO_KEY_REFERENCE
: {
8879 dprov_object_t
*object
;
8881 size_t len
, value_len
;
8883 /* check session id */
8884 if (softc
->ds_sessions
[session_id
] == NULL
) {
8885 ret
= CRYPTO_SESSION_HANDLE_INVALID
;
8889 if (key
->ck_obj_id
>= DPROV_MAX_OBJECTS
) {
8890 ret
= CRYPTO_KEY_HANDLE_INVALID
;
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
;
8902 /* check if object can be used for operation */
8903 if ((ret
= dprov_key_can_use(object
, req_type
)) !=
8907 if ((ret
= dprov_get_object_attr_ulong(object
,
8908 DPROV_CKA_KEY_TYPE
, &key_type
)) != CRYPTO_SUCCESS
)
8911 if ((ret
= dprov_get_object_attr_array(object
,
8912 DPROV_CKA_VALUE
, &value
, &len
)) != CRYPTO_SUCCESS
)
8916 if ((dprov_get_object_attr_ulong(object
, DPROV_CKA_VALUE_LEN
,
8917 &value_len
)) == CRYPTO_SUCCESS
) {
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
;
8934 ret
= CRYPTO_ARGUMENTS_BAD
;
8942 * Get the attribute list for the specified asymmetric key.
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
;
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
;
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
;
8976 /* check if object can be used for operation */
8977 if ((ret
= dprov_key_can_use(object
, req_type
)) !=
8981 ret_key
->ck_attrs
= object
->do_attr
;
8982 ret_key
->ck_count
= DPROV_MAX_ATTR
;
8987 ret
= CRYPTO_ARGUMENTS_BAD
;
8994 * Return the index of an attribute of specified type found in
8995 * the specified array of attributes. If the attribute cannot
8999 dprov_find_attr(crypto_object_attribute_t
*attr
, uint_t nattr
,
9004 for (i
= 0; i
< nattr
; i
++)
9005 if (attr
[i
].oa_value
!= NULL
&&
9006 attr
[i
].oa_type
== attr_type
)
9013 * Given the given object template and session, return whether
9014 * an object can be created from that template according to the
9016 * - private objects can be created only by a logged-in user
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;
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
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(
9090 DPROV_CKA_PRIVATE_EXPONENT
))
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
,
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
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
,
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
;
9140 crypto_attr_type_t type
;
9141 size_t old_len
, new_len
;
9144 if (nattr
> DPROV_MAX_ATTR
)
9145 return (CRYPTO_HOST_MEMORY
);
9148 /* verify that object can be created */
9149 if ((error
= dprov_template_can_create(session
, template,
9150 nattr
, check_for_secret
)) != CRYPTO_SUCCESS
)
9154 /* allocate new object */
9155 object
= kmem_zalloc(sizeof (dprov_object_t
), KM_SLEEP
);
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
)
9168 if (i
== DPROV_MAX_OBJECTS
)
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
)
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
);
9189 /* initialize object from template */
9190 for (attr
= 0, oattr
= 0; attr
< nattr
; attr
++) {
9191 if (template[attr
].oa_value
== NULL
)
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
,
9212 if (fixed_size_attribute(type
)) {
9213 offset
= old_len
- new_len
;
9216 bcopy(&template[attr
].oa_value
[offset
],
9217 object
->do_attr
[oattr
].oa_value
, new_len
);
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
;
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
;
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
;
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
;
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.
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
)
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
);
9281 /* attribute not found in object */
9284 tlen
= template[ta_idx
].oa_value_len
;
9285 olen
= object
->do_attr
[oa_idx
].oa_value_len
;
9291 /* application may think attribute is 8 bytes */
9292 if (fixed_size_attribute(type
))
9296 if (bcmp(&template[ta_idx
].oa_value
[diff
],
9297 object
->do_attr
[oa_idx
].oa_value
, olen
) != 0)
9298 /* value mismatch */
9306 * Destroy the object specified by its session and object id.
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
);
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
);
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
,
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
,
9362 return (CRYPTO_TEMPLATE_INCONSISTENT
);
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
);
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
);
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.
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
;
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
))
9413 /* go through the attributes specified in the template */
9414 for (i
= 0; i
< nattr
; i
++) {
9415 if (template[i
].oa_value
== NULL
)
9418 /* find attribute in object */
9419 type
= template[i
].oa_type
;
9420 j
= dprov_find_attr(object
->do_attr
, DPROV_MAX_ATTR
, type
);
9423 /* attribute already exists, free old value */
9424 kmem_free(object
->do_attr
[j
].oa_value
,
9425 object
->do_attr
[j
].oa_value_len
);
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
)
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
;
9446 object
->do_attr
[j
].oa_type
= type
;
9449 return (CRYPTO_SUCCESS
);
9454 * Free the specified object.
9457 dprov_free_object(dprov_object_t
*object
)
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.
9475 dprov_object_is_private(dprov_object_t
*object
)
9480 err
= dprov_get_object_attr_boolean(object
, DPROV_CKA_PRIVATE
, &ret
);
9482 if (err
!= CRYPTO_SUCCESS
)
9483 /* by default, CKA_PRIVATE is false */
9490 * Checks whether the specified object is a token or session object.
9493 dprov_object_is_token(dprov_object_t
*object
)
9498 err
= dprov_get_object_attr_boolean(object
, DPROV_CKA_TOKEN
, &ret
);
9500 if (err
!= CRYPTO_SUCCESS
)
9501 /* by default, CKA_TOKEN is false */
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.
9515 dprov_get_object_attr_scalar_common(dprov_object_t
*object
, uint64_t attr_type
,
9516 void *value
, size_t value_len
)
9519 size_t oa_value_len
;
9522 if ((attr_idx
= dprov_find_attr(object
->do_attr
, DPROV_MAX_ATTR
,
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
) {
9538 offset
= value_len
- oa_value_len
;
9540 bzero(value
, value_len
);
9544 /* incorrect attribute value length */
9545 return (CRYPTO_ATTRIBUTE_VALUE_INVALID
);
9549 bcopy(object
->do_attr
[attr_idx
].oa_value
, (uchar_t
*)value
+ offset
,
9552 return (CRYPTO_SUCCESS
);
9556 * Get the value of the a boolean attribute from the specified object.
9559 dprov_get_object_attr_boolean(dprov_object_t
*object
, uint64_t attr_type
,
9560 boolean_t
*attr_value
)
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
;
9574 * Get the value of a ulong_t attribute from the specified object.
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.
9591 dprov_get_object_attr_array(dprov_object_t
*object
, uint64_t attr_type
,
9592 void **array
, size_t *len
)
9596 if ((attr_idx
= dprov_find_attr(object
->do_attr
, DPROV_MAX_ATTR
,
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.
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
;
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
) {
9636 offset
= value_len
- oa_value_len
;
9638 bzero(value
, value_len
);
9642 /* incorrect attribute value length */
9643 return (CRYPTO_ATTRIBUTE_VALUE_INVALID
);
9647 bcopy(template[attr_idx
].oa_value
, (uchar_t
*)value
+ offset
,
9650 return (CRYPTO_SUCCESS
);
9654 * Get the value of the a boolean attribute from the specified template
9657 dprov_get_template_attr_boolean(crypto_object_attribute_t
*template,
9658 uint_t nattr
, uint64_t attr_type
, boolean_t
*attr_value
)
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
;
9673 * Get the value of a ulong_t attribute from the specified template.
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
)));
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.
9697 dprov_get_template_attr_array(crypto_object_attribute_t
*template,
9698 uint_t nattr
, uint64_t attr_type
, void **array
, size_t *len
)
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.
9719 dprov_get_key_attr_scalar_common(crypto_key_t
*key
, uint64_t attr_type
,
9720 void *value
, size_t value_len
)
9724 ASSERT(key
->ck_format
== CRYPTO_KEY_ATTR_LIST
);
9726 if ((attr_idx
= dprov_find_attr(key
->ck_attrs
, key
->ck_count
,
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.
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.
9757 dprov_get_key_attr_array(crypto_key_t
*key
, uint64_t attr_type
,
9758 void **array
, size_t *len
)
9762 ASSERT(key
->ck_format
== CRYPTO_KEY_ATTR_LIST
);
9764 if ((attr_idx
= dprov_find_attr(key
->ck_attrs
, key
->ck_count
,
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
);
9775 dprov_release_session_objects(dprov_session_t
*session
)
9777 dprov_object_t
*object
;
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.
9794 dprov_adjust_attrs(crypto_object_attribute_t
*in
, int in_count
)
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
)) {
9811 offset
= sizeof (ulong_t
) - in
[i
].oa_value_len
;
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
);