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
30static int kcf_emulate_dual(kcf_provider_desc_t *, crypto_ctx_t *,
31    kcf_req_params_t *);
32
33void
34kcf_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
45kcf_prov_tried_t *
46kcf_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
62static boolean_t
63is_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 */
78static boolean_t
79is_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 */
108int
109kcf_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	}
230out:
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 */
250kcf_provider_desc_t *
251kcf_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 */
360kcf_provider_desc_t *
361kcf_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 */
499int
500common_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 */
1320static int
1321kcf_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