xref: /illumos-gate/usr/src/uts/common/crypto/spi/kcf_spi.c (revision 90f050286227cf4c4f8aa425555d04723d331d48)
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 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  * This file is part of the core Kernel Cryptographic Framework.
30  * It implements the SPI functions exported to cryptographic
31  * providers.
32  */
33 
34 #include <sys/ksynch.h>
35 #include <sys/cmn_err.h>
36 #include <sys/ddi.h>
37 #include <sys/sunddi.h>
38 #include <sys/modctl.h>
39 #include <sys/crypto/common.h>
40 #include <sys/crypto/impl.h>
41 #include <sys/crypto/sched_impl.h>
42 #include <sys/crypto/spi.h>
43 #include <sys/taskq.h>
44 #include <sys/disp.h>
45 #include <sys/kstat.h>
46 #include <sys/policy.h>
47 
48 /*
49  * minalloc and maxalloc values to be used for taskq_create().
50  */
51 int crypto_taskq_minalloc = CYRPTO_TASKQ_MIN;
52 int crypto_taskq_maxalloc = CRYPTO_TASKQ_MAX;
53 
54 static void free_provider_list(kcf_provider_list_t *);
55 static void remove_provider(kcf_provider_desc_t *);
56 static void process_logical_providers(crypto_provider_info_t *,
57     kcf_provider_desc_t *);
58 static void copy_ops_vector_v1(crypto_ops_t *, crypto_ops_t *);
59 static void copy_ops_vector_v2(crypto_ops_t *, crypto_ops_t *);
60 static int init_prov_mechs(crypto_provider_info_t *, kcf_provider_desc_t *);
61 static int kcf_prov_kstat_update(kstat_t *, int);
62 
63 static kcf_prov_stats_t kcf_stats_ks_data_template = {
64 	{ "kcf_ops_total",		KSTAT_DATA_UINT64 },
65 	{ "kcf_ops_passed",		KSTAT_DATA_UINT64 },
66 	{ "kcf_ops_failed",		KSTAT_DATA_UINT64 },
67 	{ "kcf_ops_returned_busy",	KSTAT_DATA_UINT64 }
68 };
69 
70 #define	KCF_SPI_COPY_OPS(src, dst, ops) if ((src)->ops != NULL) \
71 	*((dst)->ops) = *((src)->ops);
72 
73 /*
74  * This routine is used to add cryptographic providers to the KEF framework.
75  * Providers pass a crypto_provider_info structure to crypto_register_provider()
76  * and get back a handle.  The crypto_provider_info structure contains a
77  * list of mechanisms supported by the provider and an ops vector containing
78  * provider entry points.  Hardware providers call this routine in their attach
79  * routines.  Software providers call this routine in their _init() routine.
80  */
81 int
82 crypto_register_provider(crypto_provider_info_t *info,
83     crypto_kcf_provider_handle_t *handle)
84 {
85 	int i;
86 	int vstatus = 0;
87 	struct modctl *mcp;
88 	char *name;
89 	char ks_name[KSTAT_STRLEN];
90 	crypto_notify_event_change_t ec;
91 
92 	kcf_provider_desc_t *prov_desc = NULL;
93 	int ret = CRYPTO_ARGUMENTS_BAD;
94 
95 	if (info->pi_interface_version > CRYPTO_SPI_VERSION_2)
96 		return (CRYPTO_VERSION_MISMATCH);
97 
98 	/*
99 	 * Check provider type, must be software, hardware, or logical.
100 	 */
101 	if (info->pi_provider_type != CRYPTO_HW_PROVIDER &&
102 	    info->pi_provider_type != CRYPTO_SW_PROVIDER &&
103 	    info->pi_provider_type != CRYPTO_LOGICAL_PROVIDER)
104 		return (CRYPTO_ARGUMENTS_BAD);
105 
106 	/*
107 	 * Allocate and initialize a new provider descriptor. We also
108 	 * hold it and release it when done.
109 	 */
110 	prov_desc = kcf_alloc_provider_desc(info);
111 	KCF_PROV_REFHOLD(prov_desc);
112 
113 	prov_desc->pd_prov_type = info->pi_provider_type;
114 
115 	/* provider-private handle, opaque to KCF */
116 	prov_desc->pd_prov_handle = info->pi_provider_handle;
117 
118 	/* copy provider description string */
119 	if (info->pi_provider_description != NULL) {
120 		/*
121 		 * pi_provider_descriptor is a string that can contain
122 		 * up to CRYPTO_PROVIDER_DESCR_MAX_LEN + 1 characters
123 		 * INCLUDING the terminating null character. A bcopy()
124 		 * is necessary here as pd_description should not have
125 		 * a null character. See comments in kcf_alloc_provider_desc()
126 		 * for details on pd_description field.
127 		 */
128 		bcopy(info->pi_provider_description, prov_desc->pd_description,
129 		    min(strlen(info->pi_provider_description),
130 		    CRYPTO_PROVIDER_DESCR_MAX_LEN));
131 	}
132 
133 	if (info->pi_provider_type != CRYPTO_LOGICAL_PROVIDER) {
134 		if (info->pi_ops_vector == NULL) {
135 			return (CRYPTO_ARGUMENTS_BAD);
136 		}
137 		copy_ops_vector_v1(info->pi_ops_vector,
138 		    prov_desc->pd_ops_vector);
139 		if (info->pi_interface_version == CRYPTO_SPI_VERSION_2) {
140 			copy_ops_vector_v2(info->pi_ops_vector,
141 			    prov_desc->pd_ops_vector);
142 			prov_desc->pd_flags = info->pi_flags;
143 		}
144 	}
145 
146 	/*
147 	 * For software providers, copy the module name and module ID.
148 	 * For hardware providers, copy the driver name and instance.
149 	 */
150 	switch (info->pi_provider_type) {
151 	case  CRYPTO_SW_PROVIDER:
152 		if (info->pi_provider_dev.pd_sw == NULL)
153 			goto bail;
154 
155 		if ((mcp = mod_getctl(info->pi_provider_dev.pd_sw)) == NULL)
156 			goto bail;
157 
158 		prov_desc->pd_module_id = mcp->mod_id;
159 		name = mcp->mod_modname;
160 		break;
161 
162 	case CRYPTO_HW_PROVIDER:
163 	case CRYPTO_LOGICAL_PROVIDER:
164 		if (info->pi_provider_dev.pd_hw == NULL)
165 			goto bail;
166 
167 		prov_desc->pd_instance =
168 		    ddi_get_instance(info->pi_provider_dev.pd_hw);
169 		name = (char *)ddi_driver_name(info->pi_provider_dev.pd_hw);
170 		break;
171 	}
172 	if (name == NULL)
173 		goto bail;
174 
175 	prov_desc->pd_name = kmem_alloc(strlen(name) + 1, KM_SLEEP);
176 	(void) strcpy(prov_desc->pd_name, name);
177 
178 	if ((prov_desc->pd_mctlp = kcf_get_modctl(info)) == NULL)
179 		goto bail;
180 
181 	/* process the mechanisms supported by the provider */
182 	if ((ret = init_prov_mechs(info, prov_desc)) != CRYPTO_SUCCESS)
183 		goto bail;
184 
185 	/*
186 	 * Add provider to providers tables, also sets the descriptor
187 	 * pd_prov_id field.
188 	 */
189 	if ((ret = kcf_prov_tab_add_provider(prov_desc)) != CRYPTO_SUCCESS) {
190 		undo_register_provider(prov_desc, B_FALSE);
191 		goto bail;
192 	}
193 
194 	if (info->pi_provider_type != CRYPTO_LOGICAL_PROVIDER) {
195 		if ((vstatus = kcf_verify_signature(prov_desc)) ==
196 		    CRYPTO_MODVERIFICATION_FAILED) {
197 			undo_register_provider(prov_desc, B_TRUE);
198 			ret = CRYPTO_MODVERIFICATION_FAILED;
199 			goto bail;
200 		}
201 	}
202 
203 	/*
204 	 * We create a taskq only for a hardware provider. The global
205 	 * software queue is used for software providers. The taskq
206 	 * is limited to one thread since tasks are guaranteed to be
207 	 * executed in the order they are scheduled, if nthreads == 1. We
208 	 * pass TASKQ_PREPOPULATE flag to keep some entries cached to
209 	 * improve performance.
210 	 */
211 	if (prov_desc->pd_prov_type == CRYPTO_HW_PROVIDER)
212 		prov_desc->pd_sched_info.ks_taskq = taskq_create("kcf_taskq",
213 		    1, minclsyspri, crypto_taskq_minalloc,
214 		    crypto_taskq_maxalloc, TASKQ_PREPOPULATE);
215 	else
216 		prov_desc->pd_sched_info.ks_taskq = NULL;
217 
218 	/* no kernel session to logical providers */
219 	if (prov_desc->pd_prov_type != CRYPTO_LOGICAL_PROVIDER) {
220 		/*
221 		 * Open a session for session-oriented providers. This session
222 		 * is used for all kernel consumers. This is fine as a provider
223 		 * is required to support multiple thread access to a session.
224 		 * We can do this only after the taskq has been created as we
225 		 * do a kcf_submit_request() to open the session.
226 		 */
227 		if (KCF_PROV_SESSION_OPS(prov_desc) != NULL) {
228 			kcf_req_params_t params;
229 
230 			KCF_WRAP_SESSION_OPS_PARAMS(&params,
231 			    KCF_OP_SESSION_OPEN, &prov_desc->pd_sid, 0,
232 			    CRYPTO_USER, NULL, 0, prov_desc);
233 			ret = kcf_submit_request(prov_desc, NULL, NULL, &params,
234 			    B_FALSE);
235 
236 			if (ret != CRYPTO_SUCCESS) {
237 				undo_register_provider(prov_desc, B_TRUE);
238 				ret = CRYPTO_FAILED;
239 				goto bail;
240 			}
241 		}
242 	}
243 
244 	if (prov_desc->pd_prov_type != CRYPTO_LOGICAL_PROVIDER) {
245 		/*
246 		 * Create the kstat for this provider. There is a kstat
247 		 * installed for each successfully registered provider.
248 		 * This kstat is deleted, when the provider unregisters.
249 		 */
250 		if (prov_desc->pd_prov_type == CRYPTO_SW_PROVIDER) {
251 			(void) snprintf(ks_name, KSTAT_STRLEN, "%s_%s",
252 			    prov_desc->pd_name, "provider_stats");
253 		} else {
254 			(void) snprintf(ks_name, KSTAT_STRLEN, "%s_%d_%u_%s",
255 			    prov_desc->pd_name, prov_desc->pd_instance,
256 			    prov_desc->pd_prov_id, "provider_stats");
257 		}
258 
259 		prov_desc->pd_kstat = kstat_create("kcf", 0, ks_name, "crypto",
260 		    KSTAT_TYPE_NAMED, sizeof (kcf_prov_stats_t) /
261 		    sizeof (kstat_named_t), KSTAT_FLAG_VIRTUAL);
262 
263 		if (prov_desc->pd_kstat != NULL) {
264 			bcopy(&kcf_stats_ks_data_template,
265 			    &prov_desc->pd_ks_data,
266 			    sizeof (kcf_stats_ks_data_template));
267 			prov_desc->pd_kstat->ks_data = &prov_desc->pd_ks_data;
268 			KCF_PROV_REFHOLD(prov_desc);
269 			KCF_PROV_IREFHOLD(prov_desc);
270 			prov_desc->pd_kstat->ks_private = prov_desc;
271 			prov_desc->pd_kstat->ks_update = kcf_prov_kstat_update;
272 			kstat_install(prov_desc->pd_kstat);
273 		}
274 	}
275 
276 	if (prov_desc->pd_prov_type == CRYPTO_HW_PROVIDER)
277 		process_logical_providers(info, prov_desc);
278 
279 	/*
280 	 * Inform interested clients of the mechanisms becoming
281 	 * available. We skip this for logical providers as they
282 	 * do not affect mechanisms.
283 	 */
284 	if (prov_desc->pd_prov_type != CRYPTO_LOGICAL_PROVIDER) {
285 		ec.ec_provider_type = prov_desc->pd_prov_type;
286 		ec.ec_change = CRYPTO_MECH_ADDED;
287 		for (i = 0; i < prov_desc->pd_mech_list_count; i++) {
288 			/* Skip any mechanisms not allowed by the policy */
289 			if (is_mech_disabled(prov_desc,
290 			    prov_desc->pd_mechanisms[i].cm_mech_name))
291 				continue;
292 
293 			(void) strncpy(ec.ec_mech_name,
294 			    prov_desc->pd_mechanisms[i].cm_mech_name,
295 			    CRYPTO_MAX_MECH_NAME);
296 			kcf_walk_ntfylist(CRYPTO_EVENT_MECHS_CHANGED, &ec);
297 		}
298 
299 	}
300 
301 	/*
302 	 * Inform interested clients of the new provider. In case of a
303 	 * logical provider, we need to notify the event only
304 	 * for the logical provider and not for the underlying
305 	 * providers which are known by pi_logical_provider_count > 0.
306 	 */
307 	if (prov_desc->pd_prov_type == CRYPTO_LOGICAL_PROVIDER ||
308 	    info->pi_logical_provider_count == 0)
309 		kcf_walk_ntfylist(CRYPTO_EVENT_PROVIDER_REGISTERED, prov_desc);
310 
311 	mutex_enter(&prov_desc->pd_lock);
312 	prov_desc->pd_state = (vstatus == 0) ? KCF_PROV_READY :
313 	    KCF_PROV_UNVERIFIED;
314 	mutex_exit(&prov_desc->pd_lock);
315 
316 	*handle = prov_desc->pd_kcf_prov_handle;
317 	KCF_PROV_REFRELE(prov_desc);
318 	return (CRYPTO_SUCCESS);
319 
320 bail:
321 	KCF_PROV_REFRELE(prov_desc);
322 	return (ret);
323 }
324 
325 /*
326  * This routine is used to notify the framework when a provider is being
327  * removed.  Hardware providers call this routine in their detach routines.
328  * Software providers call this routine in their _fini() routine.
329  */
330 int
331 crypto_unregister_provider(crypto_kcf_provider_handle_t handle)
332 {
333 	int i;
334 	uint_t mech_idx;
335 	kcf_provider_desc_t *desc;
336 	crypto_notify_event_change_t ec;
337 	kcf_prov_state_t saved_state;
338 
339 	/* lookup provider descriptor */
340 	if ((desc = kcf_prov_tab_lookup((crypto_provider_id_t)handle)) == NULL)
341 		return (CRYPTO_UNKNOWN_PROVIDER);
342 
343 	mutex_enter(&desc->pd_lock);
344 	/*
345 	 * Check if any other thread is disabling or removing
346 	 * this provider. We return if this is the case.
347 	 */
348 	if (desc->pd_state >= KCF_PROV_DISABLED) {
349 		mutex_exit(&desc->pd_lock);
350 		/* Release reference held by kcf_prov_tab_lookup(). */
351 		KCF_PROV_REFRELE(desc);
352 		return (CRYPTO_BUSY);
353 	}
354 
355 	saved_state = desc->pd_state;
356 	desc->pd_state = KCF_PROV_REMOVED;
357 
358 	if (saved_state == KCF_PROV_BUSY) {
359 		/*
360 		 * The per-provider taskq thread may be waiting. We
361 		 * signal it so that it can start failing requests.
362 		 * Note that we do not need a cv_broadcast() as we keep
363 		 * only a single thread per taskq.
364 		 */
365 		cv_signal(&desc->pd_resume_cv);
366 	}
367 
368 	if (desc->pd_prov_type == CRYPTO_SW_PROVIDER) {
369 		/*
370 		 * Check if this provider is currently being used.
371 		 * pd_irefcnt is the number of holds from the internal
372 		 * structures. We add one to account for the above lookup.
373 		 */
374 		if (desc->pd_refcnt > desc->pd_irefcnt + 1) {
375 			desc->pd_state = saved_state;
376 			mutex_exit(&desc->pd_lock);
377 			/* Release reference held by kcf_prov_tab_lookup(). */
378 			KCF_PROV_REFRELE(desc);
379 			/*
380 			 * The administrator presumably will stop the clients
381 			 * thus removing the holds, when they get the busy
382 			 * return value.  Any retry will succeed then.
383 			 */
384 			return (CRYPTO_BUSY);
385 		}
386 	}
387 	mutex_exit(&desc->pd_lock);
388 
389 	if (desc->pd_prov_type != CRYPTO_SW_PROVIDER) {
390 		remove_provider(desc);
391 	}
392 
393 	if (desc->pd_prov_type != CRYPTO_LOGICAL_PROVIDER) {
394 		/* remove the provider from the mechanisms tables */
395 		for (mech_idx = 0; mech_idx < desc->pd_mech_list_count;
396 		    mech_idx++) {
397 			kcf_remove_mech_provider(
398 			    desc->pd_mechanisms[mech_idx].cm_mech_name, desc);
399 		}
400 	}
401 
402 	/* remove provider from providers table */
403 	if (kcf_prov_tab_rem_provider((crypto_provider_id_t)handle) !=
404 	    CRYPTO_SUCCESS) {
405 		/* Release reference held by kcf_prov_tab_lookup(). */
406 		KCF_PROV_REFRELE(desc);
407 		return (CRYPTO_UNKNOWN_PROVIDER);
408 	}
409 
410 	/* destroy the kstat created for this provider */
411 	if (desc->pd_kstat != NULL) {
412 		kcf_provider_desc_t *kspd = desc->pd_kstat->ks_private;
413 
414 		/* release reference held by desc->pd_kstat->ks_private */
415 		ASSERT(desc == kspd);
416 		kstat_delete(kspd->pd_kstat);
417 		KCF_PROV_REFRELE(kspd);
418 		KCF_PROV_IREFRELE(kspd);
419 	}
420 
421 	if (desc->pd_prov_type == CRYPTO_SW_PROVIDER) {
422 		/* Release reference held by kcf_prov_tab_lookup(). */
423 		KCF_PROV_REFRELE(desc);
424 
425 		/*
426 		 * Wait till the existing requests complete.
427 		 */
428 		mutex_enter(&desc->pd_lock);
429 		while (desc->pd_state != KCF_PROV_FREED)
430 			cv_wait(&desc->pd_remove_cv, &desc->pd_lock);
431 		mutex_exit(&desc->pd_lock);
432 	} else {
433 		/*
434 		 * Wait until requests that have been sent to the provider
435 		 * complete.
436 		 */
437 		mutex_enter(&desc->pd_lock);
438 		while (desc->pd_irefcnt > 0)
439 			cv_wait(&desc->pd_remove_cv, &desc->pd_lock);
440 		mutex_exit(&desc->pd_lock);
441 	}
442 
443 	/*
444 	 * Inform interested clients of the mechanisms becoming
445 	 * unavailable. We skip this for logical providers as they
446 	 * do not affect mechanisms.
447 	 */
448 	if (desc->pd_prov_type != CRYPTO_LOGICAL_PROVIDER) {
449 		ec.ec_provider_type = desc->pd_prov_type;
450 		ec.ec_change = CRYPTO_MECH_REMOVED;
451 		for (i = 0; i < desc->pd_mech_list_count; i++) {
452 			/* Skip any mechanisms not allowed by the policy */
453 			if (is_mech_disabled(desc,
454 			    desc->pd_mechanisms[i].cm_mech_name))
455 				continue;
456 
457 			(void) strncpy(ec.ec_mech_name,
458 			    desc->pd_mechanisms[i].cm_mech_name,
459 			    CRYPTO_MAX_MECH_NAME);
460 			kcf_walk_ntfylist(CRYPTO_EVENT_MECHS_CHANGED, &ec);
461 		}
462 
463 	}
464 
465 	/*
466 	 * Inform interested clients about the departing provider.
467 	 * In case of a logical provider, we need to notify the event only
468 	 * for the logical provider and not for the underlying
469 	 * providers which are known by the KCF_LPROV_MEMBER bit.
470 	 */
471 	if (desc->pd_prov_type == CRYPTO_LOGICAL_PROVIDER ||
472 	    (desc->pd_flags & KCF_LPROV_MEMBER) == 0)
473 		kcf_walk_ntfylist(CRYPTO_EVENT_PROVIDER_UNREGISTERED, desc);
474 
475 	if (desc->pd_prov_type == CRYPTO_SW_PROVIDER) {
476 		/*
477 		 * This is the only place where kcf_free_provider_desc()
478 		 * is called directly. KCF_PROV_REFRELE() should free the
479 		 * structure in all other places.
480 		 */
481 		ASSERT(desc->pd_state == KCF_PROV_FREED &&
482 		    desc->pd_refcnt == 0);
483 		kcf_free_provider_desc(desc);
484 	} else {
485 		KCF_PROV_REFRELE(desc);
486 	}
487 
488 	return (CRYPTO_SUCCESS);
489 }
490 
491 /*
492  * This routine is used to notify the framework that the state of
493  * a cryptographic provider has changed. Valid state codes are:
494  *
495  * CRYPTO_PROVIDER_READY
496  * 	The provider indicates that it can process more requests. A provider
497  *	will notify with this event if it previously has notified us with a
498  *	CRYPTO_PROVIDER_BUSY.
499  *
500  * CRYPTO_PROVIDER_BUSY
501  * 	The provider can not take more requests.
502  *
503  * CRYPTO_PROVIDER_FAILED
504  *	The provider encountered an internal error. The framework will not
505  * 	be sending any more requests to the provider. The provider may notify
506  *	with a CRYPTO_PROVIDER_READY, if it is able to recover from the error.
507  *
508  * This routine can be called from user or interrupt context.
509  */
510 void
511 crypto_provider_notification(crypto_kcf_provider_handle_t handle, uint_t state)
512 {
513 	kcf_provider_desc_t *pd;
514 
515 	/* lookup the provider from the given handle */
516 	if ((pd = kcf_prov_tab_lookup((crypto_provider_id_t)handle)) == NULL)
517 		return;
518 
519 	mutex_enter(&pd->pd_lock);
520 
521 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
522 		cmn_err(CE_WARN, "crypto_provider_notification: "
523 		    "logical provider (%x) ignored\n", handle);
524 		goto out;
525 	}
526 	switch (state) {
527 	case CRYPTO_PROVIDER_READY:
528 		switch (pd->pd_state) {
529 		case KCF_PROV_BUSY:
530 			pd->pd_state = KCF_PROV_READY;
531 			/*
532 			 * Signal the per-provider taskq thread that it
533 			 * can start submitting requests. Note that we do
534 			 * not need a cv_broadcast() as we keep only a
535 			 * single thread per taskq.
536 			 */
537 			cv_signal(&pd->pd_resume_cv);
538 			break;
539 
540 		case KCF_PROV_FAILED:
541 			/*
542 			 * The provider recovered from the error. Let us
543 			 * use it now.
544 			 */
545 			pd->pd_state = KCF_PROV_READY;
546 			break;
547 		}
548 		break;
549 
550 	case CRYPTO_PROVIDER_BUSY:
551 		switch (pd->pd_state) {
552 		case KCF_PROV_READY:
553 			pd->pd_state = KCF_PROV_BUSY;
554 			break;
555 		}
556 		break;
557 
558 	case CRYPTO_PROVIDER_FAILED:
559 		/*
560 		 * We note the failure and return. The per-provider taskq
561 		 * thread checks this flag and starts failing the
562 		 * requests, if it is set. See process_req_hwp() for details.
563 		 */
564 		switch (pd->pd_state) {
565 		case KCF_PROV_READY:
566 			pd->pd_state = KCF_PROV_FAILED;
567 			break;
568 
569 		case KCF_PROV_BUSY:
570 			pd->pd_state = KCF_PROV_FAILED;
571 			/*
572 			 * The per-provider taskq thread may be waiting. We
573 			 * signal it so that it can start failing requests.
574 			 */
575 			cv_signal(&pd->pd_resume_cv);
576 			break;
577 		}
578 		break;
579 	}
580 out:
581 	mutex_exit(&pd->pd_lock);
582 	KCF_PROV_REFRELE(pd);
583 }
584 
585 /*
586  * This routine is used to notify the framework the result of
587  * an asynchronous request handled by a provider. Valid error
588  * codes are the same as the CRYPTO_* errors defined in common.h.
589  *
590  * This routine can be called from user or interrupt context.
591  */
592 void
593 crypto_op_notification(crypto_req_handle_t handle, int error)
594 {
595 	kcf_call_type_t ctype;
596 
597 	if ((ctype = GET_REQ_TYPE(handle)) == CRYPTO_SYNCH) {
598 		kcf_sreq_node_t *sreq = (kcf_sreq_node_t *)handle;
599 
600 		if (error != CRYPTO_SUCCESS)
601 			sreq->sn_provider->pd_sched_info.ks_nfails++;
602 		KCF_PROV_IREFRELE(sreq->sn_provider);
603 		kcf_sop_done(sreq, error);
604 	} else {
605 		kcf_areq_node_t *areq = (kcf_areq_node_t *)handle;
606 
607 		ASSERT(ctype == CRYPTO_ASYNCH);
608 		if (error != CRYPTO_SUCCESS)
609 			areq->an_provider->pd_sched_info.ks_nfails++;
610 		KCF_PROV_IREFRELE(areq->an_provider);
611 		kcf_aop_done(areq, error);
612 	}
613 }
614 
615 /*
616  * This routine is used by software providers to determine
617  * whether to use KM_SLEEP or KM_NOSLEEP during memory allocation.
618  * Note that hardware providers can always use KM_SLEEP. So,
619  * they do not need to call this routine.
620  *
621  * This routine can be called from user or interrupt context.
622  */
623 int
624 crypto_kmflag(crypto_req_handle_t handle)
625 {
626 	return (REQHNDL2_KMFLAG(handle));
627 }
628 
629 
630 /*
631  * Copy an ops vector from src to dst. Used during provider registration
632  * to copy the ops vector from the provider info structure to the
633  * provider descriptor maintained by KCF.
634  * Copying the ops vector specified by the provider is needed since the
635  * framework does not require the provider info structure to be
636  * persistent.
637  */
638 static void
639 copy_ops_vector_v1(crypto_ops_t *src_ops, crypto_ops_t *dst_ops)
640 {
641 	KCF_SPI_COPY_OPS(src_ops, dst_ops, co_control_ops);
642 	KCF_SPI_COPY_OPS(src_ops, dst_ops, co_digest_ops);
643 	KCF_SPI_COPY_OPS(src_ops, dst_ops, co_cipher_ops);
644 	KCF_SPI_COPY_OPS(src_ops, dst_ops, co_mac_ops);
645 	KCF_SPI_COPY_OPS(src_ops, dst_ops, co_sign_ops);
646 	KCF_SPI_COPY_OPS(src_ops, dst_ops, co_verify_ops);
647 	KCF_SPI_COPY_OPS(src_ops, dst_ops, co_dual_ops);
648 	KCF_SPI_COPY_OPS(src_ops, dst_ops, co_dual_cipher_mac_ops);
649 	KCF_SPI_COPY_OPS(src_ops, dst_ops, co_random_ops);
650 	KCF_SPI_COPY_OPS(src_ops, dst_ops, co_session_ops);
651 	KCF_SPI_COPY_OPS(src_ops, dst_ops, co_object_ops);
652 	KCF_SPI_COPY_OPS(src_ops, dst_ops, co_key_ops);
653 	KCF_SPI_COPY_OPS(src_ops, dst_ops, co_provider_ops);
654 	KCF_SPI_COPY_OPS(src_ops, dst_ops, co_ctx_ops);
655 }
656 
657 static void
658 copy_ops_vector_v2(crypto_ops_t *src_ops, crypto_ops_t *dst_ops)
659 {
660 	KCF_SPI_COPY_OPS(src_ops, dst_ops, co_mech_ops);
661 }
662 
663 /*
664  * Process the mechanism info structures specified by the provider
665  * during registration. A NULL crypto_provider_info_t indicates
666  * an already initialized provider descriptor.
667  *
668  * Mechanisms are not added to the kernel's mechanism table if the
669  * provider is a logical provider.
670  *
671  * Returns CRYPTO_SUCCESS on success, CRYPTO_ARGUMENTS if one
672  * of the specified mechanisms was malformed, or CRYPTO_HOST_MEMORY
673  * if the table of mechanisms is full.
674  */
675 static int
676 init_prov_mechs(crypto_provider_info_t *info, kcf_provider_desc_t *desc)
677 {
678 	uint_t mech_idx;
679 	uint_t cleanup_idx;
680 	int err = CRYPTO_SUCCESS;
681 	kcf_prov_mech_desc_t *pmd;
682 	int desc_use_count = 0;
683 	int mcount = desc->pd_mech_list_count;
684 
685 	if (desc->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
686 		if (info != NULL) {
687 			ASSERT(info->pi_mechanisms != NULL);
688 			bcopy(info->pi_mechanisms, desc->pd_mechanisms,
689 			    sizeof (crypto_mech_info_t) * mcount);
690 		}
691 		return (CRYPTO_SUCCESS);
692 	}
693 
694 	/*
695 	 * Copy the mechanism list from the provider info to the provider
696 	 * descriptor. desc->pd_mechanisms has an extra crypto_mech_info_t
697 	 * element if the provider has random_ops since we keep an internal
698 	 * mechanism, SUN_RANDOM, in this case.
699 	 */
700 	if (info != NULL) {
701 		if (info->pi_ops_vector->co_random_ops != NULL) {
702 			crypto_mech_info_t *rand_mi;
703 
704 			/*
705 			 * Need the following check as it is possible to have
706 			 * a provider that implements just random_ops and has
707 			 * pi_mechanisms == NULL.
708 			 */
709 			if (info->pi_mechanisms != NULL) {
710 				bcopy(info->pi_mechanisms, desc->pd_mechanisms,
711 				    sizeof (crypto_mech_info_t) * (mcount - 1));
712 			}
713 			rand_mi = &desc->pd_mechanisms[mcount - 1];
714 
715 			bzero(rand_mi, sizeof (crypto_mech_info_t));
716 			(void) strncpy(rand_mi->cm_mech_name, SUN_RANDOM,
717 			    CRYPTO_MAX_MECH_NAME);
718 			rand_mi->cm_func_group_mask = CRYPTO_FG_RANDOM;
719 			/*
720 			 * What we really need here is a
721 			 * CRYPTO_KEYSIZE_NOT_APPLICABLE. We make do with the
722 			 * following for now.
723 			 */
724 			rand_mi->cm_keysize_unit = CRYPTO_KEYSIZE_UNIT_IN_BITS;
725 		} else {
726 			ASSERT(info->pi_mechanisms != NULL);
727 			bcopy(info->pi_mechanisms, desc->pd_mechanisms,
728 			    sizeof (crypto_mech_info_t) * mcount);
729 		}
730 	}
731 
732 	/*
733 	 * For each mechanism support by the provider, add the provider
734 	 * to the corresponding KCF mechanism mech_entry chain.
735 	 */
736 	for (mech_idx = 0; mech_idx < desc->pd_mech_list_count; mech_idx++) {
737 		crypto_mech_info_t *mi = &desc->pd_mechanisms[mech_idx];
738 
739 		if (mi->cm_keysize_unit != CRYPTO_KEYSIZE_UNIT_IN_BITS &&
740 		    mi->cm_keysize_unit != CRYPTO_KEYSIZE_UNIT_IN_BYTES) {
741 			err = CRYPTO_ARGUMENTS_BAD;
742 			break;
743 		}
744 
745 		if (kcf_add_mech_provider(mi, desc, &pmd) != KCF_SUCCESS)
746 			break;
747 
748 		if (pmd == NULL)
749 			continue;
750 
751 		/* The provider will be used for this mechanism */
752 		desc_use_count++;
753 	}
754 
755 	/*
756 	 * Don't allow multiple software providers with disabled mechanisms
757 	 * to register. Subsequent enabling of mechanisms will result in
758 	 * an unsupported configuration, i.e. multiple software providers
759 	 * per mechanism.
760 	 */
761 	if (desc_use_count == 0 && desc->pd_prov_type == CRYPTO_SW_PROVIDER)
762 		return (CRYPTO_ARGUMENTS_BAD);
763 
764 	if (err == KCF_SUCCESS)
765 		return (CRYPTO_SUCCESS);
766 
767 	/*
768 	 * An error occurred while adding the mechanism, cleanup
769 	 * and bail.
770 	 */
771 	for (cleanup_idx = 0; cleanup_idx < mech_idx; cleanup_idx++) {
772 		kcf_remove_mech_provider(
773 		    desc->pd_mechanisms[cleanup_idx].cm_mech_name, desc);
774 	}
775 
776 	if (err == KCF_MECH_TAB_FULL)
777 		return (CRYPTO_HOST_MEMORY);
778 
779 	return (CRYPTO_ARGUMENTS_BAD);
780 }
781 
782 /*
783  * Update routine for kstat. Only privileged users are allowed to
784  * access this information, since this information is sensitive.
785  * There are some cryptographic attacks (e.g. traffic analysis)
786  * which can use this information.
787  */
788 static int
789 kcf_prov_kstat_update(kstat_t *ksp, int rw)
790 {
791 	kcf_prov_stats_t *ks_data;
792 	kcf_provider_desc_t *pd = (kcf_provider_desc_t *)ksp->ks_private;
793 
794 	if (rw == KSTAT_WRITE)
795 		return (EACCES);
796 
797 	ks_data = ksp->ks_data;
798 
799 	if (secpolicy_sys_config(CRED(), B_TRUE) != 0) {
800 		ks_data->ps_ops_total.value.ui64 = 0;
801 		ks_data->ps_ops_passed.value.ui64 = 0;
802 		ks_data->ps_ops_failed.value.ui64 = 0;
803 		ks_data->ps_ops_busy_rval.value.ui64 = 0;
804 	} else {
805 		ks_data->ps_ops_total.value.ui64 =
806 		    pd->pd_sched_info.ks_ndispatches;
807 		ks_data->ps_ops_failed.value.ui64 =
808 		    pd->pd_sched_info.ks_nfails;
809 		ks_data->ps_ops_busy_rval.value.ui64 =
810 		    pd->pd_sched_info.ks_nbusy_rval;
811 		ks_data->ps_ops_passed.value.ui64 =
812 		    pd->pd_sched_info.ks_ndispatches -
813 		    pd->pd_sched_info.ks_nfails -
814 		    pd->pd_sched_info.ks_nbusy_rval;
815 	}
816 
817 	return (0);
818 }
819 
820 
821 /*
822  * Utility routine called from failure paths in crypto_register_provider()
823  * and from crypto_load_soft_disabled().
824  */
825 void
826 undo_register_provider(kcf_provider_desc_t *desc, boolean_t remove_prov)
827 {
828 	uint_t mech_idx;
829 
830 	/* remove the provider from the mechanisms tables */
831 	for (mech_idx = 0; mech_idx < desc->pd_mech_list_count;
832 	    mech_idx++) {
833 		kcf_remove_mech_provider(
834 		    desc->pd_mechanisms[mech_idx].cm_mech_name, desc);
835 	}
836 
837 	/* remove provider from providers table */
838 	if (remove_prov)
839 		(void) kcf_prov_tab_rem_provider(desc->pd_prov_id);
840 }
841 
842 /*
843  * Utility routine called from crypto_load_soft_disabled(). Callers
844  * should have done a prior undo_register_provider().
845  */
846 void
847 redo_register_provider(kcf_provider_desc_t *pd)
848 {
849 	/* process the mechanisms supported by the provider */
850 	(void) init_prov_mechs(NULL, pd);
851 
852 	/*
853 	 * Hold provider in providers table. We should not call
854 	 * kcf_prov_tab_add_provider() here as the provider descriptor
855 	 * is still valid which means it has an entry in the provider
856 	 * table.
857 	 */
858 	KCF_PROV_REFHOLD(pd);
859 	KCF_PROV_IREFHOLD(pd);
860 }
861 
862 /*
863  * Add provider (p1) to another provider's array of providers (p2).
864  * Hardware and logical providers use this array to cross-reference
865  * each other.
866  */
867 static void
868 add_provider_to_array(kcf_provider_desc_t *p1, kcf_provider_desc_t *p2)
869 {
870 	kcf_provider_list_t *new;
871 
872 	new = kmem_alloc(sizeof (kcf_provider_list_t), KM_SLEEP);
873 	mutex_enter(&p2->pd_lock);
874 	new->pl_next = p2->pd_provider_list;
875 	p2->pd_provider_list = new;
876 	KCF_PROV_IREFHOLD(p1);
877 	new->pl_provider = p1;
878 	mutex_exit(&p2->pd_lock);
879 }
880 
881 /*
882  * Remove provider (p1) from another provider's array of providers (p2).
883  * Hardware and logical providers use this array to cross-reference
884  * each other.
885  */
886 static void
887 remove_provider_from_array(kcf_provider_desc_t *p1, kcf_provider_desc_t *p2)
888 {
889 
890 	kcf_provider_list_t *pl = NULL, **prev;
891 
892 	mutex_enter(&p2->pd_lock);
893 	for (pl = p2->pd_provider_list, prev = &p2->pd_provider_list;
894 	    pl != NULL; prev = &pl->pl_next, pl = pl->pl_next) {
895 		if (pl->pl_provider == p1) {
896 			break;
897 		}
898 	}
899 
900 	if (p1 == NULL) {
901 		mutex_exit(&p2->pd_lock);
902 		return;
903 	}
904 
905 	/* detach and free kcf_provider_list structure */
906 	KCF_PROV_IREFRELE(p1);
907 	*prev = pl->pl_next;
908 	kmem_free(pl, sizeof (*pl));
909 	mutex_exit(&p2->pd_lock);
910 }
911 
912 /*
913  * Convert an array of logical provider handles (crypto_provider_id)
914  * stored in a crypto_provider_info structure into an array of provider
915  * descriptors (kcf_provider_desc_t) attached to a logical provider.
916  */
917 static void
918 process_logical_providers(crypto_provider_info_t *info, kcf_provider_desc_t *hp)
919 {
920 	kcf_provider_desc_t *lp;
921 	crypto_provider_id_t handle;
922 	int count = info->pi_logical_provider_count;
923 	int i;
924 
925 	/* add hardware provider to each logical provider */
926 	for (i = 0; i < count; i++) {
927 		handle = info->pi_logical_providers[i];
928 		lp = kcf_prov_tab_lookup((crypto_provider_id_t)handle);
929 		if (lp == NULL) {
930 			continue;
931 		}
932 		add_provider_to_array(hp, lp);
933 		hp->pd_flags |= KCF_LPROV_MEMBER;
934 
935 		/*
936 		 * A hardware provider has to have the provider descriptor of
937 		 * every logical provider it belongs to, so it can be removed
938 		 * from the logical provider if the hardware provider
939 		 * unregisters from the framework.
940 		 */
941 		add_provider_to_array(lp, hp);
942 		KCF_PROV_REFRELE(lp);
943 	}
944 }
945 
946 /*
947  * This routine removes a provider from all of the logical or
948  * hardware providers it belongs to, and frees the provider's
949  * array of pointers to providers.
950  */
951 static void
952 remove_provider(kcf_provider_desc_t *pp)
953 {
954 	kcf_provider_desc_t *p;
955 	kcf_provider_list_t *e, *next;
956 
957 	mutex_enter(&pp->pd_lock);
958 	for (e = pp->pd_provider_list; e != NULL; e = next) {
959 		p = e->pl_provider;
960 		remove_provider_from_array(pp, p);
961 		if (p->pd_prov_type == CRYPTO_HW_PROVIDER &&
962 		    p->pd_provider_list == NULL)
963 			p->pd_flags &= ~KCF_LPROV_MEMBER;
964 		KCF_PROV_IREFRELE(p);
965 		next = e->pl_next;
966 		kmem_free(e, sizeof (*e));
967 	}
968 	pp->pd_provider_list = NULL;
969 	mutex_exit(&pp->pd_lock);
970 }
971