xref: /illumos-gate/usr/src/uts/common/crypto/core/kcf_callprov.c (revision f48205be61a214698b763ff550ab9e657525104c)
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 2007 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 contains routines which call into a provider's
30  * entry points and do other related work.
31  */
32 
33 #include <sys/types.h>
34 #include <sys/systm.h>
35 #include <sys/taskq_impl.h>
36 #include <sys/cmn_err.h>
37 
38 #include <sys/crypto/common.h>
39 #include <sys/crypto/impl.h>
40 #include <sys/crypto/sched_impl.h>
41 
42 /*
43  * Return B_TRUE if the specified entry point is NULL. We rely on the
44  * caller to provide, with offset_1 and offset_2, information to calculate
45  * the location of the entry point. The ops argument is a temporary local
46  * variable defined as caddr_t *.
47  */
48 #define	KCF_PROV_NULL_ENTRY_POINT(pd, o1, o2, ops)			\
49 	(ops = (caddr_t *)((caddr_t)(pd)->pd_ops_vector + (o1)),	\
50 	(*ops == NULL || *(caddr_t *)((caddr_t)(*ops) + (o2)) == NULL))
51 
52 
53 static int kcf_emulate_dual(kcf_provider_desc_t *, crypto_ctx_t *,
54     kcf_req_params_t *);
55 void
56 kcf_free_triedlist(kcf_prov_tried_t *list)
57 {
58 	kcf_prov_tried_t *l;
59 
60 	while ((l = list) != NULL) {
61 		list = list->pt_next;
62 		KCF_PROV_REFRELE(l->pt_pd);
63 		kmem_free(l, sizeof (kcf_prov_tried_t));
64 	}
65 }
66 
67 kcf_prov_tried_t *
68 kcf_insert_triedlist(kcf_prov_tried_t **list, kcf_provider_desc_t *pd,
69     int kmflag)
70 {
71 	kcf_prov_tried_t *l;
72 
73 	l = kmem_alloc(sizeof (kcf_prov_tried_t), kmflag);
74 	if (l == NULL)
75 		return (NULL);
76 
77 	l->pt_pd = pd;
78 	l->pt_next = *list;
79 	*list = l;
80 
81 	return (l);
82 }
83 
84 static boolean_t
85 is_in_triedlist(kcf_provider_desc_t *pd, kcf_prov_tried_t *triedl)
86 {
87 	while (triedl != NULL) {
88 		if (triedl->pt_pd == pd)
89 			return (B_TRUE);
90 		triedl = triedl->pt_next;
91 	};
92 
93 	return (B_FALSE);
94 }
95 
96 /*
97  * Search a mech entry's hardware provider list for the specified
98  * provider. Return true if found.
99  */
100 static boolean_t
101 is_valid_provider_for_mech(kcf_provider_desc_t *pd, kcf_mech_entry_t *me,
102     crypto_func_group_t fg)
103 {
104 	kcf_prov_mech_desc_t *prov_chain;
105 
106 	prov_chain = me->me_hw_prov_chain;
107 	if (prov_chain != NULL) {
108 		ASSERT(me->me_num_hwprov > 0);
109 		for (; prov_chain != NULL; prov_chain = prov_chain->pm_next) {
110 			if (prov_chain->pm_prov_desc == pd &&
111 			    IS_FG_SUPPORTED(prov_chain, fg)) {
112 				return (B_TRUE);
113 			}
114 		}
115 	}
116 	return (B_FALSE);
117 }
118 
119 /*
120  * This routine, given a logical provider, returns the least loaded
121  * provider belonging to the logical provider. The provider must be
122  * able to do the specified mechanism, i.e. check that the mechanism
123  * hasn't been disabled. In addition, just in case providers are not
124  * entirely equivalent, the provider's entry point is checked for
125  * non-nullness. This is accomplished by having the caller pass, as
126  * arguments, the offset of the function group (offset_1), and the
127  * offset of the function within the function group (offset_2).
128  * Returns NULL if no provider can be found.
129  */
130 int
131 kcf_get_hardware_provider(crypto_mech_type_t mech_type_1,
132     crypto_mech_type_t mech_type_2, boolean_t call_restrict,
133     kcf_provider_desc_t *old, kcf_provider_desc_t **new, crypto_func_group_t fg)
134 {
135 	kcf_provider_desc_t *provider, *real_pd = old;
136 	kcf_provider_desc_t *gpd = NULL;	/* good provider */
137 	kcf_provider_desc_t *bpd = NULL;	/* busy provider */
138 	kcf_provider_list_t *p;
139 	kcf_ops_class_t class;
140 	kcf_mech_entry_t *me;
141 	kcf_mech_entry_tab_t *me_tab;
142 	int index, len, gqlen = INT_MAX, rv = CRYPTO_SUCCESS;
143 
144 	/* get the mech entry for the specified mechanism */
145 	class = KCF_MECH2CLASS(mech_type_1);
146 	if ((class < KCF_FIRST_OPSCLASS) || (class > KCF_LAST_OPSCLASS)) {
147 		return (CRYPTO_MECHANISM_INVALID);
148 	}
149 
150 	me_tab = &kcf_mech_tabs_tab[class];
151 	index = KCF_MECH2INDEX(mech_type_1);
152 	if ((index < 0) || (index >= me_tab->met_size)) {
153 		return (CRYPTO_MECHANISM_INVALID);
154 	}
155 
156 	me = &((me_tab->met_tab)[index]);
157 	mutex_enter(&me->me_mutex);
158 
159 	/*
160 	 * We assume the provider descriptor will not go away because
161 	 * it is being held somewhere, i.e. its reference count has been
162 	 * incremented. In the case of the crypto module, the provider
163 	 * descriptor is held by the session structure.
164 	 */
165 	if (old->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
166 		if (old->pd_provider_list == NULL) {
167 			real_pd = NULL;
168 			rv = CRYPTO_DEVICE_ERROR;
169 			goto out;
170 		}
171 		/*
172 		 * Find the least loaded real provider. tq_nalloc gives
173 		 * the number of task entries in the task queue. We do
174 		 * not acquire tq_lock here as it is not critical to
175 		 * get the exact number and the lock contention may be
176 		 * too costly for this code path.
177 		 */
178 		mutex_enter(&old->pd_lock);
179 		p = old->pd_provider_list;
180 		while (p != NULL) {
181 			provider = p->pl_provider;
182 
183 			ASSERT(provider->pd_prov_type !=
184 			    CRYPTO_LOGICAL_PROVIDER);
185 
186 			if (call_restrict &&
187 			    (provider->pd_flags & KCF_PROV_RESTRICTED)) {
188 				p = p->pl_next;
189 				continue;
190 			}
191 
192 			if (!is_valid_provider_for_mech(provider, me, fg)) {
193 				p = p->pl_next;
194 				continue;
195 			}
196 
197 			/* provider does second mech */
198 			if (mech_type_2 != CRYPTO_MECH_INVALID) {
199 				int i;
200 
201 				i = KCF_TO_PROV_MECH_INDX(provider,
202 				    mech_type_2);
203 				if (i == KCF_INVALID_INDX) {
204 					p = p->pl_next;
205 					continue;
206 				}
207 			}
208 
209 			if (provider->pd_state != KCF_PROV_READY) {
210 				/* choose BUSY if no READY providers */
211 				if (provider->pd_state == KCF_PROV_BUSY)
212 					bpd = provider;
213 				p = p->pl_next;
214 				continue;
215 			}
216 
217 			len = provider->pd_sched_info.ks_taskq->tq_nalloc;
218 			if (len < gqlen) {
219 				gqlen = len;
220 				gpd = provider;
221 			}
222 
223 			p = p->pl_next;
224 		}
225 
226 		if (gpd != NULL) {
227 			real_pd = gpd;
228 			KCF_PROV_REFHOLD(real_pd);
229 		} else if (bpd != NULL) {
230 			real_pd = bpd;
231 			KCF_PROV_REFHOLD(real_pd);
232 		} else {
233 			/* can't find provider */
234 			real_pd = NULL;
235 			rv = CRYPTO_MECHANISM_INVALID;
236 		}
237 		mutex_exit(&old->pd_lock);
238 
239 	} else {
240 		if (!KCF_IS_PROV_USABLE(old) ||
241 		    (call_restrict && (old->pd_flags & KCF_PROV_RESTRICTED))) {
242 			real_pd = NULL;
243 			rv = CRYPTO_DEVICE_ERROR;
244 			goto out;
245 		}
246 
247 		if (!is_valid_provider_for_mech(old, me, fg)) {
248 			real_pd = NULL;
249 			rv = CRYPTO_MECHANISM_INVALID;
250 			goto out;
251 		}
252 
253 		KCF_PROV_REFHOLD(real_pd);
254 	}
255 out:
256 	mutex_exit(&me->me_mutex);
257 	*new = real_pd;
258 	return (rv);
259 }
260 
261 /*
262  * This routine, given a logical provider, returns the least loaded
263  * provider belonging to the logical provider. Just in case providers
264  * are not entirely equivalent, the provider's entry point is checked
265  * for non-nullness. This is accomplished by having the caller pass, as
266  * arguments, the offset of the function group (offset_1), and the
267  * offset of the function within the function group (offset_2).
268  * Returns NULL if no provider can be found.
269  */
270 int
271 kcf_get_hardware_provider_nomech(offset_t offset_1, offset_t offset_2,
272     boolean_t call_restrict, kcf_provider_desc_t *old,
273     kcf_provider_desc_t **new)
274 {
275 	kcf_provider_desc_t *provider, *real_pd = old;
276 	kcf_provider_desc_t *gpd = NULL;	/* good provider */
277 	kcf_provider_desc_t *bpd = NULL;	/* busy provider */
278 	kcf_provider_list_t *p;
279 	caddr_t *ops;
280 	int len, gqlen = INT_MAX, rv = CRYPTO_SUCCESS;
281 
282 	/*
283 	 * We assume the provider descriptor will not go away because
284 	 * it is being held somewhere, i.e. its reference count has been
285 	 * incremented. In the case of the crypto module, the provider
286 	 * descriptor is held by the session structure.
287 	 */
288 	if (old->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
289 		if (old->pd_provider_list == NULL) {
290 			real_pd = NULL;
291 			rv = CRYPTO_DEVICE_ERROR;
292 			goto out;
293 		}
294 		/*
295 		 * Find the least loaded real provider. tq_nalloc gives
296 		 * the number of task entries in the task queue. We do
297 		 * not acquire tq_lock here as it is not critical to
298 		 * get the exact number and the lock contention may be
299 		 * too costly for this code path.
300 		 */
301 		mutex_enter(&old->pd_lock);
302 		p = old->pd_provider_list;
303 		while (p != NULL) {
304 			provider = p->pl_provider;
305 
306 			ASSERT(provider->pd_prov_type !=
307 			    CRYPTO_LOGICAL_PROVIDER);
308 
309 			if (call_restrict &&
310 			    (provider->pd_flags & KCF_PROV_RESTRICTED)) {
311 				p = p->pl_next;
312 				continue;
313 			}
314 			if (KCF_PROV_NULL_ENTRY_POINT(provider, offset_1,
315 			    offset_2, ops)) {
316 				p = p->pl_next;
317 				continue;
318 			}
319 
320 			if (provider->pd_state != KCF_PROV_READY) {
321 				/* choose BUSY if no READY providers */
322 				if (provider->pd_state == KCF_PROV_BUSY)
323 					bpd = provider;
324 				p = p->pl_next;
325 				continue;
326 			}
327 
328 			len = provider->pd_sched_info.ks_taskq->tq_nalloc;
329 			if (len < gqlen) {
330 				gqlen = len;
331 				gpd = provider;
332 			}
333 
334 			p = p->pl_next;
335 		}
336 		mutex_exit(&old->pd_lock);
337 
338 		if (gpd != NULL) {
339 			real_pd = gpd;
340 			KCF_PROV_REFHOLD(real_pd);
341 		} else if (bpd != NULL) {
342 			real_pd = bpd;
343 			KCF_PROV_REFHOLD(real_pd);
344 		} else {
345 			/* can't find provider */
346 			real_pd = NULL;
347 			rv = CRYPTO_DEVICE_ERROR;
348 		}
349 
350 	} else {
351 		if (!KCF_IS_PROV_USABLE(old) ||
352 		    (call_restrict && (old->pd_flags & KCF_PROV_RESTRICTED))) {
353 			real_pd = NULL;
354 			rv = CRYPTO_DEVICE_ERROR;
355 			goto out;
356 		}
357 
358 		if (KCF_PROV_NULL_ENTRY_POINT(old, offset_1, offset_2, ops)) {
359 			real_pd = NULL;
360 			rv = CRYPTO_NOT_SUPPORTED;
361 			goto out;
362 		}
363 		KCF_PROV_REFHOLD(real_pd);
364 	}
365 out:
366 	*new = real_pd;
367 	return (rv);
368 }
369 
370 /*
371  * Return the next member of a logical provider, given the previous
372  * member. The function returns true if the next member is found and
373  * bumps its refcnt before returning.
374  */
375 boolean_t
376 kcf_get_next_logical_provider_member(kcf_provider_desc_t *logical_provider,
377     kcf_provider_desc_t *prev, kcf_provider_desc_t **pd)
378 {
379 	kcf_provider_list_t *p;
380 	kcf_provider_desc_t *next;
381 
382 	ASSERT(MUTEX_HELD(&logical_provider->pd_lock));
383 	p = logical_provider->pd_provider_list;
384 	while (p != NULL) {
385 		/* start the search */
386 		if (prev == NULL) {
387 			next = p->pl_provider;
388 			goto found;
389 		} else {
390 			/* find where we were before */
391 			if (p->pl_provider == prev) {
392 				if (p->pl_next != NULL) {
393 					next = p->pl_next->pl_provider;
394 					goto found;
395 				}
396 			}
397 		}
398 		p = p->pl_next;
399 	}
400 	return (B_FALSE);
401 
402 found:
403 	KCF_PROV_REFHOLD(next);
404 	*pd = next;
405 	return (B_TRUE);
406 }
407 
408 /*
409  * Return the best provider for the specified mechanism. The provider
410  * is held and it is the caller's responsibility to release it when done.
411  * The fg input argument is used as a search criterion to pick a provider.
412  * A provider has to support this function group to be picked.
413  *
414  * Find the least loaded provider in the list of providers. We do a linear
415  * search to find one. This is fine as we assume there are only a few
416  * number of providers in this list. If this assumption ever changes,
417  * we should revisit this.
418  *
419  * call_restrict represents if the caller should not be allowed to
420  * use restricted providers.
421  */
422 kcf_provider_desc_t *
423 kcf_get_mech_provider(crypto_mech_type_t mech_type, kcf_mech_entry_t **mepp,
424     int *error, kcf_prov_tried_t *triedl, crypto_func_group_t fg,
425     boolean_t call_restrict, size_t data_size)
426 {
427 	kcf_provider_desc_t *pd = NULL, *gpd = NULL;
428 	kcf_prov_mech_desc_t *prov_chain, *mdesc;
429 	int len, gqlen = INT_MAX;
430 	kcf_ops_class_t class;
431 	int index;
432 	kcf_mech_entry_t *me;
433 	kcf_mech_entry_tab_t *me_tab;
434 
435 	class = KCF_MECH2CLASS(mech_type);
436 	if ((class < KCF_FIRST_OPSCLASS) || (class > KCF_LAST_OPSCLASS)) {
437 		*error = CRYPTO_MECHANISM_INVALID;
438 		return (NULL);
439 	}
440 
441 	me_tab = &kcf_mech_tabs_tab[class];
442 	index = KCF_MECH2INDEX(mech_type);
443 	if ((index < 0) || (index >= me_tab->met_size)) {
444 		*error = CRYPTO_MECHANISM_INVALID;
445 		return (NULL);
446 	}
447 
448 	me = &((me_tab->met_tab)[index]);
449 	if (mepp != NULL)
450 		*mepp = me;
451 
452 	mutex_enter(&me->me_mutex);
453 
454 	prov_chain = me->me_hw_prov_chain;
455 
456 	/*
457 	 * We check for the threshhold for using a hardware provider for
458 	 * this amount of data. If there is no software provider available
459 	 * for the mechanism, then the threshold is ignored.
460 	 */
461 	if ((prov_chain != NULL) &&
462 	    ((data_size == 0) || (me->me_threshold == 0) ||
463 	    (data_size >= me->me_threshold) ||
464 	    ((mdesc = me->me_sw_prov) == NULL) ||
465 	    (!IS_FG_SUPPORTED(mdesc, fg)) ||
466 	    (!KCF_IS_PROV_USABLE(mdesc->pm_prov_desc)))) {
467 		ASSERT(me->me_num_hwprov > 0);
468 		/* there is at least one provider */
469 
470 		/*
471 		 * Find the least loaded provider. tq_nalloc gives
472 		 * the number of task entries in the task queue. We do
473 		 * not acquire tq_lock here as it is not critical to
474 		 * get the exact number and the lock contention may be
475 		 * too costly for this code path.
476 		 */
477 		while (prov_chain != NULL) {
478 			pd = prov_chain->pm_prov_desc;
479 
480 			if (!IS_FG_SUPPORTED(prov_chain, fg) ||
481 			    !KCF_IS_PROV_USABLE(pd) ||
482 			    IS_PROVIDER_TRIED(pd, triedl) ||
483 			    (call_restrict &&
484 				(pd->pd_flags & KCF_PROV_RESTRICTED))) {
485 				prov_chain = prov_chain->pm_next;
486 				continue;
487 			}
488 
489 			if ((len = pd->pd_sched_info.ks_taskq->tq_nalloc)
490 			    < gqlen) {
491 				gqlen = len;
492 				gpd = pd;
493 			}
494 
495 			prov_chain = prov_chain->pm_next;
496 		}
497 
498 		pd = gpd;
499 	}
500 
501 	/* No HW provider for this mech, is there a SW provider? */
502 	if (pd == NULL && (mdesc = me->me_sw_prov) != NULL) {
503 		pd = mdesc->pm_prov_desc;
504 		if (!IS_FG_SUPPORTED(mdesc, fg) ||
505 		    !KCF_IS_PROV_USABLE(pd) ||
506 		    IS_PROVIDER_TRIED(pd, triedl) ||
507 		    (call_restrict && (pd->pd_flags & KCF_PROV_RESTRICTED)))
508 			pd = NULL;
509 	}
510 
511 	if (pd == NULL) {
512 		/*
513 		 * We do not want to report CRYPTO_MECH_NOT_SUPPORTED, when
514 		 * we are in the "fallback to the next provider" case. Rather
515 		 * we preserve the error, so that the client gets the right
516 		 * error code.
517 		 */
518 		if (triedl == NULL)
519 			*error = CRYPTO_MECH_NOT_SUPPORTED;
520 	} else
521 		KCF_PROV_REFHOLD(pd);
522 
523 	mutex_exit(&me->me_mutex);
524 	return (pd);
525 }
526 
527 /*
528  * Very similar to kcf_get_mech_provider(). Finds the best provider capable of
529  * a dual operation with both me1 and me2.
530  * When no dual-ops capable providers are available, return the best provider
531  * for me1 only, and sets *prov_mt2 to CRYPTO_INVALID_MECHID;
532  * We assume/expect that a slower HW capable of the dual is still
533  * faster than the 2 fastest providers capable of the individual ops
534  * separately.
535  */
536 kcf_provider_desc_t *
537 kcf_get_dual_provider(crypto_mechanism_t *mech1, crypto_mechanism_t *mech2,
538     kcf_mech_entry_t **mepp, crypto_mech_type_t *prov_mt1,
539     crypto_mech_type_t *prov_mt2, int *error, kcf_prov_tried_t *triedl,
540     crypto_func_group_t fg1, crypto_func_group_t fg2, boolean_t call_restrict,
541     size_t data_size)
542 {
543 	kcf_provider_desc_t *pd = NULL, *pdm1 = NULL, *pdm1m2 = NULL;
544 	kcf_prov_mech_desc_t *prov_chain, *mdesc;
545 	int len, gqlen = INT_MAX, dgqlen = INT_MAX;
546 	crypto_mech_info_list_t *mil;
547 	crypto_mech_type_t m2id =  mech2->cm_type;
548 	kcf_mech_entry_t *me;
549 
550 	/* when mech is a valid mechanism, me will be its mech_entry */
551 	if (kcf_get_mech_entry(mech1->cm_type, &me) != KCF_SUCCESS) {
552 		*error = CRYPTO_MECHANISM_INVALID;
553 		return (NULL);
554 	}
555 
556 	*prov_mt2 = CRYPTO_MECH_INVALID;
557 
558 	if (mepp != NULL)
559 		*mepp = me;
560 	mutex_enter(&me->me_mutex);
561 
562 	prov_chain = me->me_hw_prov_chain;
563 	/*
564 	 * We check the threshold for using a hardware provider for
565 	 * this amount of data. If there is no software provider available
566 	 * for the first mechanism, then the threshold is ignored.
567 	 */
568 	if ((prov_chain != NULL) &&
569 	    ((data_size == 0) || (me->me_threshold == 0) ||
570 	    (data_size >= me->me_threshold) ||
571 	    ((mdesc = me->me_sw_prov) == NULL) ||
572 	    (!IS_FG_SUPPORTED(mdesc, fg1)) ||
573 	    (!KCF_IS_PROV_USABLE(mdesc->pm_prov_desc)))) {
574 		/* there is at least one provider */
575 		ASSERT(me->me_num_hwprov > 0);
576 
577 		/*
578 		 * Find the least loaded provider capable of the combo
579 		 * me1 + me2, and save a pointer to the least loaded
580 		 * provider capable of me1 only.
581 		 */
582 		while (prov_chain != NULL) {
583 			pd = prov_chain->pm_prov_desc;
584 			len = pd->pd_sched_info.ks_taskq->tq_nalloc;
585 
586 			if (!IS_FG_SUPPORTED(prov_chain, fg1) ||
587 			    !KCF_IS_PROV_USABLE(pd) ||
588 			    IS_PROVIDER_TRIED(pd, triedl) ||
589 			    (call_restrict &&
590 				(pd->pd_flags & KCF_PROV_RESTRICTED))) {
591 				prov_chain = prov_chain->pm_next;
592 				continue;
593 			}
594 
595 			/* Save the best provider capable of m1 */
596 			if (len < gqlen) {
597 				*prov_mt1 =
598 				    prov_chain->pm_mech_info.cm_mech_number;
599 				gqlen = len;
600 				pdm1 = pd;
601 			}
602 
603 			/* See if pd can do me2 too */
604 			for (mil = prov_chain->pm_mi_list;
605 			    mil != NULL; mil = mil->ml_next) {
606 				if ((mil->ml_mech_info.cm_func_group_mask &
607 				    fg2) == 0)
608 					continue;
609 
610 				if ((mil->ml_kcf_mechid == m2id) &&
611 				    (len < dgqlen)) {
612 					/* Bingo! */
613 					dgqlen = len;
614 					pdm1m2 = pd;
615 					*prov_mt2 =
616 					    mil->ml_mech_info.cm_mech_number;
617 					*prov_mt1 = prov_chain->
618 					    pm_mech_info.cm_mech_number;
619 					break;
620 				}
621 			}
622 
623 			prov_chain = prov_chain->pm_next;
624 		}
625 
626 		pd =  (pdm1m2 != NULL) ? pdm1m2 : pdm1;
627 	}
628 
629 	/* no HW provider for this mech, is there a SW provider? */
630 	if (pd == NULL && (mdesc = me->me_sw_prov) != NULL) {
631 		pd = mdesc->pm_prov_desc;
632 		if (!IS_FG_SUPPORTED(mdesc, fg1) ||
633 		    !KCF_IS_PROV_USABLE(pd) ||
634 		    IS_PROVIDER_TRIED(pd, triedl) ||
635 		    (call_restrict && (pd->pd_flags & KCF_PROV_RESTRICTED)))
636 			pd = NULL;
637 		else {
638 			/* See if pd can do me2 too */
639 			for (mil = me->me_sw_prov->pm_mi_list;
640 			    mil != NULL; mil = mil->ml_next) {
641 				if ((mil->ml_mech_info.cm_func_group_mask &
642 				    fg2) == 0)
643 					continue;
644 
645 				if (mil->ml_kcf_mechid == m2id) {
646 					/* Bingo! */
647 					*prov_mt2 =
648 					    mil->ml_mech_info.cm_mech_number;
649 					break;
650 				}
651 			}
652 			*prov_mt1 = me->me_sw_prov->pm_mech_info.cm_mech_number;
653 		}
654 	}
655 
656 	if (pd == NULL)
657 		*error = CRYPTO_MECH_NOT_SUPPORTED;
658 	else
659 		KCF_PROV_REFHOLD(pd);
660 
661 	mutex_exit(&me->me_mutex);
662 	return (pd);
663 }
664 
665 /*
666  * Do the actual work of calling the provider routines.
667  *
668  * pd - Provider structure
669  * ctx - Context for this operation
670  * params - Parameters for this operation
671  * rhndl - Request handle to use for notification
672  *
673  * The return values are the same as that of the respective SPI.
674  */
675 int
676 common_submit_request(kcf_provider_desc_t *pd, crypto_ctx_t *ctx,
677     kcf_req_params_t *params, crypto_req_handle_t rhndl)
678 {
679 	int err = CRYPTO_ARGUMENTS_BAD;
680 	kcf_op_type_t optype;
681 
682 	optype = params->rp_optype;
683 
684 	switch (params->rp_opgrp) {
685 	case KCF_OG_DIGEST: {
686 		kcf_digest_ops_params_t *dops = &params->rp_u.digest_params;
687 
688 		switch (optype) {
689 		case KCF_OP_INIT:
690 			/*
691 			 * We should do this only here and not in KCF_WRAP_*
692 			 * macros. This is because we may want to try other
693 			 * providers, in case we recover from a failure.
694 			 */
695 			KCF_SET_PROVIDER_MECHNUM(dops->do_framework_mechtype,
696 			    pd, &dops->do_mech);
697 
698 			err = KCF_PROV_DIGEST_INIT(pd, ctx, &dops->do_mech,
699 			    rhndl);
700 			break;
701 
702 		case KCF_OP_SINGLE:
703 			err = KCF_PROV_DIGEST(pd, ctx, dops->do_data,
704 			    dops->do_digest, rhndl);
705 			break;
706 
707 		case KCF_OP_UPDATE:
708 			err = KCF_PROV_DIGEST_UPDATE(pd, ctx,
709 			    dops->do_data, rhndl);
710 			break;
711 
712 		case KCF_OP_FINAL:
713 			err = KCF_PROV_DIGEST_FINAL(pd, ctx,
714 			    dops->do_digest, rhndl);
715 			break;
716 
717 		case KCF_OP_ATOMIC:
718 			ASSERT(ctx == NULL);
719 			KCF_SET_PROVIDER_MECHNUM(dops->do_framework_mechtype,
720 			    pd, &dops->do_mech);
721 			err = KCF_PROV_DIGEST_ATOMIC(pd, dops->do_sid,
722 			    &dops->do_mech, dops->do_data, dops->do_digest,
723 			    rhndl);
724 			break;
725 
726 		case KCF_OP_DIGEST_KEY:
727 			err = KCF_PROV_DIGEST_KEY(pd, ctx, dops->do_digest_key,
728 			    rhndl);
729 			break;
730 
731 		default:
732 			break;
733 		}
734 		break;
735 	}
736 
737 	case KCF_OG_MAC: {
738 		kcf_mac_ops_params_t *mops = &params->rp_u.mac_params;
739 
740 		switch (optype) {
741 		case KCF_OP_INIT:
742 			KCF_SET_PROVIDER_MECHNUM(mops->mo_framework_mechtype,
743 			    pd, &mops->mo_mech);
744 
745 			err = KCF_PROV_MAC_INIT(pd, ctx, &mops->mo_mech,
746 			    mops->mo_key, mops->mo_templ, rhndl);
747 			break;
748 
749 		case KCF_OP_SINGLE:
750 			err = KCF_PROV_MAC(pd, ctx, mops->mo_data,
751 			    mops->mo_mac, rhndl);
752 			break;
753 
754 		case KCF_OP_UPDATE:
755 			err = KCF_PROV_MAC_UPDATE(pd, ctx, mops->mo_data,
756 			    rhndl);
757 			break;
758 
759 		case KCF_OP_FINAL:
760 			err = KCF_PROV_MAC_FINAL(pd, ctx, mops->mo_mac, rhndl);
761 			break;
762 
763 		case KCF_OP_ATOMIC:
764 			ASSERT(ctx == NULL);
765 			KCF_SET_PROVIDER_MECHNUM(mops->mo_framework_mechtype,
766 			    pd, &mops->mo_mech);
767 
768 			err = KCF_PROV_MAC_ATOMIC(pd, mops->mo_sid,
769 			    &mops->mo_mech, mops->mo_key, mops->mo_data,
770 			    mops->mo_mac, mops->mo_templ, rhndl);
771 			break;
772 
773 		case KCF_OP_MAC_VERIFY_ATOMIC:
774 			ASSERT(ctx == NULL);
775 			KCF_SET_PROVIDER_MECHNUM(mops->mo_framework_mechtype,
776 			    pd, &mops->mo_mech);
777 
778 			err = KCF_PROV_MAC_VERIFY_ATOMIC(pd, mops->mo_sid,
779 			    &mops->mo_mech, mops->mo_key, mops->mo_data,
780 			    mops->mo_mac, mops->mo_templ, rhndl);
781 			break;
782 
783 		default:
784 			break;
785 		}
786 		break;
787 	}
788 
789 	case KCF_OG_ENCRYPT: {
790 		kcf_encrypt_ops_params_t *eops = &params->rp_u.encrypt_params;
791 
792 		switch (optype) {
793 		case KCF_OP_INIT:
794 			KCF_SET_PROVIDER_MECHNUM(eops->eo_framework_mechtype,
795 			    pd, &eops->eo_mech);
796 
797 			err = KCF_PROV_ENCRYPT_INIT(pd, ctx, &eops->eo_mech,
798 			    eops->eo_key, eops->eo_templ, rhndl);
799 			break;
800 
801 		case KCF_OP_SINGLE:
802 			err = KCF_PROV_ENCRYPT(pd, ctx, eops->eo_plaintext,
803 			    eops->eo_ciphertext, rhndl);
804 			break;
805 
806 		case KCF_OP_UPDATE:
807 			err = KCF_PROV_ENCRYPT_UPDATE(pd, ctx,
808 			    eops->eo_plaintext, eops->eo_ciphertext, rhndl);
809 			break;
810 
811 		case KCF_OP_FINAL:
812 			err = KCF_PROV_ENCRYPT_FINAL(pd, ctx,
813 			    eops->eo_ciphertext, rhndl);
814 			break;
815 
816 		case KCF_OP_ATOMIC:
817 			ASSERT(ctx == NULL);
818 			KCF_SET_PROVIDER_MECHNUM(eops->eo_framework_mechtype,
819 			    pd, &eops->eo_mech);
820 
821 			err = KCF_PROV_ENCRYPT_ATOMIC(pd, eops->eo_sid,
822 			    &eops->eo_mech, eops->eo_key, eops->eo_plaintext,
823 			    eops->eo_ciphertext, eops->eo_templ, rhndl);
824 			break;
825 
826 		default:
827 			break;
828 		}
829 		break;
830 	}
831 
832 	case KCF_OG_DECRYPT: {
833 		kcf_decrypt_ops_params_t *dcrops = &params->rp_u.decrypt_params;
834 
835 		switch (optype) {
836 		case KCF_OP_INIT:
837 			KCF_SET_PROVIDER_MECHNUM(dcrops->dop_framework_mechtype,
838 			    pd, &dcrops->dop_mech);
839 
840 			err = KCF_PROV_DECRYPT_INIT(pd, ctx, &dcrops->dop_mech,
841 			    dcrops->dop_key, dcrops->dop_templ, rhndl);
842 			break;
843 
844 		case KCF_OP_SINGLE:
845 			err = KCF_PROV_DECRYPT(pd, ctx, dcrops->dop_ciphertext,
846 			    dcrops->dop_plaintext, rhndl);
847 			break;
848 
849 		case KCF_OP_UPDATE:
850 			err = KCF_PROV_DECRYPT_UPDATE(pd, ctx,
851 			    dcrops->dop_ciphertext, dcrops->dop_plaintext,
852 			    rhndl);
853 			break;
854 
855 		case KCF_OP_FINAL:
856 			err = KCF_PROV_DECRYPT_FINAL(pd, ctx,
857 			    dcrops->dop_plaintext, rhndl);
858 			break;
859 
860 		case KCF_OP_ATOMIC:
861 			ASSERT(ctx == NULL);
862 			KCF_SET_PROVIDER_MECHNUM(dcrops->dop_framework_mechtype,
863 			    pd, &dcrops->dop_mech);
864 
865 			err = KCF_PROV_DECRYPT_ATOMIC(pd, dcrops->dop_sid,
866 			    &dcrops->dop_mech, dcrops->dop_key,
867 			    dcrops->dop_ciphertext, dcrops->dop_plaintext,
868 			    dcrops->dop_templ, rhndl);
869 			break;
870 
871 		default:
872 			break;
873 		}
874 		break;
875 	}
876 
877 	case KCF_OG_SIGN: {
878 		kcf_sign_ops_params_t *sops = &params->rp_u.sign_params;
879 
880 		switch (optype) {
881 		case KCF_OP_INIT:
882 			KCF_SET_PROVIDER_MECHNUM(sops->so_framework_mechtype,
883 			    pd, &sops->so_mech);
884 
885 			err = KCF_PROV_SIGN_INIT(pd, ctx, &sops->so_mech,
886 			    sops->so_key, sops->so_templ, rhndl);
887 			break;
888 
889 		case KCF_OP_SIGN_RECOVER_INIT:
890 			KCF_SET_PROVIDER_MECHNUM(sops->so_framework_mechtype,
891 			    pd, &sops->so_mech);
892 
893 			err = KCF_PROV_SIGN_RECOVER_INIT(pd, ctx,
894 			    &sops->so_mech, sops->so_key, sops->so_templ,
895 			    rhndl);
896 			break;
897 
898 		case KCF_OP_SINGLE:
899 			err = KCF_PROV_SIGN(pd, ctx, sops->so_data,
900 			    sops->so_signature, rhndl);
901 			break;
902 
903 		case KCF_OP_SIGN_RECOVER:
904 			err = KCF_PROV_SIGN_RECOVER(pd, ctx,
905 			    sops->so_data, sops->so_signature, rhndl);
906 			break;
907 
908 		case KCF_OP_UPDATE:
909 			err = KCF_PROV_SIGN_UPDATE(pd, ctx, sops->so_data,
910 			    rhndl);
911 			break;
912 
913 		case KCF_OP_FINAL:
914 			err = KCF_PROV_SIGN_FINAL(pd, ctx, sops->so_signature,
915 			    rhndl);
916 			break;
917 
918 		case KCF_OP_ATOMIC:
919 			ASSERT(ctx == NULL);
920 			KCF_SET_PROVIDER_MECHNUM(sops->so_framework_mechtype,
921 			    pd, &sops->so_mech);
922 
923 			err = KCF_PROV_SIGN_ATOMIC(pd, sops->so_sid,
924 			    &sops->so_mech, sops->so_key, sops->so_data,
925 			    sops->so_templ, sops->so_signature, rhndl);
926 			break;
927 
928 		case KCF_OP_SIGN_RECOVER_ATOMIC:
929 			ASSERT(ctx == NULL);
930 			KCF_SET_PROVIDER_MECHNUM(sops->so_framework_mechtype,
931 			    pd, &sops->so_mech);
932 
933 			err = KCF_PROV_SIGN_RECOVER_ATOMIC(pd, sops->so_sid,
934 			    &sops->so_mech, sops->so_key, sops->so_data,
935 			    sops->so_templ, sops->so_signature, rhndl);
936 			break;
937 
938 		default:
939 			break;
940 		}
941 		break;
942 	}
943 
944 	case KCF_OG_VERIFY: {
945 		kcf_verify_ops_params_t *vops = &params->rp_u.verify_params;
946 
947 		switch (optype) {
948 		case KCF_OP_INIT:
949 			KCF_SET_PROVIDER_MECHNUM(vops->vo_framework_mechtype,
950 			    pd, &vops->vo_mech);
951 
952 			err = KCF_PROV_VERIFY_INIT(pd, ctx, &vops->vo_mech,
953 			    vops->vo_key, vops->vo_templ, rhndl);
954 			break;
955 
956 		case KCF_OP_VERIFY_RECOVER_INIT:
957 			KCF_SET_PROVIDER_MECHNUM(vops->vo_framework_mechtype,
958 			    pd, &vops->vo_mech);
959 
960 			err = KCF_PROV_VERIFY_RECOVER_INIT(pd, ctx,
961 			    &vops->vo_mech, vops->vo_key, vops->vo_templ,
962 			    rhndl);
963 			break;
964 
965 		case KCF_OP_SINGLE:
966 			err = KCF_PROV_VERIFY(pd, ctx, vops->vo_data,
967 			    vops->vo_signature, rhndl);
968 			break;
969 
970 		case KCF_OP_VERIFY_RECOVER:
971 			err = KCF_PROV_VERIFY_RECOVER(pd, ctx,
972 			    vops->vo_signature, vops->vo_data, rhndl);
973 			break;
974 
975 		case KCF_OP_UPDATE:
976 			err = KCF_PROV_VERIFY_UPDATE(pd, ctx, vops->vo_data,
977 			    rhndl);
978 			break;
979 
980 		case KCF_OP_FINAL:
981 			err = KCF_PROV_VERIFY_FINAL(pd, ctx, vops->vo_signature,
982 			    rhndl);
983 			break;
984 
985 		case KCF_OP_ATOMIC:
986 			ASSERT(ctx == NULL);
987 			KCF_SET_PROVIDER_MECHNUM(vops->vo_framework_mechtype,
988 			    pd, &vops->vo_mech);
989 
990 			err = KCF_PROV_VERIFY_ATOMIC(pd, vops->vo_sid,
991 			    &vops->vo_mech, vops->vo_key, vops->vo_data,
992 			    vops->vo_templ, vops->vo_signature, rhndl);
993 			break;
994 
995 		case KCF_OP_VERIFY_RECOVER_ATOMIC:
996 			ASSERT(ctx == NULL);
997 			KCF_SET_PROVIDER_MECHNUM(vops->vo_framework_mechtype,
998 			    pd, &vops->vo_mech);
999 
1000 			err = KCF_PROV_VERIFY_RECOVER_ATOMIC(pd, vops->vo_sid,
1001 			    &vops->vo_mech, vops->vo_key, vops->vo_signature,
1002 			    vops->vo_templ, vops->vo_data, rhndl);
1003 			break;
1004 
1005 		default:
1006 			break;
1007 		}
1008 		break;
1009 	}
1010 
1011 	case KCF_OG_ENCRYPT_MAC: {
1012 		kcf_encrypt_mac_ops_params_t *eops =
1013 		    &params->rp_u.encrypt_mac_params;
1014 		kcf_context_t *kcf_secondctx;
1015 
1016 		switch (optype) {
1017 		case KCF_OP_INIT:
1018 			kcf_secondctx = ((kcf_context_t *)
1019 			    (ctx->cc_framework_private))->kc_secondctx;
1020 
1021 			if (kcf_secondctx != NULL) {
1022 				err = kcf_emulate_dual(pd, ctx, params);
1023 				break;
1024 			}
1025 			KCF_SET_PROVIDER_MECHNUM(
1026 			    eops->em_framework_encr_mechtype,
1027 			    pd, &eops->em_encr_mech);
1028 
1029 			KCF_SET_PROVIDER_MECHNUM(
1030 			    eops->em_framework_mac_mechtype,
1031 			    pd, &eops->em_mac_mech);
1032 
1033 			err = KCF_PROV_ENCRYPT_MAC_INIT(pd, ctx,
1034 			    &eops->em_encr_mech, eops->em_encr_key,
1035 			    &eops->em_mac_mech, eops->em_mac_key,
1036 			    eops->em_encr_templ, eops->em_mac_templ,
1037 			    rhndl);
1038 
1039 			break;
1040 
1041 		case KCF_OP_SINGLE:
1042 			err = KCF_PROV_ENCRYPT_MAC(pd, ctx,
1043 			    eops->em_plaintext, eops->em_ciphertext,
1044 			    eops->em_mac, rhndl);
1045 			break;
1046 
1047 		case KCF_OP_UPDATE:
1048 			kcf_secondctx = ((kcf_context_t *)
1049 			    (ctx->cc_framework_private))->kc_secondctx;
1050 			if (kcf_secondctx != NULL) {
1051 				err = kcf_emulate_dual(pd, ctx, params);
1052 				break;
1053 			}
1054 			err = KCF_PROV_ENCRYPT_MAC_UPDATE(pd, ctx,
1055 			    eops->em_plaintext, eops->em_ciphertext, rhndl);
1056 			break;
1057 
1058 		case KCF_OP_FINAL:
1059 			kcf_secondctx = ((kcf_context_t *)
1060 			    (ctx->cc_framework_private))->kc_secondctx;
1061 			if (kcf_secondctx != NULL) {
1062 				err = kcf_emulate_dual(pd, ctx, params);
1063 				break;
1064 			}
1065 			err = KCF_PROV_ENCRYPT_MAC_FINAL(pd, ctx,
1066 			    eops->em_ciphertext, eops->em_mac, rhndl);
1067 			break;
1068 
1069 		case KCF_OP_ATOMIC:
1070 			ASSERT(ctx == NULL);
1071 
1072 			KCF_SET_PROVIDER_MECHNUM(
1073 			    eops->em_framework_encr_mechtype,
1074 			    pd, &eops->em_encr_mech);
1075 
1076 			KCF_SET_PROVIDER_MECHNUM(
1077 			    eops->em_framework_mac_mechtype,
1078 			    pd, &eops->em_mac_mech);
1079 
1080 			err = KCF_PROV_ENCRYPT_MAC_ATOMIC(pd, eops->em_sid,
1081 			    &eops->em_encr_mech, eops->em_encr_key,
1082 			    &eops->em_mac_mech, eops->em_mac_key,
1083 			    eops->em_plaintext, eops->em_ciphertext,
1084 			    eops->em_mac,
1085 			    eops->em_encr_templ, eops->em_mac_templ,
1086 			    rhndl);
1087 
1088 			break;
1089 
1090 		default:
1091 			break;
1092 		}
1093 		break;
1094 	}
1095 
1096 	case KCF_OG_MAC_DECRYPT: {
1097 		kcf_mac_decrypt_ops_params_t *dops =
1098 		    &params->rp_u.mac_decrypt_params;
1099 		kcf_context_t *kcf_secondctx;
1100 
1101 		switch (optype) {
1102 		case KCF_OP_INIT:
1103 			kcf_secondctx = ((kcf_context_t *)
1104 			    (ctx->cc_framework_private))->kc_secondctx;
1105 
1106 			if (kcf_secondctx != NULL) {
1107 				err = kcf_emulate_dual(pd, ctx, params);
1108 				break;
1109 			}
1110 			KCF_SET_PROVIDER_MECHNUM(
1111 			    dops->md_framework_mac_mechtype,
1112 			    pd, &dops->md_mac_mech);
1113 
1114 			KCF_SET_PROVIDER_MECHNUM(
1115 			    dops->md_framework_decr_mechtype,
1116 			    pd, &dops->md_decr_mech);
1117 
1118 			err = KCF_PROV_MAC_DECRYPT_INIT(pd, ctx,
1119 			    &dops->md_mac_mech, dops->md_mac_key,
1120 			    &dops->md_decr_mech, dops->md_decr_key,
1121 			    dops->md_mac_templ, dops->md_decr_templ,
1122 			    rhndl);
1123 
1124 			break;
1125 
1126 		case KCF_OP_SINGLE:
1127 			err = KCF_PROV_MAC_DECRYPT(pd, ctx,
1128 			    dops->md_ciphertext, dops->md_mac,
1129 			    dops->md_plaintext, rhndl);
1130 			break;
1131 
1132 		case KCF_OP_UPDATE:
1133 			kcf_secondctx = ((kcf_context_t *)
1134 			    (ctx->cc_framework_private))->kc_secondctx;
1135 			if (kcf_secondctx != NULL) {
1136 				err = kcf_emulate_dual(pd, ctx, params);
1137 				break;
1138 			}
1139 			err = KCF_PROV_MAC_DECRYPT_UPDATE(pd, ctx,
1140 			    dops->md_ciphertext, dops->md_plaintext, rhndl);
1141 			break;
1142 
1143 		case KCF_OP_FINAL:
1144 			kcf_secondctx = ((kcf_context_t *)
1145 			    (ctx->cc_framework_private))->kc_secondctx;
1146 			if (kcf_secondctx != NULL) {
1147 				err = kcf_emulate_dual(pd, ctx, params);
1148 				break;
1149 			}
1150 			err = KCF_PROV_MAC_DECRYPT_FINAL(pd, ctx,
1151 			    dops->md_mac, dops->md_plaintext, rhndl);
1152 			break;
1153 
1154 		case KCF_OP_ATOMIC:
1155 			ASSERT(ctx == NULL);
1156 
1157 			KCF_SET_PROVIDER_MECHNUM(
1158 			    dops->md_framework_mac_mechtype,
1159 			    pd, &dops->md_mac_mech);
1160 
1161 			KCF_SET_PROVIDER_MECHNUM(
1162 			    dops->md_framework_decr_mechtype,
1163 			    pd, &dops->md_decr_mech);
1164 
1165 			err = KCF_PROV_MAC_DECRYPT_ATOMIC(pd, dops->md_sid,
1166 			    &dops->md_mac_mech, dops->md_mac_key,
1167 			    &dops->md_decr_mech, dops->md_decr_key,
1168 			    dops->md_ciphertext, dops->md_mac,
1169 			    dops->md_plaintext,
1170 			    dops->md_mac_templ, dops->md_decr_templ,
1171 			    rhndl);
1172 
1173 			break;
1174 
1175 		case KCF_OP_MAC_VERIFY_DECRYPT_ATOMIC:
1176 			ASSERT(ctx == NULL);
1177 
1178 			KCF_SET_PROVIDER_MECHNUM(
1179 			    dops->md_framework_mac_mechtype,
1180 			    pd, &dops->md_mac_mech);
1181 
1182 			KCF_SET_PROVIDER_MECHNUM(
1183 			    dops->md_framework_decr_mechtype,
1184 			    pd, &dops->md_decr_mech);
1185 
1186 			err = KCF_PROV_MAC_VERIFY_DECRYPT_ATOMIC(pd,
1187 			    dops->md_sid, &dops->md_mac_mech, dops->md_mac_key,
1188 			    &dops->md_decr_mech, dops->md_decr_key,
1189 			    dops->md_ciphertext, dops->md_mac,
1190 			    dops->md_plaintext,
1191 			    dops->md_mac_templ, dops->md_decr_templ,
1192 			    rhndl);
1193 
1194 			break;
1195 
1196 		default:
1197 			break;
1198 		}
1199 		break;
1200 	}
1201 
1202 	case KCF_OG_KEY: {
1203 		kcf_key_ops_params_t *kops = &params->rp_u.key_params;
1204 
1205 		ASSERT(ctx == NULL);
1206 		KCF_SET_PROVIDER_MECHNUM(kops->ko_framework_mechtype, pd,
1207 		    &kops->ko_mech);
1208 
1209 		switch (optype) {
1210 		case KCF_OP_KEY_GENERATE:
1211 			err = KCF_PROV_KEY_GENERATE(pd, kops->ko_sid,
1212 			    &kops->ko_mech,
1213 			    kops->ko_key_template, kops->ko_key_attribute_count,
1214 			    kops->ko_key_object_id_ptr, rhndl);
1215 			break;
1216 
1217 		case KCF_OP_KEY_GENERATE_PAIR:
1218 			err = KCF_PROV_KEY_GENERATE_PAIR(pd, kops->ko_sid,
1219 			    &kops->ko_mech,
1220 			    kops->ko_key_template, kops->ko_key_attribute_count,
1221 			    kops->ko_private_key_template,
1222 			    kops->ko_private_key_attribute_count,
1223 			    kops->ko_key_object_id_ptr,
1224 			    kops->ko_private_key_object_id_ptr, rhndl);
1225 			break;
1226 
1227 		case KCF_OP_KEY_WRAP:
1228 			err = KCF_PROV_KEY_WRAP(pd, kops->ko_sid,
1229 			    &kops->ko_mech,
1230 			    kops->ko_key, kops->ko_key_object_id_ptr,
1231 			    kops->ko_wrapped_key, kops->ko_wrapped_key_len_ptr,
1232 			    rhndl);
1233 			break;
1234 
1235 		case KCF_OP_KEY_UNWRAP:
1236 			err = KCF_PROV_KEY_UNWRAP(pd, kops->ko_sid,
1237 			    &kops->ko_mech,
1238 			    kops->ko_key, kops->ko_wrapped_key,
1239 			    kops->ko_wrapped_key_len_ptr,
1240 			    kops->ko_key_template, kops->ko_key_attribute_count,
1241 			    kops->ko_key_object_id_ptr, rhndl);
1242 			break;
1243 
1244 		case KCF_OP_KEY_DERIVE:
1245 			err = KCF_PROV_KEY_DERIVE(pd, kops->ko_sid,
1246 			    &kops->ko_mech,
1247 			    kops->ko_key, kops->ko_key_template,
1248 			    kops->ko_key_attribute_count,
1249 			    kops->ko_key_object_id_ptr, rhndl);
1250 			break;
1251 
1252 		default:
1253 			break;
1254 		}
1255 		break;
1256 	}
1257 
1258 	case KCF_OG_RANDOM: {
1259 		kcf_random_number_ops_params_t *rops =
1260 		    &params->rp_u.random_number_params;
1261 
1262 		ASSERT(ctx == NULL);
1263 
1264 		switch (optype) {
1265 		case KCF_OP_RANDOM_SEED:
1266 			err = KCF_PROV_SEED_RANDOM(pd, rops->rn_sid,
1267 			    rops->rn_buf, rops->rn_buflen, rops->rn_entropy_est,
1268 			    rops->rn_flags, rhndl);
1269 			break;
1270 
1271 		case KCF_OP_RANDOM_GENERATE:
1272 			err = KCF_PROV_GENERATE_RANDOM(pd, rops->rn_sid,
1273 			    rops->rn_buf, rops->rn_buflen, rhndl);
1274 			break;
1275 
1276 		default:
1277 			break;
1278 		}
1279 		break;
1280 	}
1281 
1282 	case KCF_OG_SESSION: {
1283 		kcf_session_ops_params_t *sops = &params->rp_u.session_params;
1284 
1285 		ASSERT(ctx == NULL);
1286 		switch (optype) {
1287 		case KCF_OP_SESSION_OPEN:
1288 			/*
1289 			 * so_pd may be a logical provider, in which case
1290 			 * we need to check whether it has been removed.
1291 			 */
1292 			if (KCF_IS_PROV_REMOVED(sops->so_pd)) {
1293 				err = CRYPTO_DEVICE_ERROR;
1294 				break;
1295 			}
1296 			err = KCF_PROV_SESSION_OPEN(pd, sops->so_sid_ptr,
1297 			    rhndl, sops->so_pd);
1298 			break;
1299 
1300 		case KCF_OP_SESSION_CLOSE:
1301 			/*
1302 			 * so_pd may be a logical provider, in which case
1303 			 * we need to check whether it has been removed.
1304 			 */
1305 			if (KCF_IS_PROV_REMOVED(sops->so_pd)) {
1306 				err = CRYPTO_DEVICE_ERROR;
1307 				break;
1308 			}
1309 			err = KCF_PROV_SESSION_CLOSE(pd, sops->so_sid,
1310 			    rhndl, sops->so_pd);
1311 			break;
1312 
1313 		case KCF_OP_SESSION_LOGIN:
1314 			err = KCF_PROV_SESSION_LOGIN(pd, sops->so_sid,
1315 			    sops->so_user_type, sops->so_pin,
1316 			    sops->so_pin_len, rhndl);
1317 			break;
1318 
1319 		case KCF_OP_SESSION_LOGOUT:
1320 			err = KCF_PROV_SESSION_LOGOUT(pd, sops->so_sid, rhndl);
1321 			break;
1322 
1323 		default:
1324 			break;
1325 		}
1326 		break;
1327 	}
1328 
1329 	case KCF_OG_OBJECT: {
1330 		kcf_object_ops_params_t *jops = &params->rp_u.object_params;
1331 
1332 		ASSERT(ctx == NULL);
1333 		switch (optype) {
1334 		case KCF_OP_OBJECT_CREATE:
1335 			err = KCF_PROV_OBJECT_CREATE(pd, jops->oo_sid,
1336 			    jops->oo_template, jops->oo_attribute_count,
1337 			    jops->oo_object_id_ptr, rhndl);
1338 			break;
1339 
1340 		case KCF_OP_OBJECT_COPY:
1341 			err = KCF_PROV_OBJECT_COPY(pd, jops->oo_sid,
1342 			    jops->oo_object_id,
1343 			    jops->oo_template, jops->oo_attribute_count,
1344 			    jops->oo_object_id_ptr, rhndl);
1345 			break;
1346 
1347 		case KCF_OP_OBJECT_DESTROY:
1348 			err = KCF_PROV_OBJECT_DESTROY(pd, jops->oo_sid,
1349 			    jops->oo_object_id, rhndl);
1350 			break;
1351 
1352 		case KCF_OP_OBJECT_GET_SIZE:
1353 			err = KCF_PROV_OBJECT_GET_SIZE(pd, jops->oo_sid,
1354 			    jops->oo_object_id, jops->oo_object_size, rhndl);
1355 			break;
1356 
1357 		case KCF_OP_OBJECT_GET_ATTRIBUTE_VALUE:
1358 			err = KCF_PROV_OBJECT_GET_ATTRIBUTE_VALUE(pd,
1359 			    jops->oo_sid, jops->oo_object_id,
1360 			    jops->oo_template, jops->oo_attribute_count, rhndl);
1361 			break;
1362 
1363 		case KCF_OP_OBJECT_SET_ATTRIBUTE_VALUE:
1364 			err = KCF_PROV_OBJECT_SET_ATTRIBUTE_VALUE(pd,
1365 			    jops->oo_sid, jops->oo_object_id,
1366 			    jops->oo_template, jops->oo_attribute_count, rhndl);
1367 			break;
1368 
1369 		case KCF_OP_OBJECT_FIND_INIT:
1370 			err = KCF_PROV_OBJECT_FIND_INIT(pd, jops->oo_sid,
1371 			    jops->oo_template, jops->oo_attribute_count,
1372 			    jops->oo_find_init_pp_ptr, rhndl);
1373 			break;
1374 
1375 		case KCF_OP_OBJECT_FIND:
1376 			err = KCF_PROV_OBJECT_FIND(pd, jops->oo_find_pp,
1377 			    jops->oo_object_id_ptr, jops->oo_max_object_count,
1378 			    jops->oo_object_count_ptr, rhndl);
1379 			break;
1380 
1381 		case KCF_OP_OBJECT_FIND_FINAL:
1382 			err = KCF_PROV_OBJECT_FIND_FINAL(pd, jops->oo_find_pp,
1383 			    rhndl);
1384 			break;
1385 
1386 		default:
1387 			break;
1388 		}
1389 		break;
1390 	}
1391 
1392 	case KCF_OG_PROVMGMT: {
1393 		kcf_provmgmt_ops_params_t *pops = &params->rp_u.provmgmt_params;
1394 
1395 		ASSERT(ctx == NULL);
1396 		switch (optype) {
1397 		case KCF_OP_MGMT_EXTINFO:
1398 			/*
1399 			 * po_pd may be a logical provider, in which case
1400 			 * we need to check whether it has been removed.
1401 			 */
1402 			if (KCF_IS_PROV_REMOVED(pops->po_pd)) {
1403 				err = CRYPTO_DEVICE_ERROR;
1404 				break;
1405 			}
1406 			err = KCF_PROV_EXT_INFO(pd, pops->po_ext_info, rhndl,
1407 			    pops->po_pd);
1408 			break;
1409 
1410 		case KCF_OP_MGMT_INITTOKEN:
1411 			err = KCF_PROV_INIT_TOKEN(pd, pops->po_pin,
1412 			    pops->po_pin_len, pops->po_label, rhndl);
1413 			break;
1414 
1415 		case KCF_OP_MGMT_INITPIN:
1416 			err = KCF_PROV_INIT_PIN(pd, pops->po_sid, pops->po_pin,
1417 			    pops->po_pin_len, rhndl);
1418 			break;
1419 
1420 		case KCF_OP_MGMT_SETPIN:
1421 			err = KCF_PROV_SET_PIN(pd, pops->po_sid,
1422 			    pops->po_old_pin, pops->po_old_pin_len,
1423 			    pops->po_pin, pops->po_pin_len, rhndl);
1424 			break;
1425 
1426 		default:
1427 			break;
1428 		}
1429 		break;
1430 	}
1431 
1432 	case KCF_OG_NOSTORE_KEY: {
1433 		kcf_key_ops_params_t *kops = &params->rp_u.key_params;
1434 
1435 		ASSERT(ctx == NULL);
1436 		KCF_SET_PROVIDER_MECHNUM(kops->ko_framework_mechtype, pd,
1437 		    &kops->ko_mech);
1438 
1439 		switch (optype) {
1440 		case KCF_OP_KEY_GENERATE:
1441 			err = KCF_PROV_NOSTORE_KEY_GENERATE(pd, kops->ko_sid,
1442 			    &kops->ko_mech, kops->ko_key_template,
1443 			    kops->ko_key_attribute_count,
1444 			    kops->ko_out_template1,
1445 			    kops->ko_out_attribute_count1, rhndl);
1446 			break;
1447 
1448 		case KCF_OP_KEY_GENERATE_PAIR:
1449 			err = KCF_PROV_NOSTORE_KEY_GENERATE_PAIR(pd,
1450 			    kops->ko_sid, &kops->ko_mech,
1451 			    kops->ko_key_template, kops->ko_key_attribute_count,
1452 			    kops->ko_private_key_template,
1453 			    kops->ko_private_key_attribute_count,
1454 			    kops->ko_out_template1,
1455 			    kops->ko_out_attribute_count1,
1456 			    kops->ko_out_template2,
1457 			    kops->ko_out_attribute_count2,
1458 			    rhndl);
1459 			break;
1460 
1461 		case KCF_OP_KEY_DERIVE:
1462 			err = KCF_PROV_NOSTORE_KEY_DERIVE(pd, kops->ko_sid,
1463 			    &kops->ko_mech, kops->ko_key,
1464 			    kops->ko_key_template,
1465 			    kops->ko_key_attribute_count,
1466 			    kops->ko_out_template1,
1467 			    kops->ko_out_attribute_count1, rhndl);
1468 			break;
1469 
1470 		default:
1471 			break;
1472 		}
1473 		break;
1474 	}
1475 	default:
1476 		break;
1477 	}		/* end of switch(params->rp_opgrp) */
1478 
1479 	KCF_PROV_INCRSTATS(pd, err);
1480 	return (err);
1481 }
1482 
1483 /*
1484  * Emulate the call for a multipart dual ops with 2 single steps.
1485  * This routine is always called in the context of a working thread
1486  * running kcf_svc_do_run().
1487  * The single steps are submitted in a pure synchronous way (blocking).
1488  * When this routine returns, kcf_svc_do_run() will call kcf_aop_done()
1489  * so the originating consumer's callback gets invoked. kcf_aop_done()
1490  * takes care of freeing the operation context. So, this routine does
1491  * not free the operation context.
1492  *
1493  * The provider descriptor is assumed held by the callers.
1494  */
1495 static int
1496 kcf_emulate_dual(kcf_provider_desc_t *pd, crypto_ctx_t *ctx,
1497     kcf_req_params_t *params)
1498 {
1499 	int err = CRYPTO_ARGUMENTS_BAD;
1500 	kcf_op_type_t optype;
1501 	size_t save_len;
1502 	off_t save_offset;
1503 
1504 	optype = params->rp_optype;
1505 
1506 	switch (params->rp_opgrp) {
1507 	case KCF_OG_ENCRYPT_MAC: {
1508 		kcf_encrypt_mac_ops_params_t *cmops =
1509 		    &params->rp_u.encrypt_mac_params;
1510 		kcf_context_t *encr_kcf_ctx;
1511 		crypto_ctx_t *mac_ctx;
1512 		kcf_req_params_t encr_params;
1513 
1514 		encr_kcf_ctx = (kcf_context_t *)(ctx->cc_framework_private);
1515 
1516 		switch (optype) {
1517 		case KCF_OP_INIT: {
1518 			encr_kcf_ctx->kc_secondctx = NULL;
1519 
1520 			KCF_WRAP_ENCRYPT_OPS_PARAMS(&encr_params, KCF_OP_INIT,
1521 			    pd->pd_sid, &cmops->em_encr_mech,
1522 			    cmops->em_encr_key, NULL, NULL,
1523 			    cmops->em_encr_templ);
1524 
1525 			err = kcf_submit_request(pd, ctx, NULL, &encr_params,
1526 			    B_FALSE);
1527 
1528 			/* It can't be CRYPTO_QUEUED */
1529 			if (err != CRYPTO_SUCCESS) {
1530 				break;
1531 			}
1532 
1533 			err = crypto_mac_init(&cmops->em_mac_mech,
1534 			    cmops->em_mac_key, cmops->em_mac_templ,
1535 			    (crypto_context_t *)&mac_ctx, NULL);
1536 
1537 			if (err == CRYPTO_SUCCESS) {
1538 				encr_kcf_ctx->kc_secondctx = (kcf_context_t *)
1539 				    mac_ctx->cc_framework_private;
1540 				KCF_CONTEXT_REFHOLD((kcf_context_t *)
1541 				    mac_ctx->cc_framework_private);
1542 			}
1543 
1544 			break;
1545 
1546 		}
1547 		case KCF_OP_UPDATE: {
1548 			crypto_dual_data_t *ct = cmops->em_ciphertext;
1549 			crypto_data_t *pt = cmops->em_plaintext;
1550 			kcf_context_t *mac_kcf_ctx = encr_kcf_ctx->kc_secondctx;
1551 			crypto_ctx_t *mac_ctx = &mac_kcf_ctx->kc_glbl_ctx;
1552 
1553 			KCF_WRAP_ENCRYPT_OPS_PARAMS(&encr_params, KCF_OP_UPDATE,
1554 			    pd->pd_sid, NULL, NULL, pt, (crypto_data_t *)ct,
1555 			    NULL);
1556 
1557 			err = kcf_submit_request(pd, ctx, NULL, &encr_params,
1558 			    B_FALSE);
1559 
1560 			/* It can't be CRYPTO_QUEUED */
1561 			if (err != CRYPTO_SUCCESS) {
1562 				break;
1563 			}
1564 
1565 			save_offset = ct->dd_offset1;
1566 			save_len = ct->dd_len1;
1567 			if (ct->dd_len2 == 0) {
1568 				/*
1569 				 * The previous encrypt step was an
1570 				 * accumulation only and didn't produce any
1571 				 * partial output
1572 				 */
1573 				if (ct->dd_len1 == 0)
1574 					break;
1575 
1576 			} else {
1577 				ct->dd_offset1 = ct->dd_offset2;
1578 				ct->dd_len1 = ct->dd_len2;
1579 			}
1580 			err = crypto_mac_update((crypto_context_t)mac_ctx,
1581 			    (crypto_data_t *)ct, NULL);
1582 
1583 			ct->dd_offset1 = save_offset;
1584 			ct->dd_len1 = save_len;
1585 
1586 			break;
1587 		}
1588 		case KCF_OP_FINAL: {
1589 			crypto_dual_data_t *ct = cmops->em_ciphertext;
1590 			crypto_data_t *mac = cmops->em_mac;
1591 			kcf_context_t *mac_kcf_ctx = encr_kcf_ctx->kc_secondctx;
1592 			crypto_ctx_t *mac_ctx = &mac_kcf_ctx->kc_glbl_ctx;
1593 			crypto_context_t mac_context = mac_ctx;
1594 
1595 			KCF_WRAP_ENCRYPT_OPS_PARAMS(&encr_params, KCF_OP_FINAL,
1596 			    pd->pd_sid, NULL, NULL, NULL, (crypto_data_t *)ct,
1597 			    NULL);
1598 
1599 			err = kcf_submit_request(pd, ctx, NULL, &encr_params,
1600 			    B_FALSE);
1601 
1602 			/* It can't be CRYPTO_QUEUED */
1603 			if (err != CRYPTO_SUCCESS) {
1604 				crypto_cancel_ctx(mac_context);
1605 				break;
1606 			}
1607 
1608 			if (ct->dd_len2 > 0) {
1609 				save_offset = ct->dd_offset1;
1610 				save_len = ct->dd_len1;
1611 				ct->dd_offset1 = ct->dd_offset2;
1612 				ct->dd_len1 = ct->dd_len2;
1613 
1614 				err = crypto_mac_update(mac_context,
1615 				    (crypto_data_t *)ct, NULL);
1616 
1617 				ct->dd_offset1 = save_offset;
1618 				ct->dd_len1 = save_len;
1619 
1620 				if (err != CRYPTO_SUCCESS)  {
1621 					crypto_cancel_ctx(mac_context);
1622 					return (err);
1623 				}
1624 			}
1625 
1626 			/* and finally, collect the MAC */
1627 			err = crypto_mac_final(mac_context, mac, NULL);
1628 			break;
1629 		}
1630 
1631 		default:
1632 			break;
1633 		}
1634 		KCF_PROV_INCRSTATS(pd, err);
1635 		break;
1636 	}
1637 	case KCF_OG_MAC_DECRYPT: {
1638 		kcf_mac_decrypt_ops_params_t *mdops =
1639 		    &params->rp_u.mac_decrypt_params;
1640 		kcf_context_t *decr_kcf_ctx;
1641 		crypto_ctx_t *mac_ctx;
1642 		kcf_req_params_t decr_params;
1643 
1644 		decr_kcf_ctx = (kcf_context_t *)(ctx->cc_framework_private);
1645 
1646 		switch (optype) {
1647 		case KCF_OP_INIT: {
1648 			decr_kcf_ctx->kc_secondctx = NULL;
1649 
1650 			err = crypto_mac_init(&mdops->md_mac_mech,
1651 			    mdops->md_mac_key, mdops->md_mac_templ,
1652 			    (crypto_context_t *)&mac_ctx, NULL);
1653 
1654 			/* It can't be CRYPTO_QUEUED */
1655 			if (err != CRYPTO_SUCCESS) {
1656 				break;
1657 			}
1658 
1659 			KCF_WRAP_DECRYPT_OPS_PARAMS(&decr_params, KCF_OP_INIT,
1660 			    pd->pd_sid, &mdops->md_decr_mech,
1661 			    mdops->md_decr_key, NULL, NULL,
1662 			    mdops->md_decr_templ);
1663 
1664 			err = kcf_submit_request(pd, ctx, NULL, &decr_params,
1665 			    B_FALSE);
1666 
1667 			/* It can't be CRYPTO_QUEUED */
1668 			if (err != CRYPTO_SUCCESS) {
1669 				crypto_cancel_ctx((crypto_context_t)mac_ctx);
1670 				break;
1671 			}
1672 
1673 			decr_kcf_ctx->kc_secondctx = (kcf_context_t *)
1674 			    mac_ctx->cc_framework_private;
1675 			KCF_CONTEXT_REFHOLD((kcf_context_t *)
1676 			    mac_ctx->cc_framework_private);
1677 
1678 			break;
1679 
1680 		}
1681 		case KCF_OP_UPDATE: {
1682 			crypto_dual_data_t *ct = mdops->md_ciphertext;
1683 			crypto_data_t *pt = mdops->md_plaintext;
1684 			kcf_context_t *mac_kcf_ctx = decr_kcf_ctx->kc_secondctx;
1685 			crypto_ctx_t *mac_ctx = &mac_kcf_ctx->kc_glbl_ctx;
1686 
1687 			err = crypto_mac_update((crypto_context_t)mac_ctx,
1688 			    (crypto_data_t *)ct, NULL);
1689 
1690 			if (err != CRYPTO_SUCCESS)
1691 				break;
1692 
1693 			save_offset = ct->dd_offset1;
1694 			save_len = ct->dd_len1;
1695 
1696 			/* zero ct->dd_len2 means decrypt everything */
1697 			if (ct->dd_len2 > 0) {
1698 				ct->dd_offset1 = ct->dd_offset2;
1699 				ct->dd_len1 = ct->dd_len2;
1700 			}
1701 
1702 			err = crypto_decrypt_update((crypto_context_t)ctx,
1703 			    (crypto_data_t *)ct, pt, NULL);
1704 
1705 			ct->dd_offset1 = save_offset;
1706 			ct->dd_len1 = save_len;
1707 
1708 			break;
1709 		}
1710 		case KCF_OP_FINAL: {
1711 			crypto_data_t *pt = mdops->md_plaintext;
1712 			crypto_data_t *mac = mdops->md_mac;
1713 			kcf_context_t *mac_kcf_ctx = decr_kcf_ctx->kc_secondctx;
1714 			crypto_ctx_t *mac_ctx = &mac_kcf_ctx->kc_glbl_ctx;
1715 
1716 			err = crypto_mac_final((crypto_context_t)mac_ctx,
1717 			    mac, NULL);
1718 
1719 			if (err != CRYPTO_SUCCESS) {
1720 				crypto_cancel_ctx(ctx);
1721 				break;
1722 			}
1723 
1724 			/* Get the last chunk of plaintext */
1725 			KCF_CONTEXT_REFHOLD(decr_kcf_ctx);
1726 			err = crypto_decrypt_final((crypto_context_t)ctx, pt,
1727 			    NULL);
1728 
1729 			break;
1730 		}
1731 		}
1732 		break;
1733 	}
1734 	default:
1735 
1736 		break;
1737 	}		/* end of switch(params->rp_opgrp) */
1738 
1739 	return (err);
1740 }
1741