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