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