1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <sys/zfs_context.h>
27 #include <sys/crypto/common.h>
28 #include <sys/crypto/api.h>
29 #include <sys/crypto/impl.h>
30 
31 /* Cryptographic mechanisms tables and their access functions */
32 
33 /*
34  * Internal numbers assigned to mechanisms are coded as follows:
35  *
36  * +----------------+----------------+
37  * | mech. class    | mech. index    |
38  * <--- 32-bits --->+<--- 32-bits --->
39  *
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.
50  *
51  * There are no holes in the tables.
52  */
53 
54 /*
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.
62  *
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.
66  *
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*.
70  *
71  */
72 
73 		/* Mechanisms tables */
74 
75 
76 /* RFE 4687834 Will deal with the extensibility of these tables later */
77 
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];
81 
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},
87 };
88 
89 static avl_tree_t kcf_mech_hash;
90 
91 static int
92 kcf_mech_hash_compar(const void *lhs, const void *rhs)
93 {
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));
97 }
98 
99 void
100 kcf_destroy_mech_tabs(void)
101 {
102 	for (void *cookie = NULL; avl_destroy_nodes(&kcf_mech_hash, &cookie); )
103 		;
104 	avl_destroy(&kcf_mech_hash);
105 }
106 
107 /*
108  * kcf_init_mech_tabs()
109  *
110  * Called by the misc/kcf's _init() routine to initialize the tables
111  * of mech_entry's.
112  */
113 void
114 kcf_init_mech_tabs(void)
115 {
116 	avl_create(&kcf_mech_hash, kcf_mech_hash_compar,
117 	    sizeof (kcf_mech_entry_t), offsetof(kcf_mech_entry_t, me_node));
118 }
119 
120 /*
121  * kcf_create_mech_entry()
122  *
123  * Arguments:
124  *	. The class of mechanism.
125  *	. the name of the new mechanism.
126  *
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.
136  *
137  * Context:
138  *	User context only.
139  *
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.
145  */
146 static int
147 kcf_create_mech_entry(kcf_ops_class_t class, const char *mechname)
148 {
149 	if ((class < KCF_FIRST_OPSCLASS) || (class > KCF_LAST_OPSCLASS))
150 		return (KCF_INVALID_MECH_CLASS);
151 
152 	if ((mechname == NULL) || (mechname[0] == 0))
153 		return (KCF_INVALID_MECH_NAME);
154 	/*
155 	 * First check if the mechanism is already in one of the tables.
156 	 * The mech_entry could be in another class.
157 	 */
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;
166 
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);
173 
174 			/* Add the new mechanism to the hash table */
175 			avl_insert(&kcf_mech_hash, &me_tab[i], where);
176 			return (KCF_SUCCESS);
177 		}
178 
179 	return (KCF_MECH_TAB_FULL);
180 }
181 
182 /*
183  * kcf_add_mech_provider()
184  *
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.
189  *
190  * Description:
191  *      Adds  a new provider of a mechanism to the mechanism's mech_entry
192  *	chain.
193  *
194  * Context:
195  *      User context only.
196  *
197  * Returns
198  *      KCF_SUCCESS on success
199  *      KCF_MECH_TAB_FULL otherwise.
200  */
201 int
202 kcf_add_mech_provider(short mech_indx,
203     kcf_provider_desc_t *prov_desc, kcf_prov_mech_desc_t **pmdpp)
204 {
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;
210 
211 	mech_info = &prov_desc->pd_mechanisms[mech_indx];
212 
213 	/*
214 	 * A mechanism belongs to exactly one mechanism table.
215 	 * Find the class corresponding to the function group flag of
216 	 * the mechanism.
217 	 */
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;
222 
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();
233 
234 		/*
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.
238 		 */
239 		if ((error = kcf_create_mech_entry(class,
240 		    mech_info->cm_mech_name)) != KCF_SUCCESS) {
241 			return (error);
242 		}
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);
246 	}
247 
248 	error = kcf_get_mech_entry(kcf_mech_type, &mech_entry);
249 	ASSERT(error == KCF_SUCCESS);
250 
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;
258 
259 	KCF_PROV_REFHOLD(prov_desc);
260 	KCF_PROV_IREFHOLD(prov_desc);
261 
262 	/*
263 	 * Add new kcf_prov_mech_desc at the front of HW providers
264 	 * chain.
265 	 */
266 	if (mech_entry->me_sw_prov != NULL) {
267 		/*
268 		 * There is already a provider for this mechanism.
269 		 * Since we allow only one provider per mechanism,
270 		 * report this condition.
271 		 */
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 {
283 		/*
284 		 * Set the provider as the provider for
285 		 * this mechanism.
286 		 */
287 		mech_entry->me_sw_prov = prov_mech;
288 	}
289 
290 	*pmdpp = prov_mech;
291 
292 	return (KCF_SUCCESS);
293 }
294 
295 /*
296  * kcf_remove_mech_provider()
297  *
298  * Arguments:
299  *      . mech_name: the name of the mechanism.
300  *      . prov_desc: The provider descriptor
301  *
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.
306  *
307  * Context:
308  *      User context only.
309  */
310 void
311 kcf_remove_mech_provider(const char *mech_name, kcf_provider_desc_t *prov_desc)
312 {
313 	crypto_mech_type_t mech_type;
314 	kcf_prov_mech_desc_t *prov_mech = NULL;
315 	kcf_mech_entry_t *mech_entry;
316 
317 	/* get the KCF mech type that was assigned to the mechanism */
318 	if ((mech_type = crypto_mech2id(mech_name)) ==
319 	    CRYPTO_MECH_INVALID) {
320 		/*
321 		 * Provider was not allowed for this mech due to policy or
322 		 * configuration.
323 		 */
324 		return;
325 	}
326 
327 	/* get a ptr to the mech_entry that was created */
328 	if (kcf_get_mech_entry(mech_type, &mech_entry) != KCF_SUCCESS) {
329 		/*
330 		 * Provider was not allowed for this mech due to policy or
331 		 * configuration.
332 		 */
333 		return;
334 	}
335 
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;
340 	}
341 	prov_mech = mech_entry->me_sw_prov;
342 	mech_entry->me_sw_prov = NULL;
343 
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));
348 }
349 
350 /*
351  * kcf_get_mech_entry()
352  *
353  * Arguments:
354  *      . The framework mechanism type
355  *      . Storage for the mechanism entry
356  *
357  * Description:
358  *      Retrieves the mechanism entry for the mech.
359  *
360  * Context:
361  *      User and interrupt contexts.
362  *
363  * Returns:
364  *      KCF_MECHANISM_XXX appropriate error code.
365  *      KCF_SUCCESS otherwise.
366  */
367 int
368 kcf_get_mech_entry(crypto_mech_type_t mech_type, kcf_mech_entry_t **mep)
369 {
370 	kcf_ops_class_t		class;
371 	int			index;
372 	const kcf_mech_entry_tab_t	*me_tab;
373 
374 	ASSERT(mep != NULL);
375 
376 	class = KCF_MECH2CLASS(mech_type);
377 
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);
381 	}
382 
383 	me_tab = &kcf_mech_tabs_tab[class];
384 	index = KCF_MECH2INDEX(mech_type);
385 
386 	if ((index < 0) || (index >= me_tab->met_size)) {
387 		return (KCF_INVALID_MECH_NUMBER);
388 	}
389 
390 	*mep = &((me_tab->met_tab)[index]);
391 
392 	return (KCF_SUCCESS);
393 }
394 
395 /*
396  * crypto_mech2id()
397  *
398  * Arguments:
399  *	. mechname: A null-terminated string identifying the mechanism name.
400  *
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.
405  *
406  * Context:
407  *	Process and interruption.
408  *
409  * Returns:
410  *	The unique mechanism identified by 'mechname', if found.
411  *	CRYPTO_MECH_INVALID otherwise.
412  */
413 /*
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.
418  */
419 crypto_mech_type_t
420 crypto_mech2id(const char *mechname)
421 {
422 	kcf_mech_entry_t tmptab, *found;
423 	strlcpy(tmptab.me_name, mechname, CRYPTO_MAX_MECH_NAME);
424 
425 	if ((found = avl_find(&kcf_mech_hash, &tmptab, NULL))) {
426 		ASSERT(found->me_mechid != CRYPTO_MECH_INVALID);
427 		return (found->me_mechid);
428 	}
429 
430 	return (CRYPTO_MECH_INVALID);
431 }
432 
433 #if defined(_KERNEL)
434 EXPORT_SYMBOL(crypto_mech2id);
435 #endif
436