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 http://www.opensolaris.org/os/licensing.
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 #include <sys/modhash.h>
31 
32 /* Cryptographic mechanisms tables and their access functions */
33 
34 /*
35  * Internal numbers assigned to mechanisms are coded as follows:
36  *
37  * +----------------+----------------+
38  * | mech. class    | mech. index    |
39  * <--- 32-bits --->+<--- 32-bits --->
40  *
41  * the mech_class identifies the table the mechanism belongs to.
42  * mech_index  is the index for that mechanism in the table.
43  * A mechanism belongs to exactly 1 table.
44  * The tables are:
45  * . digest_mechs_tab[] for the msg digest mechs.
46  * . cipher_mechs_tab[] for encrypt/decrypt and wrap/unwrap mechs.
47  * . mac_mechs_tab[] for MAC mechs.
48  * . sign_mechs_tab[] for sign & verify mechs.
49  * . keyops_mechs_tab[] for key/key pair generation, and key derivation.
50  * . misc_mechs_tab[] for mechs that don't belong to any of the above.
51  *
52  * There are no holes in the tables.
53  */
54 
55 /*
56  * Locking conventions:
57  * --------------------
58  * A global mutex, kcf_mech_tabs_lock, serializes writes to the
59  * mechanism table via kcf_create_mech_entry().
60  *
61  * A mutex is associated with every entry of the tables.
62  * The mutex is acquired whenever the entry is accessed for
63  * 1) retrieving the mech_id (comparing the mech name)
64  * 2) finding a provider for an xxx_init() or atomic operation.
65  * 3) altering the mechs entry to add or remove a provider.
66  *
67  * In 2), after a provider is chosen, its prov_desc is held and the
68  * entry's mutex must be dropped. The provider's working function (SPI) is
69  * called outside the mech_entry's mutex.
70  *
71  * The number of providers for a particular mechanism is not expected to be
72  * long enough to justify the cost of using rwlocks, so the per-mechanism
73  * entry mutex won't be very *hot*.
74  *
75  * When both kcf_mech_tabs_lock and a mech_entry mutex need to be held,
76  * kcf_mech_tabs_lock must always be acquired first.
77  *
78  */
79 
80 		/* Mechanisms tables */
81 
82 
83 /* RFE 4687834 Will deal with the extensibility of these tables later */
84 
85 kcf_mech_entry_t kcf_digest_mechs_tab[KCF_MAXDIGEST];
86 kcf_mech_entry_t kcf_cipher_mechs_tab[KCF_MAXCIPHER];
87 kcf_mech_entry_t kcf_mac_mechs_tab[KCF_MAXMAC];
88 kcf_mech_entry_t kcf_sign_mechs_tab[KCF_MAXSIGN];
89 kcf_mech_entry_t kcf_keyops_mechs_tab[KCF_MAXKEYOPS];
90 kcf_mech_entry_t kcf_misc_mechs_tab[KCF_MAXMISC];
91 
92 kcf_mech_entry_tab_t kcf_mech_tabs_tab[KCF_LAST_OPSCLASS + 1] = {
93 	{0, NULL},				/* No class zero */
94 	{KCF_MAXDIGEST, kcf_digest_mechs_tab},
95 	{KCF_MAXCIPHER, kcf_cipher_mechs_tab},
96 	{KCF_MAXMAC, kcf_mac_mechs_tab},
97 	{KCF_MAXSIGN, kcf_sign_mechs_tab},
98 	{KCF_MAXKEYOPS, kcf_keyops_mechs_tab},
99 	{KCF_MAXMISC, kcf_misc_mechs_tab}
100 };
101 
102 /*
103  * Per-algorithm internal thresholds for the minimum input size of before
104  * offloading to hardware provider.
105  * Dispatching a crypto operation  to a hardware provider entails paying the
106  * cost of an additional context switch.  Measurements with Sun Accelerator 4000
107  * shows that 512-byte jobs or smaller are better handled in software.
108  * There is room for refinement here.
109  *
110  */
111 int kcf_md5_threshold = 512;
112 int kcf_sha1_threshold = 512;
113 int kcf_des_threshold = 512;
114 int kcf_des3_threshold = 512;
115 int kcf_aes_threshold = 512;
116 int kcf_bf_threshold = 512;
117 int kcf_rc4_threshold = 512;
118 
119 kmutex_t kcf_mech_tabs_lock;
120 static uint32_t kcf_gen_swprov = 0;
121 
122 int kcf_mech_hash_size = 256;
123 mod_hash_t *kcf_mech_hash;	/* mech name to id hash */
124 
125 static crypto_mech_type_t
126 kcf_mech_hash_find(char *mechname)
127 {
128 	mod_hash_val_t hv;
129 	crypto_mech_type_t mt;
130 
131 	mt = CRYPTO_MECH_INVALID;
132 	if (mod_hash_find(kcf_mech_hash, (mod_hash_key_t)mechname, &hv) == 0) {
133 		mt = *(crypto_mech_type_t *)hv;
134 		ASSERT(mt != CRYPTO_MECH_INVALID);
135 	}
136 
137 	return (mt);
138 }
139 
140 void
141 kcf_destroy_mech_tabs(void)
142 {
143 	int i, max;
144 	kcf_ops_class_t class;
145 	kcf_mech_entry_t *me_tab;
146 
147 	if (kcf_mech_hash)
148 		mod_hash_destroy_hash(kcf_mech_hash);
149 
150 	mutex_destroy(&kcf_mech_tabs_lock);
151 
152 	for (class = KCF_FIRST_OPSCLASS; class <= KCF_LAST_OPSCLASS; class++) {
153 		max = kcf_mech_tabs_tab[class].met_size;
154 		me_tab = kcf_mech_tabs_tab[class].met_tab;
155 		for (i = 0; i < max; i++)
156 			mutex_destroy(&(me_tab[i].me_mutex));
157 	}
158 }
159 
160 /*
161  * kcf_init_mech_tabs()
162  *
163  * Called by the misc/kcf's _init() routine to initialize the tables
164  * of mech_entry's.
165  */
166 void
167 kcf_init_mech_tabs(void)
168 {
169 	int i, max;
170 	kcf_ops_class_t class;
171 	kcf_mech_entry_t *me_tab;
172 
173 	/* Initializes the mutex locks. */
174 
175 	mutex_init(&kcf_mech_tabs_lock, NULL, MUTEX_DEFAULT, NULL);
176 
177 	/* Then the pre-defined mechanism entries */
178 
179 	/* Two digests */
180 	(void) strncpy(kcf_digest_mechs_tab[0].me_name, SUN_CKM_MD5,
181 	    CRYPTO_MAX_MECH_NAME);
182 	kcf_digest_mechs_tab[0].me_threshold = kcf_md5_threshold;
183 
184 	(void) strncpy(kcf_digest_mechs_tab[1].me_name, SUN_CKM_SHA1,
185 	    CRYPTO_MAX_MECH_NAME);
186 	kcf_digest_mechs_tab[1].me_threshold = kcf_sha1_threshold;
187 
188 	/* The symmetric ciphers in various modes */
189 	(void) strncpy(kcf_cipher_mechs_tab[0].me_name, SUN_CKM_DES_CBC,
190 	    CRYPTO_MAX_MECH_NAME);
191 	kcf_cipher_mechs_tab[0].me_threshold = kcf_des_threshold;
192 
193 	(void) strncpy(kcf_cipher_mechs_tab[1].me_name, SUN_CKM_DES3_CBC,
194 	    CRYPTO_MAX_MECH_NAME);
195 	kcf_cipher_mechs_tab[1].me_threshold = kcf_des3_threshold;
196 
197 	(void) strncpy(kcf_cipher_mechs_tab[2].me_name, SUN_CKM_DES_ECB,
198 	    CRYPTO_MAX_MECH_NAME);
199 	kcf_cipher_mechs_tab[2].me_threshold = kcf_des_threshold;
200 
201 	(void) strncpy(kcf_cipher_mechs_tab[3].me_name, SUN_CKM_DES3_ECB,
202 	    CRYPTO_MAX_MECH_NAME);
203 	kcf_cipher_mechs_tab[3].me_threshold = kcf_des3_threshold;
204 
205 	(void) strncpy(kcf_cipher_mechs_tab[4].me_name, SUN_CKM_BLOWFISH_CBC,
206 	    CRYPTO_MAX_MECH_NAME);
207 	kcf_cipher_mechs_tab[4].me_threshold = kcf_bf_threshold;
208 
209 	(void) strncpy(kcf_cipher_mechs_tab[5].me_name, SUN_CKM_BLOWFISH_ECB,
210 	    CRYPTO_MAX_MECH_NAME);
211 	kcf_cipher_mechs_tab[5].me_threshold = kcf_bf_threshold;
212 
213 	(void) strncpy(kcf_cipher_mechs_tab[6].me_name, SUN_CKM_AES_CBC,
214 	    CRYPTO_MAX_MECH_NAME);
215 	kcf_cipher_mechs_tab[6].me_threshold = kcf_aes_threshold;
216 
217 	(void) strncpy(kcf_cipher_mechs_tab[7].me_name, SUN_CKM_AES_ECB,
218 	    CRYPTO_MAX_MECH_NAME);
219 	kcf_cipher_mechs_tab[7].me_threshold = kcf_aes_threshold;
220 
221 	(void) strncpy(kcf_cipher_mechs_tab[8].me_name, SUN_CKM_RC4,
222 	    CRYPTO_MAX_MECH_NAME);
223 	kcf_cipher_mechs_tab[8].me_threshold = kcf_rc4_threshold;
224 
225 
226 	/* 4 HMACs */
227 	(void) strncpy(kcf_mac_mechs_tab[0].me_name, SUN_CKM_MD5_HMAC,
228 	    CRYPTO_MAX_MECH_NAME);
229 	kcf_mac_mechs_tab[0].me_threshold = kcf_md5_threshold;
230 
231 	(void) strncpy(kcf_mac_mechs_tab[1].me_name, SUN_CKM_MD5_HMAC_GENERAL,
232 	    CRYPTO_MAX_MECH_NAME);
233 	kcf_mac_mechs_tab[1].me_threshold = kcf_md5_threshold;
234 
235 	(void) strncpy(kcf_mac_mechs_tab[2].me_name, SUN_CKM_SHA1_HMAC,
236 	    CRYPTO_MAX_MECH_NAME);
237 	kcf_mac_mechs_tab[2].me_threshold = kcf_sha1_threshold;
238 
239 	(void) strncpy(kcf_mac_mechs_tab[3].me_name, SUN_CKM_SHA1_HMAC_GENERAL,
240 	    CRYPTO_MAX_MECH_NAME);
241 	kcf_mac_mechs_tab[3].me_threshold = kcf_sha1_threshold;
242 
243 
244 	/* 1 random number generation pseudo mechanism */
245 	(void) strncpy(kcf_misc_mechs_tab[0].me_name, SUN_RANDOM,
246 	    CRYPTO_MAX_MECH_NAME);
247 
248 	kcf_mech_hash = mod_hash_create_strhash_nodtr("kcf mech2id hash",
249 	    kcf_mech_hash_size, mod_hash_null_valdtor);
250 
251 	for (class = KCF_FIRST_OPSCLASS; class <= KCF_LAST_OPSCLASS; class++) {
252 		max = kcf_mech_tabs_tab[class].met_size;
253 		me_tab = kcf_mech_tabs_tab[class].met_tab;
254 		for (i = 0; i < max; i++) {
255 			mutex_init(&(me_tab[i].me_mutex), NULL,
256 			    MUTEX_DEFAULT, NULL);
257 			if (me_tab[i].me_name[0] != 0) {
258 				me_tab[i].me_mechid = KCF_MECHID(class, i);
259 				(void) mod_hash_insert(kcf_mech_hash,
260 				    (mod_hash_key_t)me_tab[i].me_name,
261 				    (mod_hash_val_t)&(me_tab[i].me_mechid));
262 			}
263 		}
264 	}
265 }
266 
267 /*
268  * kcf_create_mech_entry()
269  *
270  * Arguments:
271  *	. The class of mechanism.
272  *	. the name of the new mechanism.
273  *
274  * Description:
275  *	Creates a new mech_entry for a mechanism not yet known to the
276  *	framework.
277  *	This routine is called by kcf_add_mech_provider, which is
278  *	in turn invoked for each mechanism supported by a provider.
279  *	The'class' argument depends on the crypto_func_group_t bitmask
280  *	in the registering provider's mech_info struct for this mechanism.
281  *	When there is ambiguity in the mapping between the crypto_func_group_t
282  *	and a class (dual ops, ...) the KCF_MISC_CLASS should be used.
283  *
284  * Context:
285  *	User context only.
286  *
287  * Returns:
288  *	KCF_INVALID_MECH_CLASS or KCF_INVALID_MECH_NAME if the class or
289  *	the mechname is bogus.
290  *	KCF_MECH_TAB_FULL when there is no room left in the mech. tabs.
291  *	KCF_SUCCESS otherwise.
292  */
293 static int
294 kcf_create_mech_entry(kcf_ops_class_t class, char *mechname)
295 {
296 	crypto_mech_type_t mt;
297 	kcf_mech_entry_t *me_tab;
298 	int i = 0, size;
299 
300 	if ((class < KCF_FIRST_OPSCLASS) || (class > KCF_LAST_OPSCLASS))
301 		return (KCF_INVALID_MECH_CLASS);
302 
303 	if ((mechname == NULL) || (mechname[0] == 0))
304 		return (KCF_INVALID_MECH_NAME);
305 	/*
306 	 * First check if the mechanism is already in one of the tables.
307 	 * The mech_entry could be in another class.
308 	 */
309 	mutex_enter(&kcf_mech_tabs_lock);
310 	mt = kcf_mech_hash_find(mechname);
311 	if (mt != CRYPTO_MECH_INVALID) {
312 		/* Nothing to do, regardless the suggested class. */
313 		mutex_exit(&kcf_mech_tabs_lock);
314 		return (KCF_SUCCESS);
315 	}
316 	/* Now take the next unused mech entry in the class's tab */
317 	me_tab = kcf_mech_tabs_tab[class].met_tab;
318 	size = kcf_mech_tabs_tab[class].met_size;
319 
320 	while (i < size) {
321 		mutex_enter(&(me_tab[i].me_mutex));
322 		if (me_tab[i].me_name[0] == 0) {
323 			/* Found an empty spot */
324 			(void) strlcpy(me_tab[i].me_name, mechname,
325 			    CRYPTO_MAX_MECH_NAME);
326 			me_tab[i].me_name[CRYPTO_MAX_MECH_NAME-1] = '\0';
327 			me_tab[i].me_mechid = KCF_MECHID(class, i);
328 			/*
329 			 * No a-priori information about the new mechanism, so
330 			 * the threshold is set to zero.
331 			 */
332 			me_tab[i].me_threshold = 0;
333 
334 			mutex_exit(&(me_tab[i].me_mutex));
335 			/* Add the new mechanism to the hash table */
336 			(void) mod_hash_insert(kcf_mech_hash,
337 			    (mod_hash_key_t)me_tab[i].me_name,
338 			    (mod_hash_val_t)&(me_tab[i].me_mechid));
339 			break;
340 		}
341 		mutex_exit(&(me_tab[i].me_mutex));
342 		i++;
343 	}
344 
345 	mutex_exit(&kcf_mech_tabs_lock);
346 
347 	if (i == size) {
348 		return (KCF_MECH_TAB_FULL);
349 	}
350 
351 	return (KCF_SUCCESS);
352 }
353 
354 /*
355  * kcf_add_mech_provider()
356  *
357  * Arguments:
358  *	. An index in to  the provider mechanism array
359  *      . A pointer to the provider descriptor
360  *	. A storage for the kcf_prov_mech_desc_t the entry was added at.
361  *
362  * Description:
363  *      Adds  a new provider of a mechanism to the mechanism's mech_entry
364  *	chain.
365  *
366  * Context:
367  *      User context only.
368  *
369  * Returns
370  *      KCF_SUCCESS on success
371  *      KCF_MECH_TAB_FULL otherwise.
372  */
373 int
374 kcf_add_mech_provider(short mech_indx,
375     kcf_provider_desc_t *prov_desc, kcf_prov_mech_desc_t **pmdpp)
376 {
377 	int error;
378 	kcf_mech_entry_t *mech_entry = NULL;
379 	crypto_mech_info_t *mech_info;
380 	crypto_mech_type_t kcf_mech_type, mt;
381 	kcf_prov_mech_desc_t *prov_mech, *prov_mech2;
382 	crypto_func_group_t simple_fg_mask, dual_fg_mask;
383 	crypto_mech_info_t *dmi;
384 	crypto_mech_info_list_t *mil, *mil2;
385 	kcf_mech_entry_t *me;
386 	int i;
387 
388 	ASSERT(prov_desc->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
389 
390 	mech_info = &prov_desc->pd_mechanisms[mech_indx];
391 
392 	/*
393 	 * A mechanism belongs to exactly one mechanism table.
394 	 * Find the class corresponding to the function group flag of
395 	 * the mechanism.
396 	 */
397 	kcf_mech_type = kcf_mech_hash_find(mech_info->cm_mech_name);
398 	if (kcf_mech_type == CRYPTO_MECH_INVALID) {
399 		crypto_func_group_t fg = mech_info->cm_func_group_mask;
400 		kcf_ops_class_t class;
401 
402 		if (fg & CRYPTO_FG_DIGEST || fg & CRYPTO_FG_DIGEST_ATOMIC)
403 			class = KCF_DIGEST_CLASS;
404 		else if (fg & CRYPTO_FG_ENCRYPT || fg & CRYPTO_FG_DECRYPT ||
405 		    fg & CRYPTO_FG_ENCRYPT_ATOMIC ||
406 		    fg & CRYPTO_FG_DECRYPT_ATOMIC)
407 			class = KCF_CIPHER_CLASS;
408 		else if (fg & CRYPTO_FG_MAC || fg & CRYPTO_FG_MAC_ATOMIC)
409 			class = KCF_MAC_CLASS;
410 		else if (fg & CRYPTO_FG_SIGN || fg & CRYPTO_FG_VERIFY ||
411 		    fg & CRYPTO_FG_SIGN_ATOMIC ||
412 		    fg & CRYPTO_FG_VERIFY_ATOMIC ||
413 		    fg & CRYPTO_FG_SIGN_RECOVER ||
414 		    fg & CRYPTO_FG_VERIFY_RECOVER)
415 			class = KCF_SIGN_CLASS;
416 		else if (fg & CRYPTO_FG_GENERATE ||
417 		    fg & CRYPTO_FG_GENERATE_KEY_PAIR ||
418 		    fg & CRYPTO_FG_WRAP || fg & CRYPTO_FG_UNWRAP ||
419 		    fg & CRYPTO_FG_DERIVE)
420 			class = KCF_KEYOPS_CLASS;
421 		else
422 			class = KCF_MISC_CLASS;
423 
424 		/*
425 		 * Attempt to create a new mech_entry for the specified
426 		 * mechanism. kcf_create_mech_entry() can handle the case
427 		 * where such an entry already exists.
428 		 */
429 		if ((error = kcf_create_mech_entry(class,
430 		    mech_info->cm_mech_name)) != KCF_SUCCESS) {
431 			return (error);
432 		}
433 		/* get the KCF mech type that was assigned to the mechanism */
434 		kcf_mech_type = kcf_mech_hash_find(mech_info->cm_mech_name);
435 		ASSERT(kcf_mech_type != CRYPTO_MECH_INVALID);
436 	}
437 
438 	error = kcf_get_mech_entry(kcf_mech_type, &mech_entry);
439 	ASSERT(error == KCF_SUCCESS);
440 
441 	/* allocate and initialize new kcf_prov_mech_desc */
442 	prov_mech = kmem_zalloc(sizeof (kcf_prov_mech_desc_t), KM_SLEEP);
443 	bcopy(mech_info, &prov_mech->pm_mech_info, sizeof (crypto_mech_info_t));
444 	prov_mech->pm_prov_desc = prov_desc;
445 	prov_desc->pd_mech_indx[KCF_MECH2CLASS(kcf_mech_type)]
446 	    [KCF_MECH2INDEX(kcf_mech_type)] = mech_indx;
447 
448 	KCF_PROV_REFHOLD(prov_desc);
449 	KCF_PROV_IREFHOLD(prov_desc);
450 
451 	dual_fg_mask = mech_info->cm_func_group_mask & CRYPTO_FG_DUAL_MASK;
452 
453 	if (dual_fg_mask == ((crypto_func_group_t)0))
454 		goto add_entry;
455 
456 	simple_fg_mask = (mech_info->cm_func_group_mask &
457 	    CRYPTO_FG_SIMPLEOP_MASK) | CRYPTO_FG_RANDOM;
458 
459 	for (i = 0; i < prov_desc->pd_mech_list_count; i++) {
460 		dmi = &prov_desc->pd_mechanisms[i];
461 
462 		/* skip self */
463 		if (dmi->cm_mech_number == mech_info->cm_mech_number)
464 			continue;
465 
466 		/* skip if not a dual operation mechanism */
467 		if (!(dmi->cm_func_group_mask & dual_fg_mask) ||
468 		    (dmi->cm_func_group_mask & simple_fg_mask))
469 			continue;
470 
471 		mt = kcf_mech_hash_find(dmi->cm_mech_name);
472 		if (mt == CRYPTO_MECH_INVALID)
473 			continue;
474 
475 		if (kcf_get_mech_entry(mt, &me) != KCF_SUCCESS)
476 			continue;
477 
478 		mil = kmem_zalloc(sizeof (*mil), KM_SLEEP);
479 		mil2 = kmem_zalloc(sizeof (*mil2), KM_SLEEP);
480 
481 		/*
482 		 * Ignore hard-coded entries in the mech table
483 		 * if the provider hasn't registered.
484 		 */
485 		mutex_enter(&me->me_mutex);
486 		if (me->me_hw_prov_chain == NULL && me->me_sw_prov == NULL) {
487 			mutex_exit(&me->me_mutex);
488 			kmem_free(mil, sizeof (*mil));
489 			kmem_free(mil2, sizeof (*mil2));
490 			continue;
491 		}
492 
493 		/*
494 		 * Add other dual mechanisms that have registered
495 		 * with the framework to this mechanism's
496 		 * cross-reference list.
497 		 */
498 		mil->ml_mech_info = *dmi; /* struct assignment */
499 		mil->ml_kcf_mechid = mt;
500 
501 		/* add to head of list */
502 		mil->ml_next = prov_mech->pm_mi_list;
503 		prov_mech->pm_mi_list = mil;
504 
505 		if (prov_desc->pd_prov_type == CRYPTO_HW_PROVIDER)
506 			prov_mech2 = me->me_hw_prov_chain;
507 		else
508 			prov_mech2 = me->me_sw_prov;
509 
510 		if (prov_mech2 == NULL) {
511 			kmem_free(mil2, sizeof (*mil2));
512 			mutex_exit(&me->me_mutex);
513 			continue;
514 		}
515 
516 		/*
517 		 * Update all other cross-reference lists by
518 		 * adding this new mechanism.
519 		 */
520 		while (prov_mech2 != NULL) {
521 			if (prov_mech2->pm_prov_desc == prov_desc) {
522 				/* struct assignment */
523 				mil2->ml_mech_info = *mech_info;
524 				mil2->ml_kcf_mechid = kcf_mech_type;
525 
526 				/* add to head of list */
527 				mil2->ml_next = prov_mech2->pm_mi_list;
528 				prov_mech2->pm_mi_list = mil2;
529 				break;
530 			}
531 			prov_mech2 = prov_mech2->pm_next;
532 		}
533 		if (prov_mech2 == NULL)
534 			kmem_free(mil2, sizeof (*mil2));
535 
536 		mutex_exit(&me->me_mutex);
537 	}
538 
539 add_entry:
540 	/*
541 	 * Add new kcf_prov_mech_desc at the front of HW providers
542 	 * chain.
543 	 */
544 	switch (prov_desc->pd_prov_type) {
545 
546 	case CRYPTO_HW_PROVIDER:
547 		mutex_enter(&mech_entry->me_mutex);
548 		prov_mech->pm_me = mech_entry;
549 		prov_mech->pm_next = mech_entry->me_hw_prov_chain;
550 		mech_entry->me_hw_prov_chain = prov_mech;
551 		mech_entry->me_num_hwprov++;
552 		mutex_exit(&mech_entry->me_mutex);
553 		break;
554 
555 	case CRYPTO_SW_PROVIDER:
556 		mutex_enter(&mech_entry->me_mutex);
557 		if (mech_entry->me_sw_prov != NULL) {
558 			/*
559 			 * There is already a SW provider for this mechanism.
560 			 * Since we allow only one SW provider per mechanism,
561 			 * report this condition.
562 			 */
563 			cmn_err(CE_WARN, "The cryptographic software provider "
564 			    "\"%s\" will not be used for %s. The provider "
565 			    "\"%s\" will be used for this mechanism "
566 			    "instead.", prov_desc->pd_description,
567 			    mech_info->cm_mech_name,
568 			    mech_entry->me_sw_prov->pm_prov_desc->
569 			    pd_description);
570 			KCF_PROV_REFRELE(prov_desc);
571 			kmem_free(prov_mech, sizeof (kcf_prov_mech_desc_t));
572 			prov_mech = NULL;
573 		} else {
574 			/*
575 			 * Set the provider as the software provider for
576 			 * this mechanism.
577 			 */
578 			mech_entry->me_sw_prov = prov_mech;
579 
580 			/* We'll wrap around after 4 billion registrations! */
581 			mech_entry->me_gen_swprov = kcf_gen_swprov++;
582 		}
583 		mutex_exit(&mech_entry->me_mutex);
584 		break;
585 	default:
586 		break;
587 	}
588 
589 	*pmdpp = prov_mech;
590 
591 	return (KCF_SUCCESS);
592 }
593 
594 /*
595  * kcf_remove_mech_provider()
596  *
597  * Arguments:
598  *      . mech_name: the name of the mechanism.
599  *      . prov_desc: The provider descriptor
600  *
601  * Description:
602  *      Removes a provider from chain of provider descriptors.
603  *	The provider is made unavailable to kernel consumers for the specified
604  *	mechanism.
605  *
606  * Context:
607  *      User context only.
608  */
609 void
610 kcf_remove_mech_provider(char *mech_name, kcf_provider_desc_t *prov_desc)
611 {
612 	crypto_mech_type_t mech_type;
613 	kcf_prov_mech_desc_t *prov_mech = NULL, *prov_chain;
614 	kcf_prov_mech_desc_t **prev_entry_next;
615 	kcf_mech_entry_t *mech_entry;
616 	crypto_mech_info_list_t *mil, *mil2, *next, **prev_next;
617 
618 	ASSERT(prov_desc->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
619 
620 	/* get the KCF mech type that was assigned to the mechanism */
621 	if ((mech_type = kcf_mech_hash_find(mech_name)) ==
622 	    CRYPTO_MECH_INVALID) {
623 		/*
624 		 * Provider was not allowed for this mech due to policy or
625 		 * configuration.
626 		 */
627 		return;
628 	}
629 
630 	/* get a ptr to the mech_entry that was created */
631 	if (kcf_get_mech_entry(mech_type, &mech_entry) != KCF_SUCCESS) {
632 		/*
633 		 * Provider was not allowed for this mech due to policy or
634 		 * configuration.
635 		 */
636 		return;
637 	}
638 
639 	mutex_enter(&mech_entry->me_mutex);
640 
641 	switch (prov_desc->pd_prov_type) {
642 
643 	case CRYPTO_HW_PROVIDER:
644 		/* find the provider in the mech_entry chain */
645 		prev_entry_next = &mech_entry->me_hw_prov_chain;
646 		prov_mech = mech_entry->me_hw_prov_chain;
647 		while (prov_mech != NULL &&
648 		    prov_mech->pm_prov_desc != prov_desc) {
649 			prev_entry_next = &prov_mech->pm_next;
650 			prov_mech = prov_mech->pm_next;
651 		}
652 
653 		if (prov_mech == NULL) {
654 			/* entry not found, simply return */
655 			mutex_exit(&mech_entry->me_mutex);
656 			return;
657 		}
658 
659 		/* remove provider entry from mech_entry chain */
660 		*prev_entry_next = prov_mech->pm_next;
661 		ASSERT(mech_entry->me_num_hwprov > 0);
662 		mech_entry->me_num_hwprov--;
663 		break;
664 
665 	case CRYPTO_SW_PROVIDER:
666 		if (mech_entry->me_sw_prov == NULL ||
667 		    mech_entry->me_sw_prov->pm_prov_desc != prov_desc) {
668 			/* not the software provider for this mechanism */
669 			mutex_exit(&mech_entry->me_mutex);
670 			return;
671 		}
672 		prov_mech = mech_entry->me_sw_prov;
673 		mech_entry->me_sw_prov = NULL;
674 		break;
675 	default:
676 		/* unexpected crypto_provider_type_t */
677 		mutex_exit(&mech_entry->me_mutex);
678 		return;
679 	}
680 
681 	mutex_exit(&mech_entry->me_mutex);
682 
683 	/* Free the dual ops cross-reference lists  */
684 	mil = prov_mech->pm_mi_list;
685 	while (mil != NULL) {
686 		next = mil->ml_next;
687 		if (kcf_get_mech_entry(mil->ml_kcf_mechid,
688 		    &mech_entry) != KCF_SUCCESS) {
689 			mil = next;
690 			continue;
691 		}
692 
693 		mutex_enter(&mech_entry->me_mutex);
694 		if (prov_desc->pd_prov_type == CRYPTO_HW_PROVIDER)
695 			prov_chain = mech_entry->me_hw_prov_chain;
696 		else
697 			prov_chain = mech_entry->me_sw_prov;
698 
699 		while (prov_chain != NULL) {
700 			if (prov_chain->pm_prov_desc == prov_desc) {
701 				prev_next = &prov_chain->pm_mi_list;
702 				mil2 = prov_chain->pm_mi_list;
703 				while (mil2 != NULL &&
704 				    mil2->ml_kcf_mechid != mech_type) {
705 					prev_next = &mil2->ml_next;
706 					mil2 = mil2->ml_next;
707 				}
708 				if (mil2 != NULL) {
709 					*prev_next = mil2->ml_next;
710 					kmem_free(mil2, sizeof (*mil2));
711 				}
712 				break;
713 			}
714 			prov_chain = prov_chain->pm_next;
715 		}
716 
717 		mutex_exit(&mech_entry->me_mutex);
718 		kmem_free(mil, sizeof (crypto_mech_info_list_t));
719 		mil = next;
720 	}
721 
722 	/* free entry  */
723 	KCF_PROV_REFRELE(prov_mech->pm_prov_desc);
724 	KCF_PROV_IREFRELE(prov_mech->pm_prov_desc);
725 	kmem_free(prov_mech, sizeof (kcf_prov_mech_desc_t));
726 }
727 
728 /*
729  * kcf_get_mech_entry()
730  *
731  * Arguments:
732  *      . The framework mechanism type
733  *      . Storage for the mechanism entry
734  *
735  * Description:
736  *      Retrieves the mechanism entry for the mech.
737  *
738  * Context:
739  *      User and interrupt contexts.
740  *
741  * Returns:
742  *      KCF_MECHANISM_XXX appropriate error code.
743  *      KCF_SUCCESS otherwise.
744  */
745 int
746 kcf_get_mech_entry(crypto_mech_type_t mech_type, kcf_mech_entry_t **mep)
747 {
748 	kcf_ops_class_t		class;
749 	int			index;
750 	kcf_mech_entry_tab_t	*me_tab;
751 
752 	ASSERT(mep != NULL);
753 
754 	class = KCF_MECH2CLASS(mech_type);
755 
756 	if ((class < KCF_FIRST_OPSCLASS) || (class > KCF_LAST_OPSCLASS)) {
757 		/* the caller won't need to know it's an invalid class */
758 		return (KCF_INVALID_MECH_NUMBER);
759 	}
760 
761 	me_tab = &kcf_mech_tabs_tab[class];
762 	index = KCF_MECH2INDEX(mech_type);
763 
764 	if ((index < 0) || (index >= me_tab->met_size)) {
765 		return (KCF_INVALID_MECH_NUMBER);
766 	}
767 
768 	*mep = &((me_tab->met_tab)[index]);
769 
770 	return (KCF_SUCCESS);
771 }
772 
773 /* CURRENTLY UNSUPPORTED: attempting to load the module if it isn't found */
774 /*
775  * Lookup the hash table for an entry that matches the mechname.
776  * If there are no hardware or software providers for the mechanism,
777  * but there is an unloaded software provider, this routine will attempt
778  * to load it.
779  *
780  * If the MOD_NOAUTOUNLOAD flag is not set, a software provider is
781  * in constant danger of being unloaded.  For consumers that call
782  * crypto_mech2id() only once, the provider will not be reloaded
783  * if it becomes unloaded.  If a provider gets loaded elsewhere
784  * without the MOD_NOAUTOUNLOAD flag being set, we set it now.
785  */
786 crypto_mech_type_t
787 crypto_mech2id_common(char *mechname, boolean_t load_module)
788 {
789 	crypto_mech_type_t mt = kcf_mech_hash_find(mechname);
790 	return (mt);
791 }
792