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