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 https://opensource.org/licenses/CDDL-1.0.
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 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/crypto/common.h>
27 #include <sys/crypto/impl.h>
28 #include <sys/crypto/sched_impl.h>
31 kcf_free_triedlist(kcf_prov_tried_t
*list
)
35 while ((l
= list
) != NULL
) {
37 KCF_PROV_REFRELE(l
->pt_pd
);
38 kmem_free(l
, sizeof (kcf_prov_tried_t
));
43 kcf_insert_triedlist(kcf_prov_tried_t
**list
, kcf_provider_desc_t
*pd
,
48 l
= kmem_alloc(sizeof (kcf_prov_tried_t
), kmflag
);
60 is_in_triedlist(kcf_provider_desc_t
*pd
, kcf_prov_tried_t
*triedl
)
62 while (triedl
!= NULL
) {
63 if (triedl
->pt_pd
== pd
)
65 triedl
= triedl
->pt_next
;
72 * Return the best provider for the specified mechanism. The provider
73 * is held and it is the caller's responsibility to release it when done.
74 * The fg input argument is used as a search criterion to pick a provider.
75 * A provider has to support this function group to be picked.
77 * Find the least loaded provider in the list of providers. We do a linear
78 * search to find one. This is fine as we assume there are only a few
79 * number of providers in this list. If this assumption ever changes,
80 * we should revisit this.
83 kcf_get_mech_provider(crypto_mech_type_t mech_type
, kcf_mech_entry_t
**mepp
,
84 int *error
, kcf_prov_tried_t
*triedl
, crypto_func_group_t fg
)
86 kcf_provider_desc_t
*pd
= NULL
;
87 kcf_prov_mech_desc_t
*mdesc
;
88 kcf_ops_class_t
class;
91 const kcf_mech_entry_tab_t
*me_tab
;
93 class = KCF_MECH2CLASS(mech_type
);
94 if ((class < KCF_FIRST_OPSCLASS
) || (class > KCF_LAST_OPSCLASS
)) {
95 *error
= CRYPTO_MECHANISM_INVALID
;
99 me_tab
= &kcf_mech_tabs_tab
[class];
100 index
= KCF_MECH2INDEX(mech_type
);
101 if ((index
< 0) || (index
>= me_tab
->met_size
)) {
102 *error
= CRYPTO_MECHANISM_INVALID
;
106 me
= &((me_tab
->met_tab
)[index
]);
110 /* Is there a provider? */
111 if (pd
== NULL
&& (mdesc
= me
->me_sw_prov
) != NULL
) {
112 pd
= mdesc
->pm_prov_desc
;
113 if (!IS_FG_SUPPORTED(mdesc
, fg
) ||
114 !KCF_IS_PROV_USABLE(pd
) ||
115 IS_PROVIDER_TRIED(pd
, triedl
))
121 * We do not want to report CRYPTO_MECH_NOT_SUPPORTED, when
122 * we are in the "fallback to the next provider" case. Rather
123 * we preserve the error, so that the client gets the right
127 *error
= CRYPTO_MECH_NOT_SUPPORTED
;
129 KCF_PROV_REFHOLD(pd
);