ZIL: Call brt_pending_add() replaying TX_CLONE_RANGE
[zfs.git] / module / icp / core / kcf_mech_tabs.c
blob41705e84bc4b53c422deffb2997c3757add186b7
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/zfs_context.h>
27 #include <sys/crypto/common.h>
28 #include <sys/crypto/api.h>
29 #include <sys/crypto/impl.h>
31 /* Cryptographic mechanisms tables and their access functions */
34 * Internal numbers assigned to mechanisms are coded as follows:
36 * +----------------+----------------+
37 * | mech. class | mech. index |
38 * <--- 32-bits --->+<--- 32-bits --->
40 * the mech_class identifies the table the mechanism belongs to.
41 * mech_index is the index for that mechanism in the table.
42 * A mechanism belongs to exactly 1 table.
43 * The tables are:
44 * . digest_mechs_tab[] for the msg digest mechs.
45 * . cipher_mechs_tab[] for encrypt/decrypt and wrap/unwrap mechs.
46 * . mac_mechs_tab[] for MAC mechs.
47 * . sign_mechs_tab[] for sign & verify mechs.
48 * . keyops_mechs_tab[] for key/key pair generation, and key derivation.
49 * . misc_mechs_tab[] for mechs that don't belong to any of the above.
51 * There are no holes in the tables.
55 * Locking conventions:
56 * --------------------
57 * A mutex is associated with every entry of the tables.
58 * The mutex is acquired whenever the entry is accessed for
59 * 1) retrieving the mech_id (comparing the mech name)
60 * 2) finding a provider for an xxx_init() or atomic operation.
61 * 3) altering the mechs entry to add or remove a provider.
63 * In 2), after a provider is chosen, its prov_desc is held and the
64 * entry's mutex must be dropped. The provider's working function (SPI) is
65 * called outside the mech_entry's mutex.
67 * The number of providers for a particular mechanism is not expected to be
68 * long enough to justify the cost of using rwlocks, so the per-mechanism
69 * entry mutex won't be very *hot*.
73 /* Mechanisms tables */
76 /* RFE 4687834 Will deal with the extensibility of these tables later */
78 static kcf_mech_entry_t kcf_digest_mechs_tab[KCF_MAXDIGEST];
79 static kcf_mech_entry_t kcf_cipher_mechs_tab[KCF_MAXCIPHER];
80 static kcf_mech_entry_t kcf_mac_mechs_tab[KCF_MAXMAC];
82 const kcf_mech_entry_tab_t kcf_mech_tabs_tab[KCF_LAST_OPSCLASS + 1] = {
83 {0, NULL}, /* No class zero */
84 {KCF_MAXDIGEST, kcf_digest_mechs_tab},
85 {KCF_MAXCIPHER, kcf_cipher_mechs_tab},
86 {KCF_MAXMAC, kcf_mac_mechs_tab},
89 static avl_tree_t kcf_mech_hash;
91 static int
92 kcf_mech_hash_compar(const void *lhs, const void *rhs)
94 const kcf_mech_entry_t *l = lhs, *r = rhs;
95 int cmp = strncmp(l->me_name, r->me_name, CRYPTO_MAX_MECH_NAME);
96 return ((0 < cmp) - (cmp < 0));
99 void
100 kcf_destroy_mech_tabs(void)
102 for (void *cookie = NULL; avl_destroy_nodes(&kcf_mech_hash, &cookie); )
104 avl_destroy(&kcf_mech_hash);
108 * kcf_init_mech_tabs()
110 * Called by the misc/kcf's _init() routine to initialize the tables
111 * of mech_entry's.
113 void
114 kcf_init_mech_tabs(void)
116 avl_create(&kcf_mech_hash, kcf_mech_hash_compar,
117 sizeof (kcf_mech_entry_t), offsetof(kcf_mech_entry_t, me_node));
121 * kcf_create_mech_entry()
123 * Arguments:
124 * . The class of mechanism.
125 * . the name of the new mechanism.
127 * Description:
128 * Creates a new mech_entry for a mechanism not yet known to the
129 * framework.
130 * This routine is called by kcf_add_mech_provider, which is
131 * in turn invoked for each mechanism supported by a provider.
132 * The'class' argument depends on the crypto_func_group_t bitmask
133 * in the registering provider's mech_info struct for this mechanism.
134 * When there is ambiguity in the mapping between the crypto_func_group_t
135 * and a class (dual ops, ...) the KCF_MISC_CLASS should be used.
137 * Context:
138 * User context only.
140 * Returns:
141 * KCF_INVALID_MECH_CLASS or KCF_INVALID_MECH_NAME if the class or
142 * the mechname is bogus.
143 * KCF_MECH_TAB_FULL when there is no room left in the mech. tabs.
144 * KCF_SUCCESS otherwise.
146 static int
147 kcf_create_mech_entry(kcf_ops_class_t class, const char *mechname)
149 if ((class < KCF_FIRST_OPSCLASS) || (class > KCF_LAST_OPSCLASS))
150 return (KCF_INVALID_MECH_CLASS);
152 if ((mechname == NULL) || (mechname[0] == 0))
153 return (KCF_INVALID_MECH_NAME);
155 * First check if the mechanism is already in one of the tables.
156 * The mech_entry could be in another class.
158 avl_index_t where = 0;
159 kcf_mech_entry_t tmptab;
160 strlcpy(tmptab.me_name, mechname, CRYPTO_MAX_MECH_NAME);
161 if (avl_find(&kcf_mech_hash, &tmptab, &where) != NULL)
162 return (KCF_SUCCESS);
163 /* Now take the next unused mech entry in the class's tab */
164 kcf_mech_entry_t *me_tab = kcf_mech_tabs_tab[class].met_tab;
165 int size = kcf_mech_tabs_tab[class].met_size;
167 for (int i = 0; i < size; ++i)
168 if (me_tab[i].me_name[0] == 0) {
169 /* Found an empty spot */
170 strlcpy(me_tab[i].me_name, mechname,
171 CRYPTO_MAX_MECH_NAME);
172 me_tab[i].me_mechid = KCF_MECHID(class, i);
174 /* Add the new mechanism to the hash table */
175 avl_insert(&kcf_mech_hash, &me_tab[i], where);
176 return (KCF_SUCCESS);
179 return (KCF_MECH_TAB_FULL);
183 * kcf_add_mech_provider()
185 * Arguments:
186 * . An index in to the provider mechanism array
187 * . A pointer to the provider descriptor
188 * . A storage for the kcf_prov_mech_desc_t the entry was added at.
190 * Description:
191 * Adds a new provider of a mechanism to the mechanism's mech_entry
192 * chain.
194 * Context:
195 * User context only.
197 * Returns
198 * KCF_SUCCESS on success
199 * KCF_MECH_TAB_FULL otherwise.
202 kcf_add_mech_provider(short mech_indx,
203 kcf_provider_desc_t *prov_desc, kcf_prov_mech_desc_t **pmdpp)
205 int error;
206 kcf_mech_entry_t *mech_entry = NULL;
207 const crypto_mech_info_t *mech_info;
208 crypto_mech_type_t kcf_mech_type;
209 kcf_prov_mech_desc_t *prov_mech;
211 mech_info = &prov_desc->pd_mechanisms[mech_indx];
214 * A mechanism belongs to exactly one mechanism table.
215 * Find the class corresponding to the function group flag of
216 * the mechanism.
218 kcf_mech_type = crypto_mech2id(mech_info->cm_mech_name);
219 if (kcf_mech_type == CRYPTO_MECH_INVALID) {
220 crypto_func_group_t fg = mech_info->cm_func_group_mask;
221 kcf_ops_class_t class;
223 if (fg & CRYPTO_FG_DIGEST || fg & CRYPTO_FG_DIGEST_ATOMIC)
224 class = KCF_DIGEST_CLASS;
225 else if (fg & CRYPTO_FG_ENCRYPT || fg & CRYPTO_FG_DECRYPT ||
226 fg & CRYPTO_FG_ENCRYPT_ATOMIC ||
227 fg & CRYPTO_FG_DECRYPT_ATOMIC)
228 class = KCF_CIPHER_CLASS;
229 else if (fg & CRYPTO_FG_MAC || fg & CRYPTO_FG_MAC_ATOMIC)
230 class = KCF_MAC_CLASS;
231 else
232 __builtin_unreachable();
235 * Attempt to create a new mech_entry for the specified
236 * mechanism. kcf_create_mech_entry() can handle the case
237 * where such an entry already exists.
239 if ((error = kcf_create_mech_entry(class,
240 mech_info->cm_mech_name)) != KCF_SUCCESS) {
241 return (error);
243 /* get the KCF mech type that was assigned to the mechanism */
244 kcf_mech_type = crypto_mech2id(mech_info->cm_mech_name);
245 ASSERT(kcf_mech_type != CRYPTO_MECH_INVALID);
248 error = kcf_get_mech_entry(kcf_mech_type, &mech_entry);
249 ASSERT(error == KCF_SUCCESS);
251 /* allocate and initialize new kcf_prov_mech_desc */
252 prov_mech = kmem_zalloc(sizeof (kcf_prov_mech_desc_t), KM_SLEEP);
253 memcpy(&prov_mech->pm_mech_info, mech_info,
254 sizeof (crypto_mech_info_t));
255 prov_mech->pm_prov_desc = prov_desc;
256 prov_desc->pd_mech_indx[KCF_MECH2CLASS(kcf_mech_type)]
257 [KCF_MECH2INDEX(kcf_mech_type)] = mech_indx;
259 KCF_PROV_REFHOLD(prov_desc);
260 KCF_PROV_IREFHOLD(prov_desc);
263 * Add new kcf_prov_mech_desc at the front of HW providers
264 * chain.
266 if (mech_entry->me_sw_prov != NULL) {
268 * There is already a provider for this mechanism.
269 * Since we allow only one provider per mechanism,
270 * report this condition.
272 cmn_err(CE_WARN, "The cryptographic provider "
273 "\"%s\" will not be used for %s. The provider "
274 "\"%s\" will be used for this mechanism "
275 "instead.", prov_desc->pd_description,
276 mech_info->cm_mech_name,
277 mech_entry->me_sw_prov->pm_prov_desc->
278 pd_description);
279 KCF_PROV_REFRELE(prov_desc);
280 kmem_free(prov_mech, sizeof (kcf_prov_mech_desc_t));
281 prov_mech = NULL;
282 } else {
284 * Set the provider as the provider for
285 * this mechanism.
287 mech_entry->me_sw_prov = prov_mech;
290 *pmdpp = prov_mech;
292 return (KCF_SUCCESS);
296 * kcf_remove_mech_provider()
298 * Arguments:
299 * . mech_name: the name of the mechanism.
300 * . prov_desc: The provider descriptor
302 * Description:
303 * Removes a provider from chain of provider descriptors.
304 * The provider is made unavailable to kernel consumers for the specified
305 * mechanism.
307 * Context:
308 * User context only.
310 void
311 kcf_remove_mech_provider(const char *mech_name, kcf_provider_desc_t *prov_desc)
313 crypto_mech_type_t mech_type;
314 kcf_prov_mech_desc_t *prov_mech = NULL;
315 kcf_mech_entry_t *mech_entry;
317 /* get the KCF mech type that was assigned to the mechanism */
318 if ((mech_type = crypto_mech2id(mech_name)) ==
319 CRYPTO_MECH_INVALID) {
321 * Provider was not allowed for this mech due to policy or
322 * configuration.
324 return;
327 /* get a ptr to the mech_entry that was created */
328 if (kcf_get_mech_entry(mech_type, &mech_entry) != KCF_SUCCESS) {
330 * Provider was not allowed for this mech due to policy or
331 * configuration.
333 return;
336 if (mech_entry->me_sw_prov == NULL ||
337 mech_entry->me_sw_prov->pm_prov_desc != prov_desc) {
338 /* not the provider for this mechanism */
339 return;
341 prov_mech = mech_entry->me_sw_prov;
342 mech_entry->me_sw_prov = NULL;
344 /* free entry */
345 KCF_PROV_IREFRELE(prov_mech->pm_prov_desc);
346 KCF_PROV_REFRELE(prov_mech->pm_prov_desc);
347 kmem_free(prov_mech, sizeof (kcf_prov_mech_desc_t));
351 * kcf_get_mech_entry()
353 * Arguments:
354 * . The framework mechanism type
355 * . Storage for the mechanism entry
357 * Description:
358 * Retrieves the mechanism entry for the mech.
360 * Context:
361 * User and interrupt contexts.
363 * Returns:
364 * KCF_MECHANISM_XXX appropriate error code.
365 * KCF_SUCCESS otherwise.
368 kcf_get_mech_entry(crypto_mech_type_t mech_type, kcf_mech_entry_t **mep)
370 kcf_ops_class_t class;
371 int index;
372 const kcf_mech_entry_tab_t *me_tab;
374 ASSERT(mep != NULL);
376 class = KCF_MECH2CLASS(mech_type);
378 if ((class < KCF_FIRST_OPSCLASS) || (class > KCF_LAST_OPSCLASS)) {
379 /* the caller won't need to know it's an invalid class */
380 return (KCF_INVALID_MECH_NUMBER);
383 me_tab = &kcf_mech_tabs_tab[class];
384 index = KCF_MECH2INDEX(mech_type);
386 if ((index < 0) || (index >= me_tab->met_size)) {
387 return (KCF_INVALID_MECH_NUMBER);
390 *mep = &((me_tab->met_tab)[index]);
392 return (KCF_SUCCESS);
396 * crypto_mech2id()
398 * Arguments:
399 * . mechname: A null-terminated string identifying the mechanism name.
401 * Description:
402 * Walks the mechanisms tables, looking for an entry that matches the
403 * mechname. Once it find it, it builds the 64-bit mech_type and returns
404 * it.
406 * Context:
407 * Process and interruption.
409 * Returns:
410 * The unique mechanism identified by 'mechname', if found.
411 * CRYPTO_MECH_INVALID otherwise.
414 * Lookup the hash table for an entry that matches the mechname.
415 * If there are no providers for the mechanism,
416 * but there is an unloaded provider, this routine will attempt
417 * to load it.
419 crypto_mech_type_t
420 crypto_mech2id(const char *mechname)
422 kcf_mech_entry_t tmptab, *found;
423 strlcpy(tmptab.me_name, mechname, CRYPTO_MAX_MECH_NAME);
425 if ((found = avl_find(&kcf_mech_hash, &tmptab, NULL))) {
426 ASSERT(found->me_mechid != CRYPTO_MECH_INVALID);
427 return (found->me_mechid);
430 return (CRYPTO_MECH_INVALID);
433 #if defined(_KERNEL)
434 EXPORT_SYMBOL(crypto_mech2id);
435 #endif