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