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