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