xref: /illumos-gate/usr/src/uts/common/crypto/core/kcf_cryptoadm.c (revision 56f33205c9ed776c3c909e07d52e94610a675740)
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 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * Core KCF (Kernel Cryptographic Framework). This file implements
28  * the cryptoadm entry points.
29  */
30 
31 #include <sys/systm.h>
32 #include <sys/errno.h>
33 #include <sys/cmn_err.h>
34 #include <sys/rwlock.h>
35 #include <sys/kmem.h>
36 #include <sys/modctl.h>
37 #include <sys/sunddi.h>
38 #include <sys/door.h>
39 #include <sys/crypto/common.h>
40 #include <sys/crypto/api.h>
41 #include <sys/crypto/spi.h>
42 #include <sys/crypto/impl.h>
43 #include <sys/crypto/sched_impl.h>
44 
45 /* protects the the soft_config_list. */
46 kmutex_t soft_config_mutex;
47 
48 /*
49  * This linked list contains software configuration entries.
50  * The initial list is just software providers loaded by kcf_soft_config_init().
51  * Additional entries may appear for both hardware and software providers
52  * from kcf.conf.  These come from "cryptoadm start", which reads file kcf.conf
53  * and updates this table using the CRYPTO_LOAD_SOFT_CONFIG ioctl.
54  * Further cryptoadm commands modify this file and update this table with ioctl.
55  * This list is protected by the soft_config_mutex.
56  */
57 kcf_soft_conf_entry_t *soft_config_list;
58 
59 static int add_soft_config(char *, uint_t, crypto_mech_name_t *);
60 static int dup_mech_names(kcf_provider_desc_t *, crypto_mech_name_t **,
61     uint_t *, int);
62 static void free_soft_config_entry(kcf_soft_conf_entry_t *);
63 
64 #define	KCF_MAX_CONFIG_ENTRIES 512 /* maximum entries in soft_config_list */
65 
66 #if DEBUG
67 extern int kcf_frmwrk_debug;
68 static void kcf_soft_config_dump(char *message);
69 #endif /* DEBUG */
70 
71 /*
72  * Count and return the number of mechanisms in an array of crypto_mech_name_t
73  * (excluding final NUL-character string element).
74  */
75 static int
76 count_mechanisms(crypto_mech_name_t mechs[]) {
77 	int	count;
78 	for (count = 0; mechs[count][0] != '\0'; ++count);
79 	return (count);
80 }
81 
82 /*
83  * Initialize a mutex and populate soft_config_list with default entries
84  * of kernel software providers.
85  * Called from kcf module _init().
86  */
87 void
88 kcf_soft_config_init(void)
89 {
90 	typedef struct {
91 		char			*name;
92 		crypto_mech_name_t	*mechs;
93 	} initial_soft_config_entry_t;
94 
95 	/*
96 	 * This provides initial default values to soft_config_list.
97 	 * It is equivalent to these lines in /etc/crypto/kcf.conf
98 	 * (without line breaks and indenting):
99 	 *
100 	 * # /etc/crypto/kcf.conf
101 	 * des:supportedlist=CKM_DES_CBC,CKM_DES_ECB,CKM_DES3_CBC,CKM_DES3_ECB
102 	 * aes:supportedlist=CKM_AES_ECB,CKM_AES_CBC,CKM_AES_CTR,CKM_AES_CCM,\
103 	 * CKM_AES_GCM,CKM_AES_GMAC
104 	 * arcfour:supportedlist=CKM_RC4
105 	 * blowfish:supportedlist=CKM_BLOWFISH_ECB,CKM_BLOWFISH_CBC
106 	 * ecc:supportedlist=CKM_EC_KEY_PAIR_GEN,CKM_ECDH1_DERIVE,CKM_ECDSA,\
107 	 * CKM_ECDSA_SHA1
108 	 * sha1:supportedlist=CKM_SHA_1,CKM_SHA_1_HMAC_GENERAL,CKM_SHA_1_HMAC
109 	 * sha2:supportedlist=CKM_SHA256,CKM_SHA256_HMAC,\
110 	 * CKM_SHA256_HMAC_GENERAL,CKM_SHA384,CKM_SHA384_HMAC,\
111 	 * CKM_SHA384_HMAC_GENERAL,CKM_SHA512,CKM_SHA512_HMAC,\
112 	 * CKM_SHA512_HMAC_GENERAL
113 	 * md4:supportedlist=CKM_MD4
114 	 * md5:supportedlist=CKM_MD5,CKM_MD5_HMAC_GENERAL,CKM_MD5_HMAC
115 	 * rsa:supportedlist=CKM_RSA_PKCS,CKM_RSA_X_509,CKM_MD5_RSA_PKCS,\
116 	 * CKM_SHA1_RSA_PKCS,CKM_SHA256_RSA_PKCS,CKM_SHA384_RSA_PKCS,\
117 	 * CKM_SHA512_RSA_PKCS
118 	 * swrand:supportedlist=random
119 	 *
120 	 * WARNING: If you add a new kernel crypto provider or mechanism,
121 	 * you must update these structures.
122 	 *
123 	 * 1. To add a new mechanism to a provider add the string to the
124 	 * appropriate array below and comment above.
125 	 *
126 	 * 2. To add a new provider, create a new *_mechs array listing the
127 	 * provider's mechanism(s) and a new comment line above.
128 	 * Add the new *_mechs array to initial_soft_config_entry[].
129 	 *
130 	 * 3. If appropriate (that is the new mechanism is needed before
131 	 * cryptosvc runs), add to kcf_init_mech_tabs() in kcf_mech_tabs.c.
132 	 */
133 	static crypto_mech_name_t	des_mechs[] = {
134 	    "CKM_DES_CBC", "CKM_DES_ECB", "CKM_DES3_CBC", "CKM_DES3_ECB", ""};
135 	static crypto_mech_name_t	aes_mechs[] = {
136 	    "CKM_AES_ECB", "CKM_AES_CBC", "CKM_AES_CTR", "CKM_AES_CCM",
137 	    "CKM_AES_GCM", "CKM_AES_GMAC", ""};
138 	static crypto_mech_name_t	arcfour_mechs[] = {
139 	    "CKM_RC4", ""};
140 	static crypto_mech_name_t	blowfish_mechs[] = {
141 	    "CKM_BLOWFISH_ECB", "CKM_BLOWFISH_CBC", ""};
142 	static crypto_mech_name_t	ecc_mechs[] = {
143 	    "CKM_EC_KEY_PAIR_GEN", "CKM_ECDH1_DERIVE", "CKM_ECDSA",
144 	    "CKM_ECDSA_SHA1", ""};
145 	static crypto_mech_name_t	sha1_mechs[] = {
146 	    "CKM_SHA_1", "CKM_SHA_1_HMAC_GENERAL", "CKM_SHA_1_HMAC", ""};
147 	static crypto_mech_name_t	sha2_mechs[] = {
148 	    "CKM_SHA256", "CKM_SHA256_HMAC", "CKM_SHA256_HMAC_GENERAL",
149 	    "CKM_SHA384", "CKM_SHA384_HMAC", "CKM_SHA384_HMAC_GENERAL",
150 	    "CKM_SHA512", "CKM_SHA512_HMAC", "CKM_SHA512_HMAC_GENERAL", ""};
151 	static crypto_mech_name_t	md4_mechs[] = {
152 	    "CKM_MD4", ""};
153 	static crypto_mech_name_t	md5_mechs[] = {
154 	    "CKM_MD5", "CKM_MD5_HMAC_GENERAL", "CKM_MD5_HMAC", ""};
155 	static crypto_mech_name_t	rsa_mechs[] = {
156 	    "CKM_RSA_PKCS", "CKM_RSA_X_509", "CKM_MD5_RSA_PKCS",
157 	    "CKM_SHA1_RSA_PKCS", "CKM_SHA256_RSA_PKCS", "CKM_SHA384_RSA_PKCS",
158 	    "CKM_SHA512_RSA_PKCS", ""};
159 	static crypto_mech_name_t	swrand_mechs[] = {
160 	    "random", NULL};
161 	static initial_soft_config_entry_t
162 	    initial_soft_config_entry[] = {
163 		"des", des_mechs,
164 		"aes", aes_mechs,
165 		"arcfour", arcfour_mechs,
166 		"blowfish", blowfish_mechs,
167 		"ecc", ecc_mechs,
168 		"sha1", sha1_mechs,
169 		"sha2", sha2_mechs,
170 		"md4", md4_mechs,
171 		"md5", md5_mechs,
172 		"rsa", rsa_mechs,
173 		"swrand", swrand_mechs
174 	};
175 	const int	initial_soft_config_entries =
176 	    sizeof (initial_soft_config_entry)
177 	    / sizeof (initial_soft_config_entry_t);
178 	int		i;
179 
180 	mutex_init(&soft_config_mutex, NULL, MUTEX_DRIVER, NULL);
181 
182 	/*
183 	 * Initialize soft_config_list with default providers.
184 	 * Populate the linked list backwards so the first entry appears first.
185 	 */
186 	for (i = initial_soft_config_entries - 1; i >= 0; --i) {
187 		initial_soft_config_entry_t *p = &initial_soft_config_entry[i];
188 		crypto_mech_name_t	*mechsp;
189 		uint_t			alloc_size;
190 		int			mech_count, r;
191 
192 		/* allocate/initialize memory for mechanism list */
193 		mech_count = count_mechanisms(p->mechs);
194 		alloc_size = mech_count * CRYPTO_MAX_MECH_NAME;
195 		mechsp = kmem_alloc(alloc_size, KM_SLEEP);
196 		bcopy(p->mechs, mechsp, alloc_size);
197 
198 		r = add_soft_config(p->name, mech_count, mechsp);
199 		if (r != 0)
200 			cmn_err(CE_WARN,
201 			    "add_soft_config(%s) failed; returned %d\n",
202 			    p->name, r);
203 	}
204 #if DEBUG
205 	if (kcf_frmwrk_debug >= 1)
206 		kcf_soft_config_dump("kcf_soft_config_init");
207 #endif /* DEBUG */
208 }
209 
210 
211 #if DEBUG
212 /*
213  * Dump soft_config_list, containing a list of kernel software providers
214  * and (optionally) hardware providers, with updates from kcf.conf.
215  * Dump mechanism lists too if kcf_frmwrk_debug is >= 2.
216  */
217 static void
218 kcf_soft_config_dump(char *message)
219 {
220 	kcf_soft_conf_entry_t	*p;
221 	uint_t			i;
222 
223 	mutex_enter(&soft_config_mutex);
224 	printf("Soft provider config list soft_config_list: %s\n",
225 	    message != NULL ? message : "");
226 
227 	for (p = soft_config_list; p != NULL; p = p->ce_next) {
228 		printf("ce_name: %s, %d ce_mechs\n", p->ce_name, p->ce_count);
229 		if (kcf_frmwrk_debug >= 2) {
230 			printf("\tce_mechs: ");
231 			for (i = 0; i < p->ce_count; i++) {
232 				printf("%s ", p->ce_mechs[i]);
233 			}
234 			printf("\n");
235 		}
236 	}
237 	printf("(end of soft_config_list)\n");
238 
239 	mutex_exit(&soft_config_mutex);
240 }
241 #endif /* DEBUG */
242 
243 
244 /*
245  * Utility routine to identify the providers to filter out and
246  * present only one provider. This happens when a hardware provider
247  * registers multiple units of the same device instance.
248  *
249  * Called from crypto_get_dev_list().
250  */
251 static void
252 filter_providers(uint_t count, kcf_provider_desc_t **provider_array,
253 	char *skip_providers, int *mech_counts, int *new_count)
254 {
255 	int i, j;
256 	kcf_provider_desc_t *prov1, *prov2;
257 	int n = 0;
258 
259 	for (i = 0; i < count; i++) {
260 		if (skip_providers[i] == 1)
261 			continue;
262 
263 		prov1 = provider_array[i];
264 		mech_counts[i] = prov1->pd_mech_list_count;
265 		for (j = i + 1; j < count; j++) {
266 			prov2 = provider_array[j];
267 			if (strncmp(prov1->pd_name, prov2->pd_name,
268 			    MAXNAMELEN) == 0 &&
269 			    prov1->pd_instance == prov2->pd_instance) {
270 				skip_providers[j] = 1;
271 				mech_counts[i] += prov2->pd_mech_list_count;
272 			}
273 		}
274 		n++;
275 	}
276 
277 	*new_count = n;
278 }
279 
280 
281 /*
282  * Return a list of kernel hardware providers and a count of each
283  * provider's supported mechanisms.
284  * Called from the CRYPTO_GET_DEV_LIST ioctl.
285  */
286 int
287 crypto_get_dev_list(uint_t *count, crypto_dev_list_entry_t **array)
288 {
289 	kcf_provider_desc_t **provider_array;
290 	kcf_provider_desc_t *pd;
291 	crypto_dev_list_entry_t *p;
292 	size_t skip_providers_size, mech_counts_size;
293 	char *skip_providers;
294 	uint_t provider_count;
295 	int rval, i, j, new_count, *mech_counts;
296 
297 	/*
298 	 * Take snapshot of provider table returning only hardware providers
299 	 * that are in a usable state. Logical providers not included.
300 	 */
301 	rval = kcf_get_hw_prov_tab(&provider_count, &provider_array, KM_SLEEP,
302 	    NULL, 0, B_FALSE);
303 	if (rval != CRYPTO_SUCCESS)
304 		return (rval);
305 
306 	if (provider_count == 0) {
307 		*array = NULL;
308 		*count = 0;
309 		return (CRYPTO_SUCCESS);
310 	}
311 
312 	skip_providers_size = provider_count * sizeof (char);
313 	mech_counts_size = provider_count * sizeof (int);
314 
315 	skip_providers = kmem_zalloc(skip_providers_size, KM_SLEEP);
316 	mech_counts = kmem_zalloc(mech_counts_size, KM_SLEEP);
317 	filter_providers(provider_count, provider_array, skip_providers,
318 	    mech_counts, &new_count);
319 
320 	p = kmem_alloc(new_count * sizeof (crypto_dev_list_entry_t), KM_SLEEP);
321 	for (i = 0, j = 0; i < provider_count; i++) {
322 		if (skip_providers[i] == 1) {
323 			ASSERT(mech_counts[i] == 0);
324 			continue;
325 		}
326 		pd = provider_array[i];
327 		p[j].le_mechanism_count = mech_counts[i];
328 		p[j].le_dev_instance = pd->pd_instance;
329 		(void) strncpy(p[j].le_dev_name, pd->pd_name, MAXNAMELEN);
330 		j++;
331 	}
332 
333 	kcf_free_provider_tab(provider_count, provider_array);
334 	kmem_free(skip_providers, skip_providers_size);
335 	kmem_free(mech_counts, mech_counts_size);
336 
337 	*array = p;
338 	*count = new_count;
339 	return (CRYPTO_SUCCESS);
340 }
341 
342 /*
343  * Return a buffer containing the null terminated names of software providers
344  * loaded by CRYPTO_LOAD_SOFT_CONFIG.
345  * Called from the CRYPTO_GET_SOFT_LIST ioctl.
346  */
347 int
348 crypto_get_soft_list(uint_t *count, char **array, size_t *len)
349 {
350 	char *names = NULL, *namep, *end;
351 	kcf_soft_conf_entry_t *p;
352 	uint_t n = 0, cnt = 0, final_count = 0;
353 	size_t name_len, final_size = 0;
354 
355 	/* first estimate */
356 	mutex_enter(&soft_config_mutex);
357 	for (p = soft_config_list; p != NULL; p = p->ce_next) {
358 		n += strlen(p->ce_name) + 1;
359 		cnt++;
360 	}
361 	mutex_exit(&soft_config_mutex);
362 
363 	if (cnt == 0)
364 		goto out;
365 
366 again:
367 	namep = names = kmem_alloc(n, KM_SLEEP);
368 	end = names + n;
369 	final_size = 0;
370 	final_count = 0;
371 
372 	mutex_enter(&soft_config_mutex);
373 	for (p = soft_config_list; p != NULL; p = p->ce_next) {
374 		name_len = strlen(p->ce_name) + 1;
375 		/* check for enough space */
376 		if ((namep + name_len) > end) {
377 			mutex_exit(&soft_config_mutex);
378 			kmem_free(names, n);
379 			n = n << 1;
380 			goto again;
381 		}
382 		(void) strcpy(namep, p->ce_name);
383 		namep += name_len;
384 		final_size += name_len;
385 		final_count++;
386 	}
387 	mutex_exit(&soft_config_mutex);
388 
389 	ASSERT(final_size <= n);
390 
391 	/* check if buffer we allocated is too large */
392 	if (final_size < n) {
393 		char *final_buffer;
394 
395 		final_buffer = kmem_alloc(final_size, KM_SLEEP);
396 		bcopy(names, final_buffer, final_size);
397 		kmem_free(names, n);
398 		names = final_buffer;
399 	}
400 out:
401 	*array = names;
402 	*count = final_count;
403 	*len = final_size;
404 	return (CRYPTO_SUCCESS);
405 }
406 
407 /*
408  * Check if a mechanism name is already in a mechanism name array
409  * Called by crypto_get_dev_info().
410  */
411 static boolean_t
412 duplicate(char *name, crypto_mech_name_t *array, int count)
413 {
414 	int i;
415 
416 	for (i = 0; i < count; i++) {
417 		if (strncmp(name, &array[i][0],
418 		    sizeof (crypto_mech_name_t)) == 0)
419 			return (B_TRUE);
420 	}
421 	return (B_FALSE);
422 }
423 
424 /*
425  * Return a list of kernel hardware providers for a given name and instance.
426  * For each entry, also return a list of their supported mechanisms.
427  * Called from the CRYPTO_GET_DEV_INFO ioctl.
428  */
429 int
430 crypto_get_dev_info(char *name, uint_t instance, uint_t *count,
431     crypto_mech_name_t **array)
432 {
433 	int rv;
434 	crypto_mech_name_t *mech_names, *resized_array;
435 	int i, j, k = 0, max_count;
436 	uint_t provider_count;
437 	kcf_provider_desc_t **provider_array;
438 	kcf_provider_desc_t *pd;
439 
440 	/*
441 	 * Get provider table entries matching name and instance
442 	 * for hardware providers that are in a usable state.
443 	 * Logical providers not included. NULL name matches
444 	 * all hardware providers.
445 	 */
446 	rv = kcf_get_hw_prov_tab(&provider_count, &provider_array, KM_SLEEP,
447 	    name, instance, B_FALSE);
448 	if (rv != CRYPTO_SUCCESS)
449 		return (rv);
450 
451 	if (provider_count == 0)
452 		return (CRYPTO_ARGUMENTS_BAD);
453 
454 	/* Count all mechanisms supported by all providers */
455 	max_count = 0;
456 	for (i = 0; i < provider_count; i++)
457 		max_count += provider_array[i]->pd_mech_list_count;
458 
459 	if (max_count == 0) {
460 		mech_names = NULL;
461 		goto out;
462 	}
463 
464 	/* Allocate space and copy mech names */
465 	mech_names = kmem_alloc(max_count * sizeof (crypto_mech_name_t),
466 	    KM_SLEEP);
467 
468 	k = 0;
469 	for (i = 0; i < provider_count; i++) {
470 		pd = provider_array[i];
471 		for (j = 0; j < pd->pd_mech_list_count; j++) {
472 			/* check for duplicate */
473 			if (duplicate(&pd->pd_mechanisms[j].cm_mech_name[0],
474 			    mech_names, k))
475 				continue;
476 			bcopy(&pd->pd_mechanisms[j].cm_mech_name[0],
477 			    &mech_names[k][0], sizeof (crypto_mech_name_t));
478 			k++;
479 		}
480 	}
481 
482 	/* resize */
483 	if (k != max_count) {
484 		resized_array =
485 		    kmem_alloc(k * sizeof (crypto_mech_name_t), KM_SLEEP);
486 		bcopy(mech_names, resized_array,
487 		    k * sizeof (crypto_mech_name_t));
488 		kmem_free(mech_names,
489 		    max_count * sizeof (crypto_mech_name_t));
490 		mech_names = resized_array;
491 	}
492 
493 out:
494 	kcf_free_provider_tab(provider_count, provider_array);
495 	*count = k;
496 	*array = mech_names;
497 
498 	return (CRYPTO_SUCCESS);
499 }
500 
501 /*
502  * Given a kernel software provider name, return a list of mechanisms
503  * it supports.
504  * Called from the CRYPTO_GET_SOFT_INFO ioctl.
505  */
506 int
507 crypto_get_soft_info(caddr_t name, uint_t *count, crypto_mech_name_t **array)
508 {
509 	ddi_modhandle_t modh = NULL;
510 	kcf_provider_desc_t *provider;
511 	int rv;
512 
513 	provider = kcf_prov_tab_lookup_by_name(name);
514 	if (provider == NULL) {
515 		char *tmp;
516 		int name_len;
517 
518 		/* strlen("crypto/") + NULL terminator == 8 */
519 		name_len = strlen(name);
520 		tmp = kmem_alloc(name_len + 8, KM_SLEEP);
521 		bcopy("crypto/", tmp, 7);
522 		bcopy(name, &tmp[7], name_len);
523 		tmp[name_len + 7] = '\0';
524 
525 		modh = ddi_modopen(tmp, KRTLD_MODE_FIRST, NULL);
526 		kmem_free(tmp, name_len + 8);
527 
528 		if (modh == NULL) {
529 			return (CRYPTO_ARGUMENTS_BAD);
530 		}
531 
532 		provider = kcf_prov_tab_lookup_by_name(name);
533 		if (provider == NULL) {
534 			return (CRYPTO_ARGUMENTS_BAD);
535 		}
536 	}
537 
538 	rv = dup_mech_names(provider, array, count, KM_SLEEP);
539 	KCF_PROV_REFRELE(provider);
540 	if (modh != NULL)
541 		(void) ddi_modclose(modh);
542 	return (rv);
543 }
544 
545 
546 /*
547  * Change the mechanism list for a provider.
548  * If "direction" is CRYPTO_MECH_ADDED, add new mechanisms.
549  * If "direction" is CRYPTO_MECH_REMOVED, remove the mechanism list.
550  * Called from crypto_load_dev_disabled().
551  */
552 static void
553 kcf_change_mechs(kcf_provider_desc_t *provider, uint_t count,
554     crypto_mech_name_t *array, crypto_event_change_t direction)
555 {
556 	crypto_notify_event_change_t ec;
557 	crypto_mech_info_t *mi;
558 	kcf_prov_mech_desc_t *pmd;
559 	char *mech;
560 	int i, j, n;
561 
562 	ASSERT(direction == CRYPTO_MECH_ADDED ||
563 	    direction == CRYPTO_MECH_REMOVED);
564 
565 	if (provider == NULL) {
566 		/*
567 		 * Nothing to add or remove from the tables since
568 		 * the provider isn't registered.
569 		 */
570 		return;
571 	}
572 
573 	for (i = 0; i < count; i++) {
574 		if (array[i][0] == '\0')
575 			continue;
576 
577 		mech = &array[i][0];
578 
579 		n = provider->pd_mech_list_count;
580 		for (j = 0; j < n; j++) {
581 			mi = &provider->pd_mechanisms[j];
582 			if (strncmp(mi->cm_mech_name, mech,
583 			    CRYPTO_MAX_MECH_NAME) == 0)
584 				break;
585 		}
586 		if (j == n)
587 			continue;
588 
589 		switch (direction) {
590 		case CRYPTO_MECH_ADDED:
591 			(void) kcf_add_mech_provider(j, provider, &pmd);
592 			break;
593 
594 		case CRYPTO_MECH_REMOVED:
595 			kcf_remove_mech_provider(mech, provider);
596 			break;
597 		}
598 
599 		/* Inform interested clients of the event */
600 		ec.ec_provider_type = provider->pd_prov_type;
601 		ec.ec_change = direction;
602 
603 		(void) strncpy(ec.ec_mech_name, mech, CRYPTO_MAX_MECH_NAME);
604 		kcf_walk_ntfylist(CRYPTO_EVENT_MECHS_CHANGED, &ec);
605 	}
606 }
607 
608 /*
609  * If a mech name in the second array (prev_array) is also in the
610  * first array, then a NULL character is written into the first byte
611  * of the mech name in the second array.  This effectively removes
612  * the mech name from the second array.
613  */
614 static void
615 kcf_compare_mechs(uint_t count, crypto_mech_name_t *array, uint_t prev_count,
616     crypto_mech_name_t *prev_array)
617 {
618 	int i, j;
619 
620 	for (i = 0; i < prev_count; i++) {
621 		for (j = 0; j < count; j++) {
622 			if (strncmp(&prev_array[i][0], &array[j][0],
623 			    CRYPTO_MAX_MECH_NAME) == 0) {
624 				prev_array[i][0] = '\0';
625 			}
626 		}
627 	}
628 }
629 
630 /*
631  * Called from CRYPTO_LOAD_DEV_DISABLED ioctl.
632  * If new_count is 0, then completely remove the entry.
633  */
634 int
635 crypto_load_dev_disabled(char *name, uint_t instance, uint_t new_count,
636     crypto_mech_name_t *new_array)
637 {
638 	kcf_provider_desc_t *provider = NULL;
639 	kcf_provider_desc_t **provider_array;
640 	crypto_mech_name_t *prev_array;
641 	uint_t provider_count, prev_count;
642 	int i, rv = CRYPTO_SUCCESS;
643 
644 	/*
645 	 * Remove the policy entry if new_count is 0, otherwise put disabled
646 	 * mechanisms into policy table.
647 	 */
648 	if (new_count == 0) {
649 		kcf_policy_remove_by_dev(name, instance, &prev_count,
650 		    &prev_array);
651 	} else if ((rv = kcf_policy_load_dev_disabled(name, instance, new_count,
652 	    new_array, &prev_count, &prev_array)) != CRYPTO_SUCCESS) {
653 		return (rv);
654 	}
655 
656 	/*
657 	 * Get provider table entries matching name and instance
658 	 * for providers that are are in a usable or unverified state.
659 	 */
660 	rv = kcf_get_hw_prov_tab(&provider_count, &provider_array, KM_SLEEP,
661 	    name, instance, B_TRUE);
662 	if (rv != CRYPTO_SUCCESS)
663 		return (rv);
664 
665 	for (i = 0; i < provider_count; i++) {
666 		provider = provider_array[i];
667 
668 		/* previously disabled mechanisms may become enabled */
669 		if (prev_array != NULL) {
670 			kcf_compare_mechs(new_count, new_array,
671 			    prev_count, prev_array);
672 			kcf_change_mechs(provider, prev_count, prev_array,
673 			    CRYPTO_MECH_ADDED);
674 		}
675 
676 		kcf_change_mechs(provider, new_count, new_array,
677 		    CRYPTO_MECH_REMOVED);
678 	}
679 
680 	kcf_free_provider_tab(provider_count, provider_array);
681 	crypto_free_mech_list(prev_array, prev_count);
682 	return (rv);
683 }
684 
685 /*
686  * Called from CRYPTO_LOAD_SOFT_DISABLED ioctl.
687  * If new_count is 0, then completely remove the entry.
688  */
689 int
690 crypto_load_soft_disabled(char *name, uint_t new_count,
691     crypto_mech_name_t *new_array)
692 {
693 	kcf_provider_desc_t *provider = NULL;
694 	crypto_mech_name_t *prev_array;
695 	uint_t prev_count = 0;
696 	int rv;
697 
698 	provider = kcf_prov_tab_lookup_by_name(name);
699 	if (provider != NULL) {
700 		mutex_enter(&provider->pd_lock);
701 		/*
702 		 * Check if any other thread is disabling or removing
703 		 * this provider. We return if this is the case.
704 		 */
705 		if (provider->pd_state >= KCF_PROV_DISABLED) {
706 			mutex_exit(&provider->pd_lock);
707 			KCF_PROV_REFRELE(provider);
708 			return (CRYPTO_BUSY);
709 		}
710 		provider->pd_state = KCF_PROV_DISABLED;
711 		mutex_exit(&provider->pd_lock);
712 
713 		undo_register_provider(provider, B_TRUE);
714 		KCF_PROV_REFRELE(provider);
715 		if (provider->pd_kstat != NULL)
716 			KCF_PROV_REFRELE(provider);
717 
718 		/* Wait till the existing requests complete. */
719 		while (kcf_get_refcnt(provider, B_TRUE) > 0) {
720 			/* wait 1 second and try again. */
721 			delay(1 * drv_usectohz(1000000));
722 		}
723 	}
724 
725 	if (new_count == 0) {
726 		kcf_policy_remove_by_name(name, &prev_count, &prev_array);
727 		crypto_free_mech_list(prev_array, prev_count);
728 		rv = CRYPTO_SUCCESS;
729 		goto out;
730 	}
731 
732 	/* put disabled mechanisms into policy table */
733 	if ((rv = kcf_policy_load_soft_disabled(name, new_count, new_array,
734 	    &prev_count, &prev_array)) == CRYPTO_SUCCESS) {
735 		crypto_free_mech_list(prev_array, prev_count);
736 	}
737 
738 out:
739 	if (provider != NULL) {
740 		redo_register_provider(provider);
741 		if (provider->pd_kstat != NULL)
742 			KCF_PROV_REFHOLD(provider);
743 		mutex_enter(&provider->pd_lock);
744 		provider->pd_state = KCF_PROV_READY;
745 		mutex_exit(&provider->pd_lock);
746 	} else if (rv == CRYPTO_SUCCESS) {
747 		/*
748 		 * There are some cases where it is useful to kCF clients
749 		 * to have a provider whose mechanism is enabled now to be
750 		 * available. So, we attempt to load it here.
751 		 *
752 		 * The check, new_count < prev_count, ensures that we do this
753 		 * only in the case where a mechanism(s) is now enabled.
754 		 * This check assumes that enable and disable are separate
755 		 * administrative actions and are not done in a single action.
756 		 */
757 		if ((new_count < prev_count) &&
758 		    (modload("crypto", name) != -1)) {
759 			struct modctl *mcp;
760 			boolean_t load_again = B_FALSE;
761 
762 			if ((mcp = mod_hold_by_name(name)) != NULL) {
763 				mcp->mod_loadflags |= MOD_NOAUTOUNLOAD;
764 
765 				/* memory pressure may have unloaded module */
766 				if (!mcp->mod_installed)
767 					load_again = B_TRUE;
768 				mod_release_mod(mcp);
769 
770 				if (load_again)
771 					(void) modload("crypto", name);
772 			}
773 		}
774 	}
775 
776 	return (rv);
777 }
778 
779 /* called from the CRYPTO_LOAD_SOFT_CONFIG ioctl */
780 int
781 crypto_load_soft_config(caddr_t name, uint_t count, crypto_mech_name_t *array)
782 {
783 	return (add_soft_config(name, count, array));
784 }
785 
786 /*
787  * Unload a kernel software crypto module.
788  * Called from the CRYPTO_UNLOAD_SOFT_MODULE ioctl.
789  */
790 int
791 crypto_unload_soft_module(caddr_t name)
792 {
793 	int error;
794 	modid_t id;
795 	kcf_provider_desc_t *provider;
796 	struct modctl *mcp;
797 
798 	/* verify that 'name' refers to a registered crypto provider */
799 	if ((provider = kcf_prov_tab_lookup_by_name(name)) == NULL)
800 		return (CRYPTO_UNKNOWN_PROVIDER);
801 
802 	/*
803 	 * We save the module id and release the reference. We need to
804 	 * do this as modunload() calls unregister which waits for the
805 	 * refcnt to drop to zero.
806 	 */
807 	id = provider->pd_module_id;
808 	KCF_PROV_REFRELE(provider);
809 
810 	if ((mcp = mod_hold_by_name(name)) != NULL) {
811 		mcp->mod_loadflags &= ~(MOD_NOAUTOUNLOAD);
812 		mod_release_mod(mcp);
813 	}
814 
815 	if ((error = modunload(id)) != 0) {
816 		return (error == EBUSY ? CRYPTO_BUSY : CRYPTO_FAILED);
817 	}
818 
819 	return (CRYPTO_SUCCESS);
820 }
821 
822 /*
823  * Free the list of kernel hardware crypto providers.
824  * Called by get_dev_list() for the CRYPTO_GET_DEV_LIST ioctl.
825  */
826 void
827 crypto_free_dev_list(crypto_dev_list_entry_t *array, uint_t count)
828 {
829 	if (count == 0 || array == NULL)
830 		return;
831 
832 	kmem_free(array, count * sizeof (crypto_dev_list_entry_t));
833 }
834 
835 /*
836  * Returns duplicate array of mechanisms.  The array is allocated and
837  * must be freed by the caller.
838  */
839 static int
840 dup_mech_names(kcf_provider_desc_t *provider, crypto_mech_name_t **array,
841     uint_t *count, int kmflag)
842 {
843 	crypto_mech_name_t *mech_names;
844 	uint_t n;
845 	uint_t i;
846 
847 	if ((n = provider->pd_mech_list_count) == 0) {
848 		*count = 0;
849 		*array = NULL;
850 		return (CRYPTO_SUCCESS);
851 	}
852 
853 	mech_names = kmem_alloc(n * sizeof (crypto_mech_name_t), kmflag);
854 	if (mech_names == NULL)
855 		return (CRYPTO_HOST_MEMORY);
856 
857 	for (i = 0; i < n; i++) {
858 		bcopy(&provider->pd_mechanisms[i].cm_mech_name[0],
859 		    &mech_names[i][0], sizeof (crypto_mech_name_t));
860 	}
861 
862 	*count = n;
863 	*array = mech_names;
864 	return (CRYPTO_SUCCESS);
865 }
866 
867 /*
868  * Returns B_TRUE if the specified mechanism is disabled, B_FALSE otherwise.
869  */
870 boolean_t
871 is_mech_disabled_byname(crypto_provider_type_t prov_type, char *pd_name,
872     uint_t pd_instance, crypto_mech_name_t mech_name)
873 {
874 	kcf_policy_desc_t *policy;
875 	uint_t i;
876 
877 	ASSERT(prov_type == CRYPTO_SW_PROVIDER ||
878 	    prov_type == CRYPTO_HW_PROVIDER);
879 
880 	switch (prov_type) {
881 	case CRYPTO_SW_PROVIDER:
882 		policy = kcf_policy_lookup_by_name(pd_name);
883 		/* no policy for provider - so mechanism can't be disabled */
884 		if (policy == NULL)
885 			return (B_FALSE);
886 		break;
887 
888 	case CRYPTO_HW_PROVIDER:
889 		policy = kcf_policy_lookup_by_dev(pd_name, pd_instance);
890 		/* no policy for provider - so mechanism can't be disabled */
891 		if (policy == NULL)
892 			return (B_FALSE);
893 		break;
894 	}
895 
896 	mutex_enter(&policy->pd_mutex);
897 	for (i = 0; i < policy->pd_disabled_count; i ++) {
898 		if (strncmp(mech_name, &policy->pd_disabled_mechs[i][0],
899 		    CRYPTO_MAX_MECH_NAME) == 0) {
900 			mutex_exit(&policy->pd_mutex);
901 			KCF_POLICY_REFRELE(policy);
902 			return (B_TRUE);
903 		}
904 	}
905 	mutex_exit(&policy->pd_mutex);
906 	KCF_POLICY_REFRELE(policy);
907 	return (B_FALSE);
908 }
909 
910 /*
911  * Returns B_TRUE if the specified mechanism is disabled, B_FALSE otherwise.
912  *
913  * This is a wrapper routine around is_mech_disabled_byname() above and
914  * takes a pointer kcf_provider_desc structure as argument.
915  */
916 boolean_t
917 is_mech_disabled(kcf_provider_desc_t *provider, crypto_mech_name_t name)
918 {
919 	kcf_provider_list_t *e;
920 	kcf_provider_desc_t *pd;
921 	boolean_t found = B_FALSE;
922 	uint_t count, i;
923 
924 	if (provider->pd_prov_type != CRYPTO_LOGICAL_PROVIDER) {
925 		return (is_mech_disabled_byname(provider->pd_prov_type,
926 		    provider->pd_name, provider->pd_instance, name));
927 	}
928 
929 	/*
930 	 * Lock the logical provider just in case one of its hardware
931 	 * provider members unregisters.
932 	 */
933 	mutex_enter(&provider->pd_lock);
934 	for (e = provider->pd_provider_list; e != NULL; e = e->pl_next) {
935 
936 		pd = e->pl_provider;
937 		ASSERT(pd->pd_prov_type == CRYPTO_HW_PROVIDER);
938 
939 		/* find out if mechanism is offered by hw provider */
940 		count = pd->pd_mech_list_count;
941 		for (i = 0; i < count; i++) {
942 			if (strncmp(&pd->pd_mechanisms[i].cm_mech_name[0],
943 			    name, MAXNAMELEN) == 0) {
944 				break;
945 			}
946 		}
947 		if (i == count)
948 			continue;
949 
950 		found = !is_mech_disabled_byname(pd->pd_prov_type,
951 		    pd->pd_name, pd->pd_instance, name);
952 
953 		if (found)
954 			break;
955 	}
956 	mutex_exit(&provider->pd_lock);
957 	/*
958 	 * If we found the mechanism, then it means it is still enabled for
959 	 * at least one hardware provider, so the mech can't be disabled
960 	 * for the logical provider.
961 	 */
962 	return (!found);
963 }
964 
965 /*
966  * Builds array of permitted mechanisms.  The array is allocated and
967  * must be freed by the caller.
968  */
969 int
970 crypto_build_permitted_mech_names(kcf_provider_desc_t *provider,
971     crypto_mech_name_t **array, uint_t *count, int kmflag)
972 {
973 	crypto_mech_name_t *mech_names, *p;
974 	uint_t i;
975 	uint_t scnt = provider->pd_mech_list_count;
976 	uint_t dcnt = 0;
977 
978 	/*
979 	 * Compute number of 'permitted mechanisms', which is
980 	 * 'supported mechanisms' - 'disabled mechanisms'.
981 	 */
982 	for (i = 0; i < scnt; i++) {
983 		if (is_mech_disabled(provider,
984 		    &provider->pd_mechanisms[i].cm_mech_name[0])) {
985 			dcnt++;
986 		}
987 	}
988 
989 	/* all supported mechanisms have been disabled */
990 	if (scnt == dcnt) {
991 		*count = 0;
992 		*array = NULL;
993 		return (CRYPTO_SUCCESS);
994 	}
995 
996 	mech_names = kmem_alloc((scnt - dcnt) * sizeof (crypto_mech_name_t),
997 	    kmflag);
998 	if (mech_names == NULL)
999 		return (CRYPTO_HOST_MEMORY);
1000 
1001 	/* build array of permitted mechanisms */
1002 	for (i = 0, p = mech_names; i < scnt; i++) {
1003 		if (!is_mech_disabled(provider,
1004 		    &provider->pd_mechanisms[i].cm_mech_name[0])) {
1005 			bcopy(&provider->pd_mechanisms[i].cm_mech_name[0],
1006 			    p++, sizeof (crypto_mech_name_t));
1007 		}
1008 	}
1009 
1010 	*count = scnt - dcnt;
1011 	*array = mech_names;
1012 	return (CRYPTO_SUCCESS);
1013 }
1014 
1015 /*
1016  * Free memory for elements in a kcf_soft_config_entry_t.  This entry must
1017  * have been previously removed from the soft_config_list linked list.
1018  */
1019 static void
1020 free_soft_config_entry(kcf_soft_conf_entry_t *p)
1021 {
1022 	kmem_free(p->ce_name, strlen(p->ce_name) + 1);
1023 	crypto_free_mech_list(p->ce_mechs, p->ce_count);
1024 	kmem_free(p, sizeof (kcf_soft_conf_entry_t));
1025 }
1026 
1027 /*
1028  * Store configuration information for software providers in a linked list.
1029  * If the list already contains an entry for the specified provider
1030  * and the specified mechanism list has at least one mechanism, then
1031  * the mechanism list for the provider is updated. If the mechanism list
1032  * is empty, the entry for the provider is removed.
1033  *
1034  * Called from kcf_soft_config_init() (to initially populate the list
1035  * with default kernel providers) and from crypto_load_soft_config() for
1036  * the CRYPTO_LOAD_SOFT_CONFIG ioctl (for third-party kernel modules).
1037  *
1038  * Important note: the array argument must be allocated memory
1039  * since it is consumed in soft_config_list.
1040  *
1041  * Parameters:
1042  * name		Provider name to add or remove.
1043  * count	Number of mechanisms to add.
1044  *		If 0, then remove provider from the list (instead of add).
1045  * array	An array of "count" mechanism names (use only if count > 0).
1046  */
1047 static int
1048 add_soft_config(char *name, uint_t count, crypto_mech_name_t *array)
1049 {
1050 	static uint_t soft_config_count = 0;
1051 	kcf_soft_conf_entry_t *prev = NULL, *entry = NULL, *new_entry, *p;
1052 	size_t name_len;
1053 
1054 	/*
1055 	 * Allocate storage for a new entry.
1056 	 * Free later if an entry already exists.
1057 	 */
1058 	name_len = strlen(name) + 1;
1059 	new_entry = kmem_zalloc(sizeof (kcf_soft_conf_entry_t), KM_SLEEP);
1060 	new_entry->ce_name = kmem_alloc(name_len, KM_SLEEP);
1061 	(void) strcpy(new_entry->ce_name, name);
1062 
1063 	mutex_enter(&soft_config_mutex);
1064 
1065 	/* Search to see if provider already in soft_config_list */
1066 	for (p = soft_config_list; p != NULL; p = p->ce_next) {
1067 		if (strncmp(name, p->ce_name, MAXNAMELEN) == 0) { /* found */
1068 			entry = p;
1069 			break;
1070 		}
1071 		prev = p;
1072 	}
1073 
1074 	if (entry == NULL) { /* new provider (not in soft_config_list) */
1075 		if (count == 0) { /* free memory--no entry exists to remove */
1076 			mutex_exit(&soft_config_mutex);
1077 			kmem_free(new_entry->ce_name, name_len);
1078 			kmem_free(new_entry, sizeof (kcf_soft_conf_entry_t));
1079 			return (CRYPTO_SUCCESS);
1080 		}
1081 
1082 		if (soft_config_count > KCF_MAX_CONFIG_ENTRIES) { /* full */
1083 			mutex_exit(&soft_config_mutex);
1084 			kmem_free(new_entry->ce_name, name_len);
1085 			kmem_free(new_entry, sizeof (kcf_soft_conf_entry_t));
1086 			cmn_err(CE_WARN, "out of soft_config_list entries");
1087 			return (CRYPTO_FAILED);
1088 		}
1089 
1090 		/* add new provider to head of list */
1091 		new_entry->ce_next = soft_config_list;
1092 		soft_config_list = new_entry;
1093 		soft_config_count++;
1094 		entry = new_entry;
1095 
1096 	} else { /* mechanism already in soft_config_list */
1097 		kmem_free(new_entry->ce_name, name_len);
1098 		kmem_free(new_entry, sizeof (kcf_soft_conf_entry_t));
1099 	}
1100 
1101 	if (count == 0) { /* remove provider entry from soft_config_list */
1102 		if (prev == NULL) {
1103 			/* entry to remove is at the head of the list */
1104 			soft_config_list = entry->ce_next;
1105 		} else {
1106 			prev->ce_next = entry->ce_next;
1107 		}
1108 		soft_config_count--;
1109 		mutex_exit(&soft_config_mutex);
1110 
1111 		/* free entry */
1112 		free_soft_config_entry(entry);
1113 
1114 	} else { /* add provider entry to soft_config_list */
1115 		/*
1116 		 * Don't replace a mechanism list if it's already present.
1117 		 * This is because the default entries for Software providers
1118 		 * are more up-to-date than possibly stale entries in kcf.conf.
1119 		 * If an entry is to be deleted, the proper way to do it is
1120 		 * to add it to the disablelist (with cryptoadm(1M)),
1121 		 * instead of removing it from the supportedlist.
1122 		 */
1123 		if (entry->ce_mechs == NULL) { /* add new mechanisms */
1124 			entry->ce_mechs = array;
1125 			entry->ce_count = count;
1126 			mutex_exit(&soft_config_mutex);
1127 		} else { /* ignore replacement mechanism list */
1128 			mutex_exit(&soft_config_mutex);
1129 			crypto_free_mech_list(array, count);
1130 		}
1131 	}
1132 
1133 	return (CRYPTO_SUCCESS);
1134 }
1135 
1136 /*
1137  * This function removes a module entry from the soft_config_list.
1138  *
1139  * This comes in handy if FIPS 140 is enabled, but fails to validate.  At
1140  * which point when the kernel reports its' supported modules, it shows only
1141  * those that are not within the boundary
1142  */
1143 void
1144 remove_soft_config(char *name)
1145 {
1146 	kcf_soft_conf_entry_t *p, *entry = NULL, *prev = NULL;
1147 
1148 	mutex_enter(&soft_config_mutex);
1149 	/* Search for provider in soft_config_list */
1150 	for (p = soft_config_list; p != NULL; p = p->ce_next) {
1151 		if (strncmp(name, p->ce_name, MAXNAMELEN) == 0) {
1152 			entry = p;
1153 			break;
1154 		}
1155 		prev = p;
1156 	}
1157 
1158 	if (prev == NULL) {
1159 		/* entry to remove is at the head of the list */
1160 		soft_config_list = entry->ce_next;
1161 	} else {
1162 		prev->ce_next = entry->ce_next;
1163 	}
1164 
1165 	mutex_exit(&soft_config_mutex);
1166 
1167 	/* free entry */
1168 	free_soft_config_entry(entry);
1169 }
1170 
1171 /*
1172  * This routine searches the soft_config_list for the first entry that
1173  * has the specified mechanism in its mechanism list.  If found,
1174  * a buffer containing the name of the software module that implements
1175  * the mechanism is allocated and stored in 'name'.
1176  */
1177 int
1178 get_sw_provider_for_mech(crypto_mech_name_t mech, char **name)
1179 {
1180 	kcf_soft_conf_entry_t *p, *next;
1181 	char tmp_name[MAXNAMELEN];
1182 	size_t name_len = 0;
1183 	int i;
1184 
1185 	mutex_enter(&soft_config_mutex);
1186 	p = soft_config_list;
1187 	while (p != NULL) {
1188 		next = p->ce_next;
1189 		for (i = 0; i < p->ce_count; i++) {
1190 			if (strncmp(mech, &p->ce_mechs[i][0],
1191 			    CRYPTO_MAX_MECH_NAME) == 0) {
1192 				name_len = strlen(p->ce_name) + 1;
1193 				bcopy(p->ce_name, tmp_name, name_len);
1194 				break;
1195 			}
1196 		}
1197 		p = next;
1198 	}
1199 	mutex_exit(&soft_config_mutex);
1200 
1201 	if (name_len == 0)
1202 		return (CRYPTO_FAILED);
1203 
1204 	*name = kmem_alloc(name_len, KM_SLEEP);
1205 	bcopy(tmp_name, *name, name_len);
1206 	return (CRYPTO_SUCCESS);
1207 }
1208