xref: /titanic_52/usr/src/uts/common/crypto/core/kcf_prov_tabs.c (revision 6ea3c0609e50782557505b88bb391b786bca32c9)
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 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * This file is part of the core Kernel Cryptographic Framework.
28  * It implements the management of tables of Providers. Entries to
29  * added and removed when cryptographic providers register with
30  * and unregister from the framework, respectively. The KCF scheduler
31  * and ioctl pseudo driver call this function to obtain the list
32  * of available providers.
33  *
34  * The provider table is indexed by crypto_provider_id_t. Each
35  * element of the table contains a pointer to a provider descriptor,
36  * or NULL if the entry is free.
37  *
38  * This file also implements helper functions to allocate and free
39  * provider descriptors.
40  */
41 
42 #include <sys/types.h>
43 #include <sys/kmem.h>
44 #include <sys/cmn_err.h>
45 #include <sys/ddi.h>
46 #include <sys/sunddi.h>
47 #include <sys/ksynch.h>
48 #include <sys/crypto/common.h>
49 #include <sys/crypto/impl.h>
50 #include <sys/crypto/sched_impl.h>
51 #include <sys/crypto/spi.h>
52 
53 #define	KCF_MAX_PROVIDERS	512	/* max number of providers */
54 
55 /*
56  * Prov_tab is an array of providers which is updated when
57  * a crypto provider registers with kcf. The provider calls the
58  * SPI routine, crypto_register_provider(), which in turn calls
59  * kcf_prov_tab_add_provider().
60  *
61  * A provider unregisters by calling crypto_unregister_provider()
62  * which triggers the removal of the prov_tab entry.
63  * It also calls kcf_remove_mech_provider().
64  *
65  * prov_tab entries are not updated from kcf.conf or by cryptoadm(1M).
66  */
67 static kcf_provider_desc_t **prov_tab = NULL;
68 kmutex_t prov_tab_mutex; /* ensure exclusive access to the table */
69 static uint_t prov_tab_num = 0; /* number of providers in table */
70 static uint_t prov_tab_max = KCF_MAX_PROVIDERS;
71 
72 static void kcf_free_unregistered_provs();
73 #if DEBUG
74 extern int kcf_frmwrk_debug;
75 static void kcf_prov_tab_dump(char *message);
76 #endif /* DEBUG */
77 
78 
79 /*
80  * Initialize a mutex and the KCF providers table, prov_tab.
81  * The providers table is dynamically allocated with prov_tab_max entries.
82  * Called from kcf module _init().
83  */
84 void
85 kcf_prov_tab_init(void)
86 {
87 	mutex_init(&prov_tab_mutex, NULL, MUTEX_DRIVER, NULL);
88 
89 	prov_tab = kmem_zalloc(prov_tab_max * sizeof (kcf_provider_desc_t *),
90 	    KM_SLEEP);
91 }
92 
93 /*
94  * Add a provider to the provider table. If no free entry can be found
95  * for the new provider, returns CRYPTO_HOST_MEMORY. Otherwise, add
96  * the provider to the table, initialize the pd_prov_id field
97  * of the specified provider descriptor to the index in that table,
98  * and return CRYPTO_SUCCESS. Note that a REFHOLD is done on the
99  * provider when pointed to by a table entry.
100  */
101 int
102 kcf_prov_tab_add_provider(kcf_provider_desc_t *prov_desc)
103 {
104 	uint_t i;
105 
106 	ASSERT(prov_tab != NULL);
107 
108 	mutex_enter(&prov_tab_mutex);
109 
110 	/* see if any slots can be freed */
111 	if (kcf_need_provtab_walk)
112 		kcf_free_unregistered_provs();
113 
114 	/* find free slot in providers table */
115 	for (i = 0; i < KCF_MAX_PROVIDERS && prov_tab[i] != NULL; i++)
116 		;
117 	if (i == KCF_MAX_PROVIDERS) {
118 		/* ran out of providers entries */
119 		mutex_exit(&prov_tab_mutex);
120 		cmn_err(CE_WARN, "out of providers entries");
121 		return (CRYPTO_HOST_MEMORY);
122 	}
123 
124 	/* initialize entry */
125 	prov_tab[i] = prov_desc;
126 	KCF_PROV_REFHOLD(prov_desc);
127 	prov_tab_num++;
128 
129 	mutex_exit(&prov_tab_mutex);
130 
131 	/* update provider descriptor */
132 	prov_desc->pd_prov_id = i;
133 
134 	/*
135 	 * The KCF-private provider handle is defined as the internal
136 	 * provider id.
137 	 */
138 	prov_desc->pd_kcf_prov_handle =
139 	    (crypto_kcf_provider_handle_t)prov_desc->pd_prov_id;
140 
141 #if DEBUG
142 	if (kcf_frmwrk_debug >= 1)
143 		kcf_prov_tab_dump("kcf_prov_tab_add_provider");
144 #endif /* DEBUG */
145 
146 	return (CRYPTO_SUCCESS);
147 }
148 
149 /*
150  * Remove the provider specified by its id. A REFRELE is done on the
151  * corresponding provider descriptor before this function returns.
152  * Returns CRYPTO_UNKNOWN_PROVIDER if the provider id is not valid.
153  */
154 int
155 kcf_prov_tab_rem_provider(crypto_provider_id_t prov_id)
156 {
157 	kcf_provider_desc_t *prov_desc;
158 
159 	ASSERT(prov_tab != NULL);
160 	ASSERT(prov_tab_num != (uint_t)-1); /* underflow */
161 
162 	/*
163 	 * Validate provider id, since it can be specified by a 3rd-party
164 	 * provider.
165 	 */
166 
167 	mutex_enter(&prov_tab_mutex);
168 	if (prov_id >= KCF_MAX_PROVIDERS ||
169 	    ((prov_desc = prov_tab[prov_id]) == NULL)) {
170 		mutex_exit(&prov_tab_mutex);
171 		return (CRYPTO_INVALID_PROVIDER_ID);
172 	}
173 
174 	if (kcf_need_provtab_walk)
175 		kcf_free_unregistered_provs();
176 	mutex_exit(&prov_tab_mutex);
177 
178 	/*
179 	 * The provider id must remain valid until the associated provider
180 	 * descriptor is freed. For this reason, we simply release our
181 	 * reference to the descriptor here. When the reference count
182 	 * reaches zero, kcf_free_provider_desc() will be invoked and
183 	 * the associated entry in the providers table will be released
184 	 * at that time.
185 	 */
186 
187 	KCF_PROV_REFRELE(prov_desc);
188 
189 #if DEBUG
190 	if (kcf_frmwrk_debug >= 1)
191 		kcf_prov_tab_dump("kcf_prov_tab_rem_provider");
192 #endif /* DEBUG */
193 
194 	return (CRYPTO_SUCCESS);
195 }
196 
197 /*
198  * Returns the provider descriptor corresponding to the specified
199  * provider id. A REFHOLD is done on the descriptor before it is
200  * returned to the caller. It is the responsibility of the caller
201  * to do a REFRELE once it is done with the provider descriptor.
202  */
203 kcf_provider_desc_t *
204 kcf_prov_tab_lookup(crypto_provider_id_t prov_id)
205 {
206 	kcf_provider_desc_t *prov_desc;
207 
208 	mutex_enter(&prov_tab_mutex);
209 
210 	prov_desc = prov_tab[prov_id];
211 
212 	if (prov_desc == NULL) {
213 		mutex_exit(&prov_tab_mutex);
214 		return (NULL);
215 	}
216 
217 	KCF_PROV_REFHOLD(prov_desc);
218 
219 	mutex_exit(&prov_tab_mutex);
220 
221 	return (prov_desc);
222 }
223 
224 static void
225 allocate_ops_v1(crypto_ops_t *src, crypto_ops_t *dst, uint_t *mech_list_count)
226 {
227 	if (src->co_control_ops != NULL)
228 		dst->co_control_ops = kmem_alloc(sizeof (crypto_control_ops_t),
229 		    KM_SLEEP);
230 
231 	if (src->co_digest_ops != NULL)
232 		dst->co_digest_ops = kmem_alloc(sizeof (crypto_digest_ops_t),
233 		    KM_SLEEP);
234 
235 	if (src->co_cipher_ops != NULL)
236 		dst->co_cipher_ops = kmem_alloc(sizeof (crypto_cipher_ops_t),
237 		    KM_SLEEP);
238 
239 	if (src->co_mac_ops != NULL)
240 		dst->co_mac_ops = kmem_alloc(sizeof (crypto_mac_ops_t),
241 		    KM_SLEEP);
242 
243 	if (src->co_sign_ops != NULL)
244 		dst->co_sign_ops = kmem_alloc(sizeof (crypto_sign_ops_t),
245 		    KM_SLEEP);
246 
247 	if (src->co_verify_ops != NULL)
248 		dst->co_verify_ops = kmem_alloc(sizeof (crypto_verify_ops_t),
249 		    KM_SLEEP);
250 
251 	if (src->co_dual_ops != NULL)
252 		dst->co_dual_ops = kmem_alloc(sizeof (crypto_dual_ops_t),
253 		    KM_SLEEP);
254 
255 	if (src->co_dual_cipher_mac_ops != NULL)
256 		dst->co_dual_cipher_mac_ops = kmem_alloc(
257 		    sizeof (crypto_dual_cipher_mac_ops_t), KM_SLEEP);
258 
259 	if (src->co_random_ops != NULL) {
260 		dst->co_random_ops = kmem_alloc(
261 		    sizeof (crypto_random_number_ops_t), KM_SLEEP);
262 
263 		/*
264 		 * Allocate storage to store the array of supported mechanisms
265 		 * specified by provider. We allocate extra mechanism storage
266 		 * if the provider has random_ops since we keep an internal
267 		 * mechanism, SUN_RANDOM, in this case.
268 		 */
269 		(*mech_list_count)++;
270 	}
271 
272 	if (src->co_session_ops != NULL)
273 		dst->co_session_ops = kmem_alloc(sizeof (crypto_session_ops_t),
274 		    KM_SLEEP);
275 
276 	if (src->co_object_ops != NULL)
277 		dst->co_object_ops = kmem_alloc(sizeof (crypto_object_ops_t),
278 		    KM_SLEEP);
279 
280 	if (src->co_key_ops != NULL)
281 		dst->co_key_ops = kmem_alloc(sizeof (crypto_key_ops_t),
282 		    KM_SLEEP);
283 
284 	if (src->co_provider_ops != NULL)
285 		dst->co_provider_ops = kmem_alloc(
286 		    sizeof (crypto_provider_management_ops_t), KM_SLEEP);
287 
288 	if (src->co_ctx_ops != NULL)
289 		dst->co_ctx_ops = kmem_alloc(sizeof (crypto_ctx_ops_t),
290 		    KM_SLEEP);
291 }
292 
293 static void
294 allocate_ops_v2(crypto_ops_t *src, crypto_ops_t *dst)
295 {
296 	if (src->co_mech_ops != NULL)
297 		dst->co_mech_ops = kmem_alloc(sizeof (crypto_mech_ops_t),
298 		    KM_SLEEP);
299 }
300 
301 static void
302 allocate_ops_v3(crypto_ops_t *src, crypto_ops_t *dst)
303 {
304 	if (src->co_nostore_key_ops != NULL)
305 		dst->co_nostore_key_ops =
306 		    kmem_alloc(sizeof (crypto_nostore_key_ops_t), KM_SLEEP);
307 }
308 
309 static void
310 allocate_ops_v4(crypto_ops_t *src, crypto_ops_t *dst)
311 {
312 	if (src->co_fips140_ops != NULL)
313 		dst->co_fips140_ops =
314 		    kmem_alloc(sizeof (crypto_fips140_ops_t), KM_SLEEP);
315 }
316 
317 /*
318  * Allocate a provider descriptor. mech_list_count specifies the
319  * number of mechanisms supported by the providers, and is used
320  * to allocate storage for the mechanism table.
321  * This function may sleep while allocating memory, which is OK
322  * since it is invoked from user context during provider registration.
323  */
324 kcf_provider_desc_t *
325 kcf_alloc_provider_desc(crypto_provider_info_t *info)
326 {
327 	int i, j;
328 	kcf_provider_desc_t *desc;
329 	uint_t mech_list_count = info->pi_mech_list_count;
330 	crypto_ops_t *src_ops = info->pi_ops_vector;
331 
332 	desc = kmem_zalloc(sizeof (kcf_provider_desc_t), KM_SLEEP);
333 
334 	/*
335 	 * pd_description serves two purposes
336 	 * - Appears as a blank padded PKCS#11 style string, that will be
337 	 *   returned to applications in CK_SLOT_INFO.slotDescription.
338 	 *   This means that we should not have a null character in the
339 	 *   first CRYPTO_PROVIDER_DESCR_MAX_LEN bytes.
340 	 * - Appears as a null-terminated string that can be used by
341 	 *   other kcf routines.
342 	 *
343 	 * So, we allocate enough room for one extra null terminator
344 	 * which keeps every one happy.
345 	 */
346 	desc->pd_description = kmem_alloc(CRYPTO_PROVIDER_DESCR_MAX_LEN + 1,
347 	    KM_SLEEP);
348 	(void) memset(desc->pd_description, ' ',
349 	    CRYPTO_PROVIDER_DESCR_MAX_LEN);
350 	desc->pd_description[CRYPTO_PROVIDER_DESCR_MAX_LEN] = '\0';
351 
352 	/*
353 	 * Since the framework does not require the ops vector specified
354 	 * by the providers during registration to be persistent,
355 	 * KCF needs to allocate storage where copies of the ops
356 	 * vectors are copied.
357 	 */
358 	desc->pd_ops_vector = kmem_zalloc(sizeof (crypto_ops_t), KM_SLEEP);
359 
360 	if (info->pi_provider_type != CRYPTO_LOGICAL_PROVIDER) {
361 		allocate_ops_v1(src_ops, desc->pd_ops_vector, &mech_list_count);
362 		if (info->pi_interface_version >= CRYPTO_SPI_VERSION_2)
363 			allocate_ops_v2(src_ops, desc->pd_ops_vector);
364 		if (info->pi_interface_version >= CRYPTO_SPI_VERSION_3)
365 			allocate_ops_v3(src_ops, desc->pd_ops_vector);
366 		if (info->pi_interface_version == CRYPTO_SPI_VERSION_4)
367 			allocate_ops_v4(src_ops, desc->pd_ops_vector);
368 	}
369 
370 	desc->pd_mech_list_count = mech_list_count;
371 	desc->pd_mechanisms = kmem_zalloc(sizeof (crypto_mech_info_t) *
372 	    mech_list_count, KM_SLEEP);
373 	for (i = 0; i < KCF_OPS_CLASSSIZE; i++)
374 		for (j = 0; j < KCF_MAXMECHTAB; j++)
375 			desc->pd_mech_indx[i][j] = KCF_INVALID_INDX;
376 
377 	desc->pd_prov_id = KCF_PROVID_INVALID;
378 	desc->pd_state = KCF_PROV_ALLOCATED;
379 
380 	mutex_init(&desc->pd_lock, NULL, MUTEX_DEFAULT, NULL);
381 	cv_init(&desc->pd_resume_cv, NULL, CV_DEFAULT, NULL);
382 
383 	desc->pd_nbins = max_ncpus;
384 	desc->pd_percpu_bins =
385 	    kmem_zalloc(desc->pd_nbins * sizeof (kcf_prov_cpu_t), KM_SLEEP);
386 
387 	return (desc);
388 }
389 
390 /*
391  * Free a provider descriptor. Caller must hold prov_tab_mutex.
392  *
393  * Caution: This routine drops prov_tab_mutex.
394  */
395 void
396 kcf_free_provider_desc(kcf_provider_desc_t *desc)
397 {
398 	if (desc == NULL)
399 		return;
400 
401 	ASSERT(MUTEX_HELD(&prov_tab_mutex));
402 	if (desc->pd_prov_id != KCF_PROVID_INVALID) {
403 		/* release the associated providers table entry */
404 		ASSERT(prov_tab[desc->pd_prov_id] != NULL);
405 		prov_tab[desc->pd_prov_id] = NULL;
406 		prov_tab_num--;
407 	}
408 	mutex_exit(&prov_tab_mutex);
409 
410 	/* free the kernel memory associated with the provider descriptor */
411 
412 	if (desc->pd_description != NULL)
413 		kmem_free(desc->pd_description,
414 		    CRYPTO_PROVIDER_DESCR_MAX_LEN + 1);
415 
416 	if (desc->pd_ops_vector != NULL) {
417 
418 		if (desc->pd_ops_vector->co_control_ops != NULL)
419 			kmem_free(desc->pd_ops_vector->co_control_ops,
420 			    sizeof (crypto_control_ops_t));
421 
422 		if (desc->pd_ops_vector->co_digest_ops != NULL)
423 			kmem_free(desc->pd_ops_vector->co_digest_ops,
424 			    sizeof (crypto_digest_ops_t));
425 
426 		if (desc->pd_ops_vector->co_cipher_ops != NULL)
427 			kmem_free(desc->pd_ops_vector->co_cipher_ops,
428 			    sizeof (crypto_cipher_ops_t));
429 
430 		if (desc->pd_ops_vector->co_mac_ops != NULL)
431 			kmem_free(desc->pd_ops_vector->co_mac_ops,
432 			    sizeof (crypto_mac_ops_t));
433 
434 		if (desc->pd_ops_vector->co_sign_ops != NULL)
435 			kmem_free(desc->pd_ops_vector->co_sign_ops,
436 			    sizeof (crypto_sign_ops_t));
437 
438 		if (desc->pd_ops_vector->co_verify_ops != NULL)
439 			kmem_free(desc->pd_ops_vector->co_verify_ops,
440 			    sizeof (crypto_verify_ops_t));
441 
442 		if (desc->pd_ops_vector->co_dual_ops != NULL)
443 			kmem_free(desc->pd_ops_vector->co_dual_ops,
444 			    sizeof (crypto_dual_ops_t));
445 
446 		if (desc->pd_ops_vector->co_dual_cipher_mac_ops != NULL)
447 			kmem_free(desc->pd_ops_vector->co_dual_cipher_mac_ops,
448 			    sizeof (crypto_dual_cipher_mac_ops_t));
449 
450 		if (desc->pd_ops_vector->co_random_ops != NULL)
451 			kmem_free(desc->pd_ops_vector->co_random_ops,
452 			    sizeof (crypto_random_number_ops_t));
453 
454 		if (desc->pd_ops_vector->co_session_ops != NULL)
455 			kmem_free(desc->pd_ops_vector->co_session_ops,
456 			    sizeof (crypto_session_ops_t));
457 
458 		if (desc->pd_ops_vector->co_object_ops != NULL)
459 			kmem_free(desc->pd_ops_vector->co_object_ops,
460 			    sizeof (crypto_object_ops_t));
461 
462 		if (desc->pd_ops_vector->co_key_ops != NULL)
463 			kmem_free(desc->pd_ops_vector->co_key_ops,
464 			    sizeof (crypto_key_ops_t));
465 
466 		if (desc->pd_ops_vector->co_provider_ops != NULL)
467 			kmem_free(desc->pd_ops_vector->co_provider_ops,
468 			    sizeof (crypto_provider_management_ops_t));
469 
470 		if (desc->pd_ops_vector->co_ctx_ops != NULL)
471 			kmem_free(desc->pd_ops_vector->co_ctx_ops,
472 			    sizeof (crypto_ctx_ops_t));
473 
474 		if (desc->pd_ops_vector->co_mech_ops != NULL)
475 			kmem_free(desc->pd_ops_vector->co_mech_ops,
476 			    sizeof (crypto_mech_ops_t));
477 
478 		if (desc->pd_ops_vector->co_nostore_key_ops != NULL)
479 			kmem_free(desc->pd_ops_vector->co_nostore_key_ops,
480 			    sizeof (crypto_nostore_key_ops_t));
481 
482 		if (desc->pd_ops_vector->co_fips140_ops != NULL)
483 			kmem_free(desc->pd_ops_vector->co_fips140_ops,
484 			    sizeof (crypto_fips140_ops_t));
485 
486 		kmem_free(desc->pd_ops_vector, sizeof (crypto_ops_t));
487 	}
488 
489 	if (desc->pd_mechanisms != NULL)
490 		/* free the memory associated with the mechanism info's */
491 		kmem_free(desc->pd_mechanisms, sizeof (crypto_mech_info_t) *
492 		    desc->pd_mech_list_count);
493 
494 	if (desc->pd_name != NULL) {
495 		kmem_free(desc->pd_name, strlen(desc->pd_name) + 1);
496 	}
497 
498 	if (desc->pd_taskq != NULL)
499 		taskq_destroy(desc->pd_taskq);
500 
501 	if (desc->pd_percpu_bins != NULL) {
502 		kmem_free(desc->pd_percpu_bins,
503 		    desc->pd_nbins * sizeof (kcf_prov_cpu_t));
504 	}
505 
506 	kmem_free(desc, sizeof (kcf_provider_desc_t));
507 }
508 
509 /*
510  * Returns the provider descriptor corresponding to the specified
511  * module name. A REFHOLD is done on the descriptor before it is
512  * returned to the caller. It is the responsibility of the caller
513  * to do a REFRELE once it is done with the provider descriptor.
514  * Only software providers are returned by this function.
515  */
516 kcf_provider_desc_t *
517 kcf_prov_tab_lookup_by_name(char *module_name)
518 {
519 	kcf_provider_desc_t *prov_desc;
520 	uint_t i;
521 
522 	mutex_enter(&prov_tab_mutex);
523 
524 	for (i = 0; i < KCF_MAX_PROVIDERS; i++) {
525 		if ((prov_desc = prov_tab[i]) != NULL &&
526 		    (!KCF_IS_PROV_REMOVED(prov_desc)) &&
527 		    prov_desc->pd_prov_type == CRYPTO_SW_PROVIDER) {
528 			ASSERT(prov_desc->pd_name != NULL);
529 			if (strncmp(module_name, prov_desc->pd_name,
530 			    MAXNAMELEN) == 0) {
531 				KCF_PROV_REFHOLD(prov_desc);
532 				mutex_exit(&prov_tab_mutex);
533 				return (prov_desc);
534 			}
535 		}
536 	}
537 
538 	mutex_exit(&prov_tab_mutex);
539 	return (NULL);
540 }
541 
542 /*
543  * Returns the provider descriptor corresponding to the specified
544  * device name and instance. A REFHOLD is done on the descriptor
545  * before it is returned to the caller. It is the responsibility
546  * of the caller to do a REFRELE once it is done with the provider
547  * descriptor. Only hardware providers are returned by this function.
548  */
549 kcf_provider_desc_t *
550 kcf_prov_tab_lookup_by_dev(char *name, uint_t instance)
551 {
552 	kcf_provider_desc_t *prov_desc;
553 	uint_t i;
554 
555 	mutex_enter(&prov_tab_mutex);
556 
557 	for (i = 0; i < KCF_MAX_PROVIDERS; i++) {
558 		if ((prov_desc = prov_tab[i]) != NULL &&
559 		    (!KCF_IS_PROV_REMOVED(prov_desc)) &&
560 		    prov_desc->pd_prov_type == CRYPTO_HW_PROVIDER) {
561 			ASSERT(prov_desc->pd_name != NULL);
562 			if (strncmp(prov_desc->pd_name, name,
563 			    MAXNAMELEN) == 0 &&
564 			    prov_desc->pd_instance == instance) {
565 				KCF_PROV_REFHOLD(prov_desc);
566 				mutex_exit(&prov_tab_mutex);
567 				return (prov_desc);
568 			}
569 		}
570 	}
571 
572 	mutex_exit(&prov_tab_mutex);
573 	return (NULL);
574 }
575 
576 /*
577  * Returns an array of hardware and logical provider descriptors,
578  * a.k.a the PKCS#11 slot list. A REFHOLD is done on each descriptor
579  * before the array is returned. The entire table can be freed by
580  * calling kcf_free_provider_tab().
581  */
582 int
583 kcf_get_slot_list(uint_t *count, kcf_provider_desc_t ***array,
584     boolean_t unverified)
585 {
586 	kcf_provider_desc_t *prov_desc;
587 	kcf_provider_desc_t **p = NULL;
588 	char *last;
589 	uint_t cnt = 0;
590 	uint_t i, j;
591 	int rval = CRYPTO_SUCCESS;
592 	size_t n, final_size;
593 
594 	/* count the providers */
595 	mutex_enter(&prov_tab_mutex);
596 	for (i = 0; i < KCF_MAX_PROVIDERS; i++) {
597 		if ((prov_desc = prov_tab[i]) != NULL &&
598 		    ((prov_desc->pd_prov_type == CRYPTO_HW_PROVIDER &&
599 		    (prov_desc->pd_flags & CRYPTO_HIDE_PROVIDER) == 0) ||
600 		    prov_desc->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)) {
601 			if (KCF_IS_PROV_USABLE(prov_desc) ||
602 			    (unverified && KCF_IS_PROV_UNVERIFIED(prov_desc))) {
603 				cnt++;
604 			}
605 		}
606 	}
607 	mutex_exit(&prov_tab_mutex);
608 
609 	if (cnt == 0)
610 		goto out;
611 
612 	n = cnt * sizeof (kcf_provider_desc_t *);
613 again:
614 	p = kmem_zalloc(n, KM_SLEEP);
615 
616 	/* pointer to last entry in the array */
617 	last = (char *)&p[cnt-1];
618 
619 	mutex_enter(&prov_tab_mutex);
620 	/* fill the slot list */
621 	for (i = 0, j = 0; i < KCF_MAX_PROVIDERS; i++) {
622 		if ((prov_desc = prov_tab[i]) != NULL &&
623 		    ((prov_desc->pd_prov_type == CRYPTO_HW_PROVIDER &&
624 		    (prov_desc->pd_flags & CRYPTO_HIDE_PROVIDER) == 0) ||
625 		    prov_desc->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)) {
626 			if (KCF_IS_PROV_USABLE(prov_desc) ||
627 			    (unverified && KCF_IS_PROV_UNVERIFIED(prov_desc))) {
628 				if ((char *)&p[j] > last) {
629 					mutex_exit(&prov_tab_mutex);
630 					kcf_free_provider_tab(cnt, p);
631 					n = n << 1;
632 					cnt = cnt << 1;
633 					goto again;
634 				}
635 				p[j++] = prov_desc;
636 				KCF_PROV_REFHOLD(prov_desc);
637 			}
638 		}
639 	}
640 	mutex_exit(&prov_tab_mutex);
641 
642 	final_size = j * sizeof (kcf_provider_desc_t *);
643 	cnt = j;
644 	ASSERT(final_size <= n);
645 
646 	/* check if buffer we allocated is too large */
647 	if (final_size < n) {
648 		char *final_buffer = NULL;
649 
650 		if (final_size > 0) {
651 			final_buffer = kmem_alloc(final_size, KM_SLEEP);
652 			bcopy(p, final_buffer, final_size);
653 		}
654 		kmem_free(p, n);
655 		p = (kcf_provider_desc_t **)(void *)final_buffer;
656 	}
657 out:
658 	*count = cnt;
659 	*array = p;
660 	return (rval);
661 }
662 
663 /*
664  * Returns an array of hardware provider descriptors. This routine
665  * used by cryptoadm(1M). A REFHOLD is done on each descriptor before
666  * the array is returned. The entire table can be freed by calling
667  * kcf_free_provider_tab().
668  *
669  * A NULL name argument puts all hardware providers in the array.
670  * A non-NULL name argument puts only those providers in the array
671  * which match the name and instance arguments.
672  */
673 int
674 kcf_get_hw_prov_tab(uint_t *count, kcf_provider_desc_t ***array,  int kmflag,
675     char *name, uint_t instance, boolean_t unverified)
676 {
677 	kcf_provider_desc_t *prov_desc;
678 	kcf_provider_desc_t **p = NULL;
679 	char *last;
680 	uint_t cnt = 0;
681 	uint_t i, j;
682 	int rval = CRYPTO_SUCCESS;
683 	size_t n, final_size;
684 
685 	/* count the providers */
686 	mutex_enter(&prov_tab_mutex);
687 	for (i = 0; i < KCF_MAX_PROVIDERS; i++) {
688 		if ((prov_desc = prov_tab[i]) != NULL &&
689 		    prov_desc->pd_prov_type == CRYPTO_HW_PROVIDER) {
690 			if (KCF_IS_PROV_USABLE(prov_desc) ||
691 			    (unverified && KCF_IS_PROV_UNVERIFIED(prov_desc))) {
692 				if (name == NULL ||
693 				    (strncmp(prov_desc->pd_name, name,
694 				    MAXNAMELEN) == 0 &&
695 				    prov_desc->pd_instance == instance)) {
696 					cnt++;
697 				}
698 			}
699 		}
700 	}
701 	mutex_exit(&prov_tab_mutex);
702 
703 	if (cnt == 0)
704 		goto out;
705 
706 	n = cnt * sizeof (kcf_provider_desc_t *);
707 again:
708 	p = kmem_zalloc(n, kmflag);
709 	if (p == NULL) {
710 		rval = CRYPTO_HOST_MEMORY;
711 		goto out;
712 	}
713 	/* pointer to last entry in the array */
714 	last = (char *)&p[cnt-1];
715 
716 	mutex_enter(&prov_tab_mutex);
717 	for (i = 0, j = 0; i < KCF_MAX_PROVIDERS; i++) {
718 		if ((prov_desc = prov_tab[i]) != NULL &&
719 		    prov_desc->pd_prov_type == CRYPTO_HW_PROVIDER) {
720 			if (KCF_IS_PROV_USABLE(prov_desc) ||
721 			    (unverified && KCF_IS_PROV_UNVERIFIED(prov_desc))) {
722 				if (name == NULL ||
723 				    (strncmp(prov_desc->pd_name, name,
724 				    MAXNAMELEN) == 0 &&
725 				    prov_desc->pd_instance == instance)) {
726 					if ((char *)&p[j] > last) {
727 						mutex_exit(&prov_tab_mutex);
728 						kcf_free_provider_tab(cnt, p);
729 						n = n << 1;
730 						cnt = cnt << 1;
731 						goto again;
732 					}
733 					p[j++] = prov_desc;
734 					KCF_PROV_REFHOLD(prov_desc);
735 				}
736 			}
737 		}
738 	}
739 	mutex_exit(&prov_tab_mutex);
740 
741 	final_size = j * sizeof (kcf_provider_desc_t *);
742 	ASSERT(final_size <= n);
743 
744 	/* check if buffer we allocated is too large */
745 	if (final_size < n) {
746 		char *final_buffer = NULL;
747 
748 		if (final_size > 0) {
749 			final_buffer = kmem_alloc(final_size, kmflag);
750 			if (final_buffer == NULL) {
751 				kcf_free_provider_tab(cnt, p);
752 				cnt = 0;
753 				p = NULL;
754 				rval = CRYPTO_HOST_MEMORY;
755 				goto out;
756 			}
757 			bcopy(p, final_buffer, final_size);
758 		}
759 		kmem_free(p, n);
760 		p = (kcf_provider_desc_t **)(void *)final_buffer;
761 	}
762 	cnt = j;
763 out:
764 	*count = cnt;
765 	*array = p;
766 	return (rval);
767 }
768 
769 /*
770  * Free an array of hardware provider descriptors.  A REFRELE
771  * is done on each descriptor before the table is freed.
772  */
773 void
774 kcf_free_provider_tab(uint_t count, kcf_provider_desc_t **array)
775 {
776 	kcf_provider_desc_t *prov_desc;
777 	int i;
778 
779 	for (i = 0; i < count; i++) {
780 		if ((prov_desc = array[i]) != NULL) {
781 			KCF_PROV_REFRELE(prov_desc);
782 		}
783 	}
784 	kmem_free(array, count * sizeof (kcf_provider_desc_t *));
785 }
786 
787 /*
788  * Returns in the location pointed to by pd a pointer to the descriptor
789  * for the software provider for the specified mechanism.
790  * The provider descriptor is returned held and it is the caller's
791  * responsibility to release it when done. The mechanism entry
792  * is returned if the optional argument mep is non NULL.
793  *
794  * Returns one of the CRYPTO_ * error codes on failure, and
795  * CRYPTO_SUCCESS on success.
796  */
797 int
798 kcf_get_sw_prov(crypto_mech_type_t mech_type, kcf_provider_desc_t **pd,
799     kcf_mech_entry_t **mep, boolean_t log_warn)
800 {
801 	kcf_mech_entry_t *me;
802 	kcf_lock_withpad_t *mp;
803 
804 	/* get the mechanism entry for this mechanism */
805 	if (kcf_get_mech_entry(mech_type, &me) != KCF_SUCCESS)
806 		return (CRYPTO_MECHANISM_INVALID);
807 
808 	/*
809 	 * Get the software provider for this mechanism.
810 	 * Lock the mech_entry until we grab the 'pd'.
811 	 */
812 	mp = &me_mutexes[CPU_SEQID];
813 	mutex_enter(&mp->kl_lock);
814 
815 	if (me->me_sw_prov == NULL ||
816 	    (*pd = me->me_sw_prov->pm_prov_desc) == NULL) {
817 		/* no SW provider for this mechanism */
818 		if (log_warn)
819 			cmn_err(CE_WARN, "no SW provider for \"%s\"\n",
820 			    me->me_name);
821 		mutex_exit(&mp->kl_lock);
822 		return (CRYPTO_MECH_NOT_SUPPORTED);
823 	}
824 
825 	KCF_PROV_REFHOLD(*pd);
826 	mutex_exit(&mp->kl_lock);
827 
828 	if (mep != NULL)
829 		*mep = me;
830 
831 	return (CRYPTO_SUCCESS);
832 }
833 
834 #if DEBUG
835 /*
836  * Dump the Kernel crypto providers table, prov_tab.
837  * If kcf_frmwrk_debug is >=2, also dump the mechanism lists.
838  */
839 static void
840 kcf_prov_tab_dump(char *message)
841 {
842 	uint_t i, j;
843 
844 	mutex_enter(&prov_tab_mutex);
845 	printf("Providers table prov_tab at %s:\n",
846 	    message != NULL ? message : "");
847 
848 	for (i = 0; i < KCF_MAX_PROVIDERS; i++) {
849 		kcf_provider_desc_t *p = prov_tab[i];
850 		if (p != NULL) {
851 			printf("[%d]: (%s) %d mechanisms, %s\n", i,
852 			    (p->pd_prov_type == CRYPTO_HW_PROVIDER) ?
853 			    "HW" : "SW",
854 			    p->pd_mech_list_count, p->pd_description);
855 			if (kcf_frmwrk_debug >= 2) {
856 				printf("\tpd_mechanisms: ");
857 				for (j = 0; j < p->pd_mech_list_count; ++j) {
858 					printf("%s \n",
859 					    p->pd_mechanisms[j].cm_mech_name);
860 				}
861 				printf("\n");
862 			}
863 		}
864 	}
865 	printf("(end of providers table)\n");
866 
867 	mutex_exit(&prov_tab_mutex);
868 }
869 
870 #endif /* DEBUG */
871 
872 
873 /* protected by prov_tab_mutex */
874 boolean_t kcf_need_provtab_walk = B_FALSE;
875 
876 /* Caller must hold prov_tab_mutex */
877 static void
878 kcf_free_unregistered_provs()
879 {
880 	int i;
881 	kcf_provider_desc_t *pd;
882 	boolean_t walk_again = B_FALSE;
883 
884 	ASSERT(MUTEX_HELD(&prov_tab_mutex));
885 	for (i = 0; i < KCF_MAX_PROVIDERS; i++) {
886 		if ((pd = prov_tab[i]) == NULL ||
887 		    pd->pd_prov_type == CRYPTO_SW_PROVIDER ||
888 		    pd->pd_state != KCF_PROV_UNREGISTERED)
889 			continue;
890 
891 		if (kcf_get_refcnt(pd, B_TRUE) == 0) {
892 			/* kcf_free_provider_desc drops prov_tab_mutex */
893 			kcf_free_provider_desc(pd);
894 			mutex_enter(&prov_tab_mutex);
895 		} else
896 			walk_again = B_TRUE;
897 	}
898 
899 	kcf_need_provtab_walk = walk_again;
900 }
901