xref: /freebsd-src/sys/contrib/openzfs/module/icp/api/kcf_cipher.c (revision eda14cbc264d6969b02f2b1994cef11148e914f1)
1*eda14cbcSMatt Macy /*
2*eda14cbcSMatt Macy  * CDDL HEADER START
3*eda14cbcSMatt Macy  *
4*eda14cbcSMatt Macy  * The contents of this file are subject to the terms of the
5*eda14cbcSMatt Macy  * Common Development and Distribution License (the "License").
6*eda14cbcSMatt Macy  * You may not use this file except in compliance with the License.
7*eda14cbcSMatt Macy  *
8*eda14cbcSMatt Macy  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*eda14cbcSMatt Macy  * or http://www.opensolaris.org/os/licensing.
10*eda14cbcSMatt Macy  * See the License for the specific language governing permissions
11*eda14cbcSMatt Macy  * and limitations under the License.
12*eda14cbcSMatt Macy  *
13*eda14cbcSMatt Macy  * When distributing Covered Code, include this CDDL HEADER in each
14*eda14cbcSMatt Macy  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*eda14cbcSMatt Macy  * If applicable, add the following below this CDDL HEADER, with the
16*eda14cbcSMatt Macy  * fields enclosed by brackets "[]" replaced with your own identifying
17*eda14cbcSMatt Macy  * information: Portions Copyright [yyyy] [name of copyright owner]
18*eda14cbcSMatt Macy  *
19*eda14cbcSMatt Macy  * CDDL HEADER END
20*eda14cbcSMatt Macy  */
21*eda14cbcSMatt Macy /*
22*eda14cbcSMatt Macy  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23*eda14cbcSMatt Macy  * Use is subject to license terms.
24*eda14cbcSMatt Macy  */
25*eda14cbcSMatt Macy 
26*eda14cbcSMatt Macy #include <sys/zfs_context.h>
27*eda14cbcSMatt Macy #include <sys/crypto/common.h>
28*eda14cbcSMatt Macy #include <sys/crypto/impl.h>
29*eda14cbcSMatt Macy #include <sys/crypto/api.h>
30*eda14cbcSMatt Macy #include <sys/crypto/spi.h>
31*eda14cbcSMatt Macy #include <sys/crypto/sched_impl.h>
32*eda14cbcSMatt Macy 
33*eda14cbcSMatt Macy /*
34*eda14cbcSMatt Macy  * Encryption and decryption routines.
35*eda14cbcSMatt Macy  */
36*eda14cbcSMatt Macy 
37*eda14cbcSMatt Macy /*
38*eda14cbcSMatt Macy  * The following are the possible returned values common to all the routines
39*eda14cbcSMatt Macy  * below. The applicability of some of these return values depends on the
40*eda14cbcSMatt Macy  * presence of the arguments.
41*eda14cbcSMatt Macy  *
42*eda14cbcSMatt Macy  *	CRYPTO_SUCCESS:	The operation completed successfully.
43*eda14cbcSMatt Macy  *	CRYPTO_QUEUED:	A request was submitted successfully. The callback
44*eda14cbcSMatt Macy  *			routine will be called when the operation is done.
45*eda14cbcSMatt Macy  *	CRYPTO_INVALID_MECH_NUMBER, CRYPTO_INVALID_MECH_PARAM, or
46*eda14cbcSMatt Macy  *	CRYPTO_INVALID_MECH for problems with the 'mech'.
47*eda14cbcSMatt Macy  *	CRYPTO_INVALID_DATA for bogus 'data'
48*eda14cbcSMatt Macy  *	CRYPTO_HOST_MEMORY for failure to allocate memory to handle this work.
49*eda14cbcSMatt Macy  *	CRYPTO_INVALID_CONTEXT: Not a valid context.
50*eda14cbcSMatt Macy  *	CRYPTO_BUSY:	Cannot process the request now. Schedule a
51*eda14cbcSMatt Macy  *			crypto_bufcall(), or try later.
52*eda14cbcSMatt Macy  *	CRYPTO_NOT_SUPPORTED and CRYPTO_MECH_NOT_SUPPORTED: No provider is
53*eda14cbcSMatt Macy  *			capable of a function or a mechanism.
54*eda14cbcSMatt Macy  *	CRYPTO_INVALID_KEY: bogus 'key' argument.
55*eda14cbcSMatt Macy  *	CRYPTO_INVALID_PLAINTEXT: bogus 'plaintext' argument.
56*eda14cbcSMatt Macy  *	CRYPTO_INVALID_CIPHERTEXT: bogus 'ciphertext' argument.
57*eda14cbcSMatt Macy  */
58*eda14cbcSMatt Macy 
59*eda14cbcSMatt Macy /*
60*eda14cbcSMatt Macy  * crypto_cipher_init_prov()
61*eda14cbcSMatt Macy  *
62*eda14cbcSMatt Macy  * Arguments:
63*eda14cbcSMatt Macy  *
64*eda14cbcSMatt Macy  *	pd:	provider descriptor
65*eda14cbcSMatt Macy  *	sid:	session id
66*eda14cbcSMatt Macy  *	mech:	crypto_mechanism_t pointer.
67*eda14cbcSMatt Macy  *		mech_type is a valid value previously returned by
68*eda14cbcSMatt Macy  *		crypto_mech2id();
69*eda14cbcSMatt Macy  *		When the mech's parameter is not NULL, its definition depends
70*eda14cbcSMatt Macy  *		on the standard definition of the mechanism.
71*eda14cbcSMatt Macy  *	key:	pointer to a crypto_key_t structure.
72*eda14cbcSMatt Macy  *	tmpl:	a crypto_ctx_template_t, opaque template of a context of an
73*eda14cbcSMatt Macy  *		encryption  or decryption with the 'mech' using 'key'.
74*eda14cbcSMatt Macy  *		'tmpl' is created by a previous call to
75*eda14cbcSMatt Macy  *		crypto_create_ctx_template().
76*eda14cbcSMatt Macy  *	ctxp:	Pointer to a crypto_context_t.
77*eda14cbcSMatt Macy  *	func:	CRYPTO_FG_ENCRYPT or CRYPTO_FG_DECRYPT.
78*eda14cbcSMatt Macy  *	cr:	crypto_call_req_t calling conditions and call back info.
79*eda14cbcSMatt Macy  *
80*eda14cbcSMatt Macy  * Description:
81*eda14cbcSMatt Macy  *	This is a common function invoked internally by both
82*eda14cbcSMatt Macy  *	crypto_encrypt_init() and crypto_decrypt_init().
83*eda14cbcSMatt Macy  *	Asynchronously submits a request for, or synchronously performs the
84*eda14cbcSMatt Macy  *	initialization of an encryption or a decryption operation.
85*eda14cbcSMatt Macy  *	When possible and applicable, will internally use the pre-expanded key
86*eda14cbcSMatt Macy  *	schedule from the context template, tmpl.
87*eda14cbcSMatt Macy  *	When complete and successful, 'ctxp' will contain a crypto_context_t
88*eda14cbcSMatt Macy  *	valid for later calls to encrypt_update() and encrypt_final(), or
89*eda14cbcSMatt Macy  *	decrypt_update() and decrypt_final().
90*eda14cbcSMatt Macy  *	The caller should hold a reference on the specified provider
91*eda14cbcSMatt Macy  *	descriptor before calling this function.
92*eda14cbcSMatt Macy  *
93*eda14cbcSMatt Macy  * Context:
94*eda14cbcSMatt Macy  *	Process or interrupt, according to the semantics dictated by the 'cr'.
95*eda14cbcSMatt Macy  *
96*eda14cbcSMatt Macy  * Returns:
97*eda14cbcSMatt Macy  *	See comment in the beginning of the file.
98*eda14cbcSMatt Macy  */
99*eda14cbcSMatt Macy static int
100*eda14cbcSMatt Macy crypto_cipher_init_prov(crypto_provider_t provider, crypto_session_id_t sid,
101*eda14cbcSMatt Macy     crypto_mechanism_t *mech, crypto_key_t *key,
102*eda14cbcSMatt Macy     crypto_spi_ctx_template_t tmpl, crypto_context_t *ctxp,
103*eda14cbcSMatt Macy     crypto_call_req_t *crq, crypto_func_group_t func)
104*eda14cbcSMatt Macy {
105*eda14cbcSMatt Macy 	int error;
106*eda14cbcSMatt Macy 	crypto_ctx_t *ctx;
107*eda14cbcSMatt Macy 	kcf_req_params_t params;
108*eda14cbcSMatt Macy 	kcf_provider_desc_t *pd = provider;
109*eda14cbcSMatt Macy 	kcf_provider_desc_t *real_provider = pd;
110*eda14cbcSMatt Macy 
111*eda14cbcSMatt Macy 	ASSERT(KCF_PROV_REFHELD(pd));
112*eda14cbcSMatt Macy 
113*eda14cbcSMatt Macy 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
114*eda14cbcSMatt Macy 		if (func == CRYPTO_FG_ENCRYPT) {
115*eda14cbcSMatt Macy 			error = kcf_get_hardware_provider(mech->cm_type,
116*eda14cbcSMatt Macy 			    CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd,
117*eda14cbcSMatt Macy 			    &real_provider, CRYPTO_FG_ENCRYPT);
118*eda14cbcSMatt Macy 		} else {
119*eda14cbcSMatt Macy 			error = kcf_get_hardware_provider(mech->cm_type,
120*eda14cbcSMatt Macy 			    CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd,
121*eda14cbcSMatt Macy 			    &real_provider, CRYPTO_FG_DECRYPT);
122*eda14cbcSMatt Macy 		}
123*eda14cbcSMatt Macy 
124*eda14cbcSMatt Macy 		if (error != CRYPTO_SUCCESS)
125*eda14cbcSMatt Macy 			return (error);
126*eda14cbcSMatt Macy 	}
127*eda14cbcSMatt Macy 
128*eda14cbcSMatt Macy 	/* Allocate and initialize the canonical context */
129*eda14cbcSMatt Macy 	if ((ctx = kcf_new_ctx(crq, real_provider, sid)) == NULL) {
130*eda14cbcSMatt Macy 		if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
131*eda14cbcSMatt Macy 			KCF_PROV_REFRELE(real_provider);
132*eda14cbcSMatt Macy 		return (CRYPTO_HOST_MEMORY);
133*eda14cbcSMatt Macy 	}
134*eda14cbcSMatt Macy 
135*eda14cbcSMatt Macy 	/* The fast path for SW providers. */
136*eda14cbcSMatt Macy 	if (CHECK_FASTPATH(crq, pd)) {
137*eda14cbcSMatt Macy 		crypto_mechanism_t lmech;
138*eda14cbcSMatt Macy 
139*eda14cbcSMatt Macy 		lmech = *mech;
140*eda14cbcSMatt Macy 		KCF_SET_PROVIDER_MECHNUM(mech->cm_type, real_provider, &lmech);
141*eda14cbcSMatt Macy 
142*eda14cbcSMatt Macy 		if (func == CRYPTO_FG_ENCRYPT)
143*eda14cbcSMatt Macy 			error = KCF_PROV_ENCRYPT_INIT(real_provider, ctx,
144*eda14cbcSMatt Macy 			    &lmech, key, tmpl, KCF_SWFP_RHNDL(crq));
145*eda14cbcSMatt Macy 		else {
146*eda14cbcSMatt Macy 			ASSERT(func == CRYPTO_FG_DECRYPT);
147*eda14cbcSMatt Macy 
148*eda14cbcSMatt Macy 			error = KCF_PROV_DECRYPT_INIT(real_provider, ctx,
149*eda14cbcSMatt Macy 			    &lmech, key, tmpl, KCF_SWFP_RHNDL(crq));
150*eda14cbcSMatt Macy 		}
151*eda14cbcSMatt Macy 		KCF_PROV_INCRSTATS(pd, error);
152*eda14cbcSMatt Macy 
153*eda14cbcSMatt Macy 		goto done;
154*eda14cbcSMatt Macy 	}
155*eda14cbcSMatt Macy 
156*eda14cbcSMatt Macy 	/* Check if context sharing is possible */
157*eda14cbcSMatt Macy 	if (pd->pd_prov_type == CRYPTO_HW_PROVIDER &&
158*eda14cbcSMatt Macy 	    key->ck_format == CRYPTO_KEY_RAW &&
159*eda14cbcSMatt Macy 	    KCF_CAN_SHARE_OPSTATE(pd, mech->cm_type)) {
160*eda14cbcSMatt Macy 		kcf_context_t *tctxp = (kcf_context_t *)ctx;
161*eda14cbcSMatt Macy 		kcf_provider_desc_t *tpd = NULL;
162*eda14cbcSMatt Macy 		crypto_mech_info_t *sinfo;
163*eda14cbcSMatt Macy 
164*eda14cbcSMatt Macy 		if ((kcf_get_sw_prov(mech->cm_type, &tpd, &tctxp->kc_mech,
165*eda14cbcSMatt Macy 		    B_FALSE) == CRYPTO_SUCCESS)) {
166*eda14cbcSMatt Macy 			int tlen;
167*eda14cbcSMatt Macy 
168*eda14cbcSMatt Macy 			sinfo = &(KCF_TO_PROV_MECHINFO(tpd, mech->cm_type));
169*eda14cbcSMatt Macy 			/*
170*eda14cbcSMatt Macy 			 * key->ck_length from the consumer is always in bits.
171*eda14cbcSMatt Macy 			 * We convert it to be in the same unit registered by
172*eda14cbcSMatt Macy 			 * the provider in order to do a comparison.
173*eda14cbcSMatt Macy 			 */
174*eda14cbcSMatt Macy 			if (sinfo->cm_mech_flags & CRYPTO_KEYSIZE_UNIT_IN_BYTES)
175*eda14cbcSMatt Macy 				tlen = key->ck_length >> 3;
176*eda14cbcSMatt Macy 			else
177*eda14cbcSMatt Macy 				tlen = key->ck_length;
178*eda14cbcSMatt Macy 			/*
179*eda14cbcSMatt Macy 			 * Check if the software provider can support context
180*eda14cbcSMatt Macy 			 * sharing and support this key length.
181*eda14cbcSMatt Macy 			 */
182*eda14cbcSMatt Macy 			if ((sinfo->cm_mech_flags & CRYPTO_CAN_SHARE_OPSTATE) &&
183*eda14cbcSMatt Macy 			    (tlen >= sinfo->cm_min_key_length) &&
184*eda14cbcSMatt Macy 			    (tlen <= sinfo->cm_max_key_length)) {
185*eda14cbcSMatt Macy 				ctx->cc_flags = CRYPTO_INIT_OPSTATE;
186*eda14cbcSMatt Macy 				tctxp->kc_sw_prov_desc = tpd;
187*eda14cbcSMatt Macy 			} else
188*eda14cbcSMatt Macy 				KCF_PROV_REFRELE(tpd);
189*eda14cbcSMatt Macy 		}
190*eda14cbcSMatt Macy 	}
191*eda14cbcSMatt Macy 
192*eda14cbcSMatt Macy 	if (func == CRYPTO_FG_ENCRYPT) {
193*eda14cbcSMatt Macy 		KCF_WRAP_ENCRYPT_OPS_PARAMS(&params, KCF_OP_INIT, sid,
194*eda14cbcSMatt Macy 		    mech, key, NULL, NULL, tmpl);
195*eda14cbcSMatt Macy 	} else {
196*eda14cbcSMatt Macy 		ASSERT(func == CRYPTO_FG_DECRYPT);
197*eda14cbcSMatt Macy 		KCF_WRAP_DECRYPT_OPS_PARAMS(&params, KCF_OP_INIT, sid,
198*eda14cbcSMatt Macy 		    mech, key, NULL, NULL, tmpl);
199*eda14cbcSMatt Macy 	}
200*eda14cbcSMatt Macy 
201*eda14cbcSMatt Macy 	error = kcf_submit_request(real_provider, ctx, crq, &params,
202*eda14cbcSMatt Macy 	    B_FALSE);
203*eda14cbcSMatt Macy 
204*eda14cbcSMatt Macy 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
205*eda14cbcSMatt Macy 		KCF_PROV_REFRELE(real_provider);
206*eda14cbcSMatt Macy 
207*eda14cbcSMatt Macy done:
208*eda14cbcSMatt Macy 	if ((error == CRYPTO_SUCCESS) || (error == CRYPTO_QUEUED))
209*eda14cbcSMatt Macy 		*ctxp = (crypto_context_t)ctx;
210*eda14cbcSMatt Macy 	else {
211*eda14cbcSMatt Macy 		/* Release the hold done in kcf_new_ctx(). */
212*eda14cbcSMatt Macy 		KCF_CONTEXT_REFRELE((kcf_context_t *)ctx->cc_framework_private);
213*eda14cbcSMatt Macy 	}
214*eda14cbcSMatt Macy 
215*eda14cbcSMatt Macy 	return (error);
216*eda14cbcSMatt Macy }
217*eda14cbcSMatt Macy 
218*eda14cbcSMatt Macy /*
219*eda14cbcSMatt Macy  * Same as crypto_cipher_init_prov(), but relies on the scheduler to pick
220*eda14cbcSMatt Macy  * an appropriate provider. See crypto_cipher_init_prov() comments for more
221*eda14cbcSMatt Macy  * details.
222*eda14cbcSMatt Macy  */
223*eda14cbcSMatt Macy static int
224*eda14cbcSMatt Macy crypto_cipher_init(crypto_mechanism_t *mech, crypto_key_t *key,
225*eda14cbcSMatt Macy     crypto_ctx_template_t tmpl, crypto_context_t *ctxp,
226*eda14cbcSMatt Macy     crypto_call_req_t *crq, crypto_func_group_t func)
227*eda14cbcSMatt Macy {
228*eda14cbcSMatt Macy 	int error;
229*eda14cbcSMatt Macy 	kcf_mech_entry_t *me;
230*eda14cbcSMatt Macy 	kcf_provider_desc_t *pd;
231*eda14cbcSMatt Macy 	kcf_ctx_template_t *ctx_tmpl;
232*eda14cbcSMatt Macy 	crypto_spi_ctx_template_t spi_ctx_tmpl = NULL;
233*eda14cbcSMatt Macy 	kcf_prov_tried_t *list = NULL;
234*eda14cbcSMatt Macy 
235*eda14cbcSMatt Macy retry:
236*eda14cbcSMatt Macy 	/* pd is returned held */
237*eda14cbcSMatt Macy 	if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error,
238*eda14cbcSMatt Macy 	    list, func, CHECK_RESTRICT(crq), 0)) == NULL) {
239*eda14cbcSMatt Macy 		if (list != NULL)
240*eda14cbcSMatt Macy 			kcf_free_triedlist(list);
241*eda14cbcSMatt Macy 		return (error);
242*eda14cbcSMatt Macy 	}
243*eda14cbcSMatt Macy 
244*eda14cbcSMatt Macy 	/*
245*eda14cbcSMatt Macy 	 * For SW providers, check the validity of the context template
246*eda14cbcSMatt Macy 	 * It is very rare that the generation number mis-matches, so
247*eda14cbcSMatt Macy 	 * is acceptable to fail here, and let the consumer recover by
248*eda14cbcSMatt Macy 	 * freeing this tmpl and create a new one for the key and new SW
249*eda14cbcSMatt Macy 	 * provider
250*eda14cbcSMatt Macy 	 */
251*eda14cbcSMatt Macy 	if ((pd->pd_prov_type == CRYPTO_SW_PROVIDER) &&
252*eda14cbcSMatt Macy 	    ((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) {
253*eda14cbcSMatt Macy 		if (ctx_tmpl->ct_generation != me->me_gen_swprov) {
254*eda14cbcSMatt Macy 			if (list != NULL)
255*eda14cbcSMatt Macy 				kcf_free_triedlist(list);
256*eda14cbcSMatt Macy 			KCF_PROV_REFRELE(pd);
257*eda14cbcSMatt Macy 			return (CRYPTO_OLD_CTX_TEMPLATE);
258*eda14cbcSMatt Macy 		} else {
259*eda14cbcSMatt Macy 			spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl;
260*eda14cbcSMatt Macy 		}
261*eda14cbcSMatt Macy 	}
262*eda14cbcSMatt Macy 
263*eda14cbcSMatt Macy 	error = crypto_cipher_init_prov(pd, pd->pd_sid, mech, key,
264*eda14cbcSMatt Macy 	    spi_ctx_tmpl, ctxp, crq, func);
265*eda14cbcSMatt Macy 	if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED &&
266*eda14cbcSMatt Macy 	    IS_RECOVERABLE(error)) {
267*eda14cbcSMatt Macy 		/* Add pd to the linked list of providers tried. */
268*eda14cbcSMatt Macy 		if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL)
269*eda14cbcSMatt Macy 			goto retry;
270*eda14cbcSMatt Macy 	}
271*eda14cbcSMatt Macy 
272*eda14cbcSMatt Macy 	if (list != NULL)
273*eda14cbcSMatt Macy 		kcf_free_triedlist(list);
274*eda14cbcSMatt Macy 
275*eda14cbcSMatt Macy 	KCF_PROV_REFRELE(pd);
276*eda14cbcSMatt Macy 	return (error);
277*eda14cbcSMatt Macy }
278*eda14cbcSMatt Macy 
279*eda14cbcSMatt Macy /*
280*eda14cbcSMatt Macy  * crypto_encrypt_prov()
281*eda14cbcSMatt Macy  *
282*eda14cbcSMatt Macy  * Arguments:
283*eda14cbcSMatt Macy  *	pd:	provider descriptor
284*eda14cbcSMatt Macy  *	sid:	session id
285*eda14cbcSMatt Macy  *	mech:	crypto_mechanism_t pointer.
286*eda14cbcSMatt Macy  *		mech_type is a valid value previously returned by
287*eda14cbcSMatt Macy  *		crypto_mech2id();
288*eda14cbcSMatt Macy  *		When the mech's parameter is not NULL, its definition depends
289*eda14cbcSMatt Macy  *		on the standard definition of the mechanism.
290*eda14cbcSMatt Macy  *	key:	pointer to a crypto_key_t structure.
291*eda14cbcSMatt Macy  *	plaintext: The message to be encrypted
292*eda14cbcSMatt Macy  *	ciphertext: Storage for the encrypted message. The length needed
293*eda14cbcSMatt Macy  *		depends on the mechanism, and the plaintext's size.
294*eda14cbcSMatt Macy  *	tmpl:	a crypto_ctx_template_t, opaque template of a context of an
295*eda14cbcSMatt Macy  *		encryption with the 'mech' using 'key'. 'tmpl' is created by
296*eda14cbcSMatt Macy  *		a previous call to crypto_create_ctx_template().
297*eda14cbcSMatt Macy  *	cr:	crypto_call_req_t calling conditions and call back info.
298*eda14cbcSMatt Macy  *
299*eda14cbcSMatt Macy  * Description:
300*eda14cbcSMatt Macy  *	Asynchronously submits a request for, or synchronously performs a
301*eda14cbcSMatt Macy  *	single-part encryption of 'plaintext' with the mechanism 'mech', using
302*eda14cbcSMatt Macy  *	the key 'key'.
303*eda14cbcSMatt Macy  *	When complete and successful, 'ciphertext' will contain the encrypted
304*eda14cbcSMatt Macy  *	message.
305*eda14cbcSMatt Macy  *
306*eda14cbcSMatt Macy  * Context:
307*eda14cbcSMatt Macy  *	Process or interrupt, according to the semantics dictated by the 'cr'.
308*eda14cbcSMatt Macy  *
309*eda14cbcSMatt Macy  * Returns:
310*eda14cbcSMatt Macy  *	See comment in the beginning of the file.
311*eda14cbcSMatt Macy  */
312*eda14cbcSMatt Macy int
313*eda14cbcSMatt Macy crypto_encrypt_prov(crypto_provider_t provider, crypto_session_id_t sid,
314*eda14cbcSMatt Macy     crypto_mechanism_t *mech, crypto_data_t *plaintext, crypto_key_t *key,
315*eda14cbcSMatt Macy     crypto_ctx_template_t tmpl, crypto_data_t *ciphertext,
316*eda14cbcSMatt Macy     crypto_call_req_t *crq)
317*eda14cbcSMatt Macy {
318*eda14cbcSMatt Macy 	kcf_req_params_t params;
319*eda14cbcSMatt Macy 	kcf_provider_desc_t *pd = provider;
320*eda14cbcSMatt Macy 	kcf_provider_desc_t *real_provider = pd;
321*eda14cbcSMatt Macy 	int error;
322*eda14cbcSMatt Macy 
323*eda14cbcSMatt Macy 	ASSERT(KCF_PROV_REFHELD(pd));
324*eda14cbcSMatt Macy 
325*eda14cbcSMatt Macy 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
326*eda14cbcSMatt Macy 		error = kcf_get_hardware_provider(mech->cm_type,
327*eda14cbcSMatt Macy 		    CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd,
328*eda14cbcSMatt Macy 		    &real_provider, CRYPTO_FG_ENCRYPT_ATOMIC);
329*eda14cbcSMatt Macy 
330*eda14cbcSMatt Macy 		if (error != CRYPTO_SUCCESS)
331*eda14cbcSMatt Macy 			return (error);
332*eda14cbcSMatt Macy 	}
333*eda14cbcSMatt Macy 
334*eda14cbcSMatt Macy 	KCF_WRAP_ENCRYPT_OPS_PARAMS(&params, KCF_OP_ATOMIC, sid, mech, key,
335*eda14cbcSMatt Macy 	    plaintext, ciphertext, tmpl);
336*eda14cbcSMatt Macy 
337*eda14cbcSMatt Macy 	error = kcf_submit_request(real_provider, NULL, crq, &params, B_FALSE);
338*eda14cbcSMatt Macy 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
339*eda14cbcSMatt Macy 		KCF_PROV_REFRELE(real_provider);
340*eda14cbcSMatt Macy 
341*eda14cbcSMatt Macy 	return (error);
342*eda14cbcSMatt Macy }
343*eda14cbcSMatt Macy 
344*eda14cbcSMatt Macy /*
345*eda14cbcSMatt Macy  * Same as crypto_encrypt_prov(), but relies on the scheduler to pick
346*eda14cbcSMatt Macy  * a provider. See crypto_encrypt_prov() for more details.
347*eda14cbcSMatt Macy  */
348*eda14cbcSMatt Macy int
349*eda14cbcSMatt Macy crypto_encrypt(crypto_mechanism_t *mech, crypto_data_t *plaintext,
350*eda14cbcSMatt Macy     crypto_key_t *key, crypto_ctx_template_t tmpl, crypto_data_t *ciphertext,
351*eda14cbcSMatt Macy     crypto_call_req_t *crq)
352*eda14cbcSMatt Macy {
353*eda14cbcSMatt Macy 	int error;
354*eda14cbcSMatt Macy 	kcf_mech_entry_t *me;
355*eda14cbcSMatt Macy 	kcf_req_params_t params;
356*eda14cbcSMatt Macy 	kcf_provider_desc_t *pd;
357*eda14cbcSMatt Macy 	kcf_ctx_template_t *ctx_tmpl;
358*eda14cbcSMatt Macy 	crypto_spi_ctx_template_t spi_ctx_tmpl = NULL;
359*eda14cbcSMatt Macy 	kcf_prov_tried_t *list = NULL;
360*eda14cbcSMatt Macy 
361*eda14cbcSMatt Macy retry:
362*eda14cbcSMatt Macy 	/* pd is returned held */
363*eda14cbcSMatt Macy 	if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error,
364*eda14cbcSMatt Macy 	    list, CRYPTO_FG_ENCRYPT_ATOMIC, CHECK_RESTRICT(crq),
365*eda14cbcSMatt Macy 	    plaintext->cd_length)) == NULL) {
366*eda14cbcSMatt Macy 		if (list != NULL)
367*eda14cbcSMatt Macy 			kcf_free_triedlist(list);
368*eda14cbcSMatt Macy 		return (error);
369*eda14cbcSMatt Macy 	}
370*eda14cbcSMatt Macy 
371*eda14cbcSMatt Macy 	/*
372*eda14cbcSMatt Macy 	 * For SW providers, check the validity of the context template
373*eda14cbcSMatt Macy 	 * It is very rare that the generation number mis-matches, so
374*eda14cbcSMatt Macy 	 * is acceptable to fail here, and let the consumer recover by
375*eda14cbcSMatt Macy 	 * freeing this tmpl and create a new one for the key and new SW
376*eda14cbcSMatt Macy 	 * provider
377*eda14cbcSMatt Macy 	 */
378*eda14cbcSMatt Macy 	if ((pd->pd_prov_type == CRYPTO_SW_PROVIDER) &&
379*eda14cbcSMatt Macy 	    ((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) {
380*eda14cbcSMatt Macy 		if (ctx_tmpl->ct_generation != me->me_gen_swprov) {
381*eda14cbcSMatt Macy 			if (list != NULL)
382*eda14cbcSMatt Macy 				kcf_free_triedlist(list);
383*eda14cbcSMatt Macy 			KCF_PROV_REFRELE(pd);
384*eda14cbcSMatt Macy 			return (CRYPTO_OLD_CTX_TEMPLATE);
385*eda14cbcSMatt Macy 		} else {
386*eda14cbcSMatt Macy 			spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl;
387*eda14cbcSMatt Macy 		}
388*eda14cbcSMatt Macy 	}
389*eda14cbcSMatt Macy 
390*eda14cbcSMatt Macy 	/* The fast path for SW providers. */
391*eda14cbcSMatt Macy 	if (CHECK_FASTPATH(crq, pd)) {
392*eda14cbcSMatt Macy 		crypto_mechanism_t lmech;
393*eda14cbcSMatt Macy 
394*eda14cbcSMatt Macy 		lmech = *mech;
395*eda14cbcSMatt Macy 		KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, &lmech);
396*eda14cbcSMatt Macy 
397*eda14cbcSMatt Macy 		error = KCF_PROV_ENCRYPT_ATOMIC(pd, pd->pd_sid, &lmech, key,
398*eda14cbcSMatt Macy 		    plaintext, ciphertext, spi_ctx_tmpl, KCF_SWFP_RHNDL(crq));
399*eda14cbcSMatt Macy 		KCF_PROV_INCRSTATS(pd, error);
400*eda14cbcSMatt Macy 	} else {
401*eda14cbcSMatt Macy 		KCF_WRAP_ENCRYPT_OPS_PARAMS(&params, KCF_OP_ATOMIC, pd->pd_sid,
402*eda14cbcSMatt Macy 		    mech, key, plaintext, ciphertext, spi_ctx_tmpl);
403*eda14cbcSMatt Macy 		error = kcf_submit_request(pd, NULL, crq, &params, B_FALSE);
404*eda14cbcSMatt Macy 	}
405*eda14cbcSMatt Macy 
406*eda14cbcSMatt Macy 	if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED &&
407*eda14cbcSMatt Macy 	    IS_RECOVERABLE(error)) {
408*eda14cbcSMatt Macy 		/* Add pd to the linked list of providers tried. */
409*eda14cbcSMatt Macy 		if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL)
410*eda14cbcSMatt Macy 			goto retry;
411*eda14cbcSMatt Macy 	}
412*eda14cbcSMatt Macy 
413*eda14cbcSMatt Macy 	if (list != NULL)
414*eda14cbcSMatt Macy 		kcf_free_triedlist(list);
415*eda14cbcSMatt Macy 
416*eda14cbcSMatt Macy 	KCF_PROV_REFRELE(pd);
417*eda14cbcSMatt Macy 	return (error);
418*eda14cbcSMatt Macy }
419*eda14cbcSMatt Macy 
420*eda14cbcSMatt Macy /*
421*eda14cbcSMatt Macy  * crypto_encrypt_init_prov()
422*eda14cbcSMatt Macy  *
423*eda14cbcSMatt Macy  * Calls crypto_cipher_init_prov() to initialize an encryption operation.
424*eda14cbcSMatt Macy  */
425*eda14cbcSMatt Macy int
426*eda14cbcSMatt Macy crypto_encrypt_init_prov(crypto_provider_t pd, crypto_session_id_t sid,
427*eda14cbcSMatt Macy     crypto_mechanism_t *mech, crypto_key_t *key,
428*eda14cbcSMatt Macy     crypto_ctx_template_t tmpl, crypto_context_t *ctxp,
429*eda14cbcSMatt Macy     crypto_call_req_t *crq)
430*eda14cbcSMatt Macy {
431*eda14cbcSMatt Macy 	return (crypto_cipher_init_prov(pd, sid, mech, key, tmpl, ctxp, crq,
432*eda14cbcSMatt Macy 	    CRYPTO_FG_ENCRYPT));
433*eda14cbcSMatt Macy }
434*eda14cbcSMatt Macy 
435*eda14cbcSMatt Macy /*
436*eda14cbcSMatt Macy  * crypto_encrypt_init()
437*eda14cbcSMatt Macy  *
438*eda14cbcSMatt Macy  * Calls crypto_cipher_init() to initialize an encryption operation
439*eda14cbcSMatt Macy  */
440*eda14cbcSMatt Macy int
441*eda14cbcSMatt Macy crypto_encrypt_init(crypto_mechanism_t *mech, crypto_key_t *key,
442*eda14cbcSMatt Macy     crypto_ctx_template_t tmpl, crypto_context_t *ctxp,
443*eda14cbcSMatt Macy     crypto_call_req_t *crq)
444*eda14cbcSMatt Macy {
445*eda14cbcSMatt Macy 	return (crypto_cipher_init(mech, key, tmpl, ctxp, crq,
446*eda14cbcSMatt Macy 	    CRYPTO_FG_ENCRYPT));
447*eda14cbcSMatt Macy }
448*eda14cbcSMatt Macy 
449*eda14cbcSMatt Macy /*
450*eda14cbcSMatt Macy  * crypto_encrypt_update()
451*eda14cbcSMatt Macy  *
452*eda14cbcSMatt Macy  * Arguments:
453*eda14cbcSMatt Macy  *	context: A crypto_context_t initialized by encrypt_init().
454*eda14cbcSMatt Macy  *	plaintext: The message part to be encrypted
455*eda14cbcSMatt Macy  *	ciphertext: Storage for the encrypted message part.
456*eda14cbcSMatt Macy  *	cr:	crypto_call_req_t calling conditions and call back info.
457*eda14cbcSMatt Macy  *
458*eda14cbcSMatt Macy  * Description:
459*eda14cbcSMatt Macy  *	Asynchronously submits a request for, or synchronously performs a
460*eda14cbcSMatt Macy  *	part of an encryption operation.
461*eda14cbcSMatt Macy  *
462*eda14cbcSMatt Macy  * Context:
463*eda14cbcSMatt Macy  *	Process or interrupt, according to the semantics dictated by the 'cr'.
464*eda14cbcSMatt Macy  *
465*eda14cbcSMatt Macy  * Returns:
466*eda14cbcSMatt Macy  *	See comment in the beginning of the file.
467*eda14cbcSMatt Macy  */
468*eda14cbcSMatt Macy int
469*eda14cbcSMatt Macy crypto_encrypt_update(crypto_context_t context, crypto_data_t *plaintext,
470*eda14cbcSMatt Macy     crypto_data_t *ciphertext, crypto_call_req_t *cr)
471*eda14cbcSMatt Macy {
472*eda14cbcSMatt Macy 	crypto_ctx_t *ctx = (crypto_ctx_t *)context;
473*eda14cbcSMatt Macy 	kcf_context_t *kcf_ctx;
474*eda14cbcSMatt Macy 	kcf_provider_desc_t *pd;
475*eda14cbcSMatt Macy 	int error;
476*eda14cbcSMatt Macy 	kcf_req_params_t params;
477*eda14cbcSMatt Macy 
478*eda14cbcSMatt Macy 	if ((ctx == NULL) ||
479*eda14cbcSMatt Macy 	    ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
480*eda14cbcSMatt Macy 	    ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
481*eda14cbcSMatt Macy 		return (CRYPTO_INVALID_CONTEXT);
482*eda14cbcSMatt Macy 	}
483*eda14cbcSMatt Macy 
484*eda14cbcSMatt Macy 	ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
485*eda14cbcSMatt Macy 
486*eda14cbcSMatt Macy 	/* The fast path for SW providers. */
487*eda14cbcSMatt Macy 	if (CHECK_FASTPATH(cr, pd)) {
488*eda14cbcSMatt Macy 		error = KCF_PROV_ENCRYPT_UPDATE(pd, ctx, plaintext,
489*eda14cbcSMatt Macy 		    ciphertext, NULL);
490*eda14cbcSMatt Macy 		KCF_PROV_INCRSTATS(pd, error);
491*eda14cbcSMatt Macy 		return (error);
492*eda14cbcSMatt Macy 	}
493*eda14cbcSMatt Macy 
494*eda14cbcSMatt Macy 	/* Check if we should use a software provider for small jobs */
495*eda14cbcSMatt Macy 	if ((ctx->cc_flags & CRYPTO_USE_OPSTATE) && cr == NULL) {
496*eda14cbcSMatt Macy 		if (plaintext->cd_length < kcf_ctx->kc_mech->me_threshold &&
497*eda14cbcSMatt Macy 		    kcf_ctx->kc_sw_prov_desc != NULL &&
498*eda14cbcSMatt Macy 		    KCF_IS_PROV_USABLE(kcf_ctx->kc_sw_prov_desc)) {
499*eda14cbcSMatt Macy 			pd = kcf_ctx->kc_sw_prov_desc;
500*eda14cbcSMatt Macy 		}
501*eda14cbcSMatt Macy 	}
502*eda14cbcSMatt Macy 
503*eda14cbcSMatt Macy 	KCF_WRAP_ENCRYPT_OPS_PARAMS(&params, KCF_OP_UPDATE,
504*eda14cbcSMatt Macy 	    ctx->cc_session, NULL, NULL, plaintext, ciphertext, NULL);
505*eda14cbcSMatt Macy 	error = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
506*eda14cbcSMatt Macy 
507*eda14cbcSMatt Macy 	return (error);
508*eda14cbcSMatt Macy }
509*eda14cbcSMatt Macy 
510*eda14cbcSMatt Macy /*
511*eda14cbcSMatt Macy  * crypto_encrypt_final()
512*eda14cbcSMatt Macy  *
513*eda14cbcSMatt Macy  * Arguments:
514*eda14cbcSMatt Macy  *	context: A crypto_context_t initialized by encrypt_init().
515*eda14cbcSMatt Macy  *	ciphertext: Storage for the last part of encrypted message
516*eda14cbcSMatt Macy  *	cr:	crypto_call_req_t calling conditions and call back info.
517*eda14cbcSMatt Macy  *
518*eda14cbcSMatt Macy  * Description:
519*eda14cbcSMatt Macy  *	Asynchronously submits a request for, or synchronously performs the
520*eda14cbcSMatt Macy  *	final part of an encryption operation.
521*eda14cbcSMatt Macy  *
522*eda14cbcSMatt Macy  * Context:
523*eda14cbcSMatt Macy  *	Process or interrupt, according to the semantics dictated by the 'cr'.
524*eda14cbcSMatt Macy  *
525*eda14cbcSMatt Macy  * Returns:
526*eda14cbcSMatt Macy  *	See comment in the beginning of the file.
527*eda14cbcSMatt Macy  */
528*eda14cbcSMatt Macy int
529*eda14cbcSMatt Macy crypto_encrypt_final(crypto_context_t context, crypto_data_t *ciphertext,
530*eda14cbcSMatt Macy     crypto_call_req_t *cr)
531*eda14cbcSMatt Macy {
532*eda14cbcSMatt Macy 	crypto_ctx_t *ctx = (crypto_ctx_t *)context;
533*eda14cbcSMatt Macy 	kcf_context_t *kcf_ctx;
534*eda14cbcSMatt Macy 	kcf_provider_desc_t *pd;
535*eda14cbcSMatt Macy 	int error;
536*eda14cbcSMatt Macy 	kcf_req_params_t params;
537*eda14cbcSMatt Macy 
538*eda14cbcSMatt Macy 	if ((ctx == NULL) ||
539*eda14cbcSMatt Macy 	    ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
540*eda14cbcSMatt Macy 	    ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
541*eda14cbcSMatt Macy 		return (CRYPTO_INVALID_CONTEXT);
542*eda14cbcSMatt Macy 	}
543*eda14cbcSMatt Macy 
544*eda14cbcSMatt Macy 	ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
545*eda14cbcSMatt Macy 
546*eda14cbcSMatt Macy 	/* The fast path for SW providers. */
547*eda14cbcSMatt Macy 	if (CHECK_FASTPATH(cr, pd)) {
548*eda14cbcSMatt Macy 		error = KCF_PROV_ENCRYPT_FINAL(pd, ctx, ciphertext, NULL);
549*eda14cbcSMatt Macy 		KCF_PROV_INCRSTATS(pd, error);
550*eda14cbcSMatt Macy 	} else {
551*eda14cbcSMatt Macy 		KCF_WRAP_ENCRYPT_OPS_PARAMS(&params, KCF_OP_FINAL,
552*eda14cbcSMatt Macy 		    ctx->cc_session, NULL, NULL, NULL, ciphertext, NULL);
553*eda14cbcSMatt Macy 		error = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
554*eda14cbcSMatt Macy 	}
555*eda14cbcSMatt Macy 
556*eda14cbcSMatt Macy 	/* Release the hold done in kcf_new_ctx() during init step. */
557*eda14cbcSMatt Macy 	KCF_CONTEXT_COND_RELEASE(error, kcf_ctx);
558*eda14cbcSMatt Macy 	return (error);
559*eda14cbcSMatt Macy }
560*eda14cbcSMatt Macy 
561*eda14cbcSMatt Macy /*
562*eda14cbcSMatt Macy  * crypto_decrypt_prov()
563*eda14cbcSMatt Macy  *
564*eda14cbcSMatt Macy  * Arguments:
565*eda14cbcSMatt Macy  *	pd:	provider descriptor
566*eda14cbcSMatt Macy  *	sid:	session id
567*eda14cbcSMatt Macy  *	mech:	crypto_mechanism_t pointer.
568*eda14cbcSMatt Macy  *		mech_type is a valid value previously returned by
569*eda14cbcSMatt Macy  *		crypto_mech2id();
570*eda14cbcSMatt Macy  *		When the mech's parameter is not NULL, its definition depends
571*eda14cbcSMatt Macy  *		on the standard definition of the mechanism.
572*eda14cbcSMatt Macy  *	key:	pointer to a crypto_key_t structure.
573*eda14cbcSMatt Macy  *	ciphertext: The message to be encrypted
574*eda14cbcSMatt Macy  *	plaintext: Storage for the encrypted message. The length needed
575*eda14cbcSMatt Macy  *		depends on the mechanism, and the plaintext's size.
576*eda14cbcSMatt Macy  *	tmpl:	a crypto_ctx_template_t, opaque template of a context of an
577*eda14cbcSMatt Macy  *		encryption with the 'mech' using 'key'. 'tmpl' is created by
578*eda14cbcSMatt Macy  *		a previous call to crypto_create_ctx_template().
579*eda14cbcSMatt Macy  *	cr:	crypto_call_req_t calling conditions and call back info.
580*eda14cbcSMatt Macy  *
581*eda14cbcSMatt Macy  * Description:
582*eda14cbcSMatt Macy  *	Asynchronously submits a request for, or synchronously performs a
583*eda14cbcSMatt Macy  *	single-part decryption of 'ciphertext' with the mechanism 'mech', using
584*eda14cbcSMatt Macy  *	the key 'key'.
585*eda14cbcSMatt Macy  *	When complete and successful, 'plaintext' will contain the decrypted
586*eda14cbcSMatt Macy  *	message.
587*eda14cbcSMatt Macy  *
588*eda14cbcSMatt Macy  * Context:
589*eda14cbcSMatt Macy  *	Process or interrupt, according to the semantics dictated by the 'cr'.
590*eda14cbcSMatt Macy  *
591*eda14cbcSMatt Macy  * Returns:
592*eda14cbcSMatt Macy  *	See comment in the beginning of the file.
593*eda14cbcSMatt Macy  */
594*eda14cbcSMatt Macy int
595*eda14cbcSMatt Macy crypto_decrypt_prov(crypto_provider_t provider, crypto_session_id_t sid,
596*eda14cbcSMatt Macy     crypto_mechanism_t *mech, crypto_data_t *ciphertext, crypto_key_t *key,
597*eda14cbcSMatt Macy     crypto_ctx_template_t tmpl, crypto_data_t *plaintext,
598*eda14cbcSMatt Macy     crypto_call_req_t *crq)
599*eda14cbcSMatt Macy {
600*eda14cbcSMatt Macy 	kcf_req_params_t params;
601*eda14cbcSMatt Macy 	kcf_provider_desc_t *pd = provider;
602*eda14cbcSMatt Macy 	kcf_provider_desc_t *real_provider = pd;
603*eda14cbcSMatt Macy 	int rv;
604*eda14cbcSMatt Macy 
605*eda14cbcSMatt Macy 	ASSERT(KCF_PROV_REFHELD(pd));
606*eda14cbcSMatt Macy 
607*eda14cbcSMatt Macy 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
608*eda14cbcSMatt Macy 		rv = kcf_get_hardware_provider(mech->cm_type,
609*eda14cbcSMatt Macy 		    CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd,
610*eda14cbcSMatt Macy 		    &real_provider, CRYPTO_FG_DECRYPT_ATOMIC);
611*eda14cbcSMatt Macy 
612*eda14cbcSMatt Macy 		if (rv != CRYPTO_SUCCESS)
613*eda14cbcSMatt Macy 			return (rv);
614*eda14cbcSMatt Macy 	}
615*eda14cbcSMatt Macy 
616*eda14cbcSMatt Macy 	KCF_WRAP_DECRYPT_OPS_PARAMS(&params, KCF_OP_ATOMIC, sid, mech, key,
617*eda14cbcSMatt Macy 	    ciphertext, plaintext, tmpl);
618*eda14cbcSMatt Macy 
619*eda14cbcSMatt Macy 	rv = kcf_submit_request(real_provider, NULL, crq, &params, B_FALSE);
620*eda14cbcSMatt Macy 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
621*eda14cbcSMatt Macy 		KCF_PROV_REFRELE(real_provider);
622*eda14cbcSMatt Macy 
623*eda14cbcSMatt Macy 	return (rv);
624*eda14cbcSMatt Macy }
625*eda14cbcSMatt Macy 
626*eda14cbcSMatt Macy /*
627*eda14cbcSMatt Macy  * Same as crypto_decrypt_prov(), but relies on the KCF scheduler to
628*eda14cbcSMatt Macy  * choose a provider. See crypto_decrypt_prov() comments for more
629*eda14cbcSMatt Macy  * information.
630*eda14cbcSMatt Macy  */
631*eda14cbcSMatt Macy int
632*eda14cbcSMatt Macy crypto_decrypt(crypto_mechanism_t *mech, crypto_data_t *ciphertext,
633*eda14cbcSMatt Macy     crypto_key_t *key, crypto_ctx_template_t tmpl, crypto_data_t *plaintext,
634*eda14cbcSMatt Macy     crypto_call_req_t *crq)
635*eda14cbcSMatt Macy {
636*eda14cbcSMatt Macy 	int error;
637*eda14cbcSMatt Macy 	kcf_mech_entry_t *me;
638*eda14cbcSMatt Macy 	kcf_req_params_t params;
639*eda14cbcSMatt Macy 	kcf_provider_desc_t *pd;
640*eda14cbcSMatt Macy 	kcf_ctx_template_t *ctx_tmpl;
641*eda14cbcSMatt Macy 	crypto_spi_ctx_template_t spi_ctx_tmpl = NULL;
642*eda14cbcSMatt Macy 	kcf_prov_tried_t *list = NULL;
643*eda14cbcSMatt Macy 
644*eda14cbcSMatt Macy retry:
645*eda14cbcSMatt Macy 	/* pd is returned held */
646*eda14cbcSMatt Macy 	if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error,
647*eda14cbcSMatt Macy 	    list, CRYPTO_FG_DECRYPT_ATOMIC, CHECK_RESTRICT(crq),
648*eda14cbcSMatt Macy 	    ciphertext->cd_length)) == NULL) {
649*eda14cbcSMatt Macy 		if (list != NULL)
650*eda14cbcSMatt Macy 			kcf_free_triedlist(list);
651*eda14cbcSMatt Macy 		return (error);
652*eda14cbcSMatt Macy 	}
653*eda14cbcSMatt Macy 
654*eda14cbcSMatt Macy 	/*
655*eda14cbcSMatt Macy 	 * For SW providers, check the validity of the context template
656*eda14cbcSMatt Macy 	 * It is very rare that the generation number mis-matches, so
657*eda14cbcSMatt Macy 	 * is acceptable to fail here, and let the consumer recover by
658*eda14cbcSMatt Macy 	 * freeing this tmpl and create a new one for the key and new SW
659*eda14cbcSMatt Macy 	 * provider
660*eda14cbcSMatt Macy 	 */
661*eda14cbcSMatt Macy 	if ((pd->pd_prov_type == CRYPTO_SW_PROVIDER) &&
662*eda14cbcSMatt Macy 	    ((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) {
663*eda14cbcSMatt Macy 		if (ctx_tmpl->ct_generation != me->me_gen_swprov) {
664*eda14cbcSMatt Macy 			if (list != NULL)
665*eda14cbcSMatt Macy 				kcf_free_triedlist(list);
666*eda14cbcSMatt Macy 			KCF_PROV_REFRELE(pd);
667*eda14cbcSMatt Macy 			return (CRYPTO_OLD_CTX_TEMPLATE);
668*eda14cbcSMatt Macy 		} else {
669*eda14cbcSMatt Macy 			spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl;
670*eda14cbcSMatt Macy 		}
671*eda14cbcSMatt Macy 	}
672*eda14cbcSMatt Macy 
673*eda14cbcSMatt Macy 	/* The fast path for SW providers. */
674*eda14cbcSMatt Macy 	if (CHECK_FASTPATH(crq, pd)) {
675*eda14cbcSMatt Macy 		crypto_mechanism_t lmech;
676*eda14cbcSMatt Macy 
677*eda14cbcSMatt Macy 		lmech = *mech;
678*eda14cbcSMatt Macy 		KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, &lmech);
679*eda14cbcSMatt Macy 
680*eda14cbcSMatt Macy 		error = KCF_PROV_DECRYPT_ATOMIC(pd, pd->pd_sid, &lmech, key,
681*eda14cbcSMatt Macy 		    ciphertext, plaintext, spi_ctx_tmpl, KCF_SWFP_RHNDL(crq));
682*eda14cbcSMatt Macy 		KCF_PROV_INCRSTATS(pd, error);
683*eda14cbcSMatt Macy 	} else {
684*eda14cbcSMatt Macy 		KCF_WRAP_DECRYPT_OPS_PARAMS(&params, KCF_OP_ATOMIC, pd->pd_sid,
685*eda14cbcSMatt Macy 		    mech, key, ciphertext, plaintext, spi_ctx_tmpl);
686*eda14cbcSMatt Macy 		error = kcf_submit_request(pd, NULL, crq, &params, B_FALSE);
687*eda14cbcSMatt Macy 	}
688*eda14cbcSMatt Macy 
689*eda14cbcSMatt Macy 	if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED &&
690*eda14cbcSMatt Macy 	    IS_RECOVERABLE(error)) {
691*eda14cbcSMatt Macy 		/* Add pd to the linked list of providers tried. */
692*eda14cbcSMatt Macy 		if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL)
693*eda14cbcSMatt Macy 			goto retry;
694*eda14cbcSMatt Macy 	}
695*eda14cbcSMatt Macy 
696*eda14cbcSMatt Macy 	if (list != NULL)
697*eda14cbcSMatt Macy 		kcf_free_triedlist(list);
698*eda14cbcSMatt Macy 
699*eda14cbcSMatt Macy 	KCF_PROV_REFRELE(pd);
700*eda14cbcSMatt Macy 	return (error);
701*eda14cbcSMatt Macy }
702*eda14cbcSMatt Macy 
703*eda14cbcSMatt Macy /*
704*eda14cbcSMatt Macy  * crypto_decrypt_init_prov()
705*eda14cbcSMatt Macy  *
706*eda14cbcSMatt Macy  * Calls crypto_cipher_init_prov() to initialize a decryption operation
707*eda14cbcSMatt Macy  */
708*eda14cbcSMatt Macy int
709*eda14cbcSMatt Macy crypto_decrypt_init_prov(crypto_provider_t pd, crypto_session_id_t sid,
710*eda14cbcSMatt Macy     crypto_mechanism_t *mech, crypto_key_t *key,
711*eda14cbcSMatt Macy     crypto_ctx_template_t tmpl, crypto_context_t *ctxp,
712*eda14cbcSMatt Macy     crypto_call_req_t *crq)
713*eda14cbcSMatt Macy {
714*eda14cbcSMatt Macy 	return (crypto_cipher_init_prov(pd, sid, mech, key, tmpl, ctxp, crq,
715*eda14cbcSMatt Macy 	    CRYPTO_FG_DECRYPT));
716*eda14cbcSMatt Macy }
717*eda14cbcSMatt Macy 
718*eda14cbcSMatt Macy /*
719*eda14cbcSMatt Macy  * crypto_decrypt_init()
720*eda14cbcSMatt Macy  *
721*eda14cbcSMatt Macy  * Calls crypto_cipher_init() to initialize a decryption operation
722*eda14cbcSMatt Macy  */
723*eda14cbcSMatt Macy int
724*eda14cbcSMatt Macy crypto_decrypt_init(crypto_mechanism_t *mech, crypto_key_t *key,
725*eda14cbcSMatt Macy     crypto_ctx_template_t tmpl, crypto_context_t *ctxp,
726*eda14cbcSMatt Macy     crypto_call_req_t *crq)
727*eda14cbcSMatt Macy {
728*eda14cbcSMatt Macy 	return (crypto_cipher_init(mech, key, tmpl, ctxp, crq,
729*eda14cbcSMatt Macy 	    CRYPTO_FG_DECRYPT));
730*eda14cbcSMatt Macy }
731*eda14cbcSMatt Macy 
732*eda14cbcSMatt Macy /*
733*eda14cbcSMatt Macy  * crypto_decrypt_update()
734*eda14cbcSMatt Macy  *
735*eda14cbcSMatt Macy  * Arguments:
736*eda14cbcSMatt Macy  *	context: A crypto_context_t initialized by decrypt_init().
737*eda14cbcSMatt Macy  *	ciphertext: The message part to be decrypted
738*eda14cbcSMatt Macy  *	plaintext: Storage for the decrypted message part.
739*eda14cbcSMatt Macy  *	cr:	crypto_call_req_t calling conditions and call back info.
740*eda14cbcSMatt Macy  *
741*eda14cbcSMatt Macy  * Description:
742*eda14cbcSMatt Macy  *	Asynchronously submits a request for, or synchronously performs a
743*eda14cbcSMatt Macy  *	part of an decryption operation.
744*eda14cbcSMatt Macy  *
745*eda14cbcSMatt Macy  * Context:
746*eda14cbcSMatt Macy  *	Process or interrupt, according to the semantics dictated by the 'cr'.
747*eda14cbcSMatt Macy  *
748*eda14cbcSMatt Macy  * Returns:
749*eda14cbcSMatt Macy  *	See comment in the beginning of the file.
750*eda14cbcSMatt Macy  */
751*eda14cbcSMatt Macy int
752*eda14cbcSMatt Macy crypto_decrypt_update(crypto_context_t context, crypto_data_t *ciphertext,
753*eda14cbcSMatt Macy     crypto_data_t *plaintext, crypto_call_req_t *cr)
754*eda14cbcSMatt Macy {
755*eda14cbcSMatt Macy 	crypto_ctx_t *ctx = (crypto_ctx_t *)context;
756*eda14cbcSMatt Macy 	kcf_context_t *kcf_ctx;
757*eda14cbcSMatt Macy 	kcf_provider_desc_t *pd;
758*eda14cbcSMatt Macy 	int error;
759*eda14cbcSMatt Macy 	kcf_req_params_t params;
760*eda14cbcSMatt Macy 
761*eda14cbcSMatt Macy 	if ((ctx == NULL) ||
762*eda14cbcSMatt Macy 	    ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
763*eda14cbcSMatt Macy 	    ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
764*eda14cbcSMatt Macy 		return (CRYPTO_INVALID_CONTEXT);
765*eda14cbcSMatt Macy 	}
766*eda14cbcSMatt Macy 
767*eda14cbcSMatt Macy 	ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
768*eda14cbcSMatt Macy 
769*eda14cbcSMatt Macy 	/* The fast path for SW providers. */
770*eda14cbcSMatt Macy 	if (CHECK_FASTPATH(cr, pd)) {
771*eda14cbcSMatt Macy 		error = KCF_PROV_DECRYPT_UPDATE(pd, ctx, ciphertext,
772*eda14cbcSMatt Macy 		    plaintext, NULL);
773*eda14cbcSMatt Macy 		KCF_PROV_INCRSTATS(pd, error);
774*eda14cbcSMatt Macy 		return (error);
775*eda14cbcSMatt Macy 	}
776*eda14cbcSMatt Macy 
777*eda14cbcSMatt Macy 	/* Check if we should use a software provider for small jobs */
778*eda14cbcSMatt Macy 	if ((ctx->cc_flags & CRYPTO_USE_OPSTATE) && cr == NULL) {
779*eda14cbcSMatt Macy 		if (ciphertext->cd_length < kcf_ctx->kc_mech->me_threshold &&
780*eda14cbcSMatt Macy 		    kcf_ctx->kc_sw_prov_desc != NULL &&
781*eda14cbcSMatt Macy 		    KCF_IS_PROV_USABLE(kcf_ctx->kc_sw_prov_desc)) {
782*eda14cbcSMatt Macy 			pd = kcf_ctx->kc_sw_prov_desc;
783*eda14cbcSMatt Macy 		}
784*eda14cbcSMatt Macy 	}
785*eda14cbcSMatt Macy 
786*eda14cbcSMatt Macy 	KCF_WRAP_DECRYPT_OPS_PARAMS(&params, KCF_OP_UPDATE,
787*eda14cbcSMatt Macy 	    ctx->cc_session, NULL, NULL, ciphertext, plaintext, NULL);
788*eda14cbcSMatt Macy 	error = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
789*eda14cbcSMatt Macy 
790*eda14cbcSMatt Macy 	return (error);
791*eda14cbcSMatt Macy }
792*eda14cbcSMatt Macy 
793*eda14cbcSMatt Macy /*
794*eda14cbcSMatt Macy  * crypto_decrypt_final()
795*eda14cbcSMatt Macy  *
796*eda14cbcSMatt Macy  * Arguments:
797*eda14cbcSMatt Macy  *	context: A crypto_context_t initialized by decrypt_init().
798*eda14cbcSMatt Macy  *	plaintext: Storage for the last part of the decrypted message
799*eda14cbcSMatt Macy  *	cr:	crypto_call_req_t calling conditions and call back info.
800*eda14cbcSMatt Macy  *
801*eda14cbcSMatt Macy  * Description:
802*eda14cbcSMatt Macy  *	Asynchronously submits a request for, or synchronously performs the
803*eda14cbcSMatt Macy  *	final part of a decryption operation.
804*eda14cbcSMatt Macy  *
805*eda14cbcSMatt Macy  * Context:
806*eda14cbcSMatt Macy  *	Process or interrupt, according to the semantics dictated by the 'cr'.
807*eda14cbcSMatt Macy  *
808*eda14cbcSMatt Macy  * Returns:
809*eda14cbcSMatt Macy  *	See comment in the beginning of the file.
810*eda14cbcSMatt Macy  */
811*eda14cbcSMatt Macy int
812*eda14cbcSMatt Macy crypto_decrypt_final(crypto_context_t context, crypto_data_t *plaintext,
813*eda14cbcSMatt Macy     crypto_call_req_t *cr)
814*eda14cbcSMatt Macy {
815*eda14cbcSMatt Macy 	crypto_ctx_t *ctx = (crypto_ctx_t *)context;
816*eda14cbcSMatt Macy 	kcf_context_t *kcf_ctx;
817*eda14cbcSMatt Macy 	kcf_provider_desc_t *pd;
818*eda14cbcSMatt Macy 	int error;
819*eda14cbcSMatt Macy 	kcf_req_params_t params;
820*eda14cbcSMatt Macy 
821*eda14cbcSMatt Macy 	if ((ctx == NULL) ||
822*eda14cbcSMatt Macy 	    ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
823*eda14cbcSMatt Macy 	    ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
824*eda14cbcSMatt Macy 		return (CRYPTO_INVALID_CONTEXT);
825*eda14cbcSMatt Macy 	}
826*eda14cbcSMatt Macy 
827*eda14cbcSMatt Macy 	ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
828*eda14cbcSMatt Macy 
829*eda14cbcSMatt Macy 	/* The fast path for SW providers. */
830*eda14cbcSMatt Macy 	if (CHECK_FASTPATH(cr, pd)) {
831*eda14cbcSMatt Macy 		error = KCF_PROV_DECRYPT_FINAL(pd, ctx, plaintext,
832*eda14cbcSMatt Macy 		    NULL);
833*eda14cbcSMatt Macy 		KCF_PROV_INCRSTATS(pd, error);
834*eda14cbcSMatt Macy 	} else {
835*eda14cbcSMatt Macy 		KCF_WRAP_DECRYPT_OPS_PARAMS(&params, KCF_OP_FINAL,
836*eda14cbcSMatt Macy 		    ctx->cc_session, NULL, NULL, NULL, plaintext, NULL);
837*eda14cbcSMatt Macy 		error = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
838*eda14cbcSMatt Macy 	}
839*eda14cbcSMatt Macy 
840*eda14cbcSMatt Macy 	/* Release the hold done in kcf_new_ctx() during init step. */
841*eda14cbcSMatt Macy 	KCF_CONTEXT_COND_RELEASE(error, kcf_ctx);
842*eda14cbcSMatt Macy 	return (error);
843*eda14cbcSMatt Macy }
844*eda14cbcSMatt Macy 
845*eda14cbcSMatt Macy /*
846*eda14cbcSMatt Macy  * See comments for crypto_encrypt_update().
847*eda14cbcSMatt Macy  */
848*eda14cbcSMatt Macy int
849*eda14cbcSMatt Macy crypto_encrypt_single(crypto_context_t context, crypto_data_t *plaintext,
850*eda14cbcSMatt Macy     crypto_data_t *ciphertext, crypto_call_req_t *cr)
851*eda14cbcSMatt Macy {
852*eda14cbcSMatt Macy 	crypto_ctx_t *ctx = (crypto_ctx_t *)context;
853*eda14cbcSMatt Macy 	kcf_context_t *kcf_ctx;
854*eda14cbcSMatt Macy 	kcf_provider_desc_t *pd;
855*eda14cbcSMatt Macy 	int error;
856*eda14cbcSMatt Macy 	kcf_req_params_t params;
857*eda14cbcSMatt Macy 
858*eda14cbcSMatt Macy 	if ((ctx == NULL) ||
859*eda14cbcSMatt Macy 	    ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
860*eda14cbcSMatt Macy 	    ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
861*eda14cbcSMatt Macy 		return (CRYPTO_INVALID_CONTEXT);
862*eda14cbcSMatt Macy 	}
863*eda14cbcSMatt Macy 
864*eda14cbcSMatt Macy 	/* The fast path for SW providers. */
865*eda14cbcSMatt Macy 	if (CHECK_FASTPATH(cr, pd)) {
866*eda14cbcSMatt Macy 		error = KCF_PROV_ENCRYPT(pd, ctx, plaintext,
867*eda14cbcSMatt Macy 		    ciphertext, NULL);
868*eda14cbcSMatt Macy 		KCF_PROV_INCRSTATS(pd, error);
869*eda14cbcSMatt Macy 	} else {
870*eda14cbcSMatt Macy 		KCF_WRAP_ENCRYPT_OPS_PARAMS(&params, KCF_OP_SINGLE, pd->pd_sid,
871*eda14cbcSMatt Macy 		    NULL, NULL, plaintext, ciphertext, NULL);
872*eda14cbcSMatt Macy 		error = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
873*eda14cbcSMatt Macy 	}
874*eda14cbcSMatt Macy 
875*eda14cbcSMatt Macy 	/* Release the hold done in kcf_new_ctx() during init step. */
876*eda14cbcSMatt Macy 	KCF_CONTEXT_COND_RELEASE(error, kcf_ctx);
877*eda14cbcSMatt Macy 	return (error);
878*eda14cbcSMatt Macy }
879*eda14cbcSMatt Macy 
880*eda14cbcSMatt Macy /*
881*eda14cbcSMatt Macy  * See comments for crypto_decrypt_update().
882*eda14cbcSMatt Macy  */
883*eda14cbcSMatt Macy int
884*eda14cbcSMatt Macy crypto_decrypt_single(crypto_context_t context, crypto_data_t *ciphertext,
885*eda14cbcSMatt Macy     crypto_data_t *plaintext, crypto_call_req_t *cr)
886*eda14cbcSMatt Macy {
887*eda14cbcSMatt Macy 	crypto_ctx_t *ctx = (crypto_ctx_t *)context;
888*eda14cbcSMatt Macy 	kcf_context_t *kcf_ctx;
889*eda14cbcSMatt Macy 	kcf_provider_desc_t *pd;
890*eda14cbcSMatt Macy 	int error;
891*eda14cbcSMatt Macy 	kcf_req_params_t params;
892*eda14cbcSMatt Macy 
893*eda14cbcSMatt Macy 	if ((ctx == NULL) ||
894*eda14cbcSMatt Macy 	    ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
895*eda14cbcSMatt Macy 	    ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
896*eda14cbcSMatt Macy 		return (CRYPTO_INVALID_CONTEXT);
897*eda14cbcSMatt Macy 	}
898*eda14cbcSMatt Macy 
899*eda14cbcSMatt Macy 	/* The fast path for SW providers. */
900*eda14cbcSMatt Macy 	if (CHECK_FASTPATH(cr, pd)) {
901*eda14cbcSMatt Macy 		error = KCF_PROV_DECRYPT(pd, ctx, ciphertext,
902*eda14cbcSMatt Macy 		    plaintext, NULL);
903*eda14cbcSMatt Macy 		KCF_PROV_INCRSTATS(pd, error);
904*eda14cbcSMatt Macy 	} else {
905*eda14cbcSMatt Macy 		KCF_WRAP_DECRYPT_OPS_PARAMS(&params, KCF_OP_SINGLE, pd->pd_sid,
906*eda14cbcSMatt Macy 		    NULL, NULL, ciphertext, plaintext, NULL);
907*eda14cbcSMatt Macy 		error = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
908*eda14cbcSMatt Macy 	}
909*eda14cbcSMatt Macy 
910*eda14cbcSMatt Macy 	/* Release the hold done in kcf_new_ctx() during init step. */
911*eda14cbcSMatt Macy 	KCF_CONTEXT_COND_RELEASE(error, kcf_ctx);
912*eda14cbcSMatt Macy 	return (error);
913*eda14cbcSMatt Macy }
914*eda14cbcSMatt Macy 
915*eda14cbcSMatt Macy #if defined(_KERNEL)
916*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_encrypt_prov);
917*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_encrypt);
918*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_encrypt_init_prov);
919*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_encrypt_init);
920*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_encrypt_update);
921*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_encrypt_final);
922*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_decrypt_prov);
923*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_decrypt);
924*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_decrypt_init_prov);
925*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_decrypt_init);
926*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_decrypt_update);
927*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_decrypt_final);
928*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_encrypt_single);
929*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_decrypt_single);
930*eda14cbcSMatt Macy #endif
931