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 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * This file is part of the core Kernel Cryptographic Framework.
28 * It implements the management of tables of Providers. Entries to
29 * added and removed when cryptographic providers register with
30 * and unregister from the framework, respectively. The KCF scheduler
31 * and ioctl pseudo driver call this function to obtain the list
32 * of available providers.
34 * The provider table is indexed by crypto_provider_id_t. Each
35 * element of the table contains a pointer to a provider descriptor,
36 * or NULL if the entry is free.
38 * This file also implements helper functions to allocate and free
39 * provider descriptors.
42 #include <sys/zfs_context.h>
43 #include <sys/crypto/common.h>
44 #include <sys/crypto/impl.h>
45 #include <sys/crypto/sched_impl.h>
46 #include <sys/crypto/spi.h>
48 #define KCF_MAX_PROVIDERS 8 /* max number of providers */
51 * Prov_tab is an array of providers which is updated when
52 * a crypto provider registers with kcf. The provider calls the
53 * SPI routine, crypto_register_provider(), which in turn calls
54 * kcf_prov_tab_add_provider().
56 * A provider unregisters by calling crypto_unregister_provider()
57 * which triggers the removal of the prov_tab entry.
58 * It also calls kcf_remove_mech_provider().
60 * prov_tab entries are not updated from kcf.conf or by cryptoadm(1M).
62 static kcf_provider_desc_t
*prov_tab
[KCF_MAX_PROVIDERS
];
63 static kmutex_t prov_tab_mutex
; /* ensure exclusive access to the table */
64 static uint_t prov_tab_num
= 0; /* number of providers in table */
67 kcf_prov_tab_destroy(void)
69 mutex_destroy(&prov_tab_mutex
);
73 * Initialize a mutex and the KCF providers table, prov_tab.
74 * The providers table is dynamically allocated with KCF_MAX_PROVIDERS entries.
75 * Called from kcf module _init().
78 kcf_prov_tab_init(void)
80 mutex_init(&prov_tab_mutex
, NULL
, MUTEX_DEFAULT
, NULL
);
84 * Add a provider to the provider table. If no free entry can be found
85 * for the new provider, returns CRYPTO_HOST_MEMORY. Otherwise, add
86 * the provider to the table, initialize the pd_prov_id field
87 * of the specified provider descriptor to the index in that table,
88 * and return CRYPTO_SUCCESS. Note that a REFHOLD is done on the
89 * provider when pointed to by a table entry.
92 kcf_prov_tab_add_provider(kcf_provider_desc_t
*prov_desc
)
96 mutex_enter(&prov_tab_mutex
);
98 /* find free slot in providers table */
99 for (i
= 1; i
< KCF_MAX_PROVIDERS
&& prov_tab
[i
] != NULL
; i
++)
101 if (i
== KCF_MAX_PROVIDERS
) {
102 /* ran out of providers entries */
103 mutex_exit(&prov_tab_mutex
);
104 cmn_err(CE_WARN
, "out of providers entries");
105 return (CRYPTO_HOST_MEMORY
);
108 /* initialize entry */
109 prov_tab
[i
] = prov_desc
;
110 KCF_PROV_REFHOLD(prov_desc
);
111 KCF_PROV_IREFHOLD(prov_desc
);
114 mutex_exit(&prov_tab_mutex
);
116 /* update provider descriptor */
117 prov_desc
->pd_prov_id
= i
;
120 * The KCF-private provider handle is defined as the internal
123 prov_desc
->pd_kcf_prov_handle
=
124 (crypto_kcf_provider_handle_t
)prov_desc
->pd_prov_id
;
126 return (CRYPTO_SUCCESS
);
130 * Remove the provider specified by its id. A REFRELE is done on the
131 * corresponding provider descriptor before this function returns.
132 * Returns CRYPTO_UNKNOWN_PROVIDER if the provider id is not valid.
135 kcf_prov_tab_rem_provider(crypto_provider_id_t prov_id
)
137 kcf_provider_desc_t
*prov_desc
;
140 * Validate provider id, since it can be specified by a 3rd-party
144 mutex_enter(&prov_tab_mutex
);
145 if (prov_id
>= KCF_MAX_PROVIDERS
||
146 ((prov_desc
= prov_tab
[prov_id
]) == NULL
)) {
147 mutex_exit(&prov_tab_mutex
);
148 return (CRYPTO_INVALID_PROVIDER_ID
);
150 mutex_exit(&prov_tab_mutex
);
153 * The provider id must remain valid until the associated provider
154 * descriptor is freed. For this reason, we simply release our
155 * reference to the descriptor here. When the reference count
156 * reaches zero, kcf_free_provider_desc() will be invoked and
157 * the associated entry in the providers table will be released
161 KCF_PROV_IREFRELE(prov_desc
);
162 KCF_PROV_REFRELE(prov_desc
);
164 return (CRYPTO_SUCCESS
);
168 * Returns the provider descriptor corresponding to the specified
169 * provider id. A REFHOLD is done on the descriptor before it is
170 * returned to the caller. It is the responsibility of the caller
171 * to do a REFRELE once it is done with the provider descriptor.
173 kcf_provider_desc_t
*
174 kcf_prov_tab_lookup(crypto_provider_id_t prov_id
)
176 kcf_provider_desc_t
*prov_desc
;
178 mutex_enter(&prov_tab_mutex
);
180 prov_desc
= prov_tab
[prov_id
];
182 if (prov_desc
== NULL
) {
183 mutex_exit(&prov_tab_mutex
);
187 KCF_PROV_REFHOLD(prov_desc
);
189 mutex_exit(&prov_tab_mutex
);
195 * Allocate a provider descriptor. mech_list_count specifies the
196 * number of mechanisms supported by the providers, and is used
197 * to allocate storage for the mechanism table.
198 * This function may sleep while allocating memory, which is OK
199 * since it is invoked from user context during provider registration.
201 kcf_provider_desc_t
*
202 kcf_alloc_provider_desc(void)
204 kcf_provider_desc_t
*desc
=
205 kmem_zalloc(sizeof (kcf_provider_desc_t
), KM_SLEEP
);
207 for (int i
= 0; i
< KCF_OPS_CLASSSIZE
; i
++)
208 for (int j
= 0; j
< KCF_MAXMECHTAB
; j
++)
209 desc
->pd_mech_indx
[i
][j
] = KCF_INVALID_INDX
;
211 desc
->pd_prov_id
= KCF_PROVID_INVALID
;
212 desc
->pd_state
= KCF_PROV_ALLOCATED
;
214 mutex_init(&desc
->pd_lock
, NULL
, MUTEX_DEFAULT
, NULL
);
215 cv_init(&desc
->pd_remove_cv
, NULL
, CV_DEFAULT
, NULL
);
221 * Called by KCF_PROV_REFRELE when a provider's reference count drops
222 * to zero. We free the descriptor when the last reference is released.
223 * However, for providers, we do not free it when there is an
224 * unregister thread waiting. We signal that thread in this case and
225 * that thread is responsible for freeing the descriptor.
228 kcf_provider_zero_refcnt(kcf_provider_desc_t
*desc
)
230 mutex_enter(&desc
->pd_lock
);
231 if (desc
->pd_state
== KCF_PROV_REMOVED
||
232 desc
->pd_state
== KCF_PROV_DISABLED
) {
233 desc
->pd_state
= KCF_PROV_FREED
;
234 cv_broadcast(&desc
->pd_remove_cv
);
235 mutex_exit(&desc
->pd_lock
);
239 mutex_exit(&desc
->pd_lock
);
240 kcf_free_provider_desc(desc
);
244 * Free a provider descriptor.
247 kcf_free_provider_desc(kcf_provider_desc_t
*desc
)
252 mutex_enter(&prov_tab_mutex
);
253 if (desc
->pd_prov_id
!= KCF_PROVID_INVALID
) {
254 /* release the associated providers table entry */
255 ASSERT(prov_tab
[desc
->pd_prov_id
] != NULL
);
256 prov_tab
[desc
->pd_prov_id
] = NULL
;
259 mutex_exit(&prov_tab_mutex
);
261 /* free the kernel memory associated with the provider descriptor */
263 mutex_destroy(&desc
->pd_lock
);
264 cv_destroy(&desc
->pd_remove_cv
);
266 kmem_free(desc
, sizeof (kcf_provider_desc_t
));
270 * Returns in the location pointed to by pd a pointer to the descriptor
271 * for the provider for the specified mechanism.
272 * The provider descriptor is returned held and it is the caller's
273 * responsibility to release it when done. The mechanism entry
274 * is returned if the optional argument mep is non NULL.
276 * Returns one of the CRYPTO_ * error codes on failure, and
277 * CRYPTO_SUCCESS on success.
280 kcf_get_sw_prov(crypto_mech_type_t mech_type
, kcf_provider_desc_t
**pd
,
281 kcf_mech_entry_t
**mep
, boolean_t log_warn
)
283 kcf_mech_entry_t
*me
;
285 /* get the mechanism entry for this mechanism */
286 if (kcf_get_mech_entry(mech_type
, &me
) != KCF_SUCCESS
)
287 return (CRYPTO_MECHANISM_INVALID
);
289 /* Get the provider for this mechanism. */
290 if (me
->me_sw_prov
== NULL
||
291 (*pd
= me
->me_sw_prov
->pm_prov_desc
) == NULL
) {
292 /* no provider for this mechanism */
294 cmn_err(CE_WARN
, "no provider for \"%s\"\n",
296 return (CRYPTO_MECH_NOT_SUPPORTED
);
299 KCF_PROV_REFHOLD(*pd
);
304 return (CRYPTO_SUCCESS
);