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