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