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