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