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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
24 * Copyright 2018, Joyent, Inc.
29 * The ioctl interface for cryptographic commands.
32 #include <sys/types.h>
33 #include <sys/modctl.h>
37 #include <sys/sunddi.h>
39 #include <sys/errno.h>
40 #include <sys/ksynch.h>
46 #include <sys/mkdev.h>
47 #include <sys/model.h>
48 #include <sys/sysmacros.h>
49 #include <sys/crypto/common.h>
50 #include <sys/crypto/api.h>
51 #include <sys/crypto/impl.h>
52 #include <sys/crypto/sched_impl.h>
53 #include <sys/crypto/ioctl.h>
55 extern int kcf_des3_threshold
;
56 extern int kcf_aes_threshold
;
57 extern int kcf_rc4_threshold
;
58 extern int kcf_md5_threshold
;
59 extern int kcf_sha1_threshold
;
64 * crypto_locks protects the global array of minor structures.
65 * crypto_locks is an array of locks indexed by the cpuid. A reader needs
66 * to hold a single lock while a writer needs to hold all locks.
67 * krwlock_t is not an option here because the hold time
68 * is very small for these locks.
70 * The fields in the minor structure are protected by the cm_lock member
71 * of the minor structure. The cm_cv is used to signal decrements
72 * in the cm_refcnt, and is used with the cm_lock.
74 * The locking order is crypto_locks followed by cm_lock.
80 static int crypto_attach(dev_info_t
*, ddi_attach_cmd_t
);
81 static int crypto_detach(dev_info_t
*, ddi_detach_cmd_t
);
82 static int crypto_getinfo(dev_info_t
*, ddi_info_cmd_t
, void *, void **);
83 static int crypto_open(dev_t
*, int, int, cred_t
*);
84 static int crypto_close(dev_t
, int, int, cred_t
*);
85 static int crypto_ioctl(dev_t
, int, intptr_t, int, cred_t
*, int *);
87 static int cipher_init(dev_t
, caddr_t
, int, int (*)(crypto_provider_t
,
88 crypto_session_id_t
, crypto_mechanism_t
*, crypto_key_t
*,
89 crypto_ctx_template_t
, crypto_context_t
*, crypto_call_req_t
*));
91 static int common_digest(dev_t
, caddr_t
, int, int (*)(crypto_context_t
,
92 crypto_data_t
*, crypto_data_t
*, crypto_call_req_t
*));
94 static int cipher(dev_t
, caddr_t
, int, int (*)(crypto_context_t
,
95 crypto_data_t
*, crypto_data_t
*, crypto_call_req_t
*));
97 static int cipher_update(dev_t
, caddr_t
, int, int (*)(crypto_context_t
,
98 crypto_data_t
*, crypto_data_t
*, crypto_call_req_t
*));
100 static int common_final(dev_t
, caddr_t
, int, int (*)(crypto_context_t
,
101 crypto_data_t
*, crypto_call_req_t
*));
103 static int sign_verify_init(dev_t
, caddr_t
, int, int (*)(crypto_provider_t
,
104 crypto_session_id_t
, crypto_mechanism_t
*, crypto_key_t
*,
105 crypto_ctx_template_t
, crypto_context_t
*, crypto_call_req_t
*));
107 static int sign_verify_update(dev_t dev
, caddr_t arg
, int mode
,
108 int (*)(crypto_context_t
, crypto_data_t
*, crypto_call_req_t
*));
110 static void crypto_release_provider_session(crypto_minor_t
*,
111 crypto_provider_session_t
*);
112 static int crypto_buffer_check(size_t);
113 static int crypto_free_find_ctx(crypto_session_data_t
*);
114 static int crypto_get_provider_list(crypto_minor_t
*, uint_t
*,
115 crypto_provider_entry_t
**, boolean_t
);
117 static int crypto_create_provider_session(crypto_minor_t
*,
118 kcf_provider_desc_t
*, crypto_session_id_t
, crypto_provider_session_t
**,
119 kcf_provider_desc_t
*);
120 static int crypto_create_session_ptr(crypto_minor_t
*, kcf_provider_desc_t
*,
121 crypto_provider_session_t
*, crypto_session_id_t
*);
123 /* number of minor numbers to allocate at a time */
124 #define CRYPTO_MINOR_CHUNK 16
127 * There are two limits associated with kernel memory. The first,
128 * CRYPTO_MAX_BUFFER_LEN, is the maximum number of bytes that can be
129 * allocated for a single copyin/copyout buffer. The second limit is
130 * the total number of bytes that can be allocated by a process
131 * for copyin/copyout buffers. The latter is enforced by the
132 * project.max-crypto-memory resource control.
135 #define CRYPTO_MAX_BUFFER_LEN (2 * 1024 * 1024)
136 #define CRYPTO_MAX_FIND_COUNT 512
139 * We preapprove some bytes for each session to avoid making the costly
140 * crypto_buffer_check() calls. The preapproval is done when a new session
141 * is created and that cost is amortized over later crypto calls.
142 * Most applications create a session and then do a bunch of crypto calls
143 * in that session. So, they benefit from this optimization.
145 * Note that we may hit the project.max-crypto-memory limit a bit sooner
146 * because of this preapproval. But it is acceptable since the preapproved
147 * amount is insignificant compared to the default max-crypto-memory limit
148 * which is quarter of the machine's memory. The preapproved amount is
149 * roughly 2 * 16K(maximum SSL record size).
151 #define CRYPTO_PRE_APPROVED_LIMIT (32 * 1024)
153 /* The session table grows by CRYPTO_SESSION_CHUNK increments */
154 #define CRYPTO_SESSION_CHUNK 100
156 size_t crypto_max_buffer_len
= CRYPTO_MAX_BUFFER_LEN
;
157 size_t crypto_pre_approved_limit
= CRYPTO_PRE_APPROVED_LIMIT
;
159 #define INIT_RAW_CRYPTO_DATA(data, len) \
160 (data).cd_format = CRYPTO_DATA_RAW; \
161 (data).cd_raw.iov_base = (len > 0) ? kmem_alloc(len, KM_SLEEP) : NULL; \
162 (data).cd_raw.iov_len = len; \
163 (data).cd_offset = 0; \
164 (data).cd_length = len;
166 static struct kmem_cache
*crypto_session_cache
;
167 static crypto_minor_t
**crypto_minors
= NULL
;
168 static dev_info_t
*crypto_dip
= NULL
;
169 static minor_t crypto_minor_chunk
= CRYPTO_MINOR_CHUNK
;
170 static minor_t crypto_minors_table_count
= 0;
173 * Minors are started from 1 because vmem_alloc()
174 * returns 0 in case of failure.
176 static vmem_t
*crypto_arena
= NULL
; /* Arena for device minors */
177 static minor_t crypto_minors_count
= 0;
178 static kcf_lock_withpad_t
*crypto_locks
;
180 #define CRYPTO_ENTER_ALL_LOCKS() \
181 for (i = 0; i < max_ncpus; i++) \
182 mutex_enter(&crypto_locks[i].kl_lock);
184 #define CRYPTO_EXIT_ALL_LOCKS() \
185 for (i = 0; i < max_ncpus; i++) \
186 mutex_exit(&crypto_locks[i].kl_lock);
188 #define RETURN_LIST B_TRUE
189 #define DONT_RETURN_LIST B_FALSE
191 #define CRYPTO_OPS_OFFSET(f) offsetof(crypto_ops_t, co_##f)
192 #define CRYPTO_RANDOM_OFFSET(f) offsetof(crypto_random_number_ops_t, f)
193 #define CRYPTO_SESSION_OFFSET(f) offsetof(crypto_session_ops_t, f)
194 #define CRYPTO_OBJECT_OFFSET(f) offsetof(crypto_object_ops_t, f)
195 #define CRYPTO_PROVIDER_OFFSET(f) \
196 offsetof(crypto_provider_management_ops_t, f)
198 #define CRYPTO_CANCEL_CTX(spp) { \
199 crypto_cancel_ctx(*(spp)); \
203 #define CRYPTO_CANCEL_ALL_CTX(sp) { \
204 if ((sp)->sd_digest_ctx != NULL) { \
205 crypto_cancel_ctx((sp)->sd_digest_ctx); \
206 (sp)->sd_digest_ctx = NULL; \
208 if ((sp)->sd_encr_ctx != NULL) { \
209 crypto_cancel_ctx((sp)->sd_encr_ctx); \
210 (sp)->sd_encr_ctx = NULL; \
212 if ((sp)->sd_decr_ctx != NULL) { \
213 crypto_cancel_ctx((sp)->sd_decr_ctx); \
214 (sp)->sd_decr_ctx = NULL; \
216 if ((sp)->sd_sign_ctx != NULL) { \
217 crypto_cancel_ctx((sp)->sd_sign_ctx); \
218 (sp)->sd_sign_ctx = NULL; \
220 if ((sp)->sd_verify_ctx != NULL) { \
221 crypto_cancel_ctx((sp)->sd_verify_ctx); \
222 (sp)->sd_verify_ctx = NULL; \
224 if ((sp)->sd_sign_recover_ctx != NULL) { \
225 crypto_cancel_ctx((sp)->sd_sign_recover_ctx); \
226 (sp)->sd_sign_recover_ctx = NULL; \
228 if ((sp)->sd_verify_recover_ctx != NULL) { \
229 crypto_cancel_ctx((sp)->sd_verify_recover_ctx); \
230 (sp)->sd_verify_recover_ctx = NULL; \
232 if ((sp)->sd_mac_ctx != NULL) { \
233 crypto_cancel_ctx((sp)->sd_mac_ctx); \
234 (sp)->sd_mac_ctx = NULL; \
238 #define CRYPTO_DECREMENT_RCTL(val) if ((val) != 0) { \
240 mutex_enter(&curproc->p_lock); \
241 projp = curproc->p_task->tk_proj; \
242 ASSERT(projp != NULL); \
243 mutex_enter(&(projp->kpj_data.kpd_crypto_lock)); \
244 projp->kpj_data.kpd_crypto_mem -= (val); \
245 mutex_exit(&(projp->kpj_data.kpd_crypto_lock)); \
246 curproc->p_crypto_mem -= (val); \
247 mutex_exit(&curproc->p_lock); \
251 * We do not need to hold sd_lock in the macros below
252 * as they are called after doing a get_session_ptr() which
253 * sets the CRYPTO_SESSION_IS_BUSY flag.
255 #define CRYPTO_DECREMENT_RCTL_SESSION(sp, val, rctl_chk) \
256 if (((val) != 0) && ((sp) != NULL)) { \
257 ASSERT(((sp)->sd_flags & CRYPTO_SESSION_IS_BUSY) != 0); \
259 CRYPTO_DECREMENT_RCTL(val); \
261 (sp)->sd_pre_approved_amount += (val); \
265 #define CRYPTO_BUFFER_CHECK(sp, need, rctl_chk) \
266 ((sp->sd_pre_approved_amount >= need) ? \
267 (sp->sd_pre_approved_amount -= need, \
268 rctl_chk = B_FALSE, CRYPTO_SUCCESS) : \
269 (rctl_chk = B_TRUE, crypto_buffer_check(need)))
274 static struct cb_ops cbops
= {
275 crypto_open
, /* cb_open */
276 crypto_close
, /* cb_close */
277 nodev
, /* cb_strategy */
278 nodev
, /* cb_print */
281 nodev
, /* cb_write */
282 crypto_ioctl
, /* cb_ioctl */
283 nodev
, /* cb_devmap */
285 nodev
, /* cb_segmap */
286 nochpoll
, /* cb_chpoll */
287 ddi_prop_op
, /* cb_prop_op */
288 NULL
, /* cb_streamtab */
291 nodev
, /* cb_aread */
292 nodev
, /* cb_awrite */
295 static struct dev_ops devops
= {
296 DEVO_REV
, /* devo_rev */
298 crypto_getinfo
, /* devo_getinfo */
299 nulldev
, /* devo_identify */
300 nulldev
, /* devo_probe */
301 crypto_attach
, /* devo_attach */
302 crypto_detach
, /* devo_detach */
303 nodev
, /* devo_reset */
304 &cbops
, /* devo_cb_ops */
305 NULL
, /* devo_bus_ops */
306 NULL
, /* devo_power */
307 ddi_quiesce_not_needed
, /* devo_quiesce */
310 static struct modldrv modldrv
= {
311 &mod_driverops
, /* drv_modops */
312 "Cryptographic Library Interface", /* drv_linkinfo */
316 static struct modlinkage modlinkage
= {
317 MODREV_1
, /* ml_rev */
318 &modldrv
, /* ml_linkage */
328 return (mod_install(&modlinkage
));
334 return (mod_remove(&modlinkage
));
338 _info(struct modinfo
*modinfop
)
340 return (mod_info(&modlinkage
, modinfop
));
345 crypto_getinfo(dev_info_t
*dip
, ddi_info_cmd_t cmd
, void *arg
, void **result
)
348 case DDI_INFO_DEVT2DEVINFO
:
349 *result
= crypto_dip
;
350 return (DDI_SUCCESS
);
352 case DDI_INFO_DEVT2INSTANCE
:
354 return (DDI_SUCCESS
);
356 return (DDI_FAILURE
);
360 crypto_attach(dev_info_t
*dip
, ddi_attach_cmd_t cmd
)
364 if (cmd
!= DDI_ATTACH
) {
365 return (DDI_FAILURE
);
368 if (ddi_get_instance(dip
) != 0) {
369 /* we only allow instance 0 to attach */
370 return (DDI_FAILURE
);
373 crypto_session_cache
= kmem_cache_create("crypto_session_cache",
374 sizeof (crypto_session_data_t
), 0, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
376 if (crypto_session_cache
== NULL
)
377 return (DDI_FAILURE
);
379 /* create the minor node */
380 if (ddi_create_minor_node(dip
, "crypto", S_IFCHR
, 0,
381 DDI_PSEUDO
, 0) != DDI_SUCCESS
) {
382 kmem_cache_destroy(crypto_session_cache
);
383 crypto_session_cache
= NULL
;
384 cmn_err(CE_WARN
, "crypto_attach: failed creating minor node");
385 ddi_remove_minor_node(dip
, NULL
);
386 return (DDI_FAILURE
);
389 crypto_locks
= kmem_zalloc(max_ncpus
* sizeof (kcf_lock_withpad_t
),
391 for (i
= 0; i
< max_ncpus
; i
++)
392 mutex_init(&crypto_locks
[i
].kl_lock
, NULL
, MUTEX_DRIVER
, NULL
);
396 /* allocate integer space for minor numbers */
397 crypto_arena
= vmem_create("crypto", (void *)1,
398 CRYPTO_MINOR_CHUNK
, 1, NULL
, NULL
, NULL
, 0,
399 VM_SLEEP
| VMC_IDENTIFIER
);
401 return (DDI_SUCCESS
);
405 crypto_detach(dev_info_t
*dip
, ddi_detach_cmd_t cmd
)
408 kcf_lock_withpad_t
*mp
;
410 if (cmd
!= DDI_DETACH
)
411 return (DDI_FAILURE
);
413 mp
= &crypto_locks
[CPU_SEQID
];
414 mutex_enter(&mp
->kl_lock
);
416 /* check if device is open */
417 for (i
= 0; i
< crypto_minors_table_count
; i
++) {
418 if (crypto_minors
[i
] != NULL
) {
419 mutex_exit(&mp
->kl_lock
);
420 return (DDI_FAILURE
);
423 mutex_exit(&mp
->kl_lock
);
426 ddi_remove_minor_node(dip
, NULL
);
428 kmem_cache_destroy(crypto_session_cache
);
429 crypto_session_cache
= NULL
;
431 kmem_free(crypto_minors
,
432 sizeof (crypto_minor_t
*) * crypto_minors_table_count
);
433 crypto_minors
= NULL
;
434 crypto_minors_table_count
= 0;
435 for (i
= 0; i
< max_ncpus
; i
++)
436 mutex_destroy(&crypto_locks
[i
].kl_lock
);
437 kmem_free(crypto_locks
, max_ncpus
* sizeof (kcf_lock_withpad_t
));
440 vmem_destroy(crypto_arena
);
443 return (DDI_SUCCESS
);
448 crypto_open(dev_t
*devp
, int flag
, int otyp
, cred_t
*credp
)
450 crypto_minor_t
*cm
= NULL
;
452 kcf_lock_withpad_t
*mp
;
455 if (otyp
!= OTYP_CHR
)
458 if (crypto_dip
== NULL
)
461 /* exclusive opens are not supported */
466 mp
= &crypto_locks
[CPU_SEQID
];
467 mutex_enter(&mp
->kl_lock
);
469 /* grow the minors table if needed */
470 if (crypto_minors_count
>= crypto_minors_table_count
) {
471 crypto_minor_t
**newtable
;
472 minor_t chunk
= crypto_minor_chunk
;
477 big_count
= crypto_minors_count
+ chunk
;
478 if (big_count
> MAXMIN
) {
479 mutex_exit(&mp
->kl_lock
);
483 saved_count
= crypto_minors_table_count
;
484 new_size
= sizeof (crypto_minor_t
*) *
485 (crypto_minors_table_count
+ chunk
);
487 mutex_exit(&mp
->kl_lock
);
489 newtable
= kmem_zalloc(new_size
, KM_SLEEP
);
490 CRYPTO_ENTER_ALL_LOCKS();
492 * Check if table grew while we were sleeping.
493 * The minors table never shrinks.
495 if (crypto_minors_table_count
> saved_count
) {
496 CRYPTO_EXIT_ALL_LOCKS();
497 kmem_free(newtable
, new_size
);
501 /* we assume that bcopy() will return if count is 0 */
502 bcopy(crypto_minors
, newtable
,
503 sizeof (crypto_minor_t
*) * crypto_minors_table_count
);
505 kmem_free(crypto_minors
,
506 sizeof (crypto_minor_t
*) * crypto_minors_table_count
);
508 /* grow the minors number space */
509 if (crypto_minors_table_count
!= 0) {
510 (void) vmem_add(crypto_arena
,
511 (void *)(uintptr_t)(crypto_minors_table_count
+ 1),
512 crypto_minor_chunk
, VM_SLEEP
);
515 crypto_minors
= newtable
;
516 crypto_minors_table_count
+= chunk
;
517 CRYPTO_EXIT_ALL_LOCKS();
519 mutex_exit(&mp
->kl_lock
);
522 /* allocate a new minor number starting with 1 */
523 mn
= (minor_t
)(uintptr_t)vmem_alloc(crypto_arena
, 1, VM_SLEEP
);
525 cm
= kmem_zalloc(sizeof (crypto_minor_t
), KM_SLEEP
);
526 mutex_init(&cm
->cm_lock
, NULL
, MUTEX_DRIVER
, NULL
);
527 cv_init(&cm
->cm_cv
, NULL
, CV_DRIVER
, NULL
);
529 CRYPTO_ENTER_ALL_LOCKS();
531 crypto_minors
[mn
- 1] = cm
;
532 crypto_minors_count
++;
533 CRYPTO_EXIT_ALL_LOCKS();
535 *devp
= makedevice(getmajor(*devp
), mn
);
542 crypto_close(dev_t dev
, int flag
, int otyp
, cred_t
*credp
)
544 crypto_minor_t
*cm
= NULL
;
545 crypto_session_data_t
*sp
;
546 minor_t mn
= getminor(dev
);
549 kcf_lock_withpad_t
*mp
;
551 mp
= &crypto_locks
[CPU_SEQID
];
552 mutex_enter(&mp
->kl_lock
);
554 if (mn
> crypto_minors_table_count
) {
555 mutex_exit(&mp
->kl_lock
);
556 cmn_err(CE_WARN
, "crypto_close: bad minor (too big) %d", mn
);
560 cm
= crypto_minors
[mn
- 1];
562 mutex_exit(&mp
->kl_lock
);
563 cmn_err(CE_WARN
, "crypto_close: duplicate close of minor %d",
568 mutex_exit(&mp
->kl_lock
);
570 CRYPTO_ENTER_ALL_LOCKS();
572 * We free the minor number, mn, from the crypto_arena
573 * only later. This ensures that we won't race with another
574 * thread in crypto_open with the same minor number.
576 crypto_minors
[mn
- 1] = NULL
;
577 crypto_minors_count
--;
578 CRYPTO_EXIT_ALL_LOCKS();
580 mutex_enter(&cm
->cm_lock
);
581 cm
->cm_refcnt
--; /* decrement refcnt held in open */
582 while (cm
->cm_refcnt
> 0) {
583 cv_wait(&cm
->cm_cv
, &cm
->cm_lock
);
586 vmem_free(crypto_arena
, (void *)(uintptr_t)mn
, 1);
588 /* free all session table entries starting with 1 */
589 for (i
= 1; i
< cm
->cm_session_table_count
; i
++) {
590 if (cm
->cm_session_table
[i
] == NULL
)
593 sp
= cm
->cm_session_table
[i
];
594 ASSERT((sp
->sd_flags
& CRYPTO_SESSION_IS_BUSY
) == 0);
595 ASSERT(sp
->sd_pre_approved_amount
== 0 ||
596 sp
->sd_pre_approved_amount
== crypto_pre_approved_limit
);
597 total
+= sp
->sd_pre_approved_amount
;
598 if (sp
->sd_find_init_cookie
!= NULL
) {
599 (void) crypto_free_find_ctx(sp
);
601 crypto_release_provider_session(cm
, sp
->sd_provider_session
);
602 KCF_PROV_REFRELE(sp
->sd_provider
);
603 CRYPTO_CANCEL_ALL_CTX(sp
);
604 mutex_destroy(&sp
->sd_lock
);
605 cv_destroy(&sp
->sd_cv
);
606 kmem_cache_free(crypto_session_cache
, sp
);
607 cm
->cm_session_table
[i
] = NULL
;
610 /* free the session table */
611 if (cm
->cm_session_table
!= NULL
&& cm
->cm_session_table_count
> 0)
612 kmem_free(cm
->cm_session_table
, cm
->cm_session_table_count
*
615 total
+= (cm
->cm_session_table_count
* sizeof (void *));
616 CRYPTO_DECREMENT_RCTL(total
);
618 kcf_free_provider_tab(cm
->cm_provider_count
,
619 cm
->cm_provider_array
);
621 mutex_exit(&cm
->cm_lock
);
622 mutex_destroy(&cm
->cm_lock
);
623 cv_destroy(&cm
->cm_cv
);
624 kmem_free(cm
, sizeof (crypto_minor_t
));
629 static crypto_minor_t
*
630 crypto_hold_minor(minor_t minor
)
633 kcf_lock_withpad_t
*mp
;
635 if (minor
> crypto_minors_table_count
)
638 mp
= &crypto_locks
[CPU_SEQID
];
639 mutex_enter(&mp
->kl_lock
);
641 if ((cm
= crypto_minors
[minor
- 1]) != NULL
) {
642 atomic_inc_32(&cm
->cm_refcnt
);
644 mutex_exit(&mp
->kl_lock
);
649 crypto_release_minor(crypto_minor_t
*cm
)
651 if (atomic_dec_32_nv(&cm
->cm_refcnt
) == 0) {
652 cv_signal(&cm
->cm_cv
);
657 * Build a list of functions and other information for the provider, pd.
660 crypto_build_function_list(crypto_function_list_t
*fl
, kcf_provider_desc_t
*pd
)
663 crypto_digest_ops_t
*digest_ops
;
664 crypto_cipher_ops_t
*cipher_ops
;
665 crypto_mac_ops_t
*mac_ops
;
666 crypto_sign_ops_t
*sign_ops
;
667 crypto_verify_ops_t
*verify_ops
;
668 crypto_dual_ops_t
*dual_ops
;
669 crypto_random_number_ops_t
*random_number_ops
;
670 crypto_session_ops_t
*session_ops
;
671 crypto_object_ops_t
*object_ops
;
672 crypto_key_ops_t
*key_ops
;
673 crypto_provider_management_ops_t
*provider_ops
;
675 if ((ops
= pd
->pd_ops_vector
) == NULL
)
678 if ((digest_ops
= ops
->co_digest_ops
) != NULL
) {
679 if (digest_ops
->digest_init
!= NULL
)
680 fl
->fl_digest_init
= B_TRUE
;
681 if (digest_ops
->digest
!= NULL
)
682 fl
->fl_digest
= B_TRUE
;
683 if (digest_ops
->digest_update
!= NULL
)
684 fl
->fl_digest_update
= B_TRUE
;
685 if (digest_ops
->digest_key
!= NULL
)
686 fl
->fl_digest_key
= B_TRUE
;
687 if (digest_ops
->digest_final
!= NULL
)
688 fl
->fl_digest_final
= B_TRUE
;
690 if ((cipher_ops
= ops
->co_cipher_ops
) != NULL
) {
691 if (cipher_ops
->encrypt_init
!= NULL
)
692 fl
->fl_encrypt_init
= B_TRUE
;
693 if (cipher_ops
->encrypt
!= NULL
)
694 fl
->fl_encrypt
= B_TRUE
;
695 if (cipher_ops
->encrypt_update
!= NULL
)
696 fl
->fl_encrypt_update
= B_TRUE
;
697 if (cipher_ops
->encrypt_final
!= NULL
)
698 fl
->fl_encrypt_final
= B_TRUE
;
699 if (cipher_ops
->decrypt_init
!= NULL
)
700 fl
->fl_decrypt_init
= B_TRUE
;
701 if (cipher_ops
->decrypt
!= NULL
)
702 fl
->fl_decrypt
= B_TRUE
;
703 if (cipher_ops
->decrypt_update
!= NULL
)
704 fl
->fl_decrypt_update
= B_TRUE
;
705 if (cipher_ops
->decrypt_final
!= NULL
)
706 fl
->fl_decrypt_final
= B_TRUE
;
708 if ((mac_ops
= ops
->co_mac_ops
) != NULL
) {
709 if (mac_ops
->mac_init
!= NULL
)
710 fl
->fl_mac_init
= B_TRUE
;
711 if (mac_ops
->mac
!= NULL
)
713 if (mac_ops
->mac_update
!= NULL
)
714 fl
->fl_mac_update
= B_TRUE
;
715 if (mac_ops
->mac_final
!= NULL
)
716 fl
->fl_mac_final
= B_TRUE
;
718 if ((sign_ops
= ops
->co_sign_ops
) != NULL
) {
719 if (sign_ops
->sign_init
!= NULL
)
720 fl
->fl_sign_init
= B_TRUE
;
721 if (sign_ops
->sign
!= NULL
)
722 fl
->fl_sign
= B_TRUE
;
723 if (sign_ops
->sign_update
!= NULL
)
724 fl
->fl_sign_update
= B_TRUE
;
725 if (sign_ops
->sign_final
!= NULL
)
726 fl
->fl_sign_final
= B_TRUE
;
727 if (sign_ops
->sign_recover_init
!= NULL
)
728 fl
->fl_sign_recover_init
= B_TRUE
;
729 if (sign_ops
->sign_recover
!= NULL
)
730 fl
->fl_sign_recover
= B_TRUE
;
732 if ((verify_ops
= ops
->co_verify_ops
) != NULL
) {
733 if (verify_ops
->verify_init
!= NULL
)
734 fl
->fl_verify_init
= B_TRUE
;
735 if (verify_ops
->verify
!= NULL
)
736 fl
->fl_verify
= B_TRUE
;
737 if (verify_ops
->verify_update
!= NULL
)
738 fl
->fl_verify_update
= B_TRUE
;
739 if (verify_ops
->verify_final
!= NULL
)
740 fl
->fl_verify_final
= B_TRUE
;
741 if (verify_ops
->verify_recover_init
!= NULL
)
742 fl
->fl_verify_recover_init
= B_TRUE
;
743 if (verify_ops
->verify_recover
!= NULL
)
744 fl
->fl_verify_recover
= B_TRUE
;
746 if ((dual_ops
= ops
->co_dual_ops
) != NULL
) {
747 if (dual_ops
->digest_encrypt_update
!= NULL
)
748 fl
->fl_digest_encrypt_update
= B_TRUE
;
749 if (dual_ops
->decrypt_digest_update
!= NULL
)
750 fl
->fl_decrypt_digest_update
= B_TRUE
;
751 if (dual_ops
->sign_encrypt_update
!= NULL
)
752 fl
->fl_sign_encrypt_update
= B_TRUE
;
753 if (dual_ops
->decrypt_verify_update
!= NULL
)
754 fl
->fl_decrypt_verify_update
= B_TRUE
;
756 if ((random_number_ops
= ops
->co_random_ops
) != NULL
) {
757 if (random_number_ops
->seed_random
!= NULL
)
758 fl
->fl_seed_random
= B_TRUE
;
759 if (random_number_ops
->generate_random
!= NULL
)
760 fl
->fl_generate_random
= B_TRUE
;
762 if ((session_ops
= ops
->co_session_ops
) != NULL
) {
763 if (session_ops
->session_open
!= NULL
)
764 fl
->fl_session_open
= B_TRUE
;
765 if (session_ops
->session_close
!= NULL
)
766 fl
->fl_session_close
= B_TRUE
;
767 if (session_ops
->session_login
!= NULL
)
768 fl
->fl_session_login
= B_TRUE
;
769 if (session_ops
->session_logout
!= NULL
)
770 fl
->fl_session_logout
= B_TRUE
;
772 if ((object_ops
= ops
->co_object_ops
) != NULL
) {
773 if (object_ops
->object_create
!= NULL
)
774 fl
->fl_object_create
= B_TRUE
;
775 if (object_ops
->object_copy
!= NULL
)
776 fl
->fl_object_copy
= B_TRUE
;
777 if (object_ops
->object_destroy
!= NULL
)
778 fl
->fl_object_destroy
= B_TRUE
;
779 if (object_ops
->object_get_size
!= NULL
)
780 fl
->fl_object_get_size
= B_TRUE
;
781 if (object_ops
->object_get_attribute_value
!= NULL
)
782 fl
->fl_object_get_attribute_value
= B_TRUE
;
783 if (object_ops
->object_set_attribute_value
!= NULL
)
784 fl
->fl_object_set_attribute_value
= B_TRUE
;
785 if (object_ops
->object_find_init
!= NULL
)
786 fl
->fl_object_find_init
= B_TRUE
;
787 if (object_ops
->object_find
!= NULL
)
788 fl
->fl_object_find
= B_TRUE
;
789 if (object_ops
->object_find_final
!= NULL
)
790 fl
->fl_object_find_final
= B_TRUE
;
792 if ((key_ops
= ops
->co_key_ops
) != NULL
) {
793 if (key_ops
->key_generate
!= NULL
)
794 fl
->fl_key_generate
= B_TRUE
;
795 if (key_ops
->key_generate_pair
!= NULL
)
796 fl
->fl_key_generate_pair
= B_TRUE
;
797 if (key_ops
->key_wrap
!= NULL
)
798 fl
->fl_key_wrap
= B_TRUE
;
799 if (key_ops
->key_unwrap
!= NULL
)
800 fl
->fl_key_unwrap
= B_TRUE
;
801 if (key_ops
->key_derive
!= NULL
)
802 fl
->fl_key_derive
= B_TRUE
;
804 if ((provider_ops
= ops
->co_provider_ops
) != NULL
) {
805 if (provider_ops
->init_token
!= NULL
)
806 fl
->fl_init_token
= B_TRUE
;
807 if (provider_ops
->init_pin
!= NULL
)
808 fl
->fl_init_pin
= B_TRUE
;
809 if (provider_ops
->set_pin
!= NULL
)
810 fl
->fl_set_pin
= B_TRUE
;
813 fl
->prov_is_hash_limited
= pd
->pd_flags
& CRYPTO_HASH_NO_UPDATE
;
814 if (fl
->prov_is_hash_limited
) {
815 fl
->prov_hash_limit
= min(pd
->pd_hash_limit
,
816 min(CRYPTO_MAX_BUFFER_LEN
,
817 curproc
->p_task
->tk_proj
->kpj_data
.kpd_crypto_mem_ctl
));
820 fl
->prov_is_hmac_limited
= pd
->pd_flags
& CRYPTO_HMAC_NO_UPDATE
;
821 if (fl
->prov_is_hmac_limited
) {
822 fl
->prov_hmac_limit
= min(pd
->pd_hmac_limit
,
823 min(CRYPTO_MAX_BUFFER_LEN
,
824 curproc
->p_task
->tk_proj
->kpj_data
.kpd_crypto_mem_ctl
));
827 if (fl
->prov_is_hash_limited
|| fl
->prov_is_hmac_limited
) {
829 * XXX - The threshold should ideally be per hash/HMAC
830 * mechanism. For now, we use the same value for all
831 * hash/HMAC mechanisms. Empirical evidence suggests this
834 fl
->prov_hash_threshold
= kcf_md5_threshold
;
837 fl
->total_threshold_count
= MAX_NUM_THRESHOLD
;
838 fl
->fl_threshold
[0].mech_type
= CKM_DES3_CBC
;
839 fl
->fl_threshold
[0].mech_threshold
= kcf_des3_threshold
;
840 fl
->fl_threshold
[1].mech_type
= CKM_DES3_ECB
;
841 fl
->fl_threshold
[1].mech_threshold
= kcf_des3_threshold
;
842 fl
->fl_threshold
[2].mech_type
= CKM_AES_CBC
;
843 fl
->fl_threshold
[2].mech_threshold
= kcf_aes_threshold
;
844 fl
->fl_threshold
[3].mech_type
= CKM_AES_ECB
;
845 fl
->fl_threshold
[3].mech_threshold
= kcf_aes_threshold
;
846 fl
->fl_threshold
[4].mech_type
= CKM_RC4
;
847 fl
->fl_threshold
[4].mech_threshold
= kcf_rc4_threshold
;
848 fl
->fl_threshold
[5].mech_type
= CKM_MD5
;
849 fl
->fl_threshold
[5].mech_threshold
= kcf_md5_threshold
;
850 fl
->fl_threshold
[6].mech_type
= CKM_SHA_1
;
851 fl
->fl_threshold
[6].mech_threshold
= kcf_sha1_threshold
;
856 get_function_list(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
858 crypto_get_function_list_t get_function_list
;
860 crypto_provider_id_t provider_id
;
861 crypto_function_list_t
*fl
;
862 kcf_provider_desc_t
*provider
;
865 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
866 cmn_err(CE_WARN
, "get_function_list: failed holding minor");
870 if (copyin(arg
, &get_function_list
, sizeof (get_function_list
)) != 0) {
871 crypto_release_minor(cm
);
875 /* initialize provider_array */
876 if (cm
->cm_provider_array
== NULL
) {
877 rv
= crypto_get_provider_list(cm
, NULL
, NULL
, DONT_RETURN_LIST
);
878 if (rv
!= CRYPTO_SUCCESS
) {
883 provider_id
= get_function_list
.fl_provider_id
;
884 mutex_enter(&cm
->cm_lock
);
885 /* index must be less than count of providers */
886 if (provider_id
>= cm
->cm_provider_count
) {
887 mutex_exit(&cm
->cm_lock
);
888 rv
= CRYPTO_ARGUMENTS_BAD
;
892 ASSERT(cm
->cm_provider_array
!= NULL
);
893 provider
= cm
->cm_provider_array
[provider_id
];
894 mutex_exit(&cm
->cm_lock
);
896 fl
= &get_function_list
.fl_list
;
897 bzero(fl
, sizeof (crypto_function_list_t
));
899 if (provider
->pd_prov_type
!= CRYPTO_LOGICAL_PROVIDER
) {
900 crypto_build_function_list(fl
, provider
);
902 kcf_provider_desc_t
*prev
= NULL
, *pd
;
904 mutex_enter(&provider
->pd_lock
);
905 while (kcf_get_next_logical_provider_member(provider
,
908 crypto_build_function_list(fl
, pd
);
909 KCF_PROV_REFRELE(pd
);
911 mutex_exit(&provider
->pd_lock
);
917 crypto_release_minor(cm
);
919 get_function_list
.fl_return_value
= rv
;
921 if (copyout(&get_function_list
, arg
, sizeof (get_function_list
)) != 0) {
928 * This ioctl maps a PKCS#11 mechanism string into an internal number
929 * that is used by the kernel. pn_internal_number is set to the
934 get_mechanism_number(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
936 STRUCT_DECL(crypto_get_mechanism_number
, get_number
);
937 crypto_mech_type_t number
;
939 char *mechanism_name
;
942 STRUCT_INIT(get_number
, mode
);
944 if (copyin(arg
, STRUCT_BUF(get_number
), STRUCT_SIZE(get_number
)) != 0)
947 len
= STRUCT_FGET(get_number
, pn_mechanism_len
);
948 if (len
== 0 || len
> CRYPTO_MAX_MECH_NAME
) {
949 rv
= CRYPTO_ARGUMENTS_BAD
;
952 mechanism_name
= kmem_alloc(len
, KM_SLEEP
);
954 if (copyin(STRUCT_FGETP(get_number
, pn_mechanism_string
),
955 mechanism_name
, len
) != 0) {
956 kmem_free(mechanism_name
, len
);
961 * Get mechanism number from kcf. We set the load_module
962 * flag to false since we use only hardware providers.
964 number
= crypto_mech2id_common(mechanism_name
, B_FALSE
);
965 kmem_free(mechanism_name
, len
);
966 if (number
== CRYPTO_MECH_INVALID
) {
967 rv
= CRYPTO_ARGUMENTS_BAD
;
971 bcopy((char *)&number
, (char *)STRUCT_FADDR(get_number
,
972 pn_internal_number
), sizeof (number
));
976 STRUCT_FSET(get_number
, pn_return_value
, rv
);
978 if (copyout(STRUCT_BUF(get_number
), arg
,
979 STRUCT_SIZE(get_number
)) != 0) {
986 * This ioctl returns an array of crypto_mech_name_t entries.
987 * It lists all the PKCS#11 mechanisms available in the kernel.
991 get_mechanism_list(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
993 STRUCT_DECL(crypto_get_mechanism_list
, get_list
);
994 crypto_mech_name_t
*entries
;
1001 STRUCT_INIT(get_list
, mode
);
1003 if (copyin(arg
, STRUCT_BUF(get_list
), STRUCT_SIZE(get_list
)) != 0) {
1007 entries
= crypto_get_mech_list(&count
, KM_SLEEP
);
1009 /* Number of entries caller thinks we have */
1010 req_count
= STRUCT_FGET(get_list
, ml_count
);
1012 STRUCT_FSET(get_list
, ml_count
, count
);
1013 STRUCT_FSET(get_list
, ml_return_value
, CRYPTO_SUCCESS
);
1015 /* check if buffer is too small */
1016 if (count
> req_count
) {
1017 STRUCT_FSET(get_list
, ml_return_value
, CRYPTO_BUFFER_TOO_SMALL
);
1020 /* copyout the first stuff */
1021 if (copyout(STRUCT_BUF(get_list
), arg
, STRUCT_SIZE(get_list
)) != 0) {
1026 * If only requesting number of entries or buffer too small or an
1027 * error occurred, stop here
1029 if (req_count
== 0 || count
> req_count
|| error
!= 0) {
1033 copyout_size
= count
* sizeof (crypto_mech_name_t
);
1035 /* copyout entries */
1036 offset
= (ulong_t
)STRUCT_FADDR(get_list
, ml_list
);
1037 offset
-= (ulong_t
)STRUCT_BUF(get_list
);
1038 if (copyout(entries
, arg
+ offset
, copyout_size
) != 0) {
1043 crypto_free_mech_list(entries
, count
);
1048 * Copyout kernel array of mech_infos to user space.
1052 copyout_mechinfos(int mode
, caddr_t out
, uint_t count
,
1053 crypto_mechanism_info_t
*k_minfos
, caddr_t u_minfos
)
1055 STRUCT_DECL(crypto_mechanism_info
, mi
);
1063 STRUCT_INIT(mi
, mode
);
1065 len
= count
* STRUCT_SIZE(mi
);
1067 ASSERT(u_minfos
!= NULL
);
1069 for (i
= 0; i
< count
; i
++) {
1070 STRUCT_FSET(mi
, mi_min_key_size
, k_minfos
[i
].mi_min_key_size
);
1071 STRUCT_FSET(mi
, mi_max_key_size
, k_minfos
[i
].mi_max_key_size
);
1072 STRUCT_FSET(mi
, mi_keysize_unit
, k_minfos
[i
].mi_keysize_unit
);
1073 STRUCT_FSET(mi
, mi_usage
, k_minfos
[i
].mi_usage
);
1074 bcopy(STRUCT_BUF(mi
), p
, STRUCT_SIZE(mi
));
1075 p
+= STRUCT_SIZE(mi
);
1078 if (copyout(u_minfos
, out
, len
) != 0)
1085 * This ioctl returns information for the specified mechanism.
1089 get_all_mechanism_info(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
1091 STRUCT_DECL(crypto_get_all_mechanism_info
, get_all_mech
);
1093 STRUCT_DECL(crypto_mechanism_info
, mi
);
1095 /* LINTED E_FUNC_SET_NOT_USED */
1096 STRUCT_DECL(crypto_mechanism_info
, mi
);
1098 crypto_mech_name_t mech_name
;
1099 crypto_mech_type_t mech_type
;
1100 crypto_mechanism_info_t
*mech_infos
= NULL
;
1101 uint_t num_mech_infos
= 0;
1108 STRUCT_INIT(get_all_mech
, mode
);
1109 STRUCT_INIT(mi
, mode
);
1111 if (copyin(arg
, STRUCT_BUF(get_all_mech
),
1112 STRUCT_SIZE(get_all_mech
)) != 0) {
1116 (void) strncpy(mech_name
, STRUCT_FGET(get_all_mech
, mi_mechanism_name
),
1117 CRYPTO_MAX_MECH_NAME
);
1118 mech_type
= crypto_mech2id(mech_name
);
1120 if (mech_type
== CRYPTO_MECH_INVALID
) {
1121 rv
= CRYPTO_ARGUMENTS_BAD
;
1125 rv
= crypto_get_all_mech_info(mech_type
, &mech_infos
, &num_mech_infos
,
1127 if (rv
!= CRYPTO_SUCCESS
) {
1130 /* rv is CRYPTO_SUCCESS at this point */
1132 /* Number of entries caller thinks we have */
1133 req_count
= STRUCT_FGET(get_all_mech
, mi_count
);
1135 STRUCT_FSET(get_all_mech
, mi_count
, num_mech_infos
);
1137 /* check if buffer is too small */
1138 if (num_mech_infos
> req_count
) {
1139 rv
= CRYPTO_BUFFER_TOO_SMALL
;
1143 STRUCT_FSET(get_all_mech
, mi_return_value
, rv
);
1145 /* copy the first part */
1146 if (copyout(STRUCT_BUF(get_all_mech
), arg
,
1147 STRUCT_SIZE(get_all_mech
)) != 0) {
1152 * If only requesting number of entries, or there are no entries,
1153 * or rv is not CRYPTO_SUCCESS due to buffer too small or some other
1154 * crypto error, or an error occurred with copyout, stop here
1156 if (req_count
== 0 || num_mech_infos
== 0 || rv
!= CRYPTO_SUCCESS
||
1161 /* copyout mech_infos */
1162 offset
= (ulong_t
)STRUCT_FADDR(get_all_mech
, mi_list
);
1163 offset
-= (ulong_t
)STRUCT_BUF(get_all_mech
);
1165 u_minfos
= kmem_alloc(num_mech_infos
* STRUCT_SIZE(mi
), KM_SLEEP
);
1166 error
= copyout_mechinfos(mode
, arg
+ offset
, num_mech_infos
,
1167 mech_infos
, u_minfos
);
1168 kmem_free(u_minfos
, num_mech_infos
* STRUCT_SIZE(mi
));
1170 if (mech_infos
!= NULL
)
1171 crypto_free_all_mech_info(mech_infos
, num_mech_infos
);
1177 * 1. This routine stores provider descriptor pointers in an array
1178 * and increments each descriptor's reference count. The array
1179 * is stored in per-minor number storage.
1180 * 2. Destroys the old array and creates a new one every time
1181 * this routine is called.
1184 crypto_get_provider_list(crypto_minor_t
*cm
, uint_t
*count
,
1185 crypto_provider_entry_t
**array
, boolean_t return_slot_list
)
1187 kcf_provider_desc_t
**provider_array
;
1188 crypto_provider_entry_t
*p
= NULL
;
1189 uint_t provider_count
;
1194 * Take snapshot of provider table returning only HW entries
1195 * that are in a usable state. Also returns logical provider entries.
1197 rval
= kcf_get_slot_list(&provider_count
, &provider_array
, B_FALSE
);
1198 if (rval
!= CRYPTO_SUCCESS
)
1201 /* allocate memory before taking cm->cm_lock */
1202 if (return_slot_list
) {
1203 if (provider_count
!= 0) {
1204 p
= kmem_alloc(provider_count
*
1205 sizeof (crypto_provider_entry_t
), KM_SLEEP
);
1206 for (i
= 0; i
< provider_count
; i
++) {
1207 p
[i
].pe_provider_id
= i
;
1208 p
[i
].pe_mechanism_count
=
1209 provider_array
[i
]->pd_mech_list_count
;
1213 *count
= provider_count
;
1217 * Free existing array of providers and replace with new list.
1219 mutex_enter(&cm
->cm_lock
);
1220 if (cm
->cm_provider_array
!= NULL
) {
1221 ASSERT(cm
->cm_provider_count
> 0);
1222 kcf_free_provider_tab(cm
->cm_provider_count
,
1223 cm
->cm_provider_array
);
1226 cm
->cm_provider_array
= provider_array
;
1227 cm
->cm_provider_count
= provider_count
;
1228 mutex_exit(&cm
->cm_lock
);
1230 return (CRYPTO_SUCCESS
);
1234 * This ioctl returns an array of crypto_provider_entry_t entries.
1235 * This is how consumers learn which hardware providers are available.
1239 get_provider_list(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
1241 STRUCT_DECL(crypto_get_provider_list
, get_list
);
1242 crypto_provider_entry_t
*entries
;
1244 size_t copyout_size
;
1250 STRUCT_INIT(get_list
, mode
);
1252 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
1253 cmn_err(CE_WARN
, "get_provider_list: failed holding minor");
1257 if (copyin(arg
, STRUCT_BUF(get_list
), STRUCT_SIZE(get_list
)) != 0) {
1258 crypto_release_minor(cm
);
1262 rv
= crypto_get_provider_list(cm
, &count
, &entries
, RETURN_LIST
);
1263 if (rv
!= CRYPTO_SUCCESS
) {
1264 crypto_release_minor(cm
);
1265 STRUCT_FSET(get_list
, pl_return_value
, rv
);
1266 if (copyout(STRUCT_BUF(get_list
), arg
,
1267 STRUCT_SIZE(get_list
)) != 0) {
1272 crypto_release_minor(cm
);
1274 /* Number of slots caller thinks we have */
1275 req_count
= STRUCT_FGET(get_list
, pl_count
);
1277 /* Check if only requesting number of slots */
1278 if (req_count
== 0) {
1280 STRUCT_FSET(get_list
, pl_count
, count
);
1281 STRUCT_FSET(get_list
, pl_return_value
, CRYPTO_SUCCESS
);
1283 crypto_free_provider_list(entries
, count
);
1284 if (copyout(STRUCT_BUF(get_list
), arg
,
1285 STRUCT_SIZE(get_list
)) != 0) {
1291 /* check if buffer is too small */
1292 req_count
= STRUCT_FGET(get_list
, pl_count
);
1293 if (count
> req_count
) {
1294 STRUCT_FSET(get_list
, pl_count
, count
);
1295 STRUCT_FSET(get_list
, pl_return_value
, CRYPTO_BUFFER_TOO_SMALL
);
1296 crypto_free_provider_list(entries
, count
);
1297 if (copyout(STRUCT_BUF(get_list
), arg
,
1298 STRUCT_SIZE(get_list
)) != 0) {
1304 STRUCT_FSET(get_list
, pl_count
, count
);
1305 STRUCT_FSET(get_list
, pl_return_value
, CRYPTO_SUCCESS
);
1307 copyout_size
= count
* sizeof (crypto_provider_entry_t
);
1309 /* copyout the first stuff */
1310 if (copyout(STRUCT_BUF(get_list
), arg
, STRUCT_SIZE(get_list
)) != 0) {
1311 crypto_free_provider_list(entries
, count
);
1316 crypto_free_provider_list(entries
, count
);
1320 /* copyout entries */
1321 offset
= (ulong_t
)STRUCT_FADDR(get_list
, pl_list
);
1322 offset
-= (ulong_t
)STRUCT_BUF(get_list
);
1323 if (copyout(entries
, arg
+ offset
, copyout_size
) != 0) {
1324 crypto_free_provider_list(entries
, count
);
1328 crypto_free_provider_list(entries
, count
);
1333 ext_to_provider_data(int mode
, kcf_provider_desc_t
*provider
,
1334 crypto_provider_ext_info_t
*ei
, void *out
)
1336 STRUCT_DECL(crypto_provider_data
, pd
);
1337 STRUCT_DECL(crypto_version
, version
);
1339 STRUCT_INIT(pd
, mode
);
1340 STRUCT_INIT(version
, mode
);
1342 bcopy(provider
->pd_description
, STRUCT_FGET(pd
, pd_prov_desc
),
1343 CRYPTO_PROVIDER_DESCR_MAX_LEN
);
1345 bcopy(ei
->ei_label
, STRUCT_FGET(pd
, pd_label
), CRYPTO_EXT_SIZE_LABEL
);
1346 bcopy(ei
->ei_manufacturerID
, STRUCT_FGET(pd
, pd_manufacturerID
),
1347 CRYPTO_EXT_SIZE_MANUF
);
1348 bcopy(ei
->ei_model
, STRUCT_FGET(pd
, pd_model
), CRYPTO_EXT_SIZE_MODEL
);
1349 bcopy(ei
->ei_serial_number
, STRUCT_FGET(pd
, pd_serial_number
),
1350 CRYPTO_EXT_SIZE_SERIAL
);
1352 * We do not support ioctls for dual-function crypto operations yet.
1353 * So, we clear this flag as it might have been set by a provider.
1355 ei
->ei_flags
&= ~CRYPTO_EXTF_DUAL_CRYPTO_OPERATIONS
;
1357 STRUCT_FSET(pd
, pd_flags
, ei
->ei_flags
);
1358 STRUCT_FSET(pd
, pd_max_session_count
, ei
->ei_max_session_count
);
1359 STRUCT_FSET(pd
, pd_session_count
, (int)CRYPTO_UNAVAILABLE_INFO
);
1360 STRUCT_FSET(pd
, pd_max_rw_session_count
, ei
->ei_max_session_count
);
1361 STRUCT_FSET(pd
, pd_rw_session_count
, (int)CRYPTO_UNAVAILABLE_INFO
);
1362 STRUCT_FSET(pd
, pd_max_pin_len
, ei
->ei_max_pin_len
);
1363 STRUCT_FSET(pd
, pd_min_pin_len
, ei
->ei_min_pin_len
);
1364 STRUCT_FSET(pd
, pd_total_public_memory
, ei
->ei_total_public_memory
);
1365 STRUCT_FSET(pd
, pd_free_public_memory
, ei
->ei_free_public_memory
);
1366 STRUCT_FSET(pd
, pd_total_private_memory
, ei
->ei_total_private_memory
);
1367 STRUCT_FSET(pd
, pd_free_private_memory
, ei
->ei_free_private_memory
);
1368 STRUCT_FSET(version
, cv_major
, ei
->ei_hardware_version
.cv_major
);
1369 STRUCT_FSET(version
, cv_minor
, ei
->ei_hardware_version
.cv_minor
);
1370 bcopy(STRUCT_BUF(version
), STRUCT_FADDR(pd
, pd_hardware_version
),
1371 STRUCT_SIZE(version
));
1372 STRUCT_FSET(version
, cv_major
, ei
->ei_firmware_version
.cv_major
);
1373 STRUCT_FSET(version
, cv_minor
, ei
->ei_firmware_version
.cv_minor
);
1374 bcopy(STRUCT_BUF(version
), STRUCT_FADDR(pd
, pd_firmware_version
),
1375 STRUCT_SIZE(version
));
1376 bcopy(ei
->ei_time
, STRUCT_FGET(pd
, pd_time
), CRYPTO_EXT_SIZE_TIME
);
1377 bcopy(STRUCT_BUF(pd
), out
, STRUCT_SIZE(pd
));
1381 * Utility routine to construct a crypto_provider_ext_info structure. Some
1382 * of the fields are constructed from information in the provider structure.
1383 * The rest of the fields have default values. We need to do this for
1384 * providers which do not support crypto_provider_management_ops routines.
1387 fabricate_ext_info(kcf_provider_desc_t
*provider
,
1388 crypto_provider_ext_info_t
*ei
)
1391 (void) memset(ei
->ei_label
, ' ', CRYPTO_EXT_SIZE_LABEL
);
1393 (void) memset(ei
->ei_manufacturerID
, ' ', CRYPTO_EXT_SIZE_MANUF
);
1394 (void) strncpy((char *)ei
->ei_manufacturerID
, "Unknown", 7);
1396 (void) memset(ei
->ei_model
, ' ', CRYPTO_EXT_SIZE_MODEL
);
1397 (void) strncpy((char *)ei
->ei_model
, "Unknown", 7);
1399 (void) memset(ei
->ei_serial_number
, ' ', CRYPTO_EXT_SIZE_SERIAL
);
1400 (void) strncpy((char *)ei
->ei_serial_number
, "Unknown", 7);
1402 if (KCF_PROV_RANDOM_OPS(provider
) != NULL
)
1403 ei
->ei_flags
|= CRYPTO_EXTF_RNG
;
1404 if (KCF_PROV_DUAL_OPS(provider
) != NULL
)
1405 ei
->ei_flags
|= CRYPTO_EXTF_DUAL_CRYPTO_OPERATIONS
;
1407 ei
->ei_max_session_count
= CRYPTO_UNAVAILABLE_INFO
;
1408 ei
->ei_max_pin_len
= 0;
1409 ei
->ei_min_pin_len
= 0;
1410 ei
->ei_total_public_memory
= CRYPTO_UNAVAILABLE_INFO
;
1411 ei
->ei_free_public_memory
= CRYPTO_UNAVAILABLE_INFO
;
1412 ei
->ei_total_private_memory
= CRYPTO_UNAVAILABLE_INFO
;
1413 ei
->ei_free_private_memory
= CRYPTO_UNAVAILABLE_INFO
;
1414 ei
->ei_hardware_version
.cv_major
= 1;
1415 ei
->ei_hardware_version
.cv_minor
= 0;
1416 ei
->ei_firmware_version
.cv_major
= 1;
1417 ei
->ei_firmware_version
.cv_minor
= 0;
1422 get_provider_info(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
1424 STRUCT_DECL(crypto_get_provider_info
, get_info
);
1426 crypto_provider_id_t provider_id
;
1427 kcf_provider_desc_t
*provider
, *real_provider
;
1428 crypto_provider_ext_info_t
*ext_info
= NULL
;
1432 kcf_req_params_t params
;
1434 STRUCT_INIT(get_info
, mode
);
1436 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
1437 cmn_err(CE_WARN
, "get_provider_info: failed holding minor");
1441 if (copyin(arg
, STRUCT_BUF(get_info
), STRUCT_SIZE(get_info
)) != 0) {
1442 crypto_release_minor(cm
);
1446 need
= sizeof (crypto_provider_ext_info_t
);
1447 if ((rv
= crypto_buffer_check(need
)) != CRYPTO_SUCCESS
) {
1452 /* initialize provider_array */
1453 if (cm
->cm_provider_array
== NULL
) {
1454 rv
= crypto_get_provider_list(cm
, NULL
, NULL
, DONT_RETURN_LIST
);
1455 if (rv
!= CRYPTO_SUCCESS
) {
1460 ext_info
= kmem_zalloc(need
, KM_SLEEP
);
1462 provider_id
= STRUCT_FGET(get_info
, gi_provider_id
);
1463 mutex_enter(&cm
->cm_lock
);
1464 /* index must be less than count of providers */
1465 if (provider_id
>= cm
->cm_provider_count
) {
1466 mutex_exit(&cm
->cm_lock
);
1467 rv
= CRYPTO_ARGUMENTS_BAD
;
1471 ASSERT(cm
->cm_provider_array
!= NULL
);
1472 provider
= cm
->cm_provider_array
[provider_id
];
1473 KCF_PROV_REFHOLD(provider
);
1474 mutex_exit(&cm
->cm_lock
);
1476 (void) kcf_get_hardware_provider_nomech(
1477 CRYPTO_OPS_OFFSET(provider_ops
), CRYPTO_PROVIDER_OFFSET(ext_info
),
1478 provider
, &real_provider
);
1480 if (real_provider
!= NULL
) {
1481 ASSERT(real_provider
== provider
||
1482 provider
->pd_prov_type
== CRYPTO_LOGICAL_PROVIDER
);
1483 KCF_WRAP_PROVMGMT_OPS_PARAMS(¶ms
, KCF_OP_MGMT_EXTINFO
,
1484 0, NULL
, 0, NULL
, 0, NULL
, ext_info
, provider
);
1485 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
,
1487 ASSERT(rv
!= CRYPTO_NOT_SUPPORTED
);
1488 KCF_PROV_REFRELE(real_provider
);
1490 /* do the best we can */
1491 fabricate_ext_info(provider
, ext_info
);
1492 rv
= CRYPTO_SUCCESS
;
1494 KCF_PROV_REFRELE(provider
);
1496 if (rv
== CRYPTO_SUCCESS
) {
1497 ext_to_provider_data(mode
, provider
, ext_info
,
1498 STRUCT_FADDR(get_info
, gi_provider_data
));
1502 CRYPTO_DECREMENT_RCTL(need
);
1503 crypto_release_minor(cm
);
1505 if (ext_info
!= NULL
)
1506 kmem_free(ext_info
, sizeof (crypto_provider_ext_info_t
));
1511 STRUCT_FSET(get_info
, gi_return_value
, rv
);
1512 if (copyout(STRUCT_BUF(get_info
), arg
, STRUCT_SIZE(get_info
)) != 0) {
1519 * This ioctl returns an array of crypto_mech_name_t entries.
1520 * This is how consumers learn which mechanisms are permitted
1525 get_provider_mechanisms(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
1527 STRUCT_DECL(crypto_get_provider_mechanisms
, get_mechanisms
);
1528 crypto_mech_name_t
*entries
;
1530 size_t copyout_size
;
1536 STRUCT_INIT(get_mechanisms
, mode
);
1538 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
1540 "get_provider_mechanisms: failed holding minor");
1544 if (copyin(arg
, STRUCT_BUF(get_mechanisms
),
1545 STRUCT_SIZE(get_mechanisms
)) != 0) {
1546 crypto_release_minor(cm
);
1550 /* get array of mechanisms from the core module */
1551 if ((err
= crypto_get_provider_mechanisms(cm
,
1552 STRUCT_FGET(get_mechanisms
, pm_provider_id
),
1553 &count
, &entries
)) != 0) {
1554 crypto_release_minor(cm
);
1555 STRUCT_FSET(get_mechanisms
, pm_return_value
, err
);
1556 if (copyout(STRUCT_BUF(get_mechanisms
), arg
,
1557 STRUCT_SIZE(get_mechanisms
)) != 0) {
1562 crypto_release_minor(cm
);
1563 /* Number of mechs caller thinks we have */
1564 req_count
= STRUCT_FGET(get_mechanisms
, pm_count
);
1566 /* Check if caller is just requesting a count of mechanisms */
1567 if (req_count
== 0) {
1568 STRUCT_FSET(get_mechanisms
, pm_count
, count
);
1569 STRUCT_FSET(get_mechanisms
, pm_return_value
, CRYPTO_SUCCESS
);
1571 crypto_free_mech_list(entries
, count
);
1572 if (copyout(STRUCT_BUF(get_mechanisms
), arg
,
1573 STRUCT_SIZE(get_mechanisms
)) != 0) {
1579 /* check if buffer is too small */
1580 if (count
> req_count
) {
1581 STRUCT_FSET(get_mechanisms
, pm_count
, count
);
1582 STRUCT_FSET(get_mechanisms
, pm_return_value
,
1583 CRYPTO_BUFFER_TOO_SMALL
);
1584 crypto_free_mech_list(entries
, count
);
1585 if (copyout(STRUCT_BUF(get_mechanisms
), arg
,
1586 STRUCT_SIZE(get_mechanisms
)) != 0) {
1592 STRUCT_FSET(get_mechanisms
, pm_count
, count
);
1593 STRUCT_FSET(get_mechanisms
, pm_return_value
, CRYPTO_SUCCESS
);
1595 copyout_size
= count
* sizeof (crypto_mech_name_t
);
1597 /* copyout the first stuff */
1598 if (copyout(STRUCT_BUF(get_mechanisms
), arg
,
1599 STRUCT_SIZE(get_mechanisms
)) != 0) {
1600 crypto_free_mech_list(entries
, count
);
1608 /* copyout entries */
1609 offset
= (ulong_t
)STRUCT_FADDR(get_mechanisms
, pm_list
);
1610 offset
-= (ulong_t
)STRUCT_BUF(get_mechanisms
);
1611 if (copyout(entries
, arg
+ offset
, copyout_size
) != 0) {
1612 crypto_free_mech_list(entries
, count
);
1616 crypto_free_mech_list(entries
, count
);
1621 * This ioctl returns information about a provider's mechanism.
1625 get_provider_mechanism_info(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
1627 crypto_get_provider_mechanism_info_t mechanism_info
;
1629 kcf_provider_desc_t
*pd
;
1630 crypto_mech_info_t
*mi
= NULL
;
1631 int rv
= CRYPTO_SUCCESS
;
1634 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
1636 "get_provider_mechanism_info: failed holding minor");
1640 if (copyin(arg
, &mechanism_info
, sizeof (mechanism_info
)) != 0) {
1641 crypto_release_minor(cm
);
1645 /* initialize provider table */
1646 if (cm
->cm_provider_array
== NULL
) {
1647 rv
= crypto_get_provider_list(cm
, NULL
, NULL
, DONT_RETURN_LIST
);
1648 if (rv
!= CRYPTO_SUCCESS
) {
1649 mutex_enter(&cm
->cm_lock
);
1655 * Provider ID must be less than the count of providers
1656 * obtained by calling get_provider_list().
1658 mutex_enter(&cm
->cm_lock
);
1659 if (mechanism_info
.mi_provider_id
>= cm
->cm_provider_count
) {
1660 rv
= CRYPTO_ARGUMENTS_BAD
;
1664 pd
= cm
->cm_provider_array
[mechanism_info
.mi_provider_id
];
1666 /* First check if the provider supports the mechanism. */
1667 for (i
= 0; i
< pd
->pd_mech_list_count
; i
++) {
1668 if (strncmp(pd
->pd_mechanisms
[i
].cm_mech_name
,
1669 mechanism_info
.mi_mechanism_name
,
1670 CRYPTO_MAX_MECH_NAME
) == 0) {
1671 mi
= &pd
->pd_mechanisms
[i
];
1677 rv
= CRYPTO_ARGUMENTS_BAD
;
1681 /* Now check if the mechanism is enabled for the provider. */
1682 if (is_mech_disabled(pd
, mechanism_info
.mi_mechanism_name
)) {
1683 rv
= CRYPTO_MECHANISM_INVALID
;
1687 mechanism_info
.mi_min_key_size
= mi
->cm_min_key_length
;
1688 mechanism_info
.mi_max_key_size
= mi
->cm_max_key_length
;
1689 mechanism_info
.mi_flags
= mi
->cm_func_group_mask
;
1692 mutex_exit(&cm
->cm_lock
);
1693 crypto_release_minor(cm
);
1694 mechanism_info
.mi_return_value
= rv
;
1695 if (copyout(&mechanism_info
, arg
, sizeof (mechanism_info
)) != 0) {
1703 * Every open of /dev/crypto multiplexes all PKCS#11 sessions across
1704 * a single session to each provider. Calls to open and close session
1705 * are not made to providers that do not support sessions. For these
1706 * providers, a session number of 0 is passed during subsequent operations,
1707 * and it is ignored by the provider.
1710 crypto_get_provider_session(crypto_minor_t
*cm
,
1711 crypto_provider_id_t provider_index
, crypto_provider_session_t
**output_ps
)
1713 kcf_provider_desc_t
*pd
, *real_provider
;
1714 kcf_req_params_t params
;
1715 crypto_provider_session_t
*ps
;
1716 crypto_session_id_t provider_session_id
= 0;
1719 ASSERT(MUTEX_HELD(&cm
->cm_lock
));
1721 /* pd may be a logical provider */
1722 pd
= cm
->cm_provider_array
[provider_index
];
1726 * Check if there is already a session to the provider.
1727 * Sessions may be to a logical provider or a real provider.
1729 for (ps
= cm
->cm_provider_session
; ps
!= NULL
; ps
= ps
->ps_next
) {
1730 if (ps
->ps_provider
== pd
)
1734 /* found existing session */
1738 return (CRYPTO_SUCCESS
);
1740 mutex_exit(&cm
->cm_lock
);
1742 /* find a hardware provider that supports session ops */
1743 (void) kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET(session_ops
),
1744 CRYPTO_SESSION_OFFSET(session_open
), pd
, &real_provider
);
1746 if (real_provider
!= NULL
) {
1747 ASSERT(real_provider
== pd
||
1748 pd
->pd_prov_type
== CRYPTO_LOGICAL_PROVIDER
);
1749 /* open session to provider */
1750 KCF_WRAP_SESSION_OPS_PARAMS(¶ms
, KCF_OP_SESSION_OPEN
,
1751 &provider_session_id
, 0, CRYPTO_USER
, NULL
, 0, pd
);
1752 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
,
1754 if (rv
!= CRYPTO_SUCCESS
) {
1755 mutex_enter(&cm
->cm_lock
);
1756 KCF_PROV_REFRELE(real_provider
);
1762 * Check if someone opened a session to the provider
1763 * while we dropped the lock.
1765 mutex_enter(&cm
->cm_lock
);
1766 for (ps
= cm
->cm_provider_session
; ps
!= NULL
; ps
= ps
->ps_next
) {
1767 if (ps
->ps_provider
== pd
) {
1768 mutex_exit(&cm
->cm_lock
);
1769 if (real_provider
!= NULL
) {
1770 KCF_WRAP_SESSION_OPS_PARAMS(¶ms
,
1771 KCF_OP_SESSION_CLOSE
, NULL
,
1772 provider_session_id
, CRYPTO_USER
, NULL
, 0,
1774 (void) kcf_submit_request(real_provider
, NULL
,
1775 NULL
, ¶ms
, B_FALSE
);
1776 KCF_PROV_REFRELE(real_provider
);
1778 mutex_enter(&cm
->cm_lock
);
1784 return (crypto_create_provider_session(cm
, pd
, provider_session_id
,
1785 output_ps
, real_provider
));
1789 crypto_create_provider_session(crypto_minor_t
*cm
, kcf_provider_desc_t
*pd
,
1790 crypto_session_id_t sid
, crypto_provider_session_t
**out_ps
,
1791 kcf_provider_desc_t
*real
)
1793 crypto_provider_session_t
*ps
;
1795 /* allocate crypto_provider_session structure */
1796 ps
= kmem_zalloc(sizeof (crypto_provider_session_t
), KM_SLEEP
);
1798 /* increment refcnt and attach to crypto_minor structure */
1799 ps
->ps_session
= sid
;
1801 KCF_PROV_REFHOLD(pd
);
1802 ps
->ps_provider
= pd
;
1804 ps
->ps_real_provider
= real
;
1806 ps
->ps_next
= cm
->cm_provider_session
;
1807 cm
->cm_provider_session
= ps
;
1810 return (CRYPTO_SUCCESS
);
1814 * Release a provider session.
1815 * If the reference count goes to zero, then close the session
1819 crypto_release_provider_session(crypto_minor_t
*cm
,
1820 crypto_provider_session_t
*provider_session
)
1822 kcf_req_params_t params
;
1823 crypto_provider_session_t
*ps
= NULL
, **prev
;
1825 ASSERT(MUTEX_HELD(&cm
->cm_lock
));
1827 /* verify that provider_session is valid */
1828 for (ps
= cm
->cm_provider_session
, prev
= &cm
->cm_provider_session
;
1829 ps
!= NULL
; prev
= &ps
->ps_next
, ps
= ps
->ps_next
) {
1830 if (ps
== provider_session
) {
1840 if (ps
->ps_refcnt
> 0)
1843 if (ps
->ps_real_provider
!= NULL
) {
1844 /* close session with provider */
1845 KCF_WRAP_SESSION_OPS_PARAMS(¶ms
, KCF_OP_SESSION_CLOSE
, NULL
,
1846 ps
->ps_session
, CRYPTO_USER
, NULL
, 0, ps
->ps_provider
);
1847 (void) kcf_submit_request(ps
->ps_real_provider
,
1848 NULL
, NULL
, ¶ms
, B_FALSE
);
1849 KCF_PROV_REFRELE(ps
->ps_real_provider
);
1851 KCF_PROV_REFRELE(ps
->ps_provider
);
1852 *prev
= ps
->ps_next
;
1853 kmem_free(ps
, sizeof (*ps
));
1857 grow_session_table(crypto_minor_t
*cm
)
1859 crypto_session_data_t
**session_table
;
1860 crypto_session_data_t
**new;
1861 uint_t session_table_count
;
1863 size_t current_allocation
;
1864 size_t new_allocation
;
1867 ASSERT(MUTEX_HELD(&cm
->cm_lock
));
1869 session_table_count
= cm
->cm_session_table_count
;
1870 session_table
= cm
->cm_session_table
;
1871 need
= session_table_count
+ CRYPTO_SESSION_CHUNK
;
1873 current_allocation
= session_table_count
* sizeof (void *);
1874 new_allocation
= need
* sizeof (void *);
1877 * Memory needed to grow the session table is checked
1878 * against the project.max-crypto-memory resource control.
1880 if ((rv
= crypto_buffer_check(new_allocation
- current_allocation
)) !=
1885 /* drop lock while we allocate memory */
1886 mutex_exit(&cm
->cm_lock
);
1887 new = kmem_zalloc(new_allocation
, KM_SLEEP
);
1888 mutex_enter(&cm
->cm_lock
);
1890 /* check if another thread increased the table size */
1891 if (session_table_count
!= cm
->cm_session_table_count
) {
1892 kmem_free(new, new_allocation
);
1893 return (CRYPTO_SUCCESS
);
1896 bcopy(session_table
, new, current_allocation
);
1897 kmem_free(session_table
, current_allocation
);
1898 cm
->cm_session_table
= new;
1899 cm
->cm_session_table_count
+= CRYPTO_SESSION_CHUNK
;
1901 return (CRYPTO_SUCCESS
);
1905 * Find unused entry in session table and return its index.
1906 * Initialize session table entry.
1910 crypto_open_session(dev_t dev
, uint_t flags
, crypto_session_id_t
*session_index
,
1911 crypto_provider_id_t provider_id
)
1915 crypto_provider_session_t
*ps
;
1916 kcf_provider_desc_t
*provider
;
1918 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
1919 cmn_err(CE_WARN
, "crypto_open_session: failed holding minor");
1920 return (CRYPTO_FAILED
);
1923 /* initialize provider_array */
1924 if (cm
->cm_provider_array
== NULL
) {
1925 rv
= crypto_get_provider_list(cm
, NULL
, NULL
, DONT_RETURN_LIST
);
1927 crypto_release_minor(cm
);
1932 mutex_enter(&cm
->cm_lock
);
1933 /* index must be less than count of providers */
1934 if (provider_id
>= cm
->cm_provider_count
) {
1935 mutex_exit(&cm
->cm_lock
);
1936 crypto_release_minor(cm
);
1937 return (CRYPTO_INVALID_PROVIDER_ID
);
1939 ASSERT(cm
->cm_provider_array
!= NULL
);
1941 rv
= crypto_get_provider_session(cm
, provider_id
, &ps
);
1942 if (rv
!= CRYPTO_SUCCESS
) {
1943 mutex_exit(&cm
->cm_lock
);
1944 crypto_release_minor(cm
);
1947 provider
= cm
->cm_provider_array
[provider_id
];
1949 rv
= crypto_create_session_ptr(cm
, provider
, ps
, session_index
);
1950 mutex_exit(&cm
->cm_lock
);
1951 crypto_release_minor(cm
);
1957 crypto_create_session_ptr(crypto_minor_t
*cm
, kcf_provider_desc_t
*provider
,
1958 crypto_provider_session_t
*ps
, crypto_session_id_t
*session_index
)
1960 crypto_session_data_t
**session_table
;
1961 crypto_session_data_t
*sp
;
1962 uint_t session_table_count
;
1966 ASSERT(MUTEX_HELD(&cm
->cm_lock
));
1969 session_table_count
= cm
->cm_session_table_count
;
1970 session_table
= cm
->cm_session_table
;
1972 /* session handles start with 1 */
1973 for (i
= 1; i
< session_table_count
; i
++) {
1974 if (session_table
[i
] == NULL
)
1978 if (i
== session_table_count
|| session_table_count
== 0) {
1979 if ((rv
= grow_session_table(cm
)) != CRYPTO_SUCCESS
) {
1980 crypto_release_provider_session(cm
, ps
);
1986 sp
= kmem_cache_alloc(crypto_session_cache
, KM_SLEEP
);
1988 sp
->sd_find_init_cookie
= NULL
;
1989 sp
->sd_digest_ctx
= NULL
;
1990 sp
->sd_encr_ctx
= NULL
;
1991 sp
->sd_decr_ctx
= NULL
;
1992 sp
->sd_sign_ctx
= NULL
;
1993 sp
->sd_verify_ctx
= NULL
;
1994 sp
->sd_mac_ctx
= NULL
;
1995 sp
->sd_sign_recover_ctx
= NULL
;
1996 sp
->sd_verify_recover_ctx
= NULL
;
1997 mutex_init(&sp
->sd_lock
, NULL
, MUTEX_DRIVER
, NULL
);
1998 cv_init(&sp
->sd_cv
, NULL
, CV_DRIVER
, NULL
);
1999 KCF_PROV_REFHOLD(provider
);
2000 sp
->sd_provider
= provider
;
2001 sp
->sd_provider_session
= ps
;
2003 /* See the comment for CRYPTO_PRE_APPROVED_LIMIT. */
2004 if ((rv
= crypto_buffer_check(crypto_pre_approved_limit
)) !=
2006 sp
->sd_pre_approved_amount
= 0;
2008 sp
->sd_pre_approved_amount
= (int)crypto_pre_approved_limit
;
2011 cm
->cm_session_table
[i
] = sp
;
2012 if (session_index
!= NULL
)
2015 return (CRYPTO_SUCCESS
);
2022 crypto_close_session(dev_t dev
, crypto_session_id_t session_index
)
2024 crypto_session_data_t
**session_table
;
2025 crypto_session_data_t
*sp
;
2028 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
2029 cmn_err(CE_WARN
, "crypto_close_session: failed holding minor");
2030 return (CRYPTO_FAILED
);
2033 mutex_enter(&cm
->cm_lock
);
2034 session_table
= cm
->cm_session_table
;
2036 if ((session_index
) == 0 ||
2037 (session_index
>= cm
->cm_session_table_count
)) {
2038 mutex_exit(&cm
->cm_lock
);
2039 crypto_release_minor(cm
);
2040 return (CRYPTO_SESSION_HANDLE_INVALID
);
2043 sp
= session_table
[session_index
];
2045 mutex_exit(&cm
->cm_lock
);
2046 crypto_release_minor(cm
);
2047 return (CRYPTO_SESSION_HANDLE_INVALID
);
2050 * If session is in use, free it when the thread
2051 * finishes with the session.
2053 mutex_enter(&sp
->sd_lock
);
2054 if (sp
->sd_flags
& CRYPTO_SESSION_IS_BUSY
) {
2055 sp
->sd_flags
|= CRYPTO_SESSION_IS_CLOSED
;
2056 mutex_exit(&sp
->sd_lock
);
2058 ASSERT(sp
->sd_pre_approved_amount
== 0 ||
2059 sp
->sd_pre_approved_amount
== crypto_pre_approved_limit
);
2060 CRYPTO_DECREMENT_RCTL(sp
->sd_pre_approved_amount
);
2062 if (sp
->sd_find_init_cookie
!= NULL
) {
2063 (void) crypto_free_find_ctx(sp
);
2066 crypto_release_provider_session(cm
, sp
->sd_provider_session
);
2067 KCF_PROV_REFRELE(sp
->sd_provider
);
2068 CRYPTO_CANCEL_ALL_CTX(sp
);
2069 mutex_destroy(&sp
->sd_lock
);
2070 cv_destroy(&sp
->sd_cv
);
2071 kmem_cache_free(crypto_session_cache
, sp
);
2072 session_table
[session_index
] = NULL
;
2075 mutex_exit(&cm
->cm_lock
);
2076 crypto_release_minor(cm
);
2078 return (CRYPTO_SUCCESS
);
2082 * This ioctl opens a session and returns the session ID in os_session.
2086 open_session(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
2088 crypto_open_session_t open_session
;
2089 crypto_session_id_t session
;
2092 if (copyin(arg
, &open_session
, sizeof (open_session
)) != 0)
2095 rv
= crypto_open_session(dev
, open_session
.os_flags
,
2096 &session
, open_session
.os_provider_id
);
2097 if (rv
!= CRYPTO_SUCCESS
) {
2098 open_session
.os_return_value
= rv
;
2099 if (copyout(&open_session
, arg
, sizeof (open_session
)) != 0) {
2105 open_session
.os_session
= session
;
2106 open_session
.os_return_value
= CRYPTO_SUCCESS
;
2108 if (copyout(&open_session
, arg
, sizeof (open_session
)) != 0) {
2115 * This ioctl closes a session.
2119 close_session(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
2121 crypto_close_session_t close_session
;
2124 if (copyin(arg
, &close_session
, sizeof (close_session
)) != 0)
2127 rv
= crypto_close_session(dev
, close_session
.cs_session
);
2128 close_session
.cs_return_value
= rv
;
2129 if (copyout(&close_session
, arg
, sizeof (close_session
)) != 0) {
2136 * Copy data model dependent mechanism structure into a kernel mechanism
2137 * structure. Allocate param storage if necessary.
2140 copyin_mech(int mode
, crypto_session_data_t
*sp
, crypto_mechanism_t
*in_mech
,
2141 crypto_mechanism_t
*out_mech
, size_t *out_rctl_bytes
,
2142 boolean_t
*out_rctl_chk
, int *out_rv
, int *out_error
)
2144 STRUCT_DECL(crypto_mechanism
, mech
);
2147 size_t rctl_bytes
= 0;
2151 STRUCT_INIT(mech
, mode
);
2152 bcopy(in_mech
, STRUCT_BUF(mech
), STRUCT_SIZE(mech
));
2153 param
= STRUCT_FGETP(mech
, cm_param
);
2154 param_len
= STRUCT_FGET(mech
, cm_param_len
);
2155 out_mech
->cm_type
= STRUCT_FGET(mech
, cm_type
);
2156 out_mech
->cm_param
= NULL
;
2157 out_mech
->cm_param_len
= 0;
2158 if (param
!= NULL
&& param_len
!= 0) {
2159 if (param_len
> crypto_max_buffer_len
) {
2160 cmn_err(CE_NOTE
, "copyin_mech: buffer greater than "
2161 "%ld bytes, pid = %d", crypto_max_buffer_len
,
2163 rv
= CRYPTO_ARGUMENTS_BAD
;
2167 rv
= CRYPTO_BUFFER_CHECK(sp
, param_len
, *out_rctl_chk
);
2168 if (rv
!= CRYPTO_SUCCESS
) {
2171 rctl_bytes
= param_len
;
2173 out_mech
->cm_param
= kmem_alloc(param_len
, KM_SLEEP
);
2174 if (copyin((char *)param
, out_mech
->cm_param
, param_len
) != 0) {
2175 kmem_free(out_mech
->cm_param
, param_len
);
2176 out_mech
->cm_param
= NULL
;
2180 out_mech
->cm_param_len
= param_len
;
2183 *out_rctl_bytes
= rctl_bytes
;
2186 return ((rv
| error
) ? B_FALSE
: B_TRUE
);
2190 * Free key attributes when key type is CRYPTO_KEY_ATTR_LIST.
2191 * The crypto_key structure is not freed.
2194 crypto_free_key_attributes(crypto_key_t
*key
)
2196 crypto_object_attribute_t
*attrs
;
2200 ASSERT(key
->ck_format
== CRYPTO_KEY_ATTR_LIST
);
2201 if (key
->ck_count
== 0 || key
->ck_attrs
== NULL
)
2204 /* compute the size of the container */
2205 len
= key
->ck_count
* sizeof (crypto_object_attribute_t
);
2207 /* total up the size of all attributes in the container */
2208 for (i
= 0; i
< key
->ck_count
; i
++) {
2209 attrs
= &key
->ck_attrs
[i
];
2210 if (attrs
->oa_value_len
!= 0 &&
2211 attrs
->oa_value
!= NULL
) {
2212 len
+= roundup(attrs
->oa_value_len
, sizeof (caddr_t
));
2216 bzero(key
->ck_attrs
, len
);
2217 kmem_free(key
->ck_attrs
, len
);
2221 * Frees allocated storage in the key structure, but doesn't free
2222 * the key structure.
2225 free_crypto_key(crypto_key_t
*key
)
2227 switch (key
->ck_format
) {
2228 case CRYPTO_KEY_RAW
: {
2231 if (key
->ck_length
== 0 || key
->ck_data
== NULL
)
2234 len
= CRYPTO_BITS2BYTES(key
->ck_length
);
2235 bzero(key
->ck_data
, len
);
2236 kmem_free(key
->ck_data
, len
);
2240 case CRYPTO_KEY_ATTR_LIST
:
2241 crypto_free_key_attributes(key
);
2250 * Copy in an array of crypto_object_attribute structures from user-space.
2251 * Kernel memory is allocated for the array and the value of each attribute
2252 * in the array. Since unprivileged users can specify the size of attributes,
2253 * the amount of memory needed is charged against the
2254 * project.max-crypto-memory resource control.
2256 * Attribute values are copied in from user-space if copyin_value is set to
2257 * B_TRUE. This routine returns B_TRUE if the copyin was successful.
2260 copyin_attributes(int mode
, crypto_session_data_t
*sp
,
2261 uint_t count
, caddr_t oc_attributes
,
2262 crypto_object_attribute_t
**k_attrs_out
, size_t *k_attrs_size_out
,
2263 caddr_t
*u_attrs_out
, int *out_rv
, int *out_error
, size_t *out_rctl_bytes
,
2264 boolean_t
*out_rctl_chk
, boolean_t copyin_value
)
2266 STRUCT_DECL(crypto_object_attribute
, oa
);
2267 crypto_object_attribute_t
*k_attrs
= NULL
;
2268 caddr_t attrs
= NULL
, ap
, p
, value
;
2269 caddr_t k_attrs_buf
;
2271 size_t k_attrs_buf_len
= 0;
2272 size_t k_attrs_total_len
= 0;
2274 size_t rctl_bytes
= 0;
2281 STRUCT_INIT(oa
, mode
);
2284 rv
= CRYPTO_SUCCESS
;
2288 if (count
> CRYPTO_MAX_ATTRIBUTE_COUNT
) {
2289 rv
= CRYPTO_ARGUMENTS_BAD
;
2293 /* compute size of crypto_object_attribute array */
2294 len
= count
* STRUCT_SIZE(oa
);
2296 /* this allocation is not charged against the user's resource limit */
2297 attrs
= kmem_alloc(len
, KM_SLEEP
);
2298 if (copyin(oc_attributes
, attrs
, len
) != 0) {
2303 /* figure out how much memory to allocate for all of the attributes */
2305 for (i
= 0; i
< count
; i
++) {
2306 bcopy(ap
, STRUCT_BUF(oa
), STRUCT_SIZE(oa
));
2307 tmp_len
= roundup(STRUCT_FGET(oa
, oa_value_len
),
2309 if (tmp_len
> crypto_max_buffer_len
) {
2310 cmn_err(CE_NOTE
, "copyin_attributes: buffer greater "
2311 "than %ld bytes, pid = %d", crypto_max_buffer_len
,
2313 rv
= CRYPTO_ARGUMENTS_BAD
;
2316 if (STRUCT_FGETP(oa
, oa_value
) != NULL
)
2317 k_attrs_buf_len
+= tmp_len
;
2318 ap
+= STRUCT_SIZE(oa
);
2321 k_attrs_len
= count
* sizeof (crypto_object_attribute_t
);
2322 k_attrs_total_len
= k_attrs_buf_len
+ k_attrs_len
;
2324 rv
= CRYPTO_BUFFER_CHECK(sp
, k_attrs_total_len
, *out_rctl_chk
);
2325 if (rv
!= CRYPTO_SUCCESS
) {
2328 rctl_bytes
= k_attrs_total_len
;
2330 /* one big allocation for everything */
2331 k_attrs
= kmem_alloc(k_attrs_total_len
, KM_SLEEP
);
2332 k_attrs_buf
= (char *)k_attrs
+ k_attrs_len
;
2336 for (i
= 0; i
< count
; i
++) {
2337 bcopy(ap
, STRUCT_BUF(oa
), STRUCT_SIZE(oa
));
2338 k_attrs
[i
].oa_type
= STRUCT_FGET(oa
, oa_type
);
2339 value
= STRUCT_FGETP(oa
, oa_value
);
2340 value_len
= STRUCT_FGET(oa
, oa_value_len
);
2341 if (value
!= NULL
&& value_len
!= 0 && copyin_value
) {
2342 if (copyin(value
, p
, value_len
) != 0) {
2343 kmem_free(k_attrs
, k_attrs_total_len
);
2350 if (value
!= NULL
) {
2351 k_attrs
[i
].oa_value
= p
;
2352 p
+= roundup(value_len
, sizeof (caddr_t
));
2354 k_attrs
[i
].oa_value
= NULL
;
2356 k_attrs
[i
].oa_value_len
= value_len
;
2357 ap
+= STRUCT_SIZE(oa
);
2360 if (attrs
!= NULL
) {
2362 * Free the array if there is a failure or the caller
2363 * doesn't want the array to be returned.
2365 if (error
!= 0 || rv
!= CRYPTO_SUCCESS
|| u_attrs_out
== NULL
) {
2366 kmem_free(attrs
, len
);
2371 if (u_attrs_out
!= NULL
)
2372 *u_attrs_out
= attrs
;
2373 if (k_attrs_size_out
!= NULL
)
2374 *k_attrs_size_out
= k_attrs_total_len
;
2375 *k_attrs_out
= k_attrs
;
2376 *out_rctl_bytes
= rctl_bytes
;
2379 return ((rv
| error
) ? B_FALSE
: B_TRUE
);
2383 * Copy data model dependent raw key into a kernel key
2384 * structure. Checks key length or attribute lengths against
2385 * resource controls before allocating memory. Returns B_TRUE
2386 * if both error and rv are set to 0.
2389 copyin_key(int mode
, crypto_session_data_t
*sp
, crypto_key_t
*in_key
,
2390 crypto_key_t
*out_key
, size_t *out_rctl_bytes
,
2391 boolean_t
*out_rctl_chk
, int *out_rv
, int *out_error
)
2393 STRUCT_DECL(crypto_key
, key
);
2394 crypto_object_attribute_t
*k_attrs
= NULL
;
2396 size_t key_bytes
= 0;
2397 size_t rctl_bytes
= 0;
2400 int rv
= CRYPTO_SUCCESS
;
2402 STRUCT_INIT(key
, mode
);
2403 bcopy(in_key
, STRUCT_BUF(key
), STRUCT_SIZE(key
));
2404 out_key
->ck_format
= STRUCT_FGET(key
, ck_format
);
2405 switch (out_key
->ck_format
) {
2406 case CRYPTO_KEY_RAW
:
2407 key_bits
= STRUCT_FGET(key
, ck_length
);
2408 if (key_bits
!= 0) {
2410 (CRYPTO_BYTES2BITS(crypto_max_buffer_len
))) {
2411 cmn_err(CE_NOTE
, "copyin_key: buffer greater "
2412 "than %ld bytes, pid = %d",
2413 crypto_max_buffer_len
, curproc
->p_pid
);
2414 rv
= CRYPTO_ARGUMENTS_BAD
;
2417 key_bytes
= CRYPTO_BITS2BYTES(key_bits
);
2419 rv
= CRYPTO_BUFFER_CHECK(sp
, key_bytes
,
2421 if (rv
!= CRYPTO_SUCCESS
) {
2424 rctl_bytes
= key_bytes
;
2426 out_key
->ck_data
= kmem_alloc(key_bytes
, KM_SLEEP
);
2428 if (copyin((char *)STRUCT_FGETP(key
, ck_data
),
2429 out_key
->ck_data
, key_bytes
) != 0) {
2430 kmem_free(out_key
->ck_data
, key_bytes
);
2431 out_key
->ck_data
= NULL
;
2432 out_key
->ck_length
= 0;
2437 out_key
->ck_length
= (ulong_t
)key_bits
;
2440 case CRYPTO_KEY_ATTR_LIST
:
2441 count
= STRUCT_FGET(key
, ck_count
);
2443 if (copyin_attributes(mode
, sp
, count
,
2444 (caddr_t
)STRUCT_FGETP(key
, ck_attrs
), &k_attrs
, NULL
, NULL
,
2445 &rv
, &error
, &rctl_bytes
, out_rctl_chk
, B_TRUE
)) {
2446 out_key
->ck_count
= count
;
2447 out_key
->ck_attrs
= k_attrs
;
2450 out_key
->ck_count
= 0;
2451 out_key
->ck_attrs
= NULL
;
2455 case CRYPTO_KEY_REFERENCE
:
2456 out_key
->ck_obj_id
= STRUCT_FGET(key
, ck_obj_id
);
2460 rv
= CRYPTO_ARGUMENTS_BAD
;
2464 *out_rctl_bytes
= rctl_bytes
;
2467 return ((rv
| error
) ? B_FALSE
: B_TRUE
);
2471 * This routine does two things:
2472 * 1. Given a crypto_minor structure and a session ID, it returns
2473 * a valid session pointer.
2474 * 2. It checks that the provider, to which the session has been opened,
2475 * has not been removed.
2478 get_session_ptr(crypto_session_id_t i
, crypto_minor_t
*cm
,
2479 crypto_session_data_t
**session_ptr
, int *out_error
, int *out_rv
)
2481 crypto_session_data_t
*sp
= NULL
;
2482 int rv
= CRYPTO_SESSION_HANDLE_INVALID
;
2485 mutex_enter(&cm
->cm_lock
);
2486 if ((i
< cm
->cm_session_table_count
) &&
2487 (cm
->cm_session_table
[i
] != NULL
)) {
2488 sp
= cm
->cm_session_table
[i
];
2489 mutex_enter(&sp
->sd_lock
);
2490 mutex_exit(&cm
->cm_lock
);
2491 while (sp
->sd_flags
& CRYPTO_SESSION_IS_BUSY
) {
2492 if (cv_wait_sig(&sp
->sd_cv
, &sp
->sd_lock
) == 0) {
2493 mutex_exit(&sp
->sd_lock
);
2500 if (sp
->sd_flags
& CRYPTO_SESSION_IS_CLOSED
) {
2501 mutex_exit(&sp
->sd_lock
);
2506 if (KCF_IS_PROV_REMOVED(sp
->sd_provider
)) {
2507 mutex_exit(&sp
->sd_lock
);
2509 rv
= CRYPTO_DEVICE_ERROR
;
2513 rv
= CRYPTO_SUCCESS
;
2514 sp
->sd_flags
|= CRYPTO_SESSION_IS_BUSY
;
2515 mutex_exit(&sp
->sd_lock
);
2517 mutex_exit(&cm
->cm_lock
);
2523 return ((rv
== CRYPTO_SUCCESS
&& error
== 0) ? B_TRUE
: B_FALSE
);
2526 #define CRYPTO_SESSION_RELE(s) if ((s) != NULL) { \
2527 mutex_enter(&((s)->sd_lock)); \
2528 (s)->sd_flags &= ~CRYPTO_SESSION_IS_BUSY; \
2529 cv_broadcast(&(s)->sd_cv); \
2530 mutex_exit(&((s)->sd_lock)); \
2535 encrypt_init(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
2537 return (cipher_init(dev
, arg
, mode
, crypto_encrypt_init_prov
));
2542 decrypt_init(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
2544 return (cipher_init(dev
, arg
, mode
, crypto_decrypt_init_prov
));
2548 * umech is a mechanism structure that has been copied from user address
2549 * space into kernel address space. Only one copyin has been done.
2550 * The mechanism parameter, if non-null, still points to user address space.
2551 * If the mechanism parameter contains pointers, they are pointers into
2552 * user address space.
2554 * kmech is a umech with all pointers and structures in kernel address space.
2556 * This routine calls the provider's entry point to copy a umech parameter
2557 * into kernel address space. Kernel memory is allocated by the provider.
2560 crypto_provider_copyin_mech_param(kcf_provider_desc_t
*pd
,
2561 crypto_mechanism_t
*umech
, crypto_mechanism_t
*kmech
, int mode
, int *error
)
2563 crypto_mech_type_t provider_mech_type
;
2566 /* get the provider's mech number */
2567 provider_mech_type
= KCF_TO_PROV_MECHNUM(pd
, umech
->cm_type
);
2569 kmech
->cm_param
= NULL
;
2570 kmech
->cm_param_len
= 0;
2571 kmech
->cm_type
= provider_mech_type
;
2572 rv
= KCF_PROV_COPYIN_MECH(pd
, umech
, kmech
, error
, mode
);
2573 kmech
->cm_type
= umech
->cm_type
;
2579 * umech is a mechanism structure that has been copied from user address
2580 * space into kernel address space. Only one copyin has been done.
2581 * The mechanism parameter, if non-null, still points to user address space.
2582 * If the mechanism parameter contains pointers, they are pointers into
2583 * user address space.
2585 * kmech is a umech with all pointers and structures in kernel address space.
2587 * This routine calls the provider's entry point to copy a kmech parameter
2588 * into user address space using umech as a template containing
2589 * user address pointers.
2592 crypto_provider_copyout_mech_param(kcf_provider_desc_t
*pd
,
2593 crypto_mechanism_t
*kmech
, crypto_mechanism_t
*umech
, int mode
, int *error
)
2595 crypto_mech_type_t provider_mech_type
;
2598 /* get the provider's mech number */
2599 provider_mech_type
= KCF_TO_PROV_MECHNUM(pd
, umech
->cm_type
);
2601 kmech
->cm_type
= provider_mech_type
;
2602 rv
= KCF_PROV_COPYOUT_MECH(pd
, kmech
, umech
, error
, mode
);
2603 kmech
->cm_type
= umech
->cm_type
;
2609 * Call the provider's entry point to free kernel memory that has been
2610 * allocated for the mechanism's parameter.
2613 crypto_free_mech(kcf_provider_desc_t
*pd
, boolean_t allocated_by_crypto_module
,
2614 crypto_mechanism_t
*mech
)
2616 crypto_mech_type_t provider_mech_type
;
2618 if (allocated_by_crypto_module
) {
2619 if (mech
->cm_param
!= NULL
)
2620 kmem_free(mech
->cm_param
, mech
->cm_param_len
);
2622 /* get the provider's mech number */
2623 provider_mech_type
= KCF_TO_PROV_MECHNUM(pd
, mech
->cm_type
);
2625 if (mech
->cm_param
!= NULL
&& mech
->cm_param_len
!= 0) {
2626 mech
->cm_type
= provider_mech_type
;
2627 (void) KCF_PROV_FREE_MECH(pd
, mech
);
2633 * ASSUMPTION: crypto_encrypt_init and crypto_decrypt_init
2634 * structures are identical except for field names.
2637 cipher_init(dev_t dev
, caddr_t arg
, int mode
, int (*init
)(crypto_provider_t
,
2638 crypto_session_id_t
, crypto_mechanism_t
*, crypto_key_t
*,
2639 crypto_ctx_template_t
, crypto_context_t
*, crypto_call_req_t
*))
2641 STRUCT_DECL(crypto_encrypt_init
, encrypt_init
);
2642 kcf_provider_desc_t
*real_provider
= NULL
;
2643 crypto_session_id_t session_id
;
2644 crypto_mechanism_t mech
;
2647 crypto_session_data_t
*sp
= NULL
;
2648 crypto_context_t cc
;
2649 crypto_ctx_t
**ctxpp
;
2650 size_t mech_rctl_bytes
= 0;
2651 boolean_t mech_rctl_chk
= B_FALSE
;
2652 size_t key_rctl_bytes
= 0;
2653 boolean_t key_rctl_chk
= B_FALSE
;
2656 boolean_t allocated_by_crypto_module
= B_FALSE
;
2657 crypto_func_group_t fg
;
2659 STRUCT_INIT(encrypt_init
, mode
);
2661 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
2662 cmn_err(CE_WARN
, "cipher_init: failed holding minor");
2666 if (copyin(arg
, STRUCT_BUF(encrypt_init
),
2667 STRUCT_SIZE(encrypt_init
)) != 0) {
2668 crypto_release_minor(cm
);
2672 mech
.cm_param
= NULL
;
2673 bzero(&key
, sizeof (crypto_key_t
));
2675 session_id
= STRUCT_FGET(encrypt_init
, ei_session
);
2677 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
2681 bcopy(STRUCT_FADDR(encrypt_init
, ei_mech
), &mech
.cm_type
,
2682 sizeof (crypto_mech_type_t
));
2684 if (init
== crypto_encrypt_init_prov
) {
2685 fg
= CRYPTO_FG_ENCRYPT
;
2687 fg
= CRYPTO_FG_DECRYPT
;
2690 /* We need the key length for provider selection so copy it in now. */
2691 if (!copyin_key(mode
, sp
, STRUCT_FADDR(encrypt_init
, ei_key
), &key
,
2692 &key_rctl_bytes
, &key_rctl_chk
, &rv
, &error
)) {
2696 if ((rv
= kcf_get_hardware_provider(mech
.cm_type
, &key
,
2697 CRYPTO_MECH_INVALID
, NULL
, sp
->sd_provider
, &real_provider
, fg
))
2698 != CRYPTO_SUCCESS
) {
2702 rv
= crypto_provider_copyin_mech_param(real_provider
,
2703 STRUCT_FADDR(encrypt_init
, ei_mech
), &mech
, mode
, &error
);
2705 if (rv
== CRYPTO_NOT_SUPPORTED
) {
2706 allocated_by_crypto_module
= B_TRUE
;
2707 if (!copyin_mech(mode
, sp
, STRUCT_FADDR(encrypt_init
, ei_mech
),
2708 &mech
, &mech_rctl_bytes
, &mech_rctl_chk
, &rv
, &error
)) {
2712 if (rv
!= CRYPTO_SUCCESS
)
2716 rv
= (init
)(real_provider
, sp
->sd_provider_session
->ps_session
,
2717 &mech
, &key
, NULL
, &cc
, NULL
);
2720 * Check if a context already exists. If so, it means it is being
2721 * abandoned. So, cancel it to avoid leaking it.
2723 ctxpp
= (init
== crypto_encrypt_init_prov
) ?
2724 &sp
->sd_encr_ctx
: &sp
->sd_decr_ctx
;
2727 CRYPTO_CANCEL_CTX(ctxpp
);
2728 *ctxpp
= (rv
== CRYPTO_SUCCESS
) ? cc
: NULL
;
2731 CRYPTO_DECREMENT_RCTL_SESSION(sp
, mech_rctl_bytes
, mech_rctl_chk
);
2732 CRYPTO_DECREMENT_RCTL_SESSION(sp
, key_rctl_bytes
, key_rctl_chk
);
2733 CRYPTO_SESSION_RELE(sp
);
2734 crypto_release_minor(cm
);
2736 if (real_provider
!= NULL
) {
2737 crypto_free_mech(real_provider
,
2738 allocated_by_crypto_module
, &mech
);
2739 KCF_PROV_REFRELE(real_provider
);
2742 free_crypto_key(&key
);
2745 /* XXX free context */
2748 STRUCT_FSET(encrypt_init
, ei_return_value
, rv
);
2749 if (copyout(STRUCT_BUF(encrypt_init
), arg
,
2750 STRUCT_SIZE(encrypt_init
)) != 0) {
2751 /* XXX free context */
2759 encrypt(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
2761 return (cipher(dev
, arg
, mode
, crypto_encrypt_single
));
2766 decrypt(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
2768 return (cipher(dev
, arg
, mode
, crypto_decrypt_single
));
2772 * ASSUMPTION: crypto_encrypt and crypto_decrypt structures
2773 * are identical except for field names.
2776 cipher(dev_t dev
, caddr_t arg
, int mode
,
2777 int (*single
)(crypto_context_t
, crypto_data_t
*, crypto_data_t
*,
2778 crypto_call_req_t
*))
2780 STRUCT_DECL(crypto_encrypt
, encrypt
);
2781 crypto_session_id_t session_id
;
2783 crypto_session_data_t
*sp
= NULL
;
2784 crypto_ctx_t
**ctxpp
;
2785 crypto_data_t data
, encr
;
2786 size_t datalen
, encrlen
, need
= 0;
2787 boolean_t do_inplace
;
2791 boolean_t rctl_chk
= B_FALSE
;
2793 STRUCT_INIT(encrypt
, mode
);
2795 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
2796 cmn_err(CE_WARN
, "cipher: failed holding minor");
2800 if (copyin(arg
, STRUCT_BUF(encrypt
), STRUCT_SIZE(encrypt
)) != 0) {
2801 crypto_release_minor(cm
);
2805 data
.cd_raw
.iov_base
= NULL
;
2806 encr
.cd_raw
.iov_base
= NULL
;
2808 datalen
= STRUCT_FGET(encrypt
, ce_datalen
);
2809 encrlen
= STRUCT_FGET(encrypt
, ce_encrlen
);
2812 * Don't allocate output buffer unless both buffer pointer and
2813 * buffer length are not NULL or 0 (length).
2815 encrbuf
= STRUCT_FGETP(encrypt
, ce_encrbuf
);
2816 if (encrbuf
== NULL
|| encrlen
== 0) {
2820 if (datalen
> crypto_max_buffer_len
||
2821 encrlen
> crypto_max_buffer_len
) {
2822 cmn_err(CE_NOTE
, "cipher: buffer greater than %ld bytes, "
2823 "pid = %d", crypto_max_buffer_len
, curproc
->p_pid
);
2824 rv
= CRYPTO_ARGUMENTS_BAD
;
2828 session_id
= STRUCT_FGET(encrypt
, ce_session
);
2830 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
2834 do_inplace
= (STRUCT_FGET(encrypt
, ce_flags
) &
2835 CRYPTO_INPLACE_OPERATION
) != 0;
2836 need
= do_inplace
? datalen
: datalen
+ encrlen
;
2838 if ((rv
= CRYPTO_BUFFER_CHECK(sp
, need
, rctl_chk
)) !=
2844 INIT_RAW_CRYPTO_DATA(data
, datalen
);
2845 data
.cd_miscdata
= NULL
;
2847 if (datalen
!= 0 && copyin(STRUCT_FGETP(encrypt
, ce_databuf
),
2848 data
.cd_raw
.iov_base
, datalen
) != 0) {
2854 /* set out = in for in-place */
2857 INIT_RAW_CRYPTO_DATA(encr
, encrlen
);
2860 ctxpp
= (single
== crypto_encrypt_single
) ?
2861 &sp
->sd_encr_ctx
: &sp
->sd_decr_ctx
;
2864 /* specify in-place buffers with output = NULL */
2865 rv
= (single
)(*ctxpp
, &encr
, NULL
, NULL
);
2867 rv
= (single
)(*ctxpp
, &data
, &encr
, NULL
);
2869 if (KCF_CONTEXT_DONE(rv
))
2872 if (rv
== CRYPTO_SUCCESS
) {
2873 ASSERT(encr
.cd_length
<= encrlen
);
2874 if (encr
.cd_length
!= 0 && copyout(encr
.cd_raw
.iov_base
,
2875 encrbuf
, encr
.cd_length
) != 0) {
2879 STRUCT_FSET(encrypt
, ce_encrlen
,
2880 (ulong_t
)encr
.cd_length
);
2883 if (rv
== CRYPTO_BUFFER_TOO_SMALL
) {
2885 * The providers return CRYPTO_BUFFER_TOO_SMALL even for case 1
2886 * of section 11.2 of the pkcs11 spec. We catch it here and
2887 * provide the correct pkcs11 return value.
2889 if (STRUCT_FGETP(encrypt
, ce_encrbuf
) == NULL
)
2890 rv
= CRYPTO_SUCCESS
;
2891 STRUCT_FSET(encrypt
, ce_encrlen
,
2892 (ulong_t
)encr
.cd_length
);
2896 CRYPTO_DECREMENT_RCTL_SESSION(sp
, need
, rctl_chk
);
2897 CRYPTO_SESSION_RELE(sp
);
2898 crypto_release_minor(cm
);
2900 if (data
.cd_raw
.iov_base
!= NULL
)
2901 kmem_free(data
.cd_raw
.iov_base
, datalen
);
2903 if (!do_inplace
&& encr
.cd_raw
.iov_base
!= NULL
)
2904 kmem_free(encr
.cd_raw
.iov_base
, encrlen
);
2909 STRUCT_FSET(encrypt
, ce_return_value
, rv
);
2910 if (copyout(STRUCT_BUF(encrypt
), arg
, STRUCT_SIZE(encrypt
)) != 0) {
2918 encrypt_update(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
2920 return (cipher_update(dev
, arg
, mode
, crypto_encrypt_update
));
2925 decrypt_update(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
2927 return (cipher_update(dev
, arg
, mode
, crypto_decrypt_update
));
2931 * ASSUMPTION: crypto_encrypt_update and crypto_decrypt_update
2932 * structures are identical except for field names.
2935 cipher_update(dev_t dev
, caddr_t arg
, int mode
,
2936 int (*update
)(crypto_context_t
, crypto_data_t
*, crypto_data_t
*,
2937 crypto_call_req_t
*))
2939 STRUCT_DECL(crypto_encrypt_update
, encrypt_update
);
2940 crypto_session_id_t session_id
;
2942 crypto_session_data_t
*sp
= NULL
;
2943 crypto_ctx_t
**ctxpp
;
2944 crypto_data_t data
, encr
;
2945 size_t datalen
, encrlen
, need
= 0;
2946 boolean_t do_inplace
;
2950 boolean_t rctl_chk
= B_FALSE
;
2952 STRUCT_INIT(encrypt_update
, mode
);
2954 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
2955 cmn_err(CE_WARN
, "cipher_update: failed holding minor");
2959 if (copyin(arg
, STRUCT_BUF(encrypt_update
),
2960 STRUCT_SIZE(encrypt_update
)) != 0) {
2961 crypto_release_minor(cm
);
2965 data
.cd_raw
.iov_base
= NULL
;
2966 encr
.cd_raw
.iov_base
= NULL
;
2968 datalen
= STRUCT_FGET(encrypt_update
, eu_datalen
);
2969 encrlen
= STRUCT_FGET(encrypt_update
, eu_encrlen
);
2972 * Don't allocate output buffer unless both buffer pointer and
2973 * buffer length are not NULL or 0 (length).
2975 encrbuf
= STRUCT_FGETP(encrypt_update
, eu_encrbuf
);
2976 if (encrbuf
== NULL
|| encrlen
== 0) {
2980 if (datalen
> crypto_max_buffer_len
||
2981 encrlen
> crypto_max_buffer_len
) {
2982 cmn_err(CE_NOTE
, "cipher_update: buffer greater than %ld "
2983 "bytes, pid = %d", crypto_max_buffer_len
, curproc
->p_pid
);
2984 rv
= CRYPTO_ARGUMENTS_BAD
;
2988 session_id
= STRUCT_FGET(encrypt_update
, eu_session
);
2990 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
2994 do_inplace
= (STRUCT_FGET(encrypt_update
, eu_flags
) &
2995 CRYPTO_INPLACE_OPERATION
) != 0;
2996 need
= do_inplace
? datalen
: datalen
+ encrlen
;
2998 if ((rv
= CRYPTO_BUFFER_CHECK(sp
, need
, rctl_chk
)) !=
3004 INIT_RAW_CRYPTO_DATA(data
, datalen
);
3005 data
.cd_miscdata
= NULL
;
3007 if (datalen
!= 0 && copyin(STRUCT_FGETP(encrypt_update
, eu_databuf
),
3008 data
.cd_raw
.iov_base
, datalen
) != 0) {
3014 /* specify in-place buffers with output = input */
3017 INIT_RAW_CRYPTO_DATA(encr
, encrlen
);
3020 ctxpp
= (update
== crypto_encrypt_update
) ?
3021 &sp
->sd_encr_ctx
: &sp
->sd_decr_ctx
;
3024 /* specify in-place buffers with output = NULL */
3025 rv
= (update
)(*ctxpp
, &encr
, NULL
, NULL
);
3027 rv
= (update
)(*ctxpp
, &data
, &encr
, NULL
);
3029 if (rv
== CRYPTO_SUCCESS
|| rv
== CRYPTO_BUFFER_TOO_SMALL
) {
3030 if (rv
== CRYPTO_SUCCESS
) {
3031 ASSERT(encr
.cd_length
<= encrlen
);
3032 if (encr
.cd_length
!= 0 && copyout(encr
.cd_raw
.iov_base
,
3033 encrbuf
, encr
.cd_length
) != 0) {
3039 * The providers return CRYPTO_BUFFER_TOO_SMALL even
3040 * for case 1 of section 11.2 of the pkcs11 spec.
3041 * We catch it here and provide the correct pkcs11
3044 if (STRUCT_FGETP(encrypt_update
, eu_encrbuf
) == NULL
)
3045 rv
= CRYPTO_SUCCESS
;
3047 STRUCT_FSET(encrypt_update
, eu_encrlen
,
3048 (ulong_t
)encr
.cd_length
);
3050 CRYPTO_CANCEL_CTX(ctxpp
);
3053 CRYPTO_DECREMENT_RCTL_SESSION(sp
, need
, rctl_chk
);
3054 CRYPTO_SESSION_RELE(sp
);
3055 crypto_release_minor(cm
);
3057 if (data
.cd_raw
.iov_base
!= NULL
)
3058 kmem_free(data
.cd_raw
.iov_base
, datalen
);
3060 if (!do_inplace
&& (encr
.cd_raw
.iov_base
!= NULL
))
3061 kmem_free(encr
.cd_raw
.iov_base
, encrlen
);
3066 STRUCT_FSET(encrypt_update
, eu_return_value
, rv
);
3067 if (copyout(STRUCT_BUF(encrypt_update
), arg
,
3068 STRUCT_SIZE(encrypt_update
)) != 0) {
3076 encrypt_final(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
3078 return (common_final(dev
, arg
, mode
, crypto_encrypt_final
));
3083 decrypt_final(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
3085 return (common_final(dev
, arg
, mode
, crypto_decrypt_final
));
3089 * ASSUMPTION: crypto_encrypt_final, crypto_decrypt_final, crypto_sign_final,
3090 * and crypto_digest_final structures are identical except for field names.
3093 common_final(dev_t dev
, caddr_t arg
, int mode
,
3094 int (*final
)(crypto_context_t
, crypto_data_t
*, crypto_call_req_t
*))
3096 STRUCT_DECL(crypto_encrypt_final
, encrypt_final
);
3097 crypto_session_id_t session_id
;
3099 crypto_session_data_t
*sp
= NULL
;
3100 crypto_ctx_t
**ctxpp
;
3102 size_t encrlen
, need
= 0;
3106 boolean_t rctl_chk
= B_FALSE
;
3108 STRUCT_INIT(encrypt_final
, mode
);
3110 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
3111 cmn_err(CE_WARN
, "common_final: failed holding minor");
3115 if (copyin(arg
, STRUCT_BUF(encrypt_final
),
3116 STRUCT_SIZE(encrypt_final
)) != 0) {
3117 crypto_release_minor(cm
);
3121 encr
.cd_format
= CRYPTO_DATA_RAW
;
3122 encr
.cd_raw
.iov_base
= NULL
;
3124 encrlen
= STRUCT_FGET(encrypt_final
, ef_encrlen
);
3127 * Don't allocate output buffer unless both buffer pointer and
3128 * buffer length are not NULL or 0 (length).
3130 encrbuf
= STRUCT_FGETP(encrypt_final
, ef_encrbuf
);
3131 if (encrbuf
== NULL
|| encrlen
== 0) {
3135 if (encrlen
> crypto_max_buffer_len
) {
3136 cmn_err(CE_NOTE
, "common_final: buffer greater than %ld "
3137 "bytes, pid = %d", crypto_max_buffer_len
, curproc
->p_pid
);
3138 rv
= CRYPTO_ARGUMENTS_BAD
;
3142 session_id
= STRUCT_FGET(encrypt_final
, ef_session
);
3144 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
3148 if ((rv
= CRYPTO_BUFFER_CHECK(sp
, encrlen
, rctl_chk
)) !=
3153 encr
.cd_raw
.iov_base
= kmem_alloc(encrlen
, KM_SLEEP
);
3154 encr
.cd_raw
.iov_len
= encrlen
;
3157 encr
.cd_length
= encrlen
;
3159 ASSERT(final
== crypto_encrypt_final
||
3160 final
== crypto_decrypt_final
|| final
== crypto_sign_final
||
3161 final
== crypto_digest_final
|| final
== crypto_mac_final
);
3163 if (final
== crypto_encrypt_final
) {
3164 ctxpp
= &sp
->sd_encr_ctx
;
3165 } else if (final
== crypto_decrypt_final
) {
3166 ctxpp
= &sp
->sd_decr_ctx
;
3167 } else if (final
== crypto_sign_final
) {
3168 ctxpp
= &sp
->sd_sign_ctx
;
3169 } else if (final
== crypto_mac_final
) {
3170 ctxpp
= &sp
->sd_mac_ctx
;
3172 ctxpp
= &sp
->sd_digest_ctx
;
3175 rv
= (final
)(*ctxpp
, &encr
, NULL
);
3176 if (KCF_CONTEXT_DONE(rv
))
3179 if (rv
== CRYPTO_SUCCESS
) {
3180 ASSERT(encr
.cd_length
<= encrlen
);
3181 if (encr
.cd_length
!= 0 && copyout(encr
.cd_raw
.iov_base
,
3182 encrbuf
, encr
.cd_length
) != 0) {
3186 STRUCT_FSET(encrypt_final
, ef_encrlen
,
3187 (ulong_t
)encr
.cd_length
);
3190 if (rv
== CRYPTO_BUFFER_TOO_SMALL
) {
3192 * The providers return CRYPTO_BUFFER_TOO_SMALL even for case 1
3193 * of section 11.2 of the pkcs11 spec. We catch it here and
3194 * provide the correct pkcs11 return value.
3196 if (STRUCT_FGETP(encrypt_final
, ef_encrbuf
) == NULL
)
3197 rv
= CRYPTO_SUCCESS
;
3198 STRUCT_FSET(encrypt_final
, ef_encrlen
,
3199 (ulong_t
)encr
.cd_length
);
3203 CRYPTO_DECREMENT_RCTL_SESSION(sp
, need
, rctl_chk
);
3204 CRYPTO_SESSION_RELE(sp
);
3205 crypto_release_minor(cm
);
3207 if (encr
.cd_raw
.iov_base
!= NULL
)
3208 kmem_free(encr
.cd_raw
.iov_base
, encrlen
);
3213 STRUCT_FSET(encrypt_final
, ef_return_value
, rv
);
3214 if (copyout(STRUCT_BUF(encrypt_final
), arg
,
3215 STRUCT_SIZE(encrypt_final
)) != 0) {
3223 digest_init(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
3225 STRUCT_DECL(crypto_digest_init
, digest_init
);
3226 kcf_provider_desc_t
*real_provider
= NULL
;
3227 crypto_session_id_t session_id
;
3228 crypto_mechanism_t mech
;
3230 crypto_session_data_t
*sp
= NULL
;
3231 crypto_context_t cc
;
3232 size_t rctl_bytes
= 0;
3233 boolean_t rctl_chk
= B_FALSE
;
3237 STRUCT_INIT(digest_init
, mode
);
3239 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
3240 cmn_err(CE_WARN
, "digest_init: failed holding minor");
3244 if (copyin(arg
, STRUCT_BUF(digest_init
),
3245 STRUCT_SIZE(digest_init
)) != 0) {
3246 crypto_release_minor(cm
);
3250 mech
.cm_param
= NULL
;
3252 session_id
= STRUCT_FGET(digest_init
, di_session
);
3254 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
3258 if (!copyin_mech(mode
, sp
, STRUCT_FADDR(digest_init
, di_mech
), &mech
,
3259 &rctl_bytes
, &rctl_chk
, &rv
, &error
)) {
3263 if ((rv
= kcf_get_hardware_provider(mech
.cm_type
, NULL
,
3264 CRYPTO_MECH_INVALID
, NULL
, sp
->sd_provider
, &real_provider
,
3265 CRYPTO_FG_DIGEST
)) != CRYPTO_SUCCESS
) {
3269 rv
= crypto_digest_init_prov(real_provider
,
3270 sp
->sd_provider_session
->ps_session
, &mech
, &cc
, NULL
);
3273 * Check if a context already exists. If so, it means it is being
3274 * abandoned. So, cancel it to avoid leaking it.
3276 if (sp
->sd_digest_ctx
!= NULL
)
3277 CRYPTO_CANCEL_CTX(&sp
->sd_digest_ctx
);
3278 sp
->sd_digest_ctx
= (rv
== CRYPTO_SUCCESS
) ? cc
: NULL
;
3280 CRYPTO_DECREMENT_RCTL_SESSION(sp
, rctl_bytes
, rctl_chk
);
3281 CRYPTO_SESSION_RELE(sp
);
3282 crypto_release_minor(cm
);
3284 if (real_provider
!= NULL
)
3285 KCF_PROV_REFRELE(real_provider
);
3287 if (mech
.cm_param
!= NULL
)
3288 kmem_free(mech
.cm_param
, mech
.cm_param_len
);
3293 STRUCT_FSET(digest_init
, di_return_value
, rv
);
3294 if (copyout(STRUCT_BUF(digest_init
), arg
,
3295 STRUCT_SIZE(digest_init
)) != 0) {
3303 digest_update(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
3305 STRUCT_DECL(crypto_digest_update
, digest_update
);
3306 crypto_session_id_t session_id
;
3308 crypto_session_data_t
*sp
= NULL
;
3310 size_t datalen
, need
= 0;
3313 boolean_t rctl_chk
= B_FALSE
;
3315 STRUCT_INIT(digest_update
, mode
);
3317 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
3318 cmn_err(CE_WARN
, "digest_update: failed holding minor");
3322 if (copyin(arg
, STRUCT_BUF(digest_update
),
3323 STRUCT_SIZE(digest_update
)) != 0) {
3324 crypto_release_minor(cm
);
3328 data
.cd_format
= CRYPTO_DATA_RAW
;
3329 data
.cd_raw
.iov_base
= NULL
;
3331 datalen
= STRUCT_FGET(digest_update
, du_datalen
);
3332 if (datalen
> crypto_max_buffer_len
) {
3333 cmn_err(CE_NOTE
, "digest_update: buffer greater than %ld "
3334 "bytes, pid = %d", crypto_max_buffer_len
, curproc
->p_pid
);
3335 rv
= CRYPTO_ARGUMENTS_BAD
;
3339 session_id
= STRUCT_FGET(digest_update
, du_session
);
3341 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
3345 if ((rv
= CRYPTO_BUFFER_CHECK(sp
, datalen
, rctl_chk
)) !=
3351 data
.cd_raw
.iov_base
= kmem_alloc(datalen
, KM_SLEEP
);
3352 data
.cd_raw
.iov_len
= datalen
;
3354 if (datalen
!= 0 && copyin(STRUCT_FGETP(digest_update
, du_databuf
),
3355 data
.cd_raw
.iov_base
, datalen
) != 0) {
3361 data
.cd_length
= datalen
;
3363 rv
= crypto_digest_update(sp
->sd_digest_ctx
, &data
, NULL
);
3364 if (rv
!= CRYPTO_SUCCESS
)
3365 CRYPTO_CANCEL_CTX(&sp
->sd_digest_ctx
);
3368 CRYPTO_DECREMENT_RCTL_SESSION(sp
, need
, rctl_chk
);
3369 CRYPTO_SESSION_RELE(sp
);
3370 crypto_release_minor(cm
);
3372 if (data
.cd_raw
.iov_base
!= NULL
)
3373 kmem_free(data
.cd_raw
.iov_base
, datalen
);
3378 STRUCT_FSET(digest_update
, du_return_value
, rv
);
3379 if (copyout(STRUCT_BUF(digest_update
), arg
,
3380 STRUCT_SIZE(digest_update
)) != 0) {
3388 digest_key(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
3390 STRUCT_DECL(crypto_digest_key
, digest_key
);
3391 crypto_session_id_t session_id
;
3394 crypto_session_data_t
*sp
= NULL
;
3395 size_t rctl_bytes
= 0;
3396 boolean_t key_rctl_chk
= B_FALSE
;
3400 STRUCT_INIT(digest_key
, mode
);
3402 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
3403 cmn_err(CE_WARN
, "digest_key: failed holding minor");
3407 if (copyin(arg
, STRUCT_BUF(digest_key
), STRUCT_SIZE(digest_key
)) != 0) {
3408 crypto_release_minor(cm
);
3412 bzero(&key
, sizeof (crypto_key_t
));
3414 session_id
= STRUCT_FGET(digest_key
, dk_session
);
3416 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
3420 if (!copyin_key(mode
, sp
, STRUCT_FADDR(digest_key
, dk_key
), &key
,
3421 &rctl_bytes
, &key_rctl_chk
, &rv
, &error
)) {
3425 rv
= crypto_digest_key_prov(sp
->sd_digest_ctx
, &key
, NULL
);
3426 if (rv
!= CRYPTO_SUCCESS
)
3427 CRYPTO_CANCEL_CTX(&sp
->sd_digest_ctx
);
3429 CRYPTO_DECREMENT_RCTL_SESSION(sp
, rctl_bytes
, key_rctl_chk
);
3430 CRYPTO_SESSION_RELE(sp
);
3431 crypto_release_minor(cm
);
3433 free_crypto_key(&key
);
3438 STRUCT_FSET(digest_key
, dk_return_value
, rv
);
3439 if (copyout(STRUCT_BUF(digest_key
), arg
,
3440 STRUCT_SIZE(digest_key
)) != 0) {
3448 digest_final(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
3450 return (common_final(dev
, arg
, mode
, crypto_digest_final
));
3455 digest(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
3457 return (common_digest(dev
, arg
, mode
, crypto_digest_single
));
3461 mac_init(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
3463 _NOTE(ARGUNUSED(rval
))
3464 return (sign_verify_init(dev
, arg
, mode
, crypto_mac_init_prov
));
3468 mac_update(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
3470 _NOTE(ARGUNUSED(rval
))
3471 return (sign_verify_update(dev
, arg
, mode
, crypto_mac_update
));
3475 mac_final(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
3477 _NOTE(ARGUNUSED(rval
))
3478 return (common_final(dev
, arg
, mode
, crypto_mac_final
));
3483 mac(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
3485 _NOTE(ARGUNUSED(rval
))
3486 return (common_digest(dev
, arg
, mode
, crypto_mac_single
));
3490 * ASSUMPTION: crypto_digest, crypto_sign, crypto_sign_recover,
3491 * and crypto_verify_recover are identical except for field names.
3494 common_digest(dev_t dev
, caddr_t arg
, int mode
,
3495 int (*single
)(crypto_context_t
, crypto_data_t
*, crypto_data_t
*,
3496 crypto_call_req_t
*))
3498 STRUCT_DECL(crypto_digest
, crypto_digest
);
3499 crypto_session_id_t session_id
;
3501 crypto_session_data_t
*sp
= NULL
;
3502 crypto_data_t data
, digest
;
3503 crypto_ctx_t
**ctxpp
;
3504 size_t datalen
, digestlen
, need
= 0;
3508 boolean_t rctl_chk
= B_FALSE
;
3510 STRUCT_INIT(crypto_digest
, mode
);
3512 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
3513 cmn_err(CE_WARN
, "common_digest: failed holding minor");
3517 if (copyin(arg
, STRUCT_BUF(crypto_digest
),
3518 STRUCT_SIZE(crypto_digest
)) != 0) {
3519 crypto_release_minor(cm
);
3523 data
.cd_raw
.iov_base
= NULL
;
3524 digest
.cd_raw
.iov_base
= NULL
;
3525 data
.cd_miscdata
= NULL
;
3526 digest
.cd_miscdata
= NULL
;
3528 datalen
= STRUCT_FGET(crypto_digest
, cd_datalen
);
3529 digestlen
= STRUCT_FGET(crypto_digest
, cd_digestlen
);
3532 * Don't allocate output buffer unless both buffer pointer and
3533 * buffer length are not NULL or 0 (length).
3535 digestbuf
= STRUCT_FGETP(crypto_digest
, cd_digestbuf
);
3536 if (digestbuf
== NULL
|| digestlen
== 0) {
3540 if (datalen
> crypto_max_buffer_len
||
3541 digestlen
> crypto_max_buffer_len
) {
3542 cmn_err(CE_NOTE
, "common_digest: buffer greater than %ld "
3543 "bytes, pid = %d", crypto_max_buffer_len
, curproc
->p_pid
);
3544 rv
= CRYPTO_ARGUMENTS_BAD
;
3548 session_id
= STRUCT_FGET(crypto_digest
, cd_session
);
3550 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
3554 need
= datalen
+ digestlen
;
3555 if ((rv
= CRYPTO_BUFFER_CHECK(sp
, need
, rctl_chk
)) !=
3561 INIT_RAW_CRYPTO_DATA(data
, datalen
);
3563 if (datalen
!= 0 && copyin(STRUCT_FGETP(crypto_digest
, cd_databuf
),
3564 data
.cd_raw
.iov_base
, datalen
) != 0) {
3569 INIT_RAW_CRYPTO_DATA(digest
, digestlen
);
3571 ASSERT(single
== crypto_digest_single
||
3572 single
== crypto_sign_single
||
3573 single
== crypto_verify_recover_single
||
3574 single
== crypto_sign_recover_single
||
3575 single
== crypto_mac_single
);
3577 if (single
== crypto_digest_single
) {
3578 ctxpp
= &sp
->sd_digest_ctx
;
3579 } else if (single
== crypto_sign_single
) {
3580 ctxpp
= &sp
->sd_sign_ctx
;
3581 } else if (single
== crypto_verify_recover_single
) {
3582 ctxpp
= &sp
->sd_verify_recover_ctx
;
3583 } else if (single
== crypto_mac_single
) {
3584 ctxpp
= &sp
->sd_mac_ctx
;
3586 ctxpp
= &sp
->sd_sign_recover_ctx
;
3588 rv
= (single
)(*ctxpp
, &data
, &digest
, NULL
);
3589 if (KCF_CONTEXT_DONE(rv
))
3592 if (rv
== CRYPTO_SUCCESS
) {
3593 ASSERT(digest
.cd_length
<= digestlen
);
3594 if (digest
.cd_length
!= 0 && copyout(digest
.cd_raw
.iov_base
,
3595 digestbuf
, digest
.cd_length
) != 0) {
3599 STRUCT_FSET(crypto_digest
, cd_digestlen
,
3600 (ulong_t
)digest
.cd_length
);
3603 if (rv
== CRYPTO_BUFFER_TOO_SMALL
) {
3605 * The providers return CRYPTO_BUFFER_TOO_SMALL even for case 1
3606 * of section 11.2 of the pkcs11 spec. We catch it here and
3607 * provide the correct pkcs11 return value.
3609 if (STRUCT_FGETP(crypto_digest
, cd_digestbuf
) == NULL
)
3610 rv
= CRYPTO_SUCCESS
;
3611 STRUCT_FSET(crypto_digest
, cd_digestlen
,
3612 (ulong_t
)digest
.cd_length
);
3616 CRYPTO_DECREMENT_RCTL_SESSION(sp
, need
, rctl_chk
);
3617 CRYPTO_SESSION_RELE(sp
);
3618 crypto_release_minor(cm
);
3620 if (data
.cd_raw
.iov_base
!= NULL
)
3621 kmem_free(data
.cd_raw
.iov_base
, datalen
);
3623 if (digest
.cd_raw
.iov_base
!= NULL
)
3624 kmem_free(digest
.cd_raw
.iov_base
, digestlen
);
3629 STRUCT_FSET(crypto_digest
, cd_return_value
, rv
);
3630 if (copyout(STRUCT_BUF(crypto_digest
), arg
,
3631 STRUCT_SIZE(crypto_digest
)) != 0) {
3638 * A helper function that does what the name suggests.
3639 * Returns 0 on success and non-zero otherwise.
3640 * On failure, out_pin is set to 0.
3643 get_pin_and_session_ptr(char *in_pin
, char **out_pin
, size_t pin_len
,
3644 crypto_minor_t
*cm
, crypto_session_id_t sid
, crypto_session_data_t
**sp
,
3645 int *rv
, int *error
)
3647 char *tmp_pin
= NULL
;
3648 int tmp_error
= 0, tmp_rv
= 0;
3650 if (pin_len
> KCF_MAX_PIN_LEN
) {
3651 tmp_rv
= CRYPTO_PIN_LEN_RANGE
;
3654 tmp_pin
= kmem_alloc(pin_len
, KM_SLEEP
);
3656 if (pin_len
!= 0 && copyin(in_pin
, tmp_pin
, pin_len
) != 0) {
3661 (void) get_session_ptr(sid
, cm
, sp
, &tmp_error
, &tmp_rv
);
3666 return (tmp_rv
| tmp_error
);
3671 set_pin(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
3673 STRUCT_DECL(crypto_set_pin
, set_pin
);
3674 kcf_provider_desc_t
*real_provider
;
3675 kcf_req_params_t params
;
3677 crypto_session_data_t
*sp
;
3678 char *old_pin
= NULL
;
3679 char *new_pin
= NULL
;
3685 STRUCT_INIT(set_pin
, mode
);
3687 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
3688 cmn_err(CE_WARN
, "set_pin: failed holding minor");
3692 if (copyin(arg
, STRUCT_BUF(set_pin
),
3693 STRUCT_SIZE(set_pin
)) != 0) {
3694 crypto_release_minor(cm
);
3698 old_pin_len
= STRUCT_FGET(set_pin
, sp_old_len
);
3700 if (get_pin_and_session_ptr(STRUCT_FGETP(set_pin
, sp_old_pin
),
3701 &old_pin
, old_pin_len
, cm
, STRUCT_FGET(set_pin
, sp_session
),
3702 &sp
, &rv
, &error
) != 0)
3705 new_pin_len
= STRUCT_FGET(set_pin
, sp_new_len
);
3706 if (new_pin_len
> KCF_MAX_PIN_LEN
) {
3707 rv
= CRYPTO_PIN_LEN_RANGE
;
3710 new_pin
= kmem_alloc(new_pin_len
, KM_SLEEP
);
3712 if (new_pin_len
!= 0 && copyin(STRUCT_FGETP(set_pin
, sp_new_pin
),
3713 new_pin
, new_pin_len
) != 0) {
3718 if ((rv
= kcf_get_hardware_provider_nomech(
3719 CRYPTO_OPS_OFFSET(provider_ops
), CRYPTO_PROVIDER_OFFSET(set_pin
),
3720 sp
->sd_provider
, &real_provider
)) != CRYPTO_SUCCESS
) {
3724 KCF_WRAP_PROVMGMT_OPS_PARAMS(¶ms
, KCF_OP_MGMT_SETPIN
,
3725 sp
->sd_provider_session
->ps_session
, old_pin
, old_pin_len
,
3726 new_pin
, new_pin_len
, NULL
, NULL
, real_provider
);
3728 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
, B_FALSE
);
3729 KCF_PROV_REFRELE(real_provider
);
3732 CRYPTO_SESSION_RELE(sp
);
3735 crypto_release_minor(cm
);
3737 if (old_pin
!= NULL
) {
3738 bzero(old_pin
, old_pin_len
);
3739 kmem_free(old_pin
, old_pin_len
);
3742 if (new_pin
!= NULL
) {
3743 bzero(new_pin
, new_pin_len
);
3744 kmem_free(new_pin
, new_pin_len
);
3750 STRUCT_FSET(set_pin
, sp_return_value
, rv
);
3751 if (copyout(STRUCT_BUF(set_pin
), arg
, STRUCT_SIZE(set_pin
)) != 0) {
3759 login(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
3761 STRUCT_DECL(crypto_login
, login
);
3762 kcf_provider_desc_t
*real_provider
;
3763 kcf_req_params_t params
;
3765 crypto_session_data_t
*sp
;
3772 STRUCT_INIT(login
, mode
);
3774 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
3775 cmn_err(CE_WARN
, "login: failed holding minor");
3779 if (copyin(arg
, STRUCT_BUF(login
), STRUCT_SIZE(login
)) != 0) {
3780 crypto_release_minor(cm
);
3784 user_type
= STRUCT_FGET(login
, co_user_type
);
3786 pin_len
= STRUCT_FGET(login
, co_pin_len
);
3788 if (get_pin_and_session_ptr(STRUCT_FGETP(login
, co_pin
),
3789 &pin
, pin_len
, cm
, STRUCT_FGET(login
, co_session
),
3790 &sp
, &rv
, &error
) != 0) {
3791 if (rv
== CRYPTO_PIN_LEN_RANGE
)
3792 rv
= CRYPTO_PIN_INCORRECT
;
3796 if ((rv
= kcf_get_hardware_provider_nomech(
3797 CRYPTO_OPS_OFFSET(session_ops
),
3798 CRYPTO_SESSION_OFFSET(session_login
), sp
->sd_provider
,
3799 &real_provider
)) != CRYPTO_SUCCESS
) {
3803 KCF_WRAP_SESSION_OPS_PARAMS(¶ms
, KCF_OP_SESSION_LOGIN
, NULL
,
3804 sp
->sd_provider_session
->ps_session
, user_type
, pin
, pin_len
,
3807 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
, B_FALSE
);
3808 KCF_PROV_REFRELE(real_provider
);
3811 CRYPTO_SESSION_RELE(sp
);
3814 crypto_release_minor(cm
);
3817 bzero(pin
, pin_len
);
3818 kmem_free(pin
, pin_len
);
3824 STRUCT_FSET(login
, co_return_value
, rv
);
3825 if (copyout(STRUCT_BUF(login
), arg
, STRUCT_SIZE(login
)) != 0) {
3833 logout(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
3835 crypto_logout_t logout
;
3836 kcf_provider_desc_t
*real_provider
;
3837 kcf_req_params_t params
;
3839 crypto_session_data_t
*sp
;
3843 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
3844 cmn_err(CE_WARN
, "logout: failed holding minor");
3848 if (copyin(arg
, &logout
, sizeof (logout
)) != 0) {
3849 crypto_release_minor(cm
);
3853 if (!get_session_ptr(logout
.cl_session
, cm
, &sp
, &error
, &rv
)) {
3857 if ((rv
= kcf_get_hardware_provider_nomech(
3858 CRYPTO_OPS_OFFSET(session_ops
),
3859 CRYPTO_SESSION_OFFSET(session_logout
), sp
->sd_provider
,
3860 &real_provider
)) != CRYPTO_SUCCESS
) {
3864 KCF_WRAP_SESSION_OPS_PARAMS(¶ms
, KCF_OP_SESSION_LOGOUT
, NULL
,
3865 sp
->sd_provider_session
->ps_session
, 0, NULL
, 0, real_provider
);
3866 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
, B_FALSE
);
3867 KCF_PROV_REFRELE(real_provider
);
3870 CRYPTO_SESSION_RELE(sp
);
3873 crypto_release_minor(cm
);
3878 logout
.cl_return_value
= rv
;
3879 if (copyout(&logout
, arg
, sizeof (logout
)) != 0) {
3887 sign_init(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
3889 return (sign_verify_init(dev
, arg
, mode
, crypto_sign_init_prov
));
3894 sign_recover_init(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
3896 return (sign_verify_init(dev
, arg
, mode
,
3897 crypto_sign_recover_init_prov
));
3902 verify_init(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
3904 return (sign_verify_init(dev
, arg
, mode
, crypto_verify_init_prov
));
3909 verify_recover_init(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
3911 return (sign_verify_init(dev
, arg
, mode
,
3912 crypto_verify_recover_init_prov
));
3916 * ASSUMPTION: crypto_sign_init, crypto_verify_init, crypto_sign_recover_init,
3917 * and crypto_verify_recover_init structures are identical
3918 * except for field names.
3921 sign_verify_init(dev_t dev
, caddr_t arg
, int mode
,
3922 int (*init
)(crypto_provider_t
, crypto_session_id_t
,
3923 crypto_mechanism_t
*, crypto_key_t
*, crypto_ctx_template_t
,
3924 crypto_context_t
*, crypto_call_req_t
*))
3926 STRUCT_DECL(crypto_sign_init
, sign_init
);
3927 kcf_provider_desc_t
*real_provider
= NULL
;
3928 crypto_session_id_t session_id
;
3929 crypto_mechanism_t mech
;
3932 crypto_session_data_t
*sp
= NULL
;
3933 crypto_context_t cc
;
3934 crypto_ctx_t
**ctxpp
;
3935 size_t mech_rctl_bytes
= 0;
3936 boolean_t mech_rctl_chk
= B_FALSE
;
3937 size_t key_rctl_bytes
= 0;
3938 boolean_t key_rctl_chk
= B_FALSE
;
3941 boolean_t allocated_by_crypto_module
= B_FALSE
;
3942 crypto_func_group_t fg
;
3944 STRUCT_INIT(sign_init
, mode
);
3946 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
3947 cmn_err(CE_WARN
, "sign_verify_init: failed holding minor");
3951 if (copyin(arg
, STRUCT_BUF(sign_init
), STRUCT_SIZE(sign_init
)) != 0) {
3952 crypto_release_minor(cm
);
3956 mech
.cm_param
= NULL
;
3957 bzero(&key
, sizeof (key
));
3959 session_id
= STRUCT_FGET(sign_init
, si_session
);
3961 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
3965 bcopy(STRUCT_FADDR(sign_init
, si_mech
), &mech
.cm_type
,
3966 sizeof (crypto_mech_type_t
));
3968 ASSERT(init
== crypto_sign_init_prov
||
3969 init
== crypto_verify_init_prov
||
3970 init
== crypto_sign_recover_init_prov
||
3971 init
== crypto_verify_recover_init_prov
||
3972 init
== crypto_mac_init_prov
);
3974 if (init
== crypto_sign_init_prov
) {
3975 fg
= CRYPTO_FG_SIGN
;
3976 ctxpp
= &sp
->sd_sign_ctx
;
3977 } else if (init
== crypto_verify_init_prov
) {
3978 fg
= CRYPTO_FG_VERIFY
;
3979 ctxpp
= &sp
->sd_verify_ctx
;
3980 } else if (init
== crypto_sign_recover_init_prov
) {
3981 fg
= CRYPTO_FG_SIGN_RECOVER
;
3982 ctxpp
= &sp
->sd_sign_recover_ctx
;
3983 } else if (init
== crypto_mac_init_prov
) {
3985 ctxpp
= &sp
->sd_mac_ctx
;
3987 fg
= CRYPTO_FG_VERIFY_RECOVER
;
3988 ctxpp
= &sp
->sd_verify_recover_ctx
;
3991 /* We need the key length for provider selection so copy it in now. */
3992 if (!copyin_key(mode
, sp
, STRUCT_FADDR(sign_init
, si_key
), &key
,
3993 &key_rctl_bytes
, &key_rctl_chk
, &rv
, &error
)) {
3997 if ((rv
= kcf_get_hardware_provider(mech
.cm_type
, &key
,
3998 CRYPTO_MECH_INVALID
, NULL
, sp
->sd_provider
, &real_provider
,
3999 fg
)) != CRYPTO_SUCCESS
) {
4003 rv
= crypto_provider_copyin_mech_param(real_provider
,
4004 STRUCT_FADDR(sign_init
, si_mech
), &mech
, mode
, &error
);
4006 if (rv
== CRYPTO_NOT_SUPPORTED
) {
4007 allocated_by_crypto_module
= B_TRUE
;
4008 if (!copyin_mech(mode
, sp
, STRUCT_FADDR(sign_init
, si_mech
),
4009 &mech
, &mech_rctl_bytes
, &mech_rctl_chk
, &rv
, &error
)) {
4013 if (rv
!= CRYPTO_SUCCESS
)
4017 rv
= (init
)(real_provider
, sp
->sd_provider_session
->ps_session
,
4018 &mech
, &key
, NULL
, &cc
, NULL
);
4021 * Check if a context already exists. If so, it means it is being
4022 * abandoned. So, cancel it to avoid leaking it.
4025 CRYPTO_CANCEL_CTX(ctxpp
);
4026 *ctxpp
= (rv
== CRYPTO_SUCCESS
) ? cc
: NULL
;
4029 CRYPTO_DECREMENT_RCTL_SESSION(sp
, mech_rctl_bytes
, mech_rctl_chk
);
4030 CRYPTO_DECREMENT_RCTL_SESSION(sp
, key_rctl_bytes
, key_rctl_chk
);
4031 CRYPTO_SESSION_RELE(sp
);
4032 crypto_release_minor(cm
);
4034 if (real_provider
!= NULL
) {
4035 crypto_free_mech(real_provider
,
4036 allocated_by_crypto_module
, &mech
);
4037 KCF_PROV_REFRELE(real_provider
);
4040 free_crypto_key(&key
);
4045 STRUCT_FSET(sign_init
, si_return_value
, rv
);
4046 if (copyout(STRUCT_BUF(sign_init
), arg
, STRUCT_SIZE(sign_init
)) != 0) {
4054 sign(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
4056 return (common_digest(dev
, arg
, mode
, crypto_sign_single
));
4061 sign_recover(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
4063 return (common_digest(dev
, arg
, mode
, crypto_sign_recover_single
));
4068 verify(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
4070 STRUCT_DECL(crypto_verify
, verify
);
4071 crypto_session_id_t session_id
;
4073 crypto_session_data_t
*sp
= NULL
;
4074 crypto_data_t data
, sign
;
4075 size_t datalen
, signlen
, need
= 0;
4078 boolean_t rctl_chk
= B_FALSE
;
4080 STRUCT_INIT(verify
, mode
);
4082 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
4083 cmn_err(CE_WARN
, "verify: failed holding minor");
4087 if (copyin(arg
, STRUCT_BUF(verify
), STRUCT_SIZE(verify
)) != 0) {
4088 crypto_release_minor(cm
);
4092 data
.cd_raw
.iov_base
= NULL
;
4093 sign
.cd_raw
.iov_base
= NULL
;
4095 datalen
= STRUCT_FGET(verify
, cv_datalen
);
4096 signlen
= STRUCT_FGET(verify
, cv_signlen
);
4097 if (datalen
> crypto_max_buffer_len
||
4098 signlen
> crypto_max_buffer_len
) {
4099 cmn_err(CE_NOTE
, "verify: buffer greater than %ld bytes, "
4100 "pid = %d", crypto_max_buffer_len
, curproc
->p_pid
);
4101 rv
= CRYPTO_ARGUMENTS_BAD
;
4105 session_id
= STRUCT_FGET(verify
, cv_session
);
4107 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
4111 need
= datalen
+ signlen
;
4112 if ((rv
= CRYPTO_BUFFER_CHECK(sp
, need
, rctl_chk
)) !=
4118 INIT_RAW_CRYPTO_DATA(data
, datalen
);
4119 INIT_RAW_CRYPTO_DATA(sign
, signlen
);
4121 if (datalen
!= 0 && copyin(STRUCT_FGETP(verify
, cv_databuf
),
4122 data
.cd_raw
.iov_base
, datalen
) != 0) {
4127 if (signlen
!= 0 && copyin(STRUCT_FGETP(verify
, cv_signbuf
),
4128 sign
.cd_raw
.iov_base
, signlen
) != 0) {
4133 rv
= crypto_verify_single(sp
->sd_verify_ctx
, &data
, &sign
, NULL
);
4134 if (KCF_CONTEXT_DONE(rv
))
4135 sp
->sd_verify_ctx
= NULL
;
4138 CRYPTO_DECREMENT_RCTL_SESSION(sp
, need
, rctl_chk
);
4139 CRYPTO_SESSION_RELE(sp
);
4140 crypto_release_minor(cm
);
4142 if (data
.cd_raw
.iov_base
!= NULL
)
4143 kmem_free(data
.cd_raw
.iov_base
, datalen
);
4145 if (sign
.cd_raw
.iov_base
!= NULL
)
4146 kmem_free(sign
.cd_raw
.iov_base
, signlen
);
4151 STRUCT_FSET(verify
, cv_return_value
, rv
);
4152 if (copyout(STRUCT_BUF(verify
), arg
, STRUCT_SIZE(verify
)) != 0) {
4160 verify_recover(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
4162 return (common_digest(dev
, arg
, mode
, crypto_verify_recover_single
));
4167 sign_update(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
4169 return (sign_verify_update(dev
, arg
, mode
, crypto_sign_update
));
4174 verify_update(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
4176 return (sign_verify_update(dev
, arg
, mode
, crypto_verify_update
));
4180 * ASSUMPTION: crypto_sign_update and crypto_verify_update structures
4181 * are identical except for field names.
4184 sign_verify_update(dev_t dev
, caddr_t arg
, int mode
,
4185 int (*update
)(crypto_context_t
, crypto_data_t
*, crypto_call_req_t
*))
4187 STRUCT_DECL(crypto_sign_update
, sign_update
);
4188 crypto_session_id_t session_id
;
4190 crypto_session_data_t
*sp
= NULL
;
4191 crypto_ctx_t
**ctxpp
;
4193 size_t datalen
, need
= 0;
4196 boolean_t rctl_chk
= B_FALSE
;
4198 STRUCT_INIT(sign_update
, mode
);
4200 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
4201 cmn_err(CE_WARN
, "sign_verify_update: failed holding minor");
4205 if (copyin(arg
, STRUCT_BUF(sign_update
),
4206 STRUCT_SIZE(sign_update
)) != 0) {
4207 crypto_release_minor(cm
);
4211 data
.cd_raw
.iov_base
= NULL
;
4212 data
.cd_miscdata
= NULL
;
4214 datalen
= STRUCT_FGET(sign_update
, su_datalen
);
4215 if (datalen
> crypto_max_buffer_len
) {
4216 cmn_err(CE_NOTE
, "sign_verify_update: buffer greater than %ld "
4217 "bytes, pid = %d", crypto_max_buffer_len
, curproc
->p_pid
);
4218 rv
= CRYPTO_ARGUMENTS_BAD
;
4222 session_id
= STRUCT_FGET(sign_update
, su_session
);
4224 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
4228 if ((rv
= CRYPTO_BUFFER_CHECK(sp
, datalen
, rctl_chk
)) !=
4234 INIT_RAW_CRYPTO_DATA(data
, datalen
);
4236 if (datalen
!= 0 && copyin(STRUCT_FGETP(sign_update
, su_databuf
),
4237 data
.cd_raw
.iov_base
, datalen
) != 0) {
4242 ASSERT(update
== crypto_sign_update
||
4243 update
== crypto_verify_update
||
4244 update
== crypto_mac_update
);
4246 if (update
== crypto_sign_update
)
4247 ctxpp
= &sp
->sd_sign_ctx
;
4248 else if (update
== crypto_verify_update
)
4249 ctxpp
= &sp
->sd_verify_ctx
;
4251 ctxpp
= &sp
->sd_mac_ctx
;
4253 rv
= (update
)(*ctxpp
, &data
, NULL
);
4254 if (rv
!= CRYPTO_SUCCESS
)
4255 CRYPTO_CANCEL_CTX(ctxpp
);
4258 CRYPTO_DECREMENT_RCTL_SESSION(sp
, need
, rctl_chk
);
4259 CRYPTO_SESSION_RELE(sp
);
4260 crypto_release_minor(cm
);
4262 if (data
.cd_raw
.iov_base
!= NULL
)
4263 kmem_free(data
.cd_raw
.iov_base
, datalen
);
4268 STRUCT_FSET(sign_update
, su_return_value
, rv
);
4269 if (copyout(STRUCT_BUF(sign_update
), arg
,
4270 STRUCT_SIZE(sign_update
)) != 0) {
4278 sign_final(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
4280 return (common_final(dev
, arg
, mode
, crypto_sign_final
));
4284 * Can't use the common final because it does a copyout of
4289 verify_final(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
4291 STRUCT_DECL(crypto_verify_final
, verify_final
);
4292 crypto_session_id_t session_id
;
4294 crypto_session_data_t
*sp
= NULL
;
4296 size_t signlen
, need
= 0;
4299 boolean_t rctl_chk
= B_FALSE
;
4301 STRUCT_INIT(verify_final
, mode
);
4303 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
4304 cmn_err(CE_WARN
, "verify_final: failed holding minor");
4308 if (copyin(arg
, STRUCT_BUF(verify_final
),
4309 STRUCT_SIZE(verify_final
)) != 0) {
4310 crypto_release_minor(cm
);
4314 sign
.cd_raw
.iov_base
= NULL
;
4316 signlen
= STRUCT_FGET(verify_final
, vf_signlen
);
4317 if (signlen
> crypto_max_buffer_len
) {
4318 cmn_err(CE_NOTE
, "verify_final: buffer greater than %ld "
4319 "bytes, pid = %d", crypto_max_buffer_len
, curproc
->p_pid
);
4320 rv
= CRYPTO_ARGUMENTS_BAD
;
4324 session_id
= STRUCT_FGET(verify_final
, vf_session
);
4326 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
4330 if ((rv
= CRYPTO_BUFFER_CHECK(sp
, signlen
, rctl_chk
)) !=
4336 INIT_RAW_CRYPTO_DATA(sign
, signlen
);
4338 if (signlen
!= 0 && copyin(STRUCT_FGETP(verify_final
, vf_signbuf
),
4339 sign
.cd_raw
.iov_base
, signlen
) != 0) {
4344 rv
= crypto_verify_final(sp
->sd_verify_ctx
, &sign
, NULL
);
4345 if (KCF_CONTEXT_DONE(rv
))
4346 sp
->sd_verify_ctx
= NULL
;
4349 CRYPTO_DECREMENT_RCTL_SESSION(sp
, need
, rctl_chk
);
4350 CRYPTO_SESSION_RELE(sp
);
4351 crypto_release_minor(cm
);
4353 if (sign
.cd_raw
.iov_base
!= NULL
)
4354 kmem_free(sign
.cd_raw
.iov_base
, signlen
);
4359 STRUCT_FSET(verify_final
, vf_return_value
, rv
);
4360 if (copyout(STRUCT_BUF(verify_final
), arg
,
4361 STRUCT_SIZE(verify_final
)) != 0) {
4369 seed_random(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
4371 STRUCT_DECL(crypto_seed_random
, seed_random
);
4372 kcf_provider_desc_t
*real_provider
= NULL
;
4373 kcf_req_params_t params
;
4374 crypto_session_id_t session_id
;
4376 crypto_session_data_t
*sp
= NULL
;
4377 uchar_t
*seed_buffer
= NULL
;
4382 boolean_t rctl_chk
= B_FALSE
;
4384 STRUCT_INIT(seed_random
, mode
);
4386 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
4387 cmn_err(CE_WARN
, "seed_random: failed holding minor");
4391 if (copyin(arg
, STRUCT_BUF(seed_random
),
4392 STRUCT_SIZE(seed_random
)) != 0) {
4393 crypto_release_minor(cm
);
4397 seed_len
= STRUCT_FGET(seed_random
, sr_seedlen
);
4398 if (seed_len
> crypto_max_buffer_len
) {
4399 cmn_err(CE_NOTE
, "seed_random: buffer greater than %ld "
4400 "bytes, pid = %d", crypto_max_buffer_len
, curproc
->p_pid
);
4401 rv
= CRYPTO_ARGUMENTS_BAD
;
4405 session_id
= STRUCT_FGET(seed_random
, sr_session
);
4407 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
4411 if ((rv
= CRYPTO_BUFFER_CHECK(sp
, seed_len
, rctl_chk
)) !=
4416 seed_buffer
= kmem_alloc(seed_len
, KM_SLEEP
);
4418 if (seed_len
!= 0 && copyin(STRUCT_FGETP(seed_random
, sr_seedbuf
),
4419 seed_buffer
, seed_len
) != 0) {
4424 if ((rv
= kcf_get_hardware_provider_nomech(
4425 CRYPTO_OPS_OFFSET(random_ops
), CRYPTO_RANDOM_OFFSET(seed_random
),
4426 sp
->sd_provider
, &real_provider
)) != CRYPTO_SUCCESS
) {
4430 KCF_WRAP_RANDOM_OPS_PARAMS(¶ms
, KCF_OP_RANDOM_SEED
,
4431 sp
->sd_provider_session
->ps_session
, seed_buffer
, seed_len
, 0,
4434 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
, B_FALSE
);
4437 CRYPTO_DECREMENT_RCTL_SESSION(sp
, need
, rctl_chk
);
4438 CRYPTO_SESSION_RELE(sp
);
4439 crypto_release_minor(cm
);
4441 if (real_provider
!= NULL
)
4442 KCF_PROV_REFRELE(real_provider
);
4444 if (seed_buffer
!= NULL
)
4445 kmem_free(seed_buffer
, seed_len
);
4450 STRUCT_FSET(seed_random
, sr_return_value
, rv
);
4451 if (copyout(STRUCT_BUF(seed_random
), arg
,
4452 STRUCT_SIZE(seed_random
)) != 0) {
4460 generate_random(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
4462 STRUCT_DECL(crypto_generate_random
, generate_random
);
4463 kcf_provider_desc_t
*real_provider
= NULL
;
4464 kcf_req_params_t params
;
4465 crypto_session_id_t session_id
;
4467 crypto_session_data_t
*sp
= NULL
;
4468 uchar_t
*buffer
= NULL
;
4473 boolean_t rctl_chk
= B_FALSE
;
4475 STRUCT_INIT(generate_random
, mode
);
4477 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
4478 cmn_err(CE_WARN
, "generate_random: failed holding minor");
4482 if (copyin(arg
, STRUCT_BUF(generate_random
),
4483 STRUCT_SIZE(generate_random
)) != 0) {
4484 crypto_release_minor(cm
);
4488 len
= STRUCT_FGET(generate_random
, gr_buflen
);
4489 if (len
> crypto_max_buffer_len
) {
4490 cmn_err(CE_NOTE
, "generate_random: buffer greater than %ld "
4491 "bytes, pid = %d", crypto_max_buffer_len
, curproc
->p_pid
);
4492 rv
= CRYPTO_ARGUMENTS_BAD
;
4496 session_id
= STRUCT_FGET(generate_random
, gr_session
);
4498 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
4502 if ((rv
= CRYPTO_BUFFER_CHECK(sp
, len
, rctl_chk
)) !=
4507 buffer
= kmem_alloc(len
, KM_SLEEP
);
4509 if ((rv
= kcf_get_hardware_provider_nomech(
4510 CRYPTO_OPS_OFFSET(random_ops
),
4511 CRYPTO_RANDOM_OFFSET(generate_random
), sp
->sd_provider
,
4512 &real_provider
)) != CRYPTO_SUCCESS
) {
4516 KCF_WRAP_RANDOM_OPS_PARAMS(¶ms
, KCF_OP_RANDOM_GENERATE
,
4517 sp
->sd_provider_session
->ps_session
, buffer
, len
, 0, 0);
4519 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
, B_FALSE
);
4521 if (rv
== CRYPTO_SUCCESS
) {
4522 if (len
!= 0 && copyout(buffer
,
4523 STRUCT_FGETP(generate_random
, gr_buf
), len
) != 0) {
4529 CRYPTO_DECREMENT_RCTL_SESSION(sp
, need
, rctl_chk
);
4530 CRYPTO_SESSION_RELE(sp
);
4531 crypto_release_minor(cm
);
4533 if (real_provider
!= NULL
)
4534 KCF_PROV_REFRELE(real_provider
);
4536 if (buffer
!= NULL
) {
4537 /* random numbers are often used to create keys */
4539 kmem_free(buffer
, len
);
4545 STRUCT_FSET(generate_random
, gr_return_value
, rv
);
4546 if (copyout(STRUCT_BUF(generate_random
), arg
,
4547 STRUCT_SIZE(generate_random
)) != 0) {
4554 * Copyout a kernel array of attributes to user space.
4555 * u_attrs is the corresponding user space array containing
4556 * user space pointers necessary for the copyout.
4560 copyout_attributes(int mode
, caddr_t out
, uint_t count
,
4561 crypto_object_attribute_t
*k_attrs
, caddr_t u_attrs
)
4563 STRUCT_DECL(crypto_object_attribute
, oa
);
4573 STRUCT_INIT(oa
, mode
);
4575 len
= count
* STRUCT_SIZE(oa
);
4577 ASSERT(u_attrs
!= NULL
);
4579 for (i
= 0; i
< count
; i
++) {
4580 /* can this bcopy be eliminated? */
4581 bcopy(p
, STRUCT_BUF(oa
), STRUCT_SIZE(oa
));
4582 value_len
= k_attrs
[i
].oa_value_len
;
4583 STRUCT_FSET(oa
, oa_type
, k_attrs
[i
].oa_type
);
4584 STRUCT_FSET(oa
, oa_value_len
, (ssize_t
)value_len
);
4585 valuep
= STRUCT_FGETP(oa
, oa_value
);
4586 if ((valuep
!= NULL
) && (value_len
!= (size_t)-1)) {
4587 if (copyout(k_attrs
[i
].oa_value
,
4588 valuep
, value_len
) != 0) {
4593 bcopy(STRUCT_BUF(oa
), p
, STRUCT_SIZE(oa
));
4594 p
+= STRUCT_SIZE(oa
);
4596 if (copyout(u_attrs
, out
, len
)) {
4606 object_create(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
4608 STRUCT_DECL(crypto_object_create
, object_create
);
4609 kcf_provider_desc_t
*real_provider
= NULL
;
4610 kcf_req_params_t params
;
4611 crypto_object_attribute_t
*k_attrs
= NULL
;
4612 crypto_session_id_t session_id
;
4614 crypto_session_data_t
*sp
= NULL
;
4615 crypto_object_id_t object_handle
;
4616 caddr_t oc_attributes
;
4617 size_t k_attrs_size
;
4618 size_t rctl_bytes
= 0;
4619 boolean_t rctl_chk
= B_FALSE
;
4624 STRUCT_INIT(object_create
, mode
);
4626 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
4627 cmn_err(CE_WARN
, "object_create: failed holding minor");
4631 if (copyin(arg
, STRUCT_BUF(object_create
),
4632 STRUCT_SIZE(object_create
)) != 0) {
4633 crypto_release_minor(cm
);
4637 count
= STRUCT_FGET(object_create
, oc_count
);
4638 oc_attributes
= STRUCT_FGETP(object_create
, oc_attributes
);
4640 session_id
= STRUCT_FGET(object_create
, oc_session
);
4641 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
4644 if (!copyin_attributes(mode
, sp
, count
, oc_attributes
, &k_attrs
,
4645 &k_attrs_size
, NULL
, &rv
, &error
, &rctl_bytes
,
4646 &rctl_chk
, B_TRUE
)) {
4650 if ((rv
= kcf_get_hardware_provider_nomech(
4651 CRYPTO_OPS_OFFSET(object_ops
),
4652 CRYPTO_OBJECT_OFFSET(object_create
), sp
->sd_provider
,
4653 &real_provider
)) != CRYPTO_SUCCESS
) {
4657 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms
, KCF_OP_OBJECT_CREATE
,
4658 sp
->sd_provider_session
->ps_session
, 0, k_attrs
, count
,
4659 &object_handle
, 0, NULL
, NULL
, 0, NULL
);
4661 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
, B_FALSE
);
4663 if (rv
== CRYPTO_SUCCESS
)
4664 STRUCT_FSET(object_create
, oc_handle
, object_handle
);
4667 CRYPTO_DECREMENT_RCTL_SESSION(sp
, rctl_bytes
, rctl_chk
);
4669 if (k_attrs
!= NULL
)
4670 kmem_free(k_attrs
, k_attrs_size
);
4675 STRUCT_FSET(object_create
, oc_return_value
, rv
);
4676 if (copyout(STRUCT_BUF(object_create
), arg
,
4677 STRUCT_SIZE(object_create
)) != 0) {
4678 if (rv
== CRYPTO_SUCCESS
) {
4679 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms
,
4680 KCF_OP_OBJECT_DESTROY
,
4681 sp
->sd_provider_session
->ps_session
, object_handle
,
4682 NULL
, 0, NULL
, 0, NULL
, NULL
, 0, NULL
);
4684 (void) kcf_submit_request(real_provider
, NULL
,
4685 NULL
, ¶ms
, B_FALSE
);
4691 CRYPTO_SESSION_RELE(sp
);
4692 crypto_release_minor(cm
);
4693 if (real_provider
!= NULL
)
4694 KCF_PROV_REFRELE(real_provider
);
4700 object_copy(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
4702 STRUCT_DECL(crypto_object_copy
, object_copy
);
4703 kcf_provider_desc_t
*real_provider
= NULL
;
4704 kcf_req_params_t params
;
4705 crypto_object_attribute_t
*k_attrs
= NULL
;
4706 crypto_session_id_t session_id
;
4708 crypto_session_data_t
*sp
= NULL
;
4709 crypto_object_id_t handle
, new_handle
;
4710 caddr_t oc_new_attributes
;
4711 size_t k_attrs_size
;
4712 size_t rctl_bytes
= 0;
4713 boolean_t rctl_chk
= B_FALSE
;
4718 STRUCT_INIT(object_copy
, mode
);
4720 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
4721 cmn_err(CE_WARN
, "object_copy: failed holding minor");
4725 if (copyin(arg
, STRUCT_BUF(object_copy
),
4726 STRUCT_SIZE(object_copy
)) != 0) {
4727 crypto_release_minor(cm
);
4731 count
= STRUCT_FGET(object_copy
, oc_count
);
4732 oc_new_attributes
= STRUCT_FGETP(object_copy
, oc_new_attributes
);
4734 session_id
= STRUCT_FGET(object_copy
, oc_session
);
4736 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
4739 if (!copyin_attributes(mode
, sp
, count
, oc_new_attributes
, &k_attrs
,
4740 &k_attrs_size
, NULL
, &rv
, &error
, &rctl_bytes
,
4741 &rctl_chk
, B_TRUE
)) {
4745 if ((rv
= kcf_get_hardware_provider_nomech(
4746 CRYPTO_OPS_OFFSET(object_ops
),
4747 CRYPTO_OBJECT_OFFSET(object_copy
), sp
->sd_provider
,
4748 &real_provider
)) != CRYPTO_SUCCESS
) {
4752 handle
= STRUCT_FGET(object_copy
, oc_handle
);
4753 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms
, KCF_OP_OBJECT_COPY
,
4754 sp
->sd_provider_session
->ps_session
, handle
, k_attrs
, count
,
4755 &new_handle
, 0, NULL
, NULL
, 0, NULL
);
4757 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
, B_FALSE
);
4759 if (rv
== CRYPTO_SUCCESS
)
4760 STRUCT_FSET(object_copy
, oc_new_handle
, new_handle
);
4763 CRYPTO_DECREMENT_RCTL_SESSION(sp
, rctl_bytes
, rctl_chk
);
4765 if (k_attrs
!= NULL
)
4766 kmem_free(k_attrs
, k_attrs_size
);
4771 STRUCT_FSET(object_copy
, oc_return_value
, rv
);
4772 if (copyout(STRUCT_BUF(object_copy
), arg
,
4773 STRUCT_SIZE(object_copy
)) != 0) {
4774 if (rv
== CRYPTO_SUCCESS
) {
4775 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms
,
4776 KCF_OP_OBJECT_DESTROY
,
4777 sp
->sd_provider_session
->ps_session
, new_handle
,
4778 NULL
, 0, NULL
, 0, NULL
, NULL
, 0, NULL
);
4780 (void) kcf_submit_request(real_provider
, NULL
,
4781 NULL
, ¶ms
, B_FALSE
);
4787 CRYPTO_SESSION_RELE(sp
);
4788 crypto_release_minor(cm
);
4789 if (real_provider
!= NULL
)
4790 KCF_PROV_REFRELE(real_provider
);
4796 object_destroy(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
4798 STRUCT_DECL(crypto_object_destroy
, object_destroy
);
4799 kcf_provider_desc_t
*real_provider
;
4800 kcf_req_params_t params
;
4801 crypto_session_id_t session_id
;
4803 crypto_session_data_t
*sp
;
4804 crypto_object_id_t handle
;
4808 STRUCT_INIT(object_destroy
, mode
);
4810 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
4811 cmn_err(CE_WARN
, "object_destroy: failed holding minor");
4815 if (copyin(arg
, STRUCT_BUF(object_destroy
),
4816 STRUCT_SIZE(object_destroy
)) != 0) {
4817 crypto_release_minor(cm
);
4821 session_id
= STRUCT_FGET(object_destroy
, od_session
);
4823 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
4827 if ((rv
= kcf_get_hardware_provider_nomech(
4828 CRYPTO_OPS_OFFSET(object_ops
),
4829 CRYPTO_OBJECT_OFFSET(object_destroy
), sp
->sd_provider
,
4830 &real_provider
)) != CRYPTO_SUCCESS
) {
4834 handle
= STRUCT_FGET(object_destroy
, od_handle
);
4835 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms
, KCF_OP_OBJECT_DESTROY
,
4836 sp
->sd_provider_session
->ps_session
, handle
, NULL
, 0, NULL
, 0,
4837 NULL
, NULL
, 0, NULL
);
4839 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
, B_FALSE
);
4840 KCF_PROV_REFRELE(real_provider
);
4843 CRYPTO_SESSION_RELE(sp
);
4846 crypto_release_minor(cm
);
4851 STRUCT_FSET(object_destroy
, od_return_value
, rv
);
4853 if (copyout(STRUCT_BUF(object_destroy
), arg
,
4854 STRUCT_SIZE(object_destroy
)) != 0) {
4862 object_get_attribute_value(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
4864 STRUCT_DECL(crypto_object_get_attribute_value
, get_attribute_value
);
4866 STRUCT_DECL(crypto_object_attribute
, oa
);
4868 /* LINTED E_FUNC_SET_NOT_USED */
4869 STRUCT_DECL(crypto_object_attribute
, oa
);
4871 kcf_provider_desc_t
*real_provider
;
4872 kcf_req_params_t params
;
4873 crypto_object_attribute_t
*k_attrs
= NULL
;
4874 crypto_session_id_t session_id
;
4876 crypto_session_data_t
*sp
= NULL
;
4877 crypto_object_id_t handle
;
4878 caddr_t og_attributes
;
4879 caddr_t u_attrs
= NULL
;
4880 size_t k_attrs_size
;
4881 size_t rctl_bytes
= 0;
4882 boolean_t rctl_chk
= B_FALSE
;
4887 STRUCT_INIT(get_attribute_value
, mode
);
4888 STRUCT_INIT(oa
, mode
);
4890 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
4892 "object_get_attribute_value: failed holding minor");
4896 if (copyin(arg
, STRUCT_BUF(get_attribute_value
),
4897 STRUCT_SIZE(get_attribute_value
)) != 0) {
4898 crypto_release_minor(cm
);
4902 count
= STRUCT_FGET(get_attribute_value
, og_count
);
4903 og_attributes
= STRUCT_FGETP(get_attribute_value
, og_attributes
);
4905 session_id
= STRUCT_FGET(get_attribute_value
, og_session
);
4907 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
4910 if (!copyin_attributes(mode
, sp
, count
, og_attributes
, &k_attrs
,
4911 &k_attrs_size
, &u_attrs
, &rv
, &error
, &rctl_bytes
,
4912 &rctl_chk
, B_FALSE
)) {
4916 if ((rv
= kcf_get_hardware_provider_nomech(
4917 CRYPTO_OPS_OFFSET(object_ops
),
4918 CRYPTO_OBJECT_OFFSET(object_get_attribute_value
),
4919 sp
->sd_provider
, &real_provider
)) != CRYPTO_SUCCESS
) {
4923 handle
= STRUCT_FGET(get_attribute_value
, og_handle
);
4924 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms
, KCF_OP_OBJECT_GET_ATTRIBUTE_VALUE
,
4925 sp
->sd_provider_session
->ps_session
, handle
, k_attrs
, count
, NULL
,
4926 0, NULL
, NULL
, 0, NULL
);
4928 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
, B_FALSE
);
4929 KCF_PROV_REFRELE(real_provider
);
4932 if (rv
== CRYPTO_SUCCESS
|| rv
== CRYPTO_ATTRIBUTE_SENSITIVE
||
4933 rv
== CRYPTO_ATTRIBUTE_TYPE_INVALID
||
4934 rv
== CRYPTO_BUFFER_TOO_SMALL
) {
4935 error
= copyout_attributes(mode
,
4936 STRUCT_FGETP(get_attribute_value
, og_attributes
),
4937 count
, k_attrs
, u_attrs
);
4941 CRYPTO_DECREMENT_RCTL_SESSION(sp
, rctl_bytes
, rctl_chk
);
4942 CRYPTO_SESSION_RELE(sp
);
4943 crypto_release_minor(cm
);
4945 if (k_attrs
!= NULL
)
4946 kmem_free(k_attrs
, k_attrs_size
);
4948 if (u_attrs
!= NULL
)
4949 kmem_free(u_attrs
, count
* STRUCT_SIZE(oa
));
4954 STRUCT_FSET(get_attribute_value
, og_return_value
, rv
);
4955 if (copyout(STRUCT_BUF(get_attribute_value
), arg
,
4956 STRUCT_SIZE(get_attribute_value
)) != 0) {
4964 object_get_size(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
4966 STRUCT_DECL(crypto_object_get_size
, object_get_size
);
4967 kcf_provider_desc_t
*real_provider
;
4968 kcf_req_params_t params
;
4969 crypto_session_id_t session_id
;
4971 crypto_session_data_t
*sp
= NULL
;
4972 crypto_object_id_t handle
;
4977 STRUCT_INIT(object_get_size
, mode
);
4979 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
4980 cmn_err(CE_WARN
, "object_get_size: failed holding minor");
4984 if (copyin(arg
, STRUCT_BUF(object_get_size
),
4985 STRUCT_SIZE(object_get_size
)) != 0) {
4986 crypto_release_minor(cm
);
4990 session_id
= STRUCT_FGET(object_get_size
, gs_session
);
4992 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
4996 if ((rv
= kcf_get_hardware_provider_nomech(
4997 CRYPTO_OPS_OFFSET(object_ops
),
4998 CRYPTO_OBJECT_OFFSET(object_get_size
),
4999 sp
->sd_provider
, &real_provider
)) != CRYPTO_SUCCESS
) {
5003 handle
= STRUCT_FGET(object_get_size
, gs_handle
);
5004 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms
, KCF_OP_OBJECT_GET_SIZE
,
5005 sp
->sd_provider_session
->ps_session
, handle
, NULL
, 0, NULL
, &size
,
5006 NULL
, NULL
, 0, NULL
);
5008 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
, B_FALSE
);
5009 KCF_PROV_REFRELE(real_provider
);
5011 if (rv
== CRYPTO_SUCCESS
) {
5012 STRUCT_FSET(object_get_size
, gs_size
, (ulong_t
)size
);
5016 crypto_release_minor(cm
);
5017 CRYPTO_SESSION_RELE(sp
);
5022 STRUCT_FSET(object_get_size
, gs_return_value
, rv
);
5023 if (copyout(STRUCT_BUF(object_get_size
), arg
,
5024 STRUCT_SIZE(object_get_size
)) != 0) {
5032 object_set_attribute_value(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
5034 STRUCT_DECL(crypto_object_set_attribute_value
, set_attribute_value
);
5035 kcf_provider_desc_t
*real_provider
;
5036 kcf_req_params_t params
;
5037 crypto_object_attribute_t
*k_attrs
= NULL
;
5038 crypto_session_id_t session_id
;
5040 crypto_session_data_t
*sp
= NULL
;
5041 crypto_object_id_t object_handle
;
5042 caddr_t sa_attributes
;
5043 size_t k_attrs_size
;
5044 size_t rctl_bytes
= 0;
5045 boolean_t rctl_chk
= B_FALSE
;
5050 STRUCT_INIT(set_attribute_value
, mode
);
5052 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
5054 "object_set_attribute_value: failed holding minor");
5058 if (copyin(arg
, STRUCT_BUF(set_attribute_value
),
5059 STRUCT_SIZE(set_attribute_value
)) != 0) {
5060 crypto_release_minor(cm
);
5064 count
= STRUCT_FGET(set_attribute_value
, sa_count
);
5065 sa_attributes
= STRUCT_FGETP(set_attribute_value
, sa_attributes
);
5067 session_id
= STRUCT_FGET(set_attribute_value
, sa_session
);
5069 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
5072 if (!copyin_attributes(mode
, sp
, count
, sa_attributes
, &k_attrs
,
5073 &k_attrs_size
, NULL
, &rv
, &error
, &rctl_bytes
,
5074 &rctl_chk
, B_TRUE
)) {
5078 if ((rv
= kcf_get_hardware_provider_nomech(
5079 CRYPTO_OPS_OFFSET(object_ops
),
5080 CRYPTO_OBJECT_OFFSET(object_set_attribute_value
),
5081 sp
->sd_provider
, &real_provider
)) != CRYPTO_SUCCESS
) {
5085 object_handle
= STRUCT_FGET(set_attribute_value
, sa_handle
);
5086 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms
, KCF_OP_OBJECT_SET_ATTRIBUTE_VALUE
,
5087 sp
->sd_provider_session
->ps_session
, object_handle
, k_attrs
, count
,
5088 NULL
, 0, NULL
, NULL
, 0, NULL
);
5090 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
, B_FALSE
);
5091 KCF_PROV_REFRELE(real_provider
);
5094 CRYPTO_DECREMENT_RCTL_SESSION(sp
, rctl_bytes
, rctl_chk
);
5095 CRYPTO_SESSION_RELE(sp
);
5096 crypto_release_minor(cm
);
5098 if (k_attrs
!= NULL
)
5099 kmem_free(k_attrs
, k_attrs_size
);
5104 STRUCT_FSET(set_attribute_value
, sa_return_value
, rv
);
5105 if (copyout(STRUCT_BUF(set_attribute_value
), arg
,
5106 STRUCT_SIZE(set_attribute_value
)) != 0) {
5114 object_find_init(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
5116 STRUCT_DECL(crypto_object_find_init
, find_init
);
5117 kcf_provider_desc_t
*real_provider
= NULL
;
5118 kcf_req_params_t params
;
5119 crypto_object_attribute_t
*k_attrs
= NULL
;
5120 crypto_session_id_t session_id
;
5122 crypto_session_data_t
*sp
= NULL
;
5124 size_t k_attrs_size
;
5125 size_t rctl_bytes
= 0;
5126 boolean_t rctl_chk
= B_FALSE
;
5132 STRUCT_INIT(find_init
, mode
);
5134 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
5135 cmn_err(CE_WARN
, "object_find_init: failed holding minor");
5139 if (copyin(arg
, STRUCT_BUF(find_init
), STRUCT_SIZE(find_init
)) != 0) {
5140 crypto_release_minor(cm
);
5144 count
= STRUCT_FGET(find_init
, fi_count
);
5145 attributes
= STRUCT_FGETP(find_init
, fi_attributes
);
5147 session_id
= STRUCT_FGET(find_init
, fi_session
);
5149 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
5152 if (!copyin_attributes(mode
, sp
, count
, attributes
, &k_attrs
,
5153 &k_attrs_size
, NULL
, &rv
, &error
, &rctl_bytes
,
5154 &rctl_chk
, B_TRUE
)) {
5158 if ((rv
= kcf_get_hardware_provider_nomech(
5159 CRYPTO_OPS_OFFSET(object_ops
),
5160 CRYPTO_OBJECT_OFFSET(object_find_init
),
5161 sp
->sd_provider
, &real_provider
)) != CRYPTO_SUCCESS
) {
5165 /* check for an active find */
5166 if (sp
->sd_find_init_cookie
!= NULL
) {
5167 rv
= CRYPTO_OPERATION_IS_ACTIVE
;
5171 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms
, KCF_OP_OBJECT_FIND_INIT
,
5172 sp
->sd_provider_session
->ps_session
, 0, k_attrs
, count
, NULL
, 0,
5173 &cookie
, NULL
, 0, NULL
);
5175 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
, B_FALSE
);
5177 if (rv
== CRYPTO_SUCCESS
) {
5179 * The cookie is allocated by a provider at the start of an
5180 * object search. It is freed when the search is terminated
5181 * by a final operation, or when the session is closed.
5182 * It contains state information about which object handles
5183 * have been returned to the caller.
5185 sp
->sd_find_init_cookie
= cookie
;
5189 CRYPTO_DECREMENT_RCTL_SESSION(sp
, rctl_bytes
, rctl_chk
);
5190 CRYPTO_SESSION_RELE(sp
);
5191 crypto_release_minor(cm
);
5193 if (real_provider
!= NULL
)
5194 KCF_PROV_REFRELE(real_provider
);
5196 if (k_attrs
!= NULL
)
5197 kmem_free(k_attrs
, k_attrs_size
);
5202 STRUCT_FSET(find_init
, fi_return_value
, rv
);
5203 if (copyout(STRUCT_BUF(find_init
), arg
, STRUCT_SIZE(find_init
)) != 0) {
5211 object_find_update(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
5213 STRUCT_DECL(crypto_object_find_update
, find_update
);
5214 kcf_provider_desc_t
*real_provider
;
5215 kcf_req_params_t params
;
5217 crypto_session_data_t
*sp
= NULL
;
5218 crypto_object_id_t
*buffer
= NULL
;
5219 crypto_session_id_t session_id
;
5220 size_t len
, rctl_bytes
= 0;
5221 uint_t count
, max_count
;
5223 boolean_t rctl_chk
= B_FALSE
;
5225 STRUCT_INIT(find_update
, mode
);
5227 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
5228 cmn_err(CE_WARN
, "object_find_update: failed holding minor");
5232 if (copyin(arg
, STRUCT_BUF(find_update
),
5233 STRUCT_SIZE(find_update
)) != 0) {
5234 crypto_release_minor(cm
);
5238 max_count
= STRUCT_FGET(find_update
, fu_max_count
);
5239 if (max_count
> CRYPTO_MAX_FIND_COUNT
) {
5240 cmn_err(CE_NOTE
, "object_find_update: count greater than %d, "
5241 "pid = %d", CRYPTO_MAX_FIND_COUNT
, curproc
->p_pid
);
5242 rv
= CRYPTO_ARGUMENTS_BAD
;
5245 len
= max_count
* sizeof (crypto_object_id_t
);
5246 session_id
= STRUCT_FGET(find_update
, fu_session
);
5248 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
5251 if ((rv
= CRYPTO_BUFFER_CHECK(sp
, len
, rctl_chk
)) !=
5256 buffer
= kmem_alloc(len
, KM_SLEEP
);
5258 if ((rv
= kcf_get_hardware_provider_nomech(
5259 CRYPTO_OPS_OFFSET(object_ops
),
5260 CRYPTO_OBJECT_OFFSET(object_find
), sp
->sd_provider
,
5261 &real_provider
)) != CRYPTO_SUCCESS
) {
5265 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms
, KCF_OP_OBJECT_FIND
,
5266 sp
->sd_provider_session
->ps_session
, 0, NULL
, 0, buffer
, 0,
5267 NULL
, sp
->sd_find_init_cookie
, max_count
, &count
);
5269 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
, B_FALSE
);
5270 KCF_PROV_REFRELE(real_provider
);
5272 if (rv
== CRYPTO_SUCCESS
) {
5273 if (count
> max_count
) {
5274 /* bad bad provider */
5279 /* copyout handles */
5281 STRUCT_FGETP(find_update
, fu_handles
),
5282 count
* sizeof (crypto_object_id_t
)) != 0) {
5286 STRUCT_FSET(find_update
, fu_count
, count
);
5290 CRYPTO_DECREMENT_RCTL_SESSION(sp
, rctl_bytes
, rctl_chk
);
5291 CRYPTO_SESSION_RELE(sp
);
5292 crypto_release_minor(cm
);
5295 kmem_free(buffer
, len
);
5300 STRUCT_FSET(find_update
, fu_return_value
, rv
);
5301 if (copyout(STRUCT_BUF(find_update
), arg
,
5302 STRUCT_SIZE(find_update
)) != 0) {
5310 * Free provider-allocated storage used for find object searches.
5313 crypto_free_find_ctx(crypto_session_data_t
*sp
)
5315 kcf_provider_desc_t
*real_provider
;
5316 kcf_req_params_t params
;
5319 if ((rv
= kcf_get_hardware_provider_nomech(
5320 CRYPTO_OPS_OFFSET(object_ops
),
5321 CRYPTO_OBJECT_OFFSET(object_find_final
),
5322 sp
->sd_provider
, &real_provider
)) != CRYPTO_SUCCESS
) {
5326 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms
, KCF_OP_OBJECT_FIND_FINAL
,
5327 sp
->sd_provider_session
->ps_session
, 0, NULL
, 0, NULL
, 0,
5328 NULL
, sp
->sd_find_init_cookie
, 0, NULL
);
5330 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
, B_FALSE
);
5331 KCF_PROV_REFRELE(real_provider
);
5337 object_find_final(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
5339 STRUCT_DECL(crypto_object_find_final
, object_find_final
);
5340 crypto_session_id_t session_id
;
5342 crypto_session_data_t
*sp
;
5346 STRUCT_INIT(object_find_final
, mode
);
5348 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
5349 cmn_err(CE_WARN
, "object_find_final: failed holding minor");
5353 if (copyin(arg
, STRUCT_BUF(object_find_final
),
5354 STRUCT_SIZE(object_find_final
)) != 0) {
5355 crypto_release_minor(cm
);
5359 session_id
= STRUCT_FGET(object_find_final
, ff_session
);
5361 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
5365 if ((rv
= crypto_free_find_ctx(sp
)) == CRYPTO_SUCCESS
) {
5366 sp
->sd_find_init_cookie
= NULL
;
5369 CRYPTO_SESSION_RELE(sp
);
5372 crypto_release_minor(cm
);
5377 STRUCT_FSET(object_find_final
, ff_return_value
, rv
);
5379 if (copyout(STRUCT_BUF(object_find_final
), arg
,
5380 STRUCT_SIZE(object_find_final
)) != 0) {
5388 object_generate_key(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
5390 STRUCT_DECL(crypto_object_generate_key
, generate_key
);
5391 kcf_provider_desc_t
*real_provider
= NULL
;
5392 kcf_req_params_t params
;
5393 crypto_mechanism_t mech
;
5394 crypto_object_attribute_t
*k_attrs
= NULL
;
5395 crypto_session_id_t session_id
;
5397 crypto_session_data_t
*sp
= NULL
;
5398 crypto_object_id_t key_handle
;
5400 size_t k_attrs_size
;
5401 size_t mech_rctl_bytes
= 0, key_rctl_bytes
= 0;
5402 boolean_t mech_rctl_chk
= B_FALSE
;
5403 boolean_t key_rctl_chk
= B_FALSE
;
5407 boolean_t allocated_by_crypto_module
= B_FALSE
;
5409 STRUCT_INIT(generate_key
, mode
);
5411 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
5412 cmn_err(CE_WARN
, "object_generate_key: failed holding minor");
5416 if (copyin(arg
, STRUCT_BUF(generate_key
),
5417 STRUCT_SIZE(generate_key
)) != 0) {
5418 crypto_release_minor(cm
);
5422 session_id
= STRUCT_FGET(generate_key
, gk_session
);
5424 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
5428 bcopy(STRUCT_FADDR(generate_key
, gk_mechanism
), &mech
.cm_type
,
5429 sizeof (crypto_mech_type_t
));
5431 if ((rv
= kcf_get_hardware_provider(mech
.cm_type
, NULL
,
5432 CRYPTO_MECH_INVALID
, NULL
, sp
->sd_provider
,
5433 &real_provider
, CRYPTO_FG_GENERATE
)) != CRYPTO_SUCCESS
) {
5437 rv
= crypto_provider_copyin_mech_param(real_provider
,
5438 STRUCT_FADDR(generate_key
, gk_mechanism
), &mech
, mode
, &error
);
5440 if (rv
== CRYPTO_NOT_SUPPORTED
) {
5441 allocated_by_crypto_module
= B_TRUE
;
5442 if (!copyin_mech(mode
, sp
,
5443 STRUCT_FADDR(generate_key
, gk_mechanism
),
5444 &mech
, &mech_rctl_bytes
, &mech_rctl_chk
, &rv
, &error
)) {
5448 if (rv
!= CRYPTO_SUCCESS
)
5452 count
= STRUCT_FGET(generate_key
, gk_count
);
5453 attributes
= STRUCT_FGETP(generate_key
, gk_attributes
);
5454 if (!copyin_attributes(mode
, sp
, count
, attributes
, &k_attrs
,
5455 &k_attrs_size
, NULL
, &rv
, &error
, &key_rctl_bytes
,
5456 &key_rctl_chk
, B_TRUE
)) {
5460 KCF_WRAP_KEY_OPS_PARAMS(¶ms
, KCF_OP_KEY_GENERATE
,
5461 sp
->sd_provider_session
->ps_session
, &mech
, k_attrs
, count
,
5462 &key_handle
, NULL
, 0, NULL
, NULL
, NULL
, 0);
5464 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
, B_FALSE
);
5466 if (rv
== CRYPTO_SUCCESS
)
5467 STRUCT_FSET(generate_key
, gk_handle
, key_handle
);
5470 CRYPTO_DECREMENT_RCTL_SESSION(sp
, mech_rctl_bytes
, mech_rctl_chk
);
5471 CRYPTO_DECREMENT_RCTL_SESSION(sp
, key_rctl_bytes
, key_rctl_chk
);
5473 if (k_attrs
!= NULL
)
5474 kmem_free(k_attrs
, k_attrs_size
);
5479 STRUCT_FSET(generate_key
, gk_return_value
, rv
);
5480 if (copyout(STRUCT_BUF(generate_key
), arg
,
5481 STRUCT_SIZE(generate_key
)) != 0) {
5482 if (rv
== CRYPTO_SUCCESS
) {
5483 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms
,
5484 KCF_OP_OBJECT_DESTROY
,
5485 sp
->sd_provider_session
->ps_session
, key_handle
,
5486 NULL
, 0, NULL
, 0, NULL
, NULL
, 0, NULL
);
5488 (void) kcf_submit_request(real_provider
, NULL
,
5489 NULL
, ¶ms
, B_FALSE
);
5495 CRYPTO_SESSION_RELE(sp
);
5496 crypto_release_minor(cm
);
5498 if (real_provider
!= NULL
) {
5499 crypto_free_mech(real_provider
,
5500 allocated_by_crypto_module
, &mech
);
5501 KCF_PROV_REFRELE(real_provider
);
5508 nostore_generate_key(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
5510 STRUCT_DECL(crypto_nostore_generate_key
, generate_key
);
5512 STRUCT_DECL(crypto_object_attribute
, oa
);
5514 /* LINTED E_FUNC_SET_NOT_USED */
5515 STRUCT_DECL(crypto_object_attribute
, oa
);
5517 kcf_provider_desc_t
*real_provider
= NULL
;
5518 kcf_req_params_t params
;
5519 crypto_mechanism_t mech
;
5520 crypto_object_attribute_t
*k_in_attrs
= NULL
;
5521 crypto_object_attribute_t
*k_out_attrs
= NULL
;
5522 crypto_session_id_t session_id
;
5524 crypto_session_data_t
*sp
= NULL
;
5525 caddr_t in_attributes
;
5526 caddr_t out_attributes
;
5527 size_t k_in_attrs_size
;
5528 size_t k_out_attrs_size
;
5529 size_t mech_rctl_bytes
= 0;
5530 boolean_t mech_rctl_chk
= B_FALSE
;
5531 size_t in_key_rctl_bytes
= 0, out_key_rctl_bytes
= 0;
5532 boolean_t in_key_rctl_chk
= B_FALSE
;
5533 boolean_t out_key_rctl_chk
= B_FALSE
;
5538 boolean_t allocated_by_crypto_module
= B_FALSE
;
5539 caddr_t u_attrs
= NULL
;
5541 STRUCT_INIT(generate_key
, mode
);
5542 STRUCT_INIT(oa
, mode
);
5544 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
5545 cmn_err(CE_WARN
, "nostore_generate_key: failed holding minor");
5549 if (copyin(arg
, STRUCT_BUF(generate_key
),
5550 STRUCT_SIZE(generate_key
)) != 0) {
5551 crypto_release_minor(cm
);
5555 session_id
= STRUCT_FGET(generate_key
, ngk_session
);
5557 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
5561 bcopy(STRUCT_FADDR(generate_key
, ngk_mechanism
), &mech
.cm_type
,
5562 sizeof (crypto_mech_type_t
));
5564 if ((rv
= kcf_get_hardware_provider(mech
.cm_type
, NULL
,
5565 CRYPTO_MECH_INVALID
, NULL
, sp
->sd_provider
,
5566 &real_provider
, CRYPTO_FG_GENERATE
)) != CRYPTO_SUCCESS
) {
5570 rv
= crypto_provider_copyin_mech_param(real_provider
,
5571 STRUCT_FADDR(generate_key
, ngk_mechanism
), &mech
, mode
, &error
);
5573 if (rv
== CRYPTO_NOT_SUPPORTED
) {
5574 allocated_by_crypto_module
= B_TRUE
;
5575 if (!copyin_mech(mode
, sp
, STRUCT_FADDR(generate_key
,
5576 ngk_mechanism
), &mech
, &mech_rctl_bytes
,
5577 &mech_rctl_chk
, &rv
, &error
)) {
5581 if (rv
!= CRYPTO_SUCCESS
)
5585 in_count
= STRUCT_FGET(generate_key
, ngk_in_count
);
5586 in_attributes
= STRUCT_FGETP(generate_key
, ngk_in_attributes
);
5587 if (!copyin_attributes(mode
, sp
, in_count
, in_attributes
, &k_in_attrs
,
5588 &k_in_attrs_size
, NULL
, &rv
, &error
, &in_key_rctl_bytes
,
5589 &in_key_rctl_chk
, B_TRUE
)) {
5593 out_count
= STRUCT_FGET(generate_key
, ngk_out_count
);
5594 out_attributes
= STRUCT_FGETP(generate_key
, ngk_out_attributes
);
5595 if (!copyin_attributes(mode
, sp
, out_count
, out_attributes
,
5597 &k_out_attrs_size
, &u_attrs
, &rv
, &error
, &out_key_rctl_bytes
,
5598 &out_key_rctl_chk
, B_FALSE
)) {
5602 KCF_WRAP_NOSTORE_KEY_OPS_PARAMS(¶ms
, KCF_OP_KEY_GENERATE
,
5603 sp
->sd_provider_session
->ps_session
, &mech
, k_in_attrs
, in_count
,
5604 NULL
, 0, NULL
, k_out_attrs
, out_count
, NULL
, 0);
5606 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
, B_FALSE
);
5608 if (rv
== CRYPTO_SUCCESS
) {
5609 error
= copyout_attributes(mode
, out_attributes
,
5610 out_count
, k_out_attrs
, u_attrs
);
5613 CRYPTO_DECREMENT_RCTL_SESSION(sp
, mech_rctl_bytes
, mech_rctl_chk
);
5614 CRYPTO_DECREMENT_RCTL_SESSION(sp
, in_key_rctl_bytes
, in_key_rctl_chk
);
5615 CRYPTO_DECREMENT_RCTL_SESSION(sp
, out_key_rctl_bytes
,
5618 if (k_in_attrs
!= NULL
)
5619 kmem_free(k_in_attrs
, k_in_attrs_size
);
5620 if (k_out_attrs
!= NULL
) {
5621 bzero(k_out_attrs
, k_out_attrs_size
);
5622 kmem_free(k_out_attrs
, k_out_attrs_size
);
5625 if (u_attrs
!= NULL
)
5626 kmem_free(u_attrs
, out_count
* STRUCT_SIZE(oa
));
5631 STRUCT_FSET(generate_key
, ngk_return_value
, rv
);
5632 if (copyout(STRUCT_BUF(generate_key
), arg
,
5633 STRUCT_SIZE(generate_key
)) != 0) {
5637 CRYPTO_SESSION_RELE(sp
);
5638 crypto_release_minor(cm
);
5640 if (real_provider
!= NULL
) {
5641 crypto_free_mech(real_provider
,
5642 allocated_by_crypto_module
, &mech
);
5643 KCF_PROV_REFRELE(real_provider
);
5650 object_generate_key_pair(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
5652 STRUCT_DECL(crypto_object_generate_key_pair
, generate_key_pair
);
5653 kcf_provider_desc_t
*real_provider
= NULL
;
5654 kcf_req_params_t params
;
5655 crypto_mechanism_t mech
;
5656 crypto_object_attribute_t
*k_pub_attrs
= NULL
;
5657 crypto_object_attribute_t
*k_pri_attrs
= NULL
;
5658 crypto_session_id_t session_id
;
5660 crypto_session_data_t
*sp
= NULL
;
5661 crypto_object_id_t pub_handle
;
5662 crypto_object_id_t pri_handle
;
5663 caddr_t pri_attributes
;
5664 caddr_t pub_attributes
;
5665 size_t k_pub_attrs_size
, k_pri_attrs_size
;
5666 size_t mech_rctl_bytes
= 0;
5667 boolean_t mech_rctl_chk
= B_FALSE
;
5668 size_t pub_rctl_bytes
= 0;
5669 boolean_t pub_rctl_chk
= B_FALSE
;
5670 size_t pri_rctl_bytes
= 0;
5671 boolean_t pri_rctl_chk
= B_FALSE
;
5676 boolean_t allocated_by_crypto_module
= B_FALSE
;
5678 STRUCT_INIT(generate_key_pair
, mode
);
5680 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
5682 "object_generate_key_pair: failed holding minor");
5686 if (copyin(arg
, STRUCT_BUF(generate_key_pair
),
5687 STRUCT_SIZE(generate_key_pair
)) != 0) {
5688 crypto_release_minor(cm
);
5692 session_id
= STRUCT_FGET(generate_key_pair
, kp_session
);
5694 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
5698 bcopy(STRUCT_FADDR(generate_key_pair
, kp_mechanism
), &mech
.cm_type
,
5699 sizeof (crypto_mech_type_t
));
5701 if ((rv
= kcf_get_hardware_provider(mech
.cm_type
, NULL
,
5702 CRYPTO_MECH_INVALID
, NULL
, sp
->sd_provider
,
5703 &real_provider
, CRYPTO_FG_GENERATE_KEY_PAIR
)) != CRYPTO_SUCCESS
) {
5707 rv
= crypto_provider_copyin_mech_param(real_provider
,
5708 STRUCT_FADDR(generate_key_pair
, kp_mechanism
), &mech
, mode
, &error
);
5710 if (rv
== CRYPTO_NOT_SUPPORTED
) {
5711 allocated_by_crypto_module
= B_TRUE
;
5712 if (!copyin_mech(mode
, sp
, STRUCT_FADDR(generate_key_pair
,
5713 kp_mechanism
), &mech
, &mech_rctl_bytes
,
5714 &mech_rctl_chk
, &rv
, &error
)) {
5718 if (rv
!= CRYPTO_SUCCESS
)
5722 pub_count
= STRUCT_FGET(generate_key_pair
, kp_public_count
);
5723 pri_count
= STRUCT_FGET(generate_key_pair
, kp_private_count
);
5725 pub_attributes
= STRUCT_FGETP(generate_key_pair
, kp_public_attributes
);
5726 if (!copyin_attributes(mode
, sp
, pub_count
, pub_attributes
,
5727 &k_pub_attrs
, &k_pub_attrs_size
, NULL
, &rv
, &error
, &pub_rctl_bytes
,
5728 &pub_rctl_chk
, B_TRUE
)) {
5732 pri_attributes
= STRUCT_FGETP(generate_key_pair
, kp_private_attributes
);
5733 if (!copyin_attributes(mode
, sp
, pri_count
, pri_attributes
,
5734 &k_pri_attrs
, &k_pri_attrs_size
, NULL
, &rv
, &error
,
5735 &pri_rctl_bytes
, &pri_rctl_chk
, B_TRUE
)) {
5739 KCF_WRAP_KEY_OPS_PARAMS(¶ms
, KCF_OP_KEY_GENERATE_PAIR
,
5740 sp
->sd_provider_session
->ps_session
, &mech
, k_pub_attrs
,
5741 pub_count
, &pub_handle
, k_pri_attrs
, pri_count
, &pri_handle
,
5744 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
, B_FALSE
);
5746 if (rv
== CRYPTO_SUCCESS
) {
5747 STRUCT_FSET(generate_key_pair
, kp_public_handle
, pub_handle
);
5748 STRUCT_FSET(generate_key_pair
, kp_private_handle
, pri_handle
);
5752 CRYPTO_DECREMENT_RCTL_SESSION(sp
, mech_rctl_bytes
, mech_rctl_chk
);
5753 CRYPTO_DECREMENT_RCTL_SESSION(sp
, pub_rctl_bytes
, pub_rctl_chk
);
5754 CRYPTO_DECREMENT_RCTL_SESSION(sp
, pri_rctl_bytes
, pri_rctl_chk
);
5756 if (k_pub_attrs
!= NULL
)
5757 kmem_free(k_pub_attrs
, k_pub_attrs_size
);
5759 if (k_pri_attrs
!= NULL
)
5760 kmem_free(k_pri_attrs
, k_pri_attrs_size
);
5765 STRUCT_FSET(generate_key_pair
, kp_return_value
, rv
);
5766 if (copyout(STRUCT_BUF(generate_key_pair
), arg
,
5767 STRUCT_SIZE(generate_key_pair
)) != 0) {
5768 if (rv
== CRYPTO_SUCCESS
) {
5769 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms
,
5770 KCF_OP_OBJECT_DESTROY
,
5771 sp
->sd_provider_session
->ps_session
, pub_handle
,
5772 NULL
, 0, NULL
, 0, NULL
, NULL
, 0, NULL
);
5774 (void) kcf_submit_request(real_provider
, NULL
,
5775 NULL
, ¶ms
, B_FALSE
);
5777 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms
,
5778 KCF_OP_OBJECT_DESTROY
,
5779 sp
->sd_provider_session
->ps_session
, pri_handle
,
5780 NULL
, 0, NULL
, 0, NULL
, NULL
, 0, NULL
);
5782 (void) kcf_submit_request(real_provider
, NULL
,
5783 NULL
, ¶ms
, B_FALSE
);
5789 CRYPTO_SESSION_RELE(sp
);
5790 crypto_release_minor(cm
);
5792 if (real_provider
!= NULL
) {
5793 crypto_free_mech(real_provider
,
5794 allocated_by_crypto_module
, &mech
);
5795 KCF_PROV_REFRELE(real_provider
);
5802 nostore_generate_key_pair(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
5804 STRUCT_DECL(crypto_nostore_generate_key_pair
, generate_key_pair
);
5806 STRUCT_DECL(crypto_object_attribute
, oa
);
5808 /* LINTED E_FUNC_SET_NOT_USED */
5809 STRUCT_DECL(crypto_object_attribute
, oa
);
5811 kcf_provider_desc_t
*real_provider
= NULL
;
5812 kcf_req_params_t params
;
5813 crypto_mechanism_t mech
;
5814 crypto_object_attribute_t
*k_in_pub_attrs
= NULL
;
5815 crypto_object_attribute_t
*k_in_pri_attrs
= NULL
;
5816 crypto_object_attribute_t
*k_out_pub_attrs
= NULL
;
5817 crypto_object_attribute_t
*k_out_pri_attrs
= NULL
;
5818 crypto_session_id_t session_id
;
5820 crypto_session_data_t
*sp
= NULL
;
5821 caddr_t in_pri_attributes
;
5822 caddr_t in_pub_attributes
;
5823 caddr_t out_pri_attributes
;
5824 caddr_t out_pub_attributes
;
5825 size_t k_in_pub_attrs_size
, k_in_pri_attrs_size
;
5826 size_t k_out_pub_attrs_size
, k_out_pri_attrs_size
;
5827 size_t mech_rctl_bytes
= 0;
5828 boolean_t mech_rctl_chk
= B_FALSE
;
5829 size_t in_pub_rctl_bytes
= 0;
5830 boolean_t in_pub_rctl_chk
= B_FALSE
;
5831 size_t in_pri_rctl_bytes
= 0;
5832 boolean_t in_pri_rctl_chk
= B_FALSE
;
5833 size_t out_pub_rctl_bytes
= 0;
5834 boolean_t out_pub_rctl_chk
= B_FALSE
;
5835 size_t out_pri_rctl_bytes
= 0;
5836 boolean_t out_pri_rctl_chk
= B_FALSE
;
5837 uint_t in_pub_count
;
5838 uint_t in_pri_count
;
5839 uint_t out_pub_count
;
5840 uint_t out_pri_count
;
5843 boolean_t allocated_by_crypto_module
= B_FALSE
;
5844 caddr_t u_pub_attrs
= NULL
;
5845 caddr_t u_pri_attrs
= NULL
;
5847 STRUCT_INIT(generate_key_pair
, mode
);
5848 STRUCT_INIT(oa
, mode
);
5850 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
5852 "nostore_generate_key_pair: failed holding minor");
5856 if (copyin(arg
, STRUCT_BUF(generate_key_pair
),
5857 STRUCT_SIZE(generate_key_pair
)) != 0) {
5858 crypto_release_minor(cm
);
5862 session_id
= STRUCT_FGET(generate_key_pair
, nkp_session
);
5864 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
5868 bcopy(STRUCT_FADDR(generate_key_pair
, nkp_mechanism
), &mech
.cm_type
,
5869 sizeof (crypto_mech_type_t
));
5871 if ((rv
= kcf_get_hardware_provider(mech
.cm_type
, NULL
,
5872 CRYPTO_MECH_INVALID
, NULL
, sp
->sd_provider
,
5873 &real_provider
, CRYPTO_FG_GENERATE_KEY_PAIR
)) != CRYPTO_SUCCESS
) {
5877 rv
= crypto_provider_copyin_mech_param(real_provider
,
5878 STRUCT_FADDR(generate_key_pair
, nkp_mechanism
), &mech
, mode
,
5881 if (rv
== CRYPTO_NOT_SUPPORTED
) {
5882 allocated_by_crypto_module
= B_TRUE
;
5883 if (!copyin_mech(mode
, sp
, STRUCT_FADDR(generate_key_pair
,
5884 nkp_mechanism
), &mech
, &mech_rctl_bytes
,
5885 &mech_rctl_chk
, &rv
, &error
)) {
5889 if (rv
!= CRYPTO_SUCCESS
)
5893 in_pub_count
= STRUCT_FGET(generate_key_pair
, nkp_in_public_count
);
5894 in_pri_count
= STRUCT_FGET(generate_key_pair
, nkp_in_private_count
);
5896 in_pub_attributes
= STRUCT_FGETP(generate_key_pair
,
5897 nkp_in_public_attributes
);
5898 if (!copyin_attributes(mode
, sp
, in_pub_count
, in_pub_attributes
,
5899 &k_in_pub_attrs
, &k_in_pub_attrs_size
, NULL
, &rv
, &error
,
5900 &in_pub_rctl_bytes
, &in_pub_rctl_chk
, B_TRUE
)) {
5904 in_pri_attributes
= STRUCT_FGETP(generate_key_pair
,
5905 nkp_in_private_attributes
);
5906 if (!copyin_attributes(mode
, sp
, in_pri_count
, in_pri_attributes
,
5907 &k_in_pri_attrs
, &k_in_pri_attrs_size
, NULL
, &rv
, &error
,
5908 &in_pri_rctl_bytes
, &in_pri_rctl_chk
, B_TRUE
)) {
5912 out_pub_count
= STRUCT_FGET(generate_key_pair
, nkp_out_public_count
);
5913 out_pri_count
= STRUCT_FGET(generate_key_pair
, nkp_out_private_count
);
5915 out_pub_attributes
= STRUCT_FGETP(generate_key_pair
,
5916 nkp_out_public_attributes
);
5917 if (!copyin_attributes(mode
, sp
, out_pub_count
, out_pub_attributes
,
5918 &k_out_pub_attrs
, &k_out_pub_attrs_size
, &u_pub_attrs
, &rv
, &error
,
5919 &out_pub_rctl_bytes
, &out_pub_rctl_chk
, B_FALSE
)) {
5923 out_pri_attributes
= STRUCT_FGETP(generate_key_pair
,
5924 nkp_out_private_attributes
);
5925 if (!copyin_attributes(mode
, sp
, out_pri_count
, out_pri_attributes
,
5926 &k_out_pri_attrs
, &k_out_pri_attrs_size
, &u_pri_attrs
, &rv
, &error
,
5927 &out_pri_rctl_bytes
, &out_pri_rctl_chk
, B_FALSE
)) {
5931 KCF_WRAP_NOSTORE_KEY_OPS_PARAMS(¶ms
, KCF_OP_KEY_GENERATE_PAIR
,
5932 sp
->sd_provider_session
->ps_session
, &mech
, k_in_pub_attrs
,
5933 in_pub_count
, k_in_pri_attrs
, in_pri_count
, NULL
, k_out_pub_attrs
,
5934 out_pub_count
, k_out_pri_attrs
, out_pri_count
);
5936 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
, B_FALSE
);
5938 if (rv
== CRYPTO_SUCCESS
) {
5939 error
= copyout_attributes(mode
, out_pub_attributes
,
5940 out_pub_count
, k_out_pub_attrs
, u_pub_attrs
);
5941 if (error
!= CRYPTO_SUCCESS
)
5943 error
= copyout_attributes(mode
, out_pri_attributes
,
5944 out_pri_count
, k_out_pri_attrs
, u_pri_attrs
);
5948 CRYPTO_DECREMENT_RCTL_SESSION(sp
, mech_rctl_bytes
, mech_rctl_chk
);
5949 CRYPTO_DECREMENT_RCTL_SESSION(sp
, in_pub_rctl_bytes
, in_pub_rctl_chk
);
5950 CRYPTO_DECREMENT_RCTL_SESSION(sp
, in_pri_rctl_bytes
, in_pri_rctl_chk
);
5951 CRYPTO_DECREMENT_RCTL_SESSION(sp
, out_pub_rctl_bytes
,
5953 CRYPTO_DECREMENT_RCTL_SESSION(sp
, out_pri_rctl_bytes
,
5956 if (k_in_pub_attrs
!= NULL
)
5957 kmem_free(k_in_pub_attrs
, k_in_pub_attrs_size
);
5959 if (k_in_pri_attrs
!= NULL
)
5960 kmem_free(k_in_pri_attrs
, k_in_pri_attrs_size
);
5962 if (k_out_pub_attrs
!= NULL
)
5963 kmem_free(k_out_pub_attrs
, k_out_pub_attrs_size
);
5965 if (k_out_pri_attrs
!= NULL
) {
5966 bzero(k_out_pri_attrs
, k_out_pri_attrs_size
);
5967 kmem_free(k_out_pri_attrs
, k_out_pri_attrs_size
);
5970 if (u_pub_attrs
!= NULL
)
5971 kmem_free(u_pub_attrs
, out_pub_count
* STRUCT_SIZE(oa
));
5973 if (u_pri_attrs
!= NULL
)
5974 kmem_free(u_pri_attrs
, out_pri_count
* STRUCT_SIZE(oa
));
5979 STRUCT_FSET(generate_key_pair
, nkp_return_value
, rv
);
5980 if (copyout(STRUCT_BUF(generate_key_pair
), arg
,
5981 STRUCT_SIZE(generate_key_pair
)) != 0) {
5985 CRYPTO_SESSION_RELE(sp
);
5986 crypto_release_minor(cm
);
5988 if (real_provider
!= NULL
) {
5989 crypto_free_mech(real_provider
,
5990 allocated_by_crypto_module
, &mech
);
5991 KCF_PROV_REFRELE(real_provider
);
5998 object_wrap_key(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
6000 STRUCT_DECL(crypto_object_wrap_key
, wrap_key
);
6001 kcf_provider_desc_t
*real_provider
= NULL
;
6002 kcf_req_params_t params
;
6003 crypto_mechanism_t mech
;
6005 crypto_session_id_t session_id
;
6007 crypto_session_data_t
*sp
= NULL
;
6008 crypto_object_id_t handle
;
6009 size_t mech_rctl_bytes
= 0, key_rctl_bytes
= 0;
6010 boolean_t mech_rctl_chk
= B_FALSE
;
6011 boolean_t key_rctl_chk
= B_FALSE
;
6012 size_t wrapped_key_rctl_bytes
= 0;
6013 boolean_t wrapped_key_rctl_chk
= B_FALSE
;
6014 size_t wrapped_key_len
, new_wrapped_key_len
;
6015 uchar_t
*wrapped_key
= NULL
;
6016 char *wrapped_key_buffer
;
6019 boolean_t allocated_by_crypto_module
= B_FALSE
;
6021 STRUCT_INIT(wrap_key
, mode
);
6023 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
6024 cmn_err(CE_WARN
, "object_wrap_key: failed holding minor");
6028 if (copyin(arg
, STRUCT_BUF(wrap_key
), STRUCT_SIZE(wrap_key
)) != 0) {
6029 crypto_release_minor(cm
);
6033 bzero(&key
, sizeof (crypto_key_t
));
6035 session_id
= STRUCT_FGET(wrap_key
, wk_session
);
6037 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
6041 bcopy(STRUCT_FADDR(wrap_key
, wk_mechanism
), &mech
.cm_type
,
6042 sizeof (crypto_mech_type_t
));
6044 /* We need the key length for provider selection so copy it in now. */
6045 if (!copyin_key(mode
, sp
, STRUCT_FADDR(wrap_key
, wk_wrapping_key
), &key
,
6046 &key_rctl_bytes
, &key_rctl_chk
, &rv
, &error
)) {
6050 wrapped_key_len
= STRUCT_FGET(wrap_key
, wk_wrapped_key_len
);
6052 if ((rv
= kcf_get_hardware_provider(mech
.cm_type
, &key
,
6053 CRYPTO_MECH_INVALID
, NULL
, sp
->sd_provider
,
6054 &real_provider
, CRYPTO_FG_WRAP
)) != CRYPTO_SUCCESS
) {
6058 rv
= crypto_provider_copyin_mech_param(real_provider
,
6059 STRUCT_FADDR(wrap_key
, wk_mechanism
), &mech
, mode
, &error
);
6061 if (rv
== CRYPTO_NOT_SUPPORTED
) {
6062 allocated_by_crypto_module
= B_TRUE
;
6063 if (!copyin_mech(mode
, sp
, STRUCT_FADDR(wrap_key
, wk_mechanism
),
6064 &mech
, &mech_rctl_bytes
, &mech_rctl_chk
, &rv
, &error
)) {
6068 if (rv
!= CRYPTO_SUCCESS
)
6073 * Don't allocate output buffer unless both buffer pointer and
6074 * buffer length are not NULL or 0 (length).
6076 wrapped_key_buffer
= STRUCT_FGETP(wrap_key
, wk_wrapped_key
);
6077 if (wrapped_key_buffer
== NULL
|| wrapped_key_len
== 0) {
6078 wrapped_key_len
= 0;
6081 if (wrapped_key_len
> crypto_max_buffer_len
) {
6082 cmn_err(CE_NOTE
, "object_wrap_key: buffer greater than %ld "
6083 "bytes, pid = %d", crypto_max_buffer_len
, curproc
->p_pid
);
6084 rv
= CRYPTO_ARGUMENTS_BAD
;
6088 if ((rv
= CRYPTO_BUFFER_CHECK(sp
, wrapped_key_len
,
6089 wrapped_key_rctl_chk
)) != CRYPTO_SUCCESS
) {
6093 /* new_wrapped_key_len can be modified by the provider */
6094 wrapped_key_rctl_bytes
= new_wrapped_key_len
= wrapped_key_len
;
6095 wrapped_key
= kmem_alloc(wrapped_key_len
, KM_SLEEP
);
6097 handle
= STRUCT_FGET(wrap_key
, wk_object_handle
);
6098 KCF_WRAP_KEY_OPS_PARAMS(¶ms
, KCF_OP_KEY_WRAP
,
6099 sp
->sd_provider_session
->ps_session
, &mech
, NULL
, 0, &handle
,
6100 NULL
, 0, NULL
, &key
, wrapped_key
, &new_wrapped_key_len
);
6102 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
, B_FALSE
);
6104 if (rv
== CRYPTO_SUCCESS
) {
6105 if (wrapped_key_len
!= 0 && copyout(wrapped_key
,
6106 wrapped_key_buffer
, new_wrapped_key_len
) != 0) {
6109 STRUCT_FSET(wrap_key
, wk_wrapped_key_len
,
6110 (ulong_t
)new_wrapped_key_len
);
6113 if (rv
== CRYPTO_BUFFER_TOO_SMALL
) {
6115 * The providers return CRYPTO_BUFFER_TOO_SMALL even for case 1
6116 * of section 11.2 of the pkcs11 spec. We catch it here and
6117 * provide the correct pkcs11 return value.
6119 if (STRUCT_FGETP(wrap_key
, wk_wrapped_key
) == NULL
)
6120 rv
= CRYPTO_SUCCESS
;
6121 STRUCT_FSET(wrap_key
, wk_wrapped_key_len
,
6122 (ulong_t
)new_wrapped_key_len
);
6126 CRYPTO_DECREMENT_RCTL_SESSION(sp
, mech_rctl_bytes
, mech_rctl_chk
);
6127 CRYPTO_DECREMENT_RCTL_SESSION(sp
, key_rctl_bytes
, key_rctl_chk
);
6128 CRYPTO_DECREMENT_RCTL_SESSION(sp
, wrapped_key_rctl_bytes
,
6129 wrapped_key_rctl_chk
);
6130 CRYPTO_SESSION_RELE(sp
);
6132 crypto_release_minor(cm
);
6134 if (real_provider
!= NULL
) {
6135 crypto_free_mech(real_provider
,
6136 allocated_by_crypto_module
, &mech
);
6137 KCF_PROV_REFRELE(real_provider
);
6140 if (wrapped_key
!= NULL
)
6141 kmem_free(wrapped_key
, wrapped_key_len
);
6143 free_crypto_key(&key
);
6148 STRUCT_FSET(wrap_key
, wk_return_value
, rv
);
6149 if (copyout(STRUCT_BUF(wrap_key
), arg
, STRUCT_SIZE(wrap_key
)) != 0) {
6157 object_unwrap_key(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
6159 STRUCT_DECL(crypto_object_unwrap_key
, unwrap_key
);
6160 kcf_provider_desc_t
*real_provider
= NULL
;
6161 kcf_req_params_t params
;
6162 crypto_mechanism_t mech
;
6163 crypto_key_t unwrapping_key
;
6164 crypto_session_id_t session_id
;
6166 crypto_session_data_t
*sp
= NULL
;
6167 crypto_object_id_t handle
;
6168 crypto_object_attribute_t
*k_attrs
= NULL
;
6169 size_t k_attrs_size
;
6170 size_t mech_rctl_bytes
= 0, unwrapping_key_rctl_bytes
= 0;
6171 boolean_t mech_rctl_chk
= B_FALSE
;
6172 boolean_t unwrapping_key_rctl_chk
= B_FALSE
;
6173 size_t wrapped_key_rctl_bytes
= 0, k_attrs_rctl_bytes
= 0;
6174 boolean_t wrapped_key_rctl_chk
= B_FALSE
;
6175 boolean_t k_attrs_rctl_chk
= B_FALSE
;
6176 size_t wrapped_key_len
;
6177 uchar_t
*wrapped_key
= NULL
;
6181 caddr_t uk_attributes
;
6182 boolean_t allocated_by_crypto_module
= B_FALSE
;
6184 STRUCT_INIT(unwrap_key
, mode
);
6186 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
6187 cmn_err(CE_WARN
, "object_unwrap_key: failed holding minor");
6191 if (copyin(arg
, STRUCT_BUF(unwrap_key
), STRUCT_SIZE(unwrap_key
)) != 0) {
6192 crypto_release_minor(cm
);
6196 bzero(&unwrapping_key
, sizeof (unwrapping_key
));
6198 session_id
= STRUCT_FGET(unwrap_key
, uk_session
);
6200 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
6204 bcopy(STRUCT_FADDR(unwrap_key
, uk_mechanism
), &mech
.cm_type
,
6205 sizeof (crypto_mech_type_t
));
6207 /* We need the key length for provider selection so copy it in now. */
6208 if (!copyin_key(mode
, sp
, STRUCT_FADDR(unwrap_key
, uk_unwrapping_key
),
6209 &unwrapping_key
, &unwrapping_key_rctl_bytes
,
6210 &unwrapping_key_rctl_chk
, &rv
, &error
)) {
6214 if ((rv
= kcf_get_hardware_provider(mech
.cm_type
, &unwrapping_key
,
6215 CRYPTO_MECH_INVALID
, NULL
, sp
->sd_provider
,
6216 &real_provider
, CRYPTO_FG_UNWRAP
)) != CRYPTO_SUCCESS
) {
6220 rv
= crypto_provider_copyin_mech_param(real_provider
,
6221 STRUCT_FADDR(unwrap_key
, uk_mechanism
), &mech
, mode
, &error
);
6223 if (rv
== CRYPTO_NOT_SUPPORTED
) {
6224 allocated_by_crypto_module
= B_TRUE
;
6225 if (!copyin_mech(mode
, sp
,
6226 STRUCT_FADDR(unwrap_key
, uk_mechanism
),
6227 &mech
, &mech_rctl_bytes
, &mech_rctl_chk
, &rv
, &error
)) {
6231 if (rv
!= CRYPTO_SUCCESS
)
6235 count
= STRUCT_FGET(unwrap_key
, uk_count
);
6236 uk_attributes
= STRUCT_FGETP(unwrap_key
, uk_attributes
);
6237 if (!copyin_attributes(mode
, sp
, count
, uk_attributes
, &k_attrs
,
6238 &k_attrs_size
, NULL
, &rv
, &error
, &k_attrs_rctl_bytes
,
6239 &k_attrs_rctl_chk
, B_TRUE
)) {
6243 wrapped_key_len
= STRUCT_FGET(unwrap_key
, uk_wrapped_key_len
);
6244 if (wrapped_key_len
> crypto_max_buffer_len
) {
6245 cmn_err(CE_NOTE
, "object_unwrap_key: buffer greater than %ld "
6246 "bytes, pid = %d", crypto_max_buffer_len
, curproc
->p_pid
);
6247 rv
= CRYPTO_ARGUMENTS_BAD
;
6251 if ((rv
= CRYPTO_BUFFER_CHECK(sp
, wrapped_key_len
,
6252 wrapped_key_rctl_chk
)) != CRYPTO_SUCCESS
) {
6255 wrapped_key_rctl_bytes
= wrapped_key_len
;
6256 wrapped_key
= kmem_alloc(wrapped_key_len
, KM_SLEEP
);
6258 if (wrapped_key_len
!= 0 && copyin(STRUCT_FGETP(unwrap_key
,
6259 uk_wrapped_key
), wrapped_key
, wrapped_key_len
) != 0) {
6264 /* wrapped_key_len is not modified by the unwrap operation */
6265 KCF_WRAP_KEY_OPS_PARAMS(¶ms
, KCF_OP_KEY_UNWRAP
,
6266 sp
->sd_provider_session
->ps_session
, &mech
, k_attrs
, count
, &handle
,
6267 NULL
, 0, NULL
, &unwrapping_key
, wrapped_key
, &wrapped_key_len
);
6269 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
, B_FALSE
);
6271 if (rv
== CRYPTO_SUCCESS
)
6272 STRUCT_FSET(unwrap_key
, uk_object_handle
, handle
);
6275 CRYPTO_DECREMENT_RCTL_SESSION(sp
, mech_rctl_bytes
, mech_rctl_chk
);
6276 CRYPTO_DECREMENT_RCTL_SESSION(sp
, unwrapping_key_rctl_bytes
,
6277 unwrapping_key_rctl_chk
);
6278 CRYPTO_DECREMENT_RCTL_SESSION(sp
, wrapped_key_rctl_bytes
,
6279 wrapped_key_rctl_chk
);
6280 CRYPTO_DECREMENT_RCTL_SESSION(sp
, k_attrs_rctl_bytes
,
6283 if (k_attrs
!= NULL
)
6284 kmem_free(k_attrs
, k_attrs_size
);
6286 if (wrapped_key
!= NULL
)
6287 kmem_free(wrapped_key
, wrapped_key_len
);
6289 free_crypto_key(&unwrapping_key
);
6294 STRUCT_FSET(unwrap_key
, uk_return_value
, rv
);
6295 if (copyout(STRUCT_BUF(unwrap_key
), arg
,
6296 STRUCT_SIZE(unwrap_key
)) != 0) {
6297 if (rv
== CRYPTO_SUCCESS
) {
6298 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms
,
6299 KCF_OP_OBJECT_DESTROY
,
6300 sp
->sd_provider_session
->ps_session
, handle
,
6301 NULL
, 0, NULL
, 0, NULL
, NULL
, 0, NULL
);
6303 (void) kcf_submit_request(real_provider
, NULL
,
6304 NULL
, ¶ms
, B_FALSE
);
6310 CRYPTO_SESSION_RELE(sp
);
6311 crypto_release_minor(cm
);
6313 if (real_provider
!= NULL
) {
6314 crypto_free_mech(real_provider
,
6315 allocated_by_crypto_module
, &mech
);
6316 KCF_PROV_REFRELE(real_provider
);
6324 object_derive_key(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
6326 STRUCT_DECL(crypto_derive_key
, derive_key
);
6327 kcf_provider_desc_t
*real_provider
= NULL
;
6328 kcf_req_params_t params
;
6329 crypto_object_attribute_t
*k_attrs
= NULL
;
6330 crypto_mechanism_t mech
;
6331 crypto_key_t base_key
;
6332 crypto_session_id_t session_id
;
6334 crypto_session_data_t
*sp
= NULL
;
6335 crypto_object_id_t handle
;
6336 size_t k_attrs_size
;
6337 size_t key_rctl_bytes
= 0, mech_rctl_bytes
= 0;
6338 boolean_t mech_rctl_chk
= B_FALSE
;
6339 boolean_t key_rctl_chk
= B_FALSE
;
6340 size_t attributes_rctl_bytes
= 0;
6341 boolean_t attributes_rctl_chk
= B_FALSE
;
6346 boolean_t allocated_by_crypto_module
= B_FALSE
;
6347 boolean_t please_destroy_object
= B_FALSE
;
6349 STRUCT_INIT(derive_key
, mode
);
6351 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
6352 cmn_err(CE_WARN
, "object_derive_key: failed holding minor");
6356 if (copyin(arg
, STRUCT_BUF(derive_key
), STRUCT_SIZE(derive_key
)) != 0) {
6357 crypto_release_minor(cm
);
6361 bzero(&base_key
, sizeof (base_key
));
6363 session_id
= STRUCT_FGET(derive_key
, dk_session
);
6365 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
6369 bcopy(STRUCT_FADDR(derive_key
, dk_mechanism
), &mech
.cm_type
,
6370 sizeof (crypto_mech_type_t
));
6372 /* We need the key length for provider selection so copy it in now. */
6373 if (!copyin_key(mode
, sp
, STRUCT_FADDR(derive_key
, dk_base_key
),
6374 &base_key
, &key_rctl_bytes
, &key_rctl_chk
, &rv
, &error
)) {
6378 if ((rv
= kcf_get_hardware_provider(mech
.cm_type
, &base_key
,
6379 CRYPTO_MECH_INVALID
, NULL
, sp
->sd_provider
,
6380 &real_provider
, CRYPTO_FG_DERIVE
)) != CRYPTO_SUCCESS
) {
6384 rv
= crypto_provider_copyin_mech_param(real_provider
,
6385 STRUCT_FADDR(derive_key
, dk_mechanism
), &mech
, mode
, &error
);
6387 if (rv
== CRYPTO_NOT_SUPPORTED
) {
6388 allocated_by_crypto_module
= B_TRUE
;
6389 if (!copyin_mech(mode
, sp
,
6390 STRUCT_FADDR(derive_key
, dk_mechanism
),
6391 &mech
, &mech_rctl_bytes
, &mech_rctl_chk
, &rv
, &error
)) {
6395 if (rv
!= CRYPTO_SUCCESS
)
6399 count
= STRUCT_FGET(derive_key
, dk_count
);
6401 attributes
= STRUCT_FGETP(derive_key
, dk_attributes
);
6402 if (!copyin_attributes(mode
, sp
, count
, attributes
, &k_attrs
,
6403 &k_attrs_size
, NULL
, &rv
, &error
,
6404 &attributes_rctl_bytes
, &attributes_rctl_chk
, B_TRUE
)) {
6408 KCF_WRAP_KEY_OPS_PARAMS(¶ms
, KCF_OP_KEY_DERIVE
,
6409 sp
->sd_provider_session
->ps_session
, &mech
, k_attrs
, count
,
6410 &handle
, NULL
, 0, NULL
, &base_key
, NULL
, NULL
);
6412 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
, B_FALSE
);
6414 if (rv
== CRYPTO_SUCCESS
) {
6415 STRUCT_FSET(derive_key
, dk_object_handle
, handle
);
6417 rv
= crypto_provider_copyout_mech_param(real_provider
,
6418 &mech
, STRUCT_FADDR(derive_key
, dk_mechanism
),
6421 if (rv
== CRYPTO_NOT_SUPPORTED
) {
6422 rv
= CRYPTO_SUCCESS
;
6426 if (rv
!= CRYPTO_SUCCESS
)
6427 please_destroy_object
= B_TRUE
;
6431 CRYPTO_DECREMENT_RCTL_SESSION(sp
, mech_rctl_bytes
, mech_rctl_chk
);
6432 CRYPTO_DECREMENT_RCTL_SESSION(sp
, key_rctl_bytes
, key_rctl_chk
);
6433 CRYPTO_DECREMENT_RCTL_SESSION(sp
, attributes_rctl_bytes
,
6434 attributes_rctl_chk
);
6436 if (k_attrs
!= NULL
)
6437 kmem_free(k_attrs
, k_attrs_size
);
6439 free_crypto_key(&base_key
);
6444 STRUCT_FSET(derive_key
, dk_return_value
, rv
);
6445 if (copyout(STRUCT_BUF(derive_key
), arg
,
6446 STRUCT_SIZE(derive_key
)) != 0) {
6447 if (rv
== CRYPTO_SUCCESS
) {
6448 please_destroy_object
= B_TRUE
;
6453 if (please_destroy_object
) {
6454 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms
, KCF_OP_OBJECT_DESTROY
,
6455 sp
->sd_provider_session
->ps_session
, handle
,
6456 NULL
, 0, NULL
, 0, NULL
, NULL
, 0, NULL
);
6458 (void) kcf_submit_request(real_provider
, NULL
,
6459 NULL
, ¶ms
, B_FALSE
);
6462 CRYPTO_SESSION_RELE(sp
);
6463 crypto_release_minor(cm
);
6465 if (real_provider
!= NULL
) {
6466 crypto_free_mech(real_provider
,
6467 allocated_by_crypto_module
, &mech
);
6468 KCF_PROV_REFRELE(real_provider
);
6475 nostore_derive_key(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
6477 STRUCT_DECL(crypto_nostore_derive_key
, derive_key
);
6479 STRUCT_DECL(crypto_object_attribute
, oa
);
6481 /* LINTED E_FUNC_SET_NOT_USED */
6482 STRUCT_DECL(crypto_object_attribute
, oa
);
6484 kcf_provider_desc_t
*real_provider
= NULL
;
6485 kcf_req_params_t params
;
6486 crypto_object_attribute_t
*k_in_attrs
= NULL
;
6487 crypto_object_attribute_t
*k_out_attrs
= NULL
;
6488 crypto_mechanism_t mech
;
6489 crypto_key_t base_key
;
6490 crypto_session_id_t session_id
;
6492 crypto_session_data_t
*sp
= NULL
;
6493 size_t k_in_attrs_size
, k_out_attrs_size
;
6494 size_t key_rctl_bytes
= 0, mech_rctl_bytes
= 0;
6495 boolean_t mech_rctl_chk
= B_FALSE
;
6496 boolean_t key_rctl_chk
= B_FALSE
;
6497 size_t in_attributes_rctl_bytes
= 0;
6498 size_t out_attributes_rctl_bytes
= 0;
6499 boolean_t in_attributes_rctl_chk
= B_FALSE
;
6500 boolean_t out_attributes_rctl_chk
= B_FALSE
;
6501 caddr_t in_attributes
, out_attributes
;
6502 uint_t in_count
, out_count
;
6505 boolean_t allocated_by_crypto_module
= B_FALSE
;
6506 caddr_t u_attrs
= NULL
;
6508 STRUCT_INIT(derive_key
, mode
);
6509 STRUCT_INIT(oa
, mode
);
6511 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
6512 cmn_err(CE_WARN
, "nostore_derive_key: failed holding minor");
6516 if (copyin(arg
, STRUCT_BUF(derive_key
), STRUCT_SIZE(derive_key
)) != 0) {
6517 crypto_release_minor(cm
);
6521 bzero(&base_key
, sizeof (base_key
));
6523 session_id
= STRUCT_FGET(derive_key
, ndk_session
);
6525 if (!get_session_ptr(session_id
, cm
, &sp
, &error
, &rv
)) {
6529 bcopy(STRUCT_FADDR(derive_key
, ndk_mechanism
), &mech
.cm_type
,
6530 sizeof (crypto_mech_type_t
));
6532 /* We need the key length for provider selection so copy it in now. */
6533 if (!copyin_key(mode
, sp
, STRUCT_FADDR(derive_key
, ndk_base_key
),
6534 &base_key
, &key_rctl_bytes
, &key_rctl_chk
, &rv
, &error
)) {
6538 if ((rv
= kcf_get_hardware_provider(mech
.cm_type
, &base_key
,
6539 CRYPTO_MECH_INVALID
, NULL
, sp
->sd_provider
,
6540 &real_provider
, CRYPTO_FG_DERIVE
)) != CRYPTO_SUCCESS
) {
6544 rv
= crypto_provider_copyin_mech_param(real_provider
,
6545 STRUCT_FADDR(derive_key
, ndk_mechanism
), &mech
, mode
, &error
);
6547 if (rv
== CRYPTO_NOT_SUPPORTED
) {
6548 allocated_by_crypto_module
= B_TRUE
;
6549 if (!copyin_mech(mode
, sp
,
6550 STRUCT_FADDR(derive_key
, ndk_mechanism
),
6551 &mech
, &mech_rctl_bytes
, &mech_rctl_chk
, &rv
, &error
)) {
6555 if (rv
!= CRYPTO_SUCCESS
)
6559 in_count
= STRUCT_FGET(derive_key
, ndk_in_count
);
6560 out_count
= STRUCT_FGET(derive_key
, ndk_out_count
);
6562 in_attributes
= STRUCT_FGETP(derive_key
, ndk_in_attributes
);
6563 if (!copyin_attributes(mode
, sp
, in_count
, in_attributes
, &k_in_attrs
,
6564 &k_in_attrs_size
, NULL
, &rv
, &error
, &in_attributes_rctl_bytes
,
6565 &in_attributes_rctl_chk
, B_TRUE
)) {
6569 out_attributes
= STRUCT_FGETP(derive_key
, ndk_out_attributes
);
6570 if (!copyin_attributes(mode
, sp
, out_count
, out_attributes
,
6571 &k_out_attrs
, &k_out_attrs_size
, &u_attrs
, &rv
, &error
,
6572 &out_attributes_rctl_bytes
,
6573 &out_attributes_rctl_chk
, B_FALSE
)) {
6577 KCF_WRAP_NOSTORE_KEY_OPS_PARAMS(¶ms
, KCF_OP_KEY_DERIVE
,
6578 sp
->sd_provider_session
->ps_session
, &mech
, k_in_attrs
, in_count
,
6579 NULL
, 0, &base_key
, k_out_attrs
, out_count
, NULL
, 0);
6581 rv
= kcf_submit_request(real_provider
, NULL
, NULL
, ¶ms
, B_FALSE
);
6583 if (rv
== CRYPTO_SUCCESS
) {
6584 rv
= crypto_provider_copyout_mech_param(real_provider
,
6585 &mech
, STRUCT_FADDR(derive_key
, ndk_mechanism
),
6588 if (rv
== CRYPTO_NOT_SUPPORTED
) {
6589 rv
= CRYPTO_SUCCESS
;
6591 /* copyout the derived secret */
6592 if (copyout_attributes(mode
, out_attributes
, out_count
,
6593 k_out_attrs
, u_attrs
) != 0)
6598 CRYPTO_DECREMENT_RCTL_SESSION(sp
, mech_rctl_bytes
, mech_rctl_chk
);
6599 CRYPTO_DECREMENT_RCTL_SESSION(sp
, key_rctl_bytes
, key_rctl_chk
);
6600 CRYPTO_DECREMENT_RCTL_SESSION(sp
, in_attributes_rctl_bytes
,
6601 in_attributes_rctl_chk
);
6602 CRYPTO_DECREMENT_RCTL_SESSION(sp
, out_attributes_rctl_bytes
,
6603 out_attributes_rctl_chk
);
6605 if (k_in_attrs
!= NULL
)
6606 kmem_free(k_in_attrs
, k_in_attrs_size
);
6607 if (k_out_attrs
!= NULL
) {
6608 bzero(k_out_attrs
, k_out_attrs_size
);
6609 kmem_free(k_out_attrs
, k_out_attrs_size
);
6612 if (u_attrs
!= NULL
)
6613 kmem_free(u_attrs
, out_count
* STRUCT_SIZE(oa
));
6615 free_crypto_key(&base_key
);
6620 STRUCT_FSET(derive_key
, ndk_return_value
, rv
);
6621 if (copyout(STRUCT_BUF(derive_key
), arg
,
6622 STRUCT_SIZE(derive_key
)) != 0) {
6626 CRYPTO_SESSION_RELE(sp
);
6627 crypto_release_minor(cm
);
6629 if (real_provider
!= NULL
) {
6630 crypto_free_mech(real_provider
,
6631 allocated_by_crypto_module
, &mech
);
6632 KCF_PROV_REFRELE(real_provider
);
6638 get_provider_by_mech(dev_t dev
, caddr_t arg
, int mode
, int *rval
)
6640 _NOTE(ARGUNUSED(mode
, rval
))
6641 kcf_mech_entry_t
*me
;
6642 kcf_provider_desc_t
*pd
;
6644 crypto_by_mech_t mech
;
6645 crypto_provider_session_t
*ps
;
6649 if ((cm
= crypto_hold_minor(getminor(dev
))) == NULL
) {
6650 cmn_err(CE_WARN
, "get_provider_by_mech: failed holding minor");
6654 bzero(&key
, sizeof (key
));
6655 key
.ck_format
= CRYPTO_KEY_RAW
;
6657 if (copyin(arg
, &mech
, sizeof (mech
)) != 0) {
6658 crypto_release_minor(cm
);
6662 key
.ck_length
= mech
.mech_keylen
;
6663 /* pd is returned held */
6664 if ((pd
= kcf_get_mech_provider(mech
.mech_type
, &key
, &me
, &error
,
6665 NULL
, mech
.mech_fg
, 0)) == NULL
) {
6670 /* don't want to allow direct access to software providers */
6671 if (pd
->pd_prov_type
== CRYPTO_SW_PROVIDER
) {
6672 rv
= CRYPTO_MECHANISM_INVALID
;
6673 KCF_PROV_REFRELE(pd
);
6674 cmn_err(CE_WARN
, "software mech_type given");
6678 mutex_enter(&cm
->cm_lock
);
6679 if ((rv
= crypto_create_provider_session(cm
, pd
, pd
->pd_sid
, &ps
, NULL
))
6681 rv
= crypto_create_session_ptr(cm
, pd
, ps
, &mech
.session_id
);
6683 mutex_exit(&cm
->cm_lock
);
6685 crypto_release_minor(cm
);
6687 if (copyout(&mech
, arg
, sizeof (mech
)) != 0)
6695 crypto_ioctl(dev_t dev
, int cmd
, intptr_t arg
, int mode
, cred_t
*c
,
6698 #define ARG ((caddr_t)arg)
6701 case CRYPTO_GET_FUNCTION_LIST
:
6702 return (get_function_list(dev
, ARG
, mode
, rval
));
6704 case CRYPTO_GET_MECHANISM_NUMBER
:
6705 return (get_mechanism_number(dev
, ARG
, mode
, rval
));
6707 case CRYPTO_GET_MECHANISM_LIST
:
6708 return (get_mechanism_list(dev
, ARG
, mode
, rval
));
6710 case CRYPTO_GET_ALL_MECHANISM_INFO
:
6711 return (get_all_mechanism_info(dev
, ARG
, mode
, rval
));
6713 case CRYPTO_GET_PROVIDER_LIST
:
6714 return (get_provider_list(dev
, ARG
, mode
, rval
));
6716 case CRYPTO_GET_PROVIDER_BY_MECH
:
6717 return (get_provider_by_mech(dev
, ARG
, mode
, rval
));
6719 case CRYPTO_GET_PROVIDER_INFO
:
6720 return (get_provider_info(dev
, ARG
, mode
, rval
));
6722 case CRYPTO_GET_PROVIDER_MECHANISMS
:
6723 return (get_provider_mechanisms(dev
, ARG
, mode
, rval
));
6725 case CRYPTO_GET_PROVIDER_MECHANISM_INFO
:
6726 return (get_provider_mechanism_info(dev
, ARG
, mode
, rval
));
6728 case CRYPTO_OPEN_SESSION
:
6729 return (open_session(dev
, ARG
, mode
, rval
));
6731 case CRYPTO_CLOSE_SESSION
:
6732 return (close_session(dev
, ARG
, mode
, rval
));
6734 case CRYPTO_ENCRYPT_INIT
:
6735 return (encrypt_init(dev
, ARG
, mode
, rval
));
6737 case CRYPTO_DECRYPT_INIT
:
6738 return (decrypt_init(dev
, ARG
, mode
, rval
));
6740 case CRYPTO_ENCRYPT
:
6741 return (encrypt(dev
, ARG
, mode
, rval
));
6743 case CRYPTO_DECRYPT
:
6744 return (decrypt(dev
, ARG
, mode
, rval
));
6746 case CRYPTO_ENCRYPT_UPDATE
:
6747 return (encrypt_update(dev
, ARG
, mode
, rval
));
6749 case CRYPTO_DECRYPT_UPDATE
:
6750 return (decrypt_update(dev
, ARG
, mode
, rval
));
6752 case CRYPTO_ENCRYPT_FINAL
:
6753 return (encrypt_final(dev
, ARG
, mode
, rval
));
6755 case CRYPTO_DECRYPT_FINAL
:
6756 return (decrypt_final(dev
, ARG
, mode
, rval
));
6758 case CRYPTO_DIGEST_INIT
:
6759 return (digest_init(dev
, ARG
, mode
, rval
));
6762 return (digest(dev
, ARG
, mode
, rval
));
6764 case CRYPTO_DIGEST_UPDATE
:
6765 return (digest_update(dev
, ARG
, mode
, rval
));
6767 case CRYPTO_DIGEST_KEY
:
6768 return (digest_key(dev
, ARG
, mode
, rval
));
6770 case CRYPTO_DIGEST_FINAL
:
6771 return (digest_final(dev
, ARG
, mode
, rval
));
6773 case CRYPTO_SIGN_INIT
:
6774 return (sign_init(dev
, ARG
, mode
, rval
));
6777 return (sign(dev
, ARG
, mode
, rval
));
6779 case CRYPTO_SIGN_UPDATE
:
6780 return (sign_update(dev
, ARG
, mode
, rval
));
6782 case CRYPTO_SIGN_FINAL
:
6783 return (sign_final(dev
, ARG
, mode
, rval
));
6785 case CRYPTO_SIGN_RECOVER_INIT
:
6786 return (sign_recover_init(dev
, ARG
, mode
, rval
));
6788 case CRYPTO_SIGN_RECOVER
:
6789 return (sign_recover(dev
, ARG
, mode
, rval
));
6791 case CRYPTO_VERIFY_INIT
:
6792 return (verify_init(dev
, ARG
, mode
, rval
));
6795 return (verify(dev
, ARG
, mode
, rval
));
6797 case CRYPTO_VERIFY_UPDATE
:
6798 return (verify_update(dev
, ARG
, mode
, rval
));
6800 case CRYPTO_VERIFY_FINAL
:
6801 return (verify_final(dev
, ARG
, mode
, rval
));
6803 case CRYPTO_VERIFY_RECOVER_INIT
:
6804 return (verify_recover_init(dev
, ARG
, mode
, rval
));
6806 case CRYPTO_VERIFY_RECOVER
:
6807 return (verify_recover(dev
, ARG
, mode
, rval
));
6809 case CRYPTO_MAC_INIT
:
6810 return (mac_init(dev
, ARG
, mode
, rval
));
6813 return (mac(dev
, ARG
, mode
, rval
));
6815 case CRYPTO_MAC_UPDATE
:
6816 return (mac_update(dev
, ARG
, mode
, rval
));
6818 case CRYPTO_MAC_FINAL
:
6819 return (mac_final(dev
, ARG
, mode
, rval
));
6821 case CRYPTO_SET_PIN
:
6822 return (set_pin(dev
, ARG
, mode
, rval
));
6825 return (login(dev
, ARG
, mode
, rval
));
6828 return (logout(dev
, ARG
, mode
, rval
));
6830 case CRYPTO_SEED_RANDOM
:
6831 return (seed_random(dev
, ARG
, mode
, rval
));
6833 case CRYPTO_GENERATE_RANDOM
:
6834 return (generate_random(dev
, ARG
, mode
, rval
));
6836 case CRYPTO_OBJECT_CREATE
:
6837 return (object_create(dev
, ARG
, mode
, rval
));
6839 case CRYPTO_OBJECT_COPY
:
6840 return (object_copy(dev
, ARG
, mode
, rval
));
6842 case CRYPTO_OBJECT_DESTROY
:
6843 return (object_destroy(dev
, ARG
, mode
, rval
));
6845 case CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE
:
6846 return (object_get_attribute_value(dev
, ARG
, mode
, rval
));
6848 case CRYPTO_OBJECT_GET_SIZE
:
6849 return (object_get_size(dev
, ARG
, mode
, rval
));
6851 case CRYPTO_OBJECT_SET_ATTRIBUTE_VALUE
:
6852 return (object_set_attribute_value(dev
, ARG
, mode
, rval
));
6854 case CRYPTO_OBJECT_FIND_INIT
:
6855 return (object_find_init(dev
, ARG
, mode
, rval
));
6857 case CRYPTO_OBJECT_FIND_UPDATE
:
6858 return (object_find_update(dev
, ARG
, mode
, rval
));
6860 case CRYPTO_OBJECT_FIND_FINAL
:
6861 return (object_find_final(dev
, ARG
, mode
, rval
));
6863 case CRYPTO_GENERATE_KEY
:
6864 return (object_generate_key(dev
, ARG
, mode
, rval
));
6866 case CRYPTO_GENERATE_KEY_PAIR
:
6867 return (object_generate_key_pair(dev
, ARG
, mode
, rval
));
6869 case CRYPTO_WRAP_KEY
:
6870 return (object_wrap_key(dev
, ARG
, mode
, rval
));
6872 case CRYPTO_UNWRAP_KEY
:
6873 return (object_unwrap_key(dev
, ARG
, mode
, rval
));
6875 case CRYPTO_DERIVE_KEY
:
6876 return (object_derive_key(dev
, ARG
, mode
, rval
));
6878 case CRYPTO_NOSTORE_GENERATE_KEY
:
6879 return (nostore_generate_key(dev
, ARG
, mode
, rval
));
6881 case CRYPTO_NOSTORE_GENERATE_KEY_PAIR
:
6882 return (nostore_generate_key_pair(dev
, ARG
, mode
, rval
));
6884 case CRYPTO_NOSTORE_DERIVE_KEY
:
6885 return (nostore_derive_key(dev
, ARG
, mode
, rval
));
6891 * Check for the project.max-crypto-memory resource control.
6894 crypto_buffer_check(size_t need
)
6899 return (CRYPTO_SUCCESS
);
6901 mutex_enter(&curproc
->p_lock
);
6902 kpj
= curproc
->p_task
->tk_proj
;
6903 mutex_enter(&(kpj
->kpj_data
.kpd_crypto_lock
));
6905 if (kpj
->kpj_data
.kpd_crypto_mem
+ need
>
6906 kpj
->kpj_data
.kpd_crypto_mem_ctl
) {
6907 if (rctl_test(rc_project_crypto_mem
,
6908 kpj
->kpj_rctls
, curproc
, need
, 0) & RCT_DENY
) {
6909 mutex_exit(&(kpj
->kpj_data
.kpd_crypto_lock
));
6910 mutex_exit(&curproc
->p_lock
);
6911 return (CRYPTO_HOST_MEMORY
);
6915 kpj
->kpj_data
.kpd_crypto_mem
+= need
;
6916 mutex_exit(&(kpj
->kpj_data
.kpd_crypto_lock
));
6918 curproc
->p_crypto_mem
+= need
;
6919 mutex_exit(&curproc
->p_lock
);
6921 return (CRYPTO_SUCCESS
);