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