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