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