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