4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
30 * This file is part of the core Kernel Cryptographic Framework.
31 * It implements the SPI functions exported to cryptographic
35 #include <sys/ksynch.h>
36 #include <sys/cmn_err.h>
38 #include <sys/sunddi.h>
39 #include <sys/modctl.h>
40 #include <sys/crypto/common.h>
41 #include <sys/crypto/impl.h>
42 #include <sys/crypto/sched_impl.h>
43 #include <sys/crypto/spi.h>
44 #include <sys/crypto/ioctladmin.h>
45 #include <sys/taskq.h>
47 #include <sys/kstat.h>
48 #include <sys/policy.h>
49 #include <sys/cpuvar.h>
52 * minalloc and maxalloc values to be used for taskq_create().
54 int crypto_taskq_threads
= CRYPTO_TASKQ_THREADS
;
55 int crypto_taskq_minalloc
= CYRPTO_TASKQ_MIN
;
56 int crypto_taskq_maxalloc
= CRYPTO_TASKQ_MAX
;
58 static void remove_provider(kcf_provider_desc_t
*);
59 static void process_logical_providers(crypto_provider_info_t
*,
60 kcf_provider_desc_t
*);
61 static int init_prov_mechs(crypto_provider_info_t
*, kcf_provider_desc_t
*);
62 static int kcf_prov_kstat_update(kstat_t
*, int);
63 static void delete_kstat(kcf_provider_desc_t
*);
65 static kcf_prov_stats_t kcf_stats_ks_data_template
= {
66 { "kcf_ops_total", KSTAT_DATA_UINT64
},
67 { "kcf_ops_passed", KSTAT_DATA_UINT64
},
68 { "kcf_ops_failed", KSTAT_DATA_UINT64
},
69 { "kcf_ops_returned_busy", KSTAT_DATA_UINT64
}
72 #define KCF_SPI_COPY_OPS(src, dst, ops) if ((src)->ops != NULL) \
73 *((dst)->ops) = *((src)->ops);
75 extern int sys_shutdown
;
78 * Copy an ops vector from src to dst. Used during provider registration
79 * to copy the ops vector from the provider info structure to the
80 * provider descriptor maintained by KCF.
81 * Copying the ops vector specified by the provider is needed since the
82 * framework does not require the provider info structure to be
86 copy_ops_vector_v1(crypto_ops_t
*src_ops
, crypto_ops_t
*dst_ops
)
88 KCF_SPI_COPY_OPS(src_ops
, dst_ops
, co_control_ops
);
89 KCF_SPI_COPY_OPS(src_ops
, dst_ops
, co_digest_ops
);
90 KCF_SPI_COPY_OPS(src_ops
, dst_ops
, co_cipher_ops
);
91 KCF_SPI_COPY_OPS(src_ops
, dst_ops
, co_mac_ops
);
92 KCF_SPI_COPY_OPS(src_ops
, dst_ops
, co_sign_ops
);
93 KCF_SPI_COPY_OPS(src_ops
, dst_ops
, co_verify_ops
);
94 KCF_SPI_COPY_OPS(src_ops
, dst_ops
, co_dual_ops
);
95 KCF_SPI_COPY_OPS(src_ops
, dst_ops
, co_dual_cipher_mac_ops
);
96 KCF_SPI_COPY_OPS(src_ops
, dst_ops
, co_random_ops
);
97 KCF_SPI_COPY_OPS(src_ops
, dst_ops
, co_session_ops
);
98 KCF_SPI_COPY_OPS(src_ops
, dst_ops
, co_object_ops
);
99 KCF_SPI_COPY_OPS(src_ops
, dst_ops
, co_key_ops
);
100 KCF_SPI_COPY_OPS(src_ops
, dst_ops
, co_provider_ops
);
101 KCF_SPI_COPY_OPS(src_ops
, dst_ops
, co_ctx_ops
);
105 copy_ops_vector_v2(crypto_ops_t
*src_ops
, crypto_ops_t
*dst_ops
)
107 KCF_SPI_COPY_OPS(src_ops
, dst_ops
, co_mech_ops
);
111 copy_ops_vector_v3(crypto_ops_t
*src_ops
, crypto_ops_t
*dst_ops
)
113 KCF_SPI_COPY_OPS(src_ops
, dst_ops
, co_nostore_key_ops
);
117 copy_ops_vector_v4(crypto_ops_t
*src_ops
, crypto_ops_t
*dst_ops
)
119 KCF_SPI_COPY_OPS(src_ops
, dst_ops
, co_fips140_ops
);
123 * This routine is used to add cryptographic providers to the KEF framework.
124 * Providers pass a crypto_provider_info structure to crypto_register_provider()
125 * and get back a handle. The crypto_provider_info structure contains a
126 * list of mechanisms supported by the provider and an ops vector containing
127 * provider entry points. Hardware providers call this routine in their attach
128 * routines. Software providers call this routine in their _init() routine.
131 crypto_register_provider(crypto_provider_info_t
*info
,
132 crypto_kcf_provider_handle_t
*handle
)
136 char ks_name
[KSTAT_STRLEN
];
137 kcf_provider_desc_t
*prov_desc
= NULL
;
138 int ret
= CRYPTO_ARGUMENTS_BAD
;
140 if (info
->pi_interface_version
> CRYPTO_SPI_VERSION_4
) {
141 ret
= CRYPTO_VERSION_MISMATCH
;
146 * Check provider type, must be software, hardware, or logical.
148 if (info
->pi_provider_type
!= CRYPTO_HW_PROVIDER
&&
149 info
->pi_provider_type
!= CRYPTO_SW_PROVIDER
&&
150 info
->pi_provider_type
!= CRYPTO_LOGICAL_PROVIDER
)
154 * Allocate and initialize a new provider descriptor. We also
155 * hold it and release it when done.
157 prov_desc
= kcf_alloc_provider_desc(info
);
158 KCF_PROV_REFHOLD(prov_desc
);
160 prov_desc
->pd_prov_type
= info
->pi_provider_type
;
162 /* provider-private handle, opaque to KCF */
163 prov_desc
->pd_prov_handle
= info
->pi_provider_handle
;
165 /* copy provider description string */
166 if (info
->pi_provider_description
!= NULL
) {
168 * pi_provider_descriptor is a string that can contain
169 * up to CRYPTO_PROVIDER_DESCR_MAX_LEN + 1 characters
170 * INCLUDING the terminating null character. A bcopy()
171 * is necessary here as pd_description should not have
172 * a null character. See comments in kcf_alloc_provider_desc()
173 * for details on pd_description field.
175 bcopy(info
->pi_provider_description
, prov_desc
->pd_description
,
176 min(strlen(info
->pi_provider_description
),
177 CRYPTO_PROVIDER_DESCR_MAX_LEN
));
180 if (info
->pi_provider_type
!= CRYPTO_LOGICAL_PROVIDER
) {
181 if (info
->pi_ops_vector
== NULL
) {
184 copy_ops_vector_v1(info
->pi_ops_vector
,
185 prov_desc
->pd_ops_vector
);
186 if (info
->pi_interface_version
>= CRYPTO_SPI_VERSION_2
) {
187 copy_ops_vector_v2(info
->pi_ops_vector
,
188 prov_desc
->pd_ops_vector
);
189 prov_desc
->pd_flags
= info
->pi_flags
;
191 if (info
->pi_interface_version
>= CRYPTO_SPI_VERSION_3
) {
192 copy_ops_vector_v3(info
->pi_ops_vector
,
193 prov_desc
->pd_ops_vector
);
195 if (info
->pi_interface_version
== CRYPTO_SPI_VERSION_4
) {
196 copy_ops_vector_v4(info
->pi_ops_vector
,
197 prov_desc
->pd_ops_vector
);
201 /* object_ops and nostore_key_ops are mutually exclusive */
202 if (prov_desc
->pd_ops_vector
->co_object_ops
&&
203 prov_desc
->pd_ops_vector
->co_nostore_key_ops
) {
207 * For software providers, copy the module name and module ID.
208 * For hardware providers, copy the driver name and instance.
210 switch (info
->pi_provider_type
) {
211 case CRYPTO_SW_PROVIDER
:
212 if (info
->pi_provider_dev
.pd_sw
== NULL
)
215 if ((mcp
= mod_getctl(info
->pi_provider_dev
.pd_sw
)) == NULL
)
218 prov_desc
->pd_module_id
= mcp
->mod_id
;
219 name
= mcp
->mod_modname
;
222 case CRYPTO_HW_PROVIDER
:
223 case CRYPTO_LOGICAL_PROVIDER
:
224 if (info
->pi_provider_dev
.pd_hw
== NULL
)
227 prov_desc
->pd_instance
=
228 ddi_get_instance(info
->pi_provider_dev
.pd_hw
);
229 name
= (char *)ddi_driver_name(info
->pi_provider_dev
.pd_hw
);
235 prov_desc
->pd_name
= kmem_alloc(strlen(name
) + 1, KM_SLEEP
);
236 (void) strcpy(prov_desc
->pd_name
, name
);
238 if ((prov_desc
->pd_mctlp
= kcf_get_modctl(info
)) == NULL
)
241 /* process the mechanisms supported by the provider */
242 if ((ret
= init_prov_mechs(info
, prov_desc
)) != CRYPTO_SUCCESS
)
246 * Add provider to providers tables, also sets the descriptor
249 if ((ret
= kcf_prov_tab_add_provider(prov_desc
)) != CRYPTO_SUCCESS
) {
250 undo_register_provider(prov_desc
, B_FALSE
);
255 * We create a taskq only for a hardware provider. The global
256 * software queue is used for software providers. We handle ordering
257 * of multi-part requests in the taskq routine. So, it is safe to
258 * have multiple threads for the taskq. We pass TASKQ_PREPOPULATE flag
259 * to keep some entries cached to improve performance.
261 if (prov_desc
->pd_prov_type
== CRYPTO_HW_PROVIDER
)
262 prov_desc
->pd_taskq
= taskq_create("kcf_taskq",
263 crypto_taskq_threads
, minclsyspri
,
264 crypto_taskq_minalloc
, crypto_taskq_maxalloc
,
267 prov_desc
->pd_taskq
= NULL
;
269 /* no kernel session to logical providers and no pd_flags */
270 if (prov_desc
->pd_prov_type
!= CRYPTO_LOGICAL_PROVIDER
) {
272 * Open a session for session-oriented providers. This session
273 * is used for all kernel consumers. This is fine as a provider
274 * is required to support multiple thread access to a session.
275 * We can do this only after the taskq has been created as we
276 * do a kcf_submit_request() to open the session.
278 if (KCF_PROV_SESSION_OPS(prov_desc
) != NULL
) {
279 kcf_req_params_t params
;
281 KCF_WRAP_SESSION_OPS_PARAMS(¶ms
,
282 KCF_OP_SESSION_OPEN
, &prov_desc
->pd_sid
, 0,
283 CRYPTO_USER
, NULL
, 0, prov_desc
);
284 ret
= kcf_submit_request(prov_desc
, NULL
, NULL
, ¶ms
,
286 if (ret
!= CRYPTO_SUCCESS
)
291 * Get the value for the maximum input length allowed if
292 * CRYPTO_HASH_NO_UPDATE or CRYPTO_HASH_NO_UPDATE is specified.
294 if (prov_desc
->pd_flags
&
295 (CRYPTO_HASH_NO_UPDATE
| CRYPTO_HMAC_NO_UPDATE
)) {
296 kcf_req_params_t params
;
297 crypto_provider_ext_info_t ext_info
;
299 if (KCF_PROV_PROVMGMT_OPS(prov_desc
) == NULL
)
302 bzero(&ext_info
, sizeof (ext_info
));
303 KCF_WRAP_PROVMGMT_OPS_PARAMS(¶ms
,
305 0, NULL
, 0, NULL
, 0, NULL
, &ext_info
, prov_desc
);
306 ret
= kcf_submit_request(prov_desc
, NULL
, NULL
,
308 if (ret
!= CRYPTO_SUCCESS
)
311 if (prov_desc
->pd_flags
& CRYPTO_HASH_NO_UPDATE
) {
312 prov_desc
->pd_hash_limit
=
313 ext_info
.ei_hash_max_input_len
;
315 if (prov_desc
->pd_flags
& CRYPTO_HMAC_NO_UPDATE
) {
316 prov_desc
->pd_hmac_limit
=
317 ext_info
.ei_hmac_max_input_len
;
322 if (prov_desc
->pd_prov_type
!= CRYPTO_LOGICAL_PROVIDER
) {
324 * Create the kstat for this provider. There is a kstat
325 * installed for each successfully registered provider.
326 * This kstat is deleted, when the provider unregisters.
328 if (prov_desc
->pd_prov_type
== CRYPTO_SW_PROVIDER
) {
329 (void) snprintf(ks_name
, KSTAT_STRLEN
, "%s_%s",
330 prov_desc
->pd_name
, "provider_stats");
332 (void) snprintf(ks_name
, KSTAT_STRLEN
, "%s_%d_%u_%s",
333 prov_desc
->pd_name
, prov_desc
->pd_instance
,
334 prov_desc
->pd_prov_id
, "provider_stats");
337 prov_desc
->pd_kstat
= kstat_create("kcf", 0, ks_name
, "crypto",
338 KSTAT_TYPE_NAMED
, sizeof (kcf_prov_stats_t
) /
339 sizeof (kstat_named_t
), KSTAT_FLAG_VIRTUAL
);
341 if (prov_desc
->pd_kstat
!= NULL
) {
342 bcopy(&kcf_stats_ks_data_template
,
343 &prov_desc
->pd_ks_data
,
344 sizeof (kcf_stats_ks_data_template
));
345 prov_desc
->pd_kstat
->ks_data
= &prov_desc
->pd_ks_data
;
346 KCF_PROV_REFHOLD(prov_desc
);
347 prov_desc
->pd_kstat
->ks_private
= prov_desc
;
348 prov_desc
->pd_kstat
->ks_update
= kcf_prov_kstat_update
;
349 kstat_install(prov_desc
->pd_kstat
);
353 if (prov_desc
->pd_prov_type
== CRYPTO_HW_PROVIDER
)
354 process_logical_providers(info
, prov_desc
);
356 mutex_enter(&prov_desc
->pd_lock
);
357 prov_desc
->pd_state
= KCF_PROV_READY
;
358 mutex_exit(&prov_desc
->pd_lock
);
359 kcf_do_notify(prov_desc
, B_TRUE
);
362 *handle
= prov_desc
->pd_kcf_prov_handle
;
363 KCF_PROV_REFRELE(prov_desc
);
364 return (CRYPTO_SUCCESS
);
367 undo_register_provider(prov_desc
, B_TRUE
);
370 KCF_PROV_REFRELE(prov_desc
);
373 if (ret
!= CRYPTO_SUCCESS
&& sys_shutdown
== 0) {
376 cmn_err(CE_WARN
, "%s failed when registering with the "
377 "Cryptographic Framework.",
378 info
->pi_provider_description
);
381 case CRYPTO_MODVERIFICATION_FAILED
:
382 cmn_err(CE_WARN
, "%s failed module verification when "
383 "registering with the Cryptographic Framework.",
384 info
->pi_provider_description
);
387 case CRYPTO_ARGUMENTS_BAD
:
388 cmn_err(CE_WARN
, "%s provided bad arguments and was "
389 "not registered with the Cryptographic Framework.",
390 info
->pi_provider_description
);
393 case CRYPTO_VERSION_MISMATCH
:
394 cmn_err(CE_WARN
, "%s was not registered with the "
395 "Cryptographic Framework as there is a SPI version "
396 "mismatch (%d) error.",
397 info
->pi_provider_description
,
398 info
->pi_interface_version
);
401 case CRYPTO_FIPS140_ERROR
:
402 cmn_err(CE_WARN
, "%s was not registered with the "
403 "Cryptographic Framework as there was a FIPS 140 "
404 "validation error.", info
->pi_provider_description
);
408 cmn_err(CE_WARN
, "%s did not register with the "
409 "Cryptographic Framework. (0x%x)",
410 info
->pi_provider_description
, ret
);
417 /* Return the number of holds on a provider. */
419 kcf_get_refcnt(kcf_provider_desc_t
*pd
, boolean_t do_lock
)
425 for (i
= 0; i
< pd
->pd_nbins
; i
++)
426 mutex_enter(&(pd
->pd_percpu_bins
[i
].kp_lock
));
428 for (i
= 0; i
< pd
->pd_nbins
; i
++)
429 refcnt
+= pd
->pd_percpu_bins
[i
].kp_holdcnt
;
432 for (i
= 0; i
< pd
->pd_nbins
; i
++)
433 mutex_exit(&(pd
->pd_percpu_bins
[i
].kp_lock
));
439 * This routine is used to notify the framework when a provider is being
440 * removed. Hardware providers call this routine in their detach routines.
441 * Software providers call this routine in their _fini() routine.
444 crypto_unregister_provider(crypto_kcf_provider_handle_t handle
)
447 kcf_provider_desc_t
*desc
;
448 kcf_prov_state_t saved_state
;
449 int ret
= CRYPTO_SUCCESS
;
451 /* lookup provider descriptor */
452 if ((desc
= kcf_prov_tab_lookup((crypto_provider_id_t
)handle
)) ==
454 ret
= CRYPTO_UNKNOWN_PROVIDER
;
458 mutex_enter(&desc
->pd_lock
);
460 * Check if any other thread is disabling or removing
461 * this provider. We return if this is the case.
463 if (desc
->pd_state
>= KCF_PROV_DISABLED
) {
464 mutex_exit(&desc
->pd_lock
);
465 /* Release reference held by kcf_prov_tab_lookup(). */
466 KCF_PROV_REFRELE(desc
);
471 saved_state
= desc
->pd_state
;
472 desc
->pd_state
= KCF_PROV_UNREGISTERING
;
474 if (saved_state
== KCF_PROV_BUSY
) {
476 * The per-provider taskq threads may be waiting. We
477 * signal them so that they can start failing requests.
479 cv_broadcast(&desc
->pd_resume_cv
);
482 mutex_exit(&desc
->pd_lock
);
484 if (desc
->pd_prov_type
!= CRYPTO_SW_PROVIDER
) {
485 remove_provider(desc
);
488 if (desc
->pd_prov_type
!= CRYPTO_LOGICAL_PROVIDER
) {
489 /* remove the provider from the mechanisms tables */
490 for (mech_idx
= 0; mech_idx
< desc
->pd_mech_list_count
;
492 kcf_remove_mech_provider(
493 desc
->pd_mechanisms
[mech_idx
].cm_mech_name
, desc
);
497 /* remove provider from providers table */
498 if (kcf_prov_tab_rem_provider((crypto_provider_id_t
)handle
) !=
500 /* Release reference held by kcf_prov_tab_lookup(). */
501 KCF_PROV_REFRELE(desc
);
502 ret
= CRYPTO_UNKNOWN_PROVIDER
;
508 if (desc
->pd_prov_type
== CRYPTO_SW_PROVIDER
) {
510 * Wait till the existing requests with the provider complete
511 * and all the holds are released. All the holds on a software
512 * provider are from kernel clients and the hold time
513 * is expected to be short. So, we won't be stuck here forever.
515 while (kcf_get_refcnt(desc
, B_TRUE
) > 1) {
516 /* wait 1 second and try again. */
524 * Wait until requests that have been sent to the provider
527 for (i
= 0; i
< desc
->pd_nbins
; i
++) {
528 mp
= &(desc
->pd_percpu_bins
[i
]);
530 mutex_enter(&mp
->kp_lock
);
531 while (mp
->kp_jobcnt
> 0) {
532 cv_wait(&mp
->kp_cv
, &mp
->kp_lock
);
534 mutex_exit(&mp
->kp_lock
);
538 mutex_enter(&desc
->pd_lock
);
539 desc
->pd_state
= KCF_PROV_UNREGISTERED
;
540 mutex_exit(&desc
->pd_lock
);
542 kcf_do_notify(desc
, B_FALSE
);
544 mutex_enter(&prov_tab_mutex
);
545 /* Release reference held by kcf_prov_tab_lookup(). */
546 KCF_PROV_REFRELE(desc
);
548 if (kcf_get_refcnt(desc
, B_TRUE
) == 0) {
549 /* kcf_free_provider_desc drops prov_tab_mutex */
550 kcf_free_provider_desc(desc
);
552 ASSERT(desc
->pd_prov_type
!= CRYPTO_SW_PROVIDER
);
554 * We could avoid this if /dev/crypto can proactively
555 * remove any holds on us from a dormant PKCS #11 app.
556 * For now, we check the provider table for
557 * KCF_PROV_UNREGISTERED entries when a provider is
558 * added to the table or when a provider is removed from it
559 * and free them when refcnt reaches zero.
561 kcf_need_provtab_walk
= B_TRUE
;
562 mutex_exit(&prov_tab_mutex
);
566 if (ret
!= CRYPTO_SUCCESS
&& sys_shutdown
== 0) {
568 case CRYPTO_UNKNOWN_PROVIDER
:
569 cmn_err(CE_WARN
, "Unknown provider \"%s\" was "
570 "requested to unregister from the cryptographic "
571 "framework.", desc
->pd_description
);
575 cmn_err(CE_WARN
, "%s could not be unregistered from "
576 "the Cryptographic Framework as it is busy.",
577 desc
->pd_description
);
581 cmn_err(CE_WARN
, "%s did not unregister with the "
582 "Cryptographic Framework. (0x%x)",
583 desc
->pd_description
, ret
);
591 * This routine is used to notify the framework that the state of
592 * a cryptographic provider has changed. Valid state codes are:
594 * CRYPTO_PROVIDER_READY
595 * The provider indicates that it can process more requests. A provider
596 * will notify with this event if it previously has notified us with a
597 * CRYPTO_PROVIDER_BUSY.
599 * CRYPTO_PROVIDER_BUSY
600 * The provider can not take more requests.
602 * CRYPTO_PROVIDER_FAILED
603 * The provider encountered an internal error. The framework will not
604 * be sending any more requests to the provider. The provider may notify
605 * with a CRYPTO_PROVIDER_READY, if it is able to recover from the error.
607 * This routine can be called from user or interrupt context.
610 crypto_provider_notification(crypto_kcf_provider_handle_t handle
, uint_t state
)
612 kcf_provider_desc_t
*pd
;
614 /* lookup the provider from the given handle */
615 if ((pd
= kcf_prov_tab_lookup((crypto_provider_id_t
)handle
)) == NULL
)
618 mutex_enter(&pd
->pd_lock
);
620 if (pd
->pd_state
<= KCF_PROV_VERIFICATION_FAILED
)
623 if (pd
->pd_prov_type
== CRYPTO_LOGICAL_PROVIDER
) {
624 cmn_err(CE_WARN
, "crypto_provider_notification: "
625 "logical provider (%x) ignored\n", handle
);
629 case CRYPTO_PROVIDER_READY
:
630 switch (pd
->pd_state
) {
632 pd
->pd_state
= KCF_PROV_READY
;
634 * Signal the per-provider taskq threads that they
635 * can start submitting requests.
637 cv_broadcast(&pd
->pd_resume_cv
);
640 case KCF_PROV_FAILED
:
642 * The provider recovered from the error. Let us
645 pd
->pd_state
= KCF_PROV_READY
;
650 case CRYPTO_PROVIDER_BUSY
:
651 switch (pd
->pd_state
) {
653 pd
->pd_state
= KCF_PROV_BUSY
;
658 case CRYPTO_PROVIDER_FAILED
:
660 * We note the failure and return. The per-provider taskq
661 * threads check this flag and start failing the
662 * requests, if it is set. See process_req_hwp() for details.
664 switch (pd
->pd_state
) {
666 pd
->pd_state
= KCF_PROV_FAILED
;
670 pd
->pd_state
= KCF_PROV_FAILED
;
672 * The per-provider taskq threads may be waiting. We
673 * signal them so that they can start failing requests.
675 cv_broadcast(&pd
->pd_resume_cv
);
681 mutex_exit(&pd
->pd_lock
);
682 KCF_PROV_REFRELE(pd
);
686 * This routine is used to notify the framework the result of
687 * an asynchronous request handled by a provider. Valid error
688 * codes are the same as the CRYPTO_* errors defined in common.h.
690 * This routine can be called from user or interrupt context.
693 crypto_op_notification(crypto_req_handle_t handle
, int error
)
695 kcf_call_type_t ctype
;
700 if ((ctype
= GET_REQ_TYPE(handle
)) == CRYPTO_SYNCH
) {
701 kcf_sreq_node_t
*sreq
= (kcf_sreq_node_t
*)handle
;
703 KCF_PROV_JOB_RELE_STAT(sreq
->sn_mp
, (error
!= CRYPTO_SUCCESS
));
704 kcf_sop_done(sreq
, error
);
706 kcf_areq_node_t
*areq
= (kcf_areq_node_t
*)handle
;
708 ASSERT(ctype
== CRYPTO_ASYNCH
);
709 KCF_PROV_JOB_RELE_STAT(areq
->an_mp
, (error
!= CRYPTO_SUCCESS
));
710 kcf_aop_done(areq
, error
);
715 * This routine is used by software providers to determine
716 * whether to use KM_SLEEP or KM_NOSLEEP during memory allocation.
717 * Note that hardware providers can always use KM_SLEEP. So,
718 * they do not need to call this routine.
720 * This routine can be called from user or interrupt context.
723 crypto_kmflag(crypto_req_handle_t handle
)
725 return (REQHNDL2_KMFLAG(handle
));
729 * Process the mechanism info structures specified by the provider
730 * during registration. A NULL crypto_provider_info_t indicates
731 * an already initialized provider descriptor.
733 * Mechanisms are not added to the kernel's mechanism table if the
734 * provider is a logical provider.
736 * Returns CRYPTO_SUCCESS on success, CRYPTO_ARGUMENTS if one
737 * of the specified mechanisms was malformed, or CRYPTO_HOST_MEMORY
738 * if the table of mechanisms is full.
741 init_prov_mechs(crypto_provider_info_t
*info
, kcf_provider_desc_t
*desc
)
745 int err
= CRYPTO_SUCCESS
;
746 kcf_prov_mech_desc_t
*pmd
;
747 int desc_use_count
= 0;
748 int mcount
= desc
->pd_mech_list_count
;
750 if (desc
->pd_prov_type
== CRYPTO_LOGICAL_PROVIDER
) {
752 ASSERT(info
->pi_mechanisms
!= NULL
);
753 bcopy(info
->pi_mechanisms
, desc
->pd_mechanisms
,
754 sizeof (crypto_mech_info_t
) * mcount
);
756 return (CRYPTO_SUCCESS
);
760 * Copy the mechanism list from the provider info to the provider
761 * descriptor. desc->pd_mechanisms has an extra crypto_mech_info_t
762 * element if the provider has random_ops since we keep an internal
763 * mechanism, SUN_RANDOM, in this case.
766 if (info
->pi_ops_vector
->co_random_ops
!= NULL
) {
767 crypto_mech_info_t
*rand_mi
;
770 * Need the following check as it is possible to have
771 * a provider that implements just random_ops and has
772 * pi_mechanisms == NULL.
774 if (info
->pi_mechanisms
!= NULL
) {
775 bcopy(info
->pi_mechanisms
, desc
->pd_mechanisms
,
776 sizeof (crypto_mech_info_t
) * (mcount
- 1));
778 rand_mi
= &desc
->pd_mechanisms
[mcount
- 1];
780 bzero(rand_mi
, sizeof (crypto_mech_info_t
));
781 (void) strncpy(rand_mi
->cm_mech_name
, SUN_RANDOM
,
782 CRYPTO_MAX_MECH_NAME
);
783 rand_mi
->cm_func_group_mask
= CRYPTO_FG_RANDOM
;
785 ASSERT(info
->pi_mechanisms
!= NULL
);
786 bcopy(info
->pi_mechanisms
, desc
->pd_mechanisms
,
787 sizeof (crypto_mech_info_t
) * mcount
);
792 * For each mechanism support by the provider, add the provider
793 * to the corresponding KCF mechanism mech_entry chain.
795 for (mech_idx
= 0; mech_idx
< desc
->pd_mech_list_count
; mech_idx
++) {
796 crypto_mech_info_t
*mi
= &desc
->pd_mechanisms
[mech_idx
];
798 if ((mi
->cm_mech_flags
& CRYPTO_KEYSIZE_UNIT_IN_BITS
) &&
799 (mi
->cm_mech_flags
& CRYPTO_KEYSIZE_UNIT_IN_BYTES
)) {
800 err
= CRYPTO_ARGUMENTS_BAD
;
804 if ((err
= kcf_add_mech_provider(mech_idx
, desc
, &pmd
)) !=
811 /* The provider will be used for this mechanism */
816 * Don't allow multiple software providers with disabled mechanisms
817 * to register. Subsequent enabling of mechanisms will result in
818 * an unsupported configuration, i.e. multiple software providers
821 if (desc_use_count
== 0 && desc
->pd_prov_type
== CRYPTO_SW_PROVIDER
)
822 return (CRYPTO_ARGUMENTS_BAD
);
824 if (err
== KCF_SUCCESS
)
825 return (CRYPTO_SUCCESS
);
828 * An error occurred while adding the mechanism, cleanup
831 for (cleanup_idx
= 0; cleanup_idx
< mech_idx
; cleanup_idx
++) {
832 kcf_remove_mech_provider(
833 desc
->pd_mechanisms
[cleanup_idx
].cm_mech_name
, desc
);
836 if (err
== KCF_MECH_TAB_FULL
)
837 return (CRYPTO_HOST_MEMORY
);
839 return (CRYPTO_ARGUMENTS_BAD
);
843 * Update routine for kstat. Only privileged users are allowed to
844 * access this information, since this information is sensitive.
845 * There are some cryptographic attacks (e.g. traffic analysis)
846 * which can use this information.
849 kcf_prov_kstat_update(kstat_t
*ksp
, int rw
)
851 kcf_prov_stats_t
*ks_data
;
852 kcf_provider_desc_t
*pd
= (kcf_provider_desc_t
*)ksp
->ks_private
;
855 if (rw
== KSTAT_WRITE
)
858 ks_data
= ksp
->ks_data
;
860 if (secpolicy_sys_config(CRED(), B_TRUE
) != 0) {
861 ks_data
->ps_ops_total
.value
.ui64
= 0;
862 ks_data
->ps_ops_passed
.value
.ui64
= 0;
863 ks_data
->ps_ops_failed
.value
.ui64
= 0;
864 ks_data
->ps_ops_busy_rval
.value
.ui64
= 0;
866 uint64_t dtotal
, ftotal
, btotal
;
868 dtotal
= ftotal
= btotal
= 0;
869 /* No locking done since an exact count is not required. */
870 for (i
= 0; i
< pd
->pd_nbins
; i
++) {
871 dtotal
+= pd
->pd_percpu_bins
[i
].kp_ndispatches
;
872 ftotal
+= pd
->pd_percpu_bins
[i
].kp_nfails
;
873 btotal
+= pd
->pd_percpu_bins
[i
].kp_nbusy_rval
;
876 ks_data
->ps_ops_total
.value
.ui64
= dtotal
;
877 ks_data
->ps_ops_failed
.value
.ui64
= ftotal
;
878 ks_data
->ps_ops_busy_rval
.value
.ui64
= btotal
;
879 ks_data
->ps_ops_passed
.value
.ui64
= dtotal
- ftotal
- btotal
;
887 * Utility routine called from failure paths in crypto_register_provider()
888 * and from crypto_load_soft_disabled().
891 undo_register_provider(kcf_provider_desc_t
*desc
, boolean_t remove_prov
)
895 /* remove the provider from the mechanisms tables */
896 for (mech_idx
= 0; mech_idx
< desc
->pd_mech_list_count
;
898 kcf_remove_mech_provider(
899 desc
->pd_mechanisms
[mech_idx
].cm_mech_name
, desc
);
902 /* remove provider from providers table */
904 (void) kcf_prov_tab_rem_provider(desc
->pd_prov_id
);
908 * Utility routine called from crypto_load_soft_disabled(). Callers
909 * should have done a prior undo_register_provider().
912 redo_register_provider(kcf_provider_desc_t
*pd
)
914 /* process the mechanisms supported by the provider */
915 (void) init_prov_mechs(NULL
, pd
);
918 * Hold provider in providers table. We should not call
919 * kcf_prov_tab_add_provider() here as the provider descriptor
920 * is still valid which means it has an entry in the provider
923 KCF_PROV_REFHOLD(pd
);
927 * Add provider (p1) to another provider's array of providers (p2).
928 * Hardware and logical providers use this array to cross-reference
932 add_provider_to_array(kcf_provider_desc_t
*p1
, kcf_provider_desc_t
*p2
)
934 kcf_provider_list_t
*new;
936 new = kmem_alloc(sizeof (kcf_provider_list_t
), KM_SLEEP
);
937 mutex_enter(&p2
->pd_lock
);
938 new->pl_next
= p2
->pd_provider_list
;
939 p2
->pd_provider_list
= new;
940 new->pl_provider
= p1
;
941 mutex_exit(&p2
->pd_lock
);
945 * Remove provider (p1) from another provider's array of providers (p2).
946 * Hardware and logical providers use this array to cross-reference
950 remove_provider_from_array(kcf_provider_desc_t
*p1
, kcf_provider_desc_t
*p2
)
953 kcf_provider_list_t
*pl
= NULL
, **prev
;
955 mutex_enter(&p2
->pd_lock
);
956 for (pl
= p2
->pd_provider_list
, prev
= &p2
->pd_provider_list
;
957 pl
!= NULL
; prev
= &pl
->pl_next
, pl
= pl
->pl_next
) {
958 if (pl
->pl_provider
== p1
) {
964 mutex_exit(&p2
->pd_lock
);
968 /* detach and free kcf_provider_list structure */
970 kmem_free(pl
, sizeof (*pl
));
971 mutex_exit(&p2
->pd_lock
);
975 * Convert an array of logical provider handles (crypto_provider_id)
976 * stored in a crypto_provider_info structure into an array of provider
977 * descriptors (kcf_provider_desc_t) attached to a logical provider.
980 process_logical_providers(crypto_provider_info_t
*info
, kcf_provider_desc_t
*hp
)
982 kcf_provider_desc_t
*lp
;
983 crypto_provider_id_t handle
;
984 int count
= info
->pi_logical_provider_count
;
987 /* add hardware provider to each logical provider */
988 for (i
= 0; i
< count
; i
++) {
989 handle
= info
->pi_logical_providers
[i
];
990 lp
= kcf_prov_tab_lookup((crypto_provider_id_t
)handle
);
994 add_provider_to_array(hp
, lp
);
995 hp
->pd_flags
|= KCF_LPROV_MEMBER
;
998 * A hardware provider has to have the provider descriptor of
999 * every logical provider it belongs to, so it can be removed
1000 * from the logical provider if the hardware provider
1001 * unregisters from the framework.
1003 add_provider_to_array(lp
, hp
);
1004 KCF_PROV_REFRELE(lp
);
1009 * This routine removes a provider from all of the logical or
1010 * hardware providers it belongs to, and frees the provider's
1011 * array of pointers to providers.
1014 remove_provider(kcf_provider_desc_t
*pp
)
1016 kcf_provider_desc_t
*p
;
1017 kcf_provider_list_t
*e
, *next
;
1019 mutex_enter(&pp
->pd_lock
);
1020 for (e
= pp
->pd_provider_list
; e
!= NULL
; e
= next
) {
1022 remove_provider_from_array(pp
, p
);
1023 if (p
->pd_prov_type
== CRYPTO_HW_PROVIDER
&&
1024 p
->pd_provider_list
== NULL
)
1025 p
->pd_flags
&= ~KCF_LPROV_MEMBER
;
1027 kmem_free(e
, sizeof (*e
));
1029 pp
->pd_provider_list
= NULL
;
1030 mutex_exit(&pp
->pd_lock
);
1034 * Dispatch events as needed for a provider. is_added flag tells
1035 * whether the provider is registering or unregistering.
1038 kcf_do_notify(kcf_provider_desc_t
*prov_desc
, boolean_t is_added
)
1041 crypto_notify_event_change_t ec
;
1043 ASSERT(prov_desc
->pd_state
> KCF_PROV_VERIFICATION_FAILED
);
1046 * Inform interested clients of the mechanisms becoming
1047 * available/unavailable. We skip this for logical providers
1048 * as they do not affect mechanisms.
1050 if (prov_desc
->pd_prov_type
!= CRYPTO_LOGICAL_PROVIDER
) {
1051 ec
.ec_provider_type
= prov_desc
->pd_prov_type
;
1052 ec
.ec_change
= is_added
? CRYPTO_MECH_ADDED
:
1053 CRYPTO_MECH_REMOVED
;
1054 for (i
= 0; i
< prov_desc
->pd_mech_list_count
; i
++) {
1055 /* Skip any mechanisms not allowed by the policy */
1056 if (is_mech_disabled(prov_desc
,
1057 prov_desc
->pd_mechanisms
[i
].cm_mech_name
))
1060 (void) strncpy(ec
.ec_mech_name
,
1061 prov_desc
->pd_mechanisms
[i
].cm_mech_name
,
1062 CRYPTO_MAX_MECH_NAME
);
1063 kcf_walk_ntfylist(CRYPTO_EVENT_MECHS_CHANGED
, &ec
);
1069 * Inform interested clients about the new or departing provider.
1070 * In case of a logical provider, we need to notify the event only
1071 * for the logical provider and not for the underlying
1072 * providers which are known by the KCF_LPROV_MEMBER bit.
1074 if (prov_desc
->pd_prov_type
== CRYPTO_LOGICAL_PROVIDER
||
1075 (prov_desc
->pd_flags
& KCF_LPROV_MEMBER
) == 0) {
1076 kcf_walk_ntfylist(is_added
? CRYPTO_EVENT_PROVIDER_REGISTERED
:
1077 CRYPTO_EVENT_PROVIDER_UNREGISTERED
, prov_desc
);
1082 delete_kstat(kcf_provider_desc_t
*desc
)
1084 /* destroy the kstat created for this provider */
1085 if (desc
->pd_kstat
!= NULL
) {
1086 kcf_provider_desc_t
*kspd
= desc
->pd_kstat
->ks_private
;
1088 /* release reference held by desc->pd_kstat->ks_private */
1089 ASSERT(desc
== kspd
);
1090 kstat_delete(kspd
->pd_kstat
);
1091 desc
->pd_kstat
= NULL
;
1092 KCF_PROV_REFRELE(kspd
);