xref: /titanic_44/usr/src/uts/common/crypto/api/kcf_cipher.c (revision 39c23413b8df94a95f67b34cfd4a4dfc3fd0b48d)
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 2007 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 
455 	/* The fast path for SW providers. */
456 	if (CHECK_FASTPATH(cr, pd)) {
457 		error = KCF_PROV_ENCRYPT_UPDATE(pd, ctx, plaintext,
458 		    ciphertext, NULL);
459 		KCF_PROV_INCRSTATS(pd, error);
460 	} else {
461 		KCF_WRAP_ENCRYPT_OPS_PARAMS(&params, KCF_OP_UPDATE,
462 		    ctx->cc_session, NULL, NULL, plaintext, ciphertext, NULL);
463 		error = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
464 	}
465 
466 	return (error);
467 }
468 
469 /*
470  * crypto_encrypt_final()
471  *
472  * Arguments:
473  *	context: A crypto_context_t initialized by encrypt_init().
474  *	ciphertext: Storage for the last part of encrypted message
475  *	cr:	crypto_call_req_t calling conditions and call back info.
476  *
477  * Description:
478  *	Asynchronously submits a request for, or synchronously performs the
479  *	final part of an encryption operation.
480  *
481  * Context:
482  *	Process or interrupt, according to the semantics dictated by the 'cr'.
483  *
484  * Returns:
485  *	See comment in the beginning of the file.
486  */
487 int
488 crypto_encrypt_final(crypto_context_t context, crypto_data_t *ciphertext,
489     crypto_call_req_t *cr)
490 {
491 	crypto_ctx_t *ctx = (crypto_ctx_t *)context;
492 	kcf_context_t *kcf_ctx;
493 	kcf_provider_desc_t *pd;
494 	int error;
495 	kcf_req_params_t params;
496 
497 	if ((ctx == NULL) ||
498 	    ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
499 	    ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
500 		return (CRYPTO_INVALID_CONTEXT);
501 	}
502 
503 	ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
504 
505 	/* The fast path for SW providers. */
506 	if (CHECK_FASTPATH(cr, pd)) {
507 		error = KCF_PROV_ENCRYPT_FINAL(pd, ctx, ciphertext, NULL);
508 		KCF_PROV_INCRSTATS(pd, error);
509 	} else {
510 		KCF_WRAP_ENCRYPT_OPS_PARAMS(&params, KCF_OP_FINAL,
511 		    ctx->cc_session, NULL, NULL, NULL, ciphertext, NULL);
512 		error = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
513 	}
514 
515 	/* Release the hold done in kcf_new_ctx() during init step. */
516 	KCF_CONTEXT_COND_RELEASE(error, kcf_ctx);
517 	return (error);
518 }
519 
520 /*
521  * crypto_decrypt_prov()
522  *
523  * Arguments:
524  *	pd:	provider descriptor
525  *	sid:	session id
526  *	mech:	crypto_mechanism_t pointer.
527  *		mech_type is a valid value previously returned by
528  *		crypto_mech2id();
529  *		When the mech's parameter is not NULL, its definition depends
530  *		on the standard definition of the mechanism.
531  *	key:	pointer to a crypto_key_t structure.
532  *	ciphertext: The message to be encrypted
533  *	plaintext: Storage for the encrypted message. The length needed
534  *		depends on the mechanism, and the plaintext's size.
535  *	tmpl:	a crypto_ctx_template_t, opaque template of a context of an
536  *		encryption with the 'mech' using 'key'. 'tmpl' is created by
537  *		a previous call to crypto_create_ctx_template().
538  *	cr:	crypto_call_req_t calling conditions and call back info.
539  *
540  * Description:
541  *	Asynchronously submits a request for, or synchronously performs a
542  *	single-part decryption of 'ciphertext' with the mechanism 'mech', using
543  *	the key 'key'.
544  *	When complete and successful, 'plaintext' will contain the decrypted
545  *	message.
546  *
547  * Context:
548  *	Process or interrupt, according to the semantics dictated by the 'cr'.
549  *
550  * Returns:
551  *	See comment in the beginning of the file.
552  */
553 int
554 crypto_decrypt_prov(crypto_provider_t provider, crypto_session_id_t sid,
555     crypto_mechanism_t *mech, crypto_data_t *ciphertext, crypto_key_t *key,
556     crypto_ctx_template_t tmpl, crypto_data_t *plaintext,
557     crypto_call_req_t *crq)
558 {
559 	kcf_req_params_t params;
560 	kcf_provider_desc_t *pd = provider;
561 	kcf_provider_desc_t *real_provider = pd;
562 	int rv;
563 
564 	ASSERT(KCF_PROV_REFHELD(pd));
565 
566 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
567 		rv = kcf_get_hardware_provider(mech->cm_type,
568 		    CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd,
569 		    &real_provider, CRYPTO_FG_DECRYPT_ATOMIC);
570 
571 		if (rv != CRYPTO_SUCCESS)
572 			return (rv);
573 	}
574 
575 	KCF_WRAP_DECRYPT_OPS_PARAMS(&params, KCF_OP_ATOMIC, sid, mech, key,
576 	    ciphertext, plaintext, tmpl);
577 
578 	rv = kcf_submit_request(real_provider, NULL, crq, &params, B_FALSE);
579 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
580 		KCF_PROV_REFRELE(real_provider);
581 
582 	return (rv);
583 }
584 
585 /*
586  * Same as crypto_decrypt_prov(), but relies on the KCF scheduler to
587  * choose a provider. See crypto_decrypt_prov() comments for more
588  * information.
589  */
590 int
591 crypto_decrypt(crypto_mechanism_t *mech, crypto_data_t *ciphertext,
592     crypto_key_t *key, crypto_ctx_template_t tmpl, crypto_data_t *plaintext,
593     crypto_call_req_t *crq)
594 {
595 	int error;
596 	kcf_mech_entry_t *me;
597 	kcf_req_params_t params;
598 	kcf_provider_desc_t *pd;
599 	kcf_ctx_template_t *ctx_tmpl;
600 	crypto_spi_ctx_template_t spi_ctx_tmpl = NULL;
601 	kcf_prov_tried_t *list = NULL;
602 
603 retry:
604 	/* pd is returned held */
605 	if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error,
606 	    list, CRYPTO_FG_DECRYPT_ATOMIC, CHECK_RESTRICT(crq),
607 	    ciphertext->cd_length)) == NULL) {
608 		if (list != NULL)
609 			kcf_free_triedlist(list);
610 		return (error);
611 	}
612 
613 	/*
614 	 * For SW providers, check the validity of the context template
615 	 * It is very rare that the generation number mis-matches, so
616 	 * is acceptable to fail here, and let the consumer recover by
617 	 * freeing this tmpl and create a new one for the key and new SW
618 	 * provider
619 	 */
620 	if ((pd->pd_prov_type == CRYPTO_SW_PROVIDER) &&
621 	    ((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) {
622 		if (ctx_tmpl->ct_generation != me->me_gen_swprov) {
623 			if (list != NULL)
624 				kcf_free_triedlist(list);
625 			KCF_PROV_REFRELE(pd);
626 			return (CRYPTO_OLD_CTX_TEMPLATE);
627 		} else {
628 			spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl;
629 		}
630 	}
631 
632 	/* The fast path for SW providers. */
633 	if (CHECK_FASTPATH(crq, pd)) {
634 		crypto_mechanism_t lmech;
635 
636 		lmech = *mech;
637 		KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, &lmech);
638 
639 		error = KCF_PROV_DECRYPT_ATOMIC(pd, pd->pd_sid, &lmech, key,
640 		    ciphertext, plaintext, spi_ctx_tmpl, KCF_SWFP_RHNDL(crq));
641 		KCF_PROV_INCRSTATS(pd, error);
642 	} else {
643 		KCF_WRAP_DECRYPT_OPS_PARAMS(&params, KCF_OP_ATOMIC, pd->pd_sid,
644 		    mech, key, ciphertext, plaintext, spi_ctx_tmpl);
645 		error = kcf_submit_request(pd, NULL, crq, &params, B_FALSE);
646 	}
647 
648 	if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED &&
649 	    IS_RECOVERABLE(error)) {
650 		/* Add pd to the linked list of providers tried. */
651 		if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL)
652 			goto retry;
653 	}
654 
655 	if (list != NULL)
656 		kcf_free_triedlist(list);
657 
658 	KCF_PROV_REFRELE(pd);
659 	return (error);
660 }
661 
662 /*
663  * crypto_decrypt_init_prov()
664  *
665  * Calls crypto_cipher_init_prov() to initialize a decryption operation
666  */
667 int
668 crypto_decrypt_init_prov(crypto_provider_t pd, crypto_session_id_t sid,
669     crypto_mechanism_t *mech, crypto_key_t *key,
670     crypto_ctx_template_t tmpl, crypto_context_t *ctxp,
671     crypto_call_req_t *crq)
672 {
673 	return (crypto_cipher_init_prov(pd, sid, mech, key, tmpl, ctxp, crq,
674 	    CRYPTO_FG_DECRYPT));
675 }
676 
677 /*
678  * crypto_decrypt_init()
679  *
680  * Calls crypto_cipher_init() to initialize a decryption operation
681  */
682 int
683 crypto_decrypt_init(crypto_mechanism_t *mech, crypto_key_t *key,
684     crypto_ctx_template_t tmpl, crypto_context_t *ctxp,
685     crypto_call_req_t *crq)
686 {
687 	return (crypto_cipher_init(mech, key, tmpl, ctxp, crq,
688 	    CRYPTO_FG_DECRYPT));
689 }
690 
691 /*
692  * crypto_decrypt_update()
693  *
694  * Arguments:
695  *	context: A crypto_context_t initialized by decrypt_init().
696  *	ciphertext: The message part to be decrypted
697  *	plaintext: Storage for the decrypted message part.
698  *	cr:	crypto_call_req_t calling conditions and call back info.
699  *
700  * Description:
701  *	Asynchronously submits a request for, or synchronously performs a
702  *	part of an decryption operation.
703  *
704  * Context:
705  *	Process or interrupt, according to the semantics dictated by the 'cr'.
706  *
707  * Returns:
708  *	See comment in the beginning of the file.
709  */
710 int
711 crypto_decrypt_update(crypto_context_t context, crypto_data_t *ciphertext,
712     crypto_data_t *plaintext, crypto_call_req_t *cr)
713 {
714 	crypto_ctx_t *ctx = (crypto_ctx_t *)context;
715 	kcf_context_t *kcf_ctx;
716 	kcf_provider_desc_t *pd;
717 	int error;
718 	kcf_req_params_t params;
719 
720 	if ((ctx == NULL) ||
721 	    ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
722 	    ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
723 		return (CRYPTO_INVALID_CONTEXT);
724 	}
725 
726 	ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
727 
728 	/* The fast path for SW providers. */
729 	if (CHECK_FASTPATH(cr, pd)) {
730 		error = KCF_PROV_DECRYPT_UPDATE(pd, ctx, ciphertext,
731 		    plaintext, NULL);
732 		KCF_PROV_INCRSTATS(pd, error);
733 	} else {
734 		KCF_WRAP_DECRYPT_OPS_PARAMS(&params, KCF_OP_UPDATE,
735 		    ctx->cc_session, NULL, NULL, ciphertext, plaintext, NULL);
736 		error = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
737 	}
738 
739 	return (error);
740 }
741 
742 /*
743  * crypto_decrypt_final()
744  *
745  * Arguments:
746  *	context: A crypto_context_t initialized by decrypt_init().
747  *	plaintext: Storage for the last part of the decrypted message
748  *	cr:	crypto_call_req_t calling conditions and call back info.
749  *
750  * Description:
751  *	Asynchronously submits a request for, or synchronously performs the
752  *	final part of a decryption operation.
753  *
754  * Context:
755  *	Process or interrupt, according to the semantics dictated by the 'cr'.
756  *
757  * Returns:
758  *	See comment in the beginning of the file.
759  */
760 int
761 crypto_decrypt_final(crypto_context_t context, crypto_data_t *plaintext,
762     crypto_call_req_t *cr)
763 {
764 	crypto_ctx_t *ctx = (crypto_ctx_t *)context;
765 	kcf_context_t *kcf_ctx;
766 	kcf_provider_desc_t *pd;
767 	int error;
768 	kcf_req_params_t params;
769 
770 	if ((ctx == NULL) ||
771 	    ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
772 	    ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
773 		return (CRYPTO_INVALID_CONTEXT);
774 	}
775 
776 	ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
777 
778 	/* The fast path for SW providers. */
779 	if (CHECK_FASTPATH(cr, pd)) {
780 		error = KCF_PROV_DECRYPT_FINAL(pd, ctx, plaintext,
781 		    NULL);
782 		KCF_PROV_INCRSTATS(pd, error);
783 	} else {
784 		KCF_WRAP_DECRYPT_OPS_PARAMS(&params, KCF_OP_FINAL,
785 		    ctx->cc_session, NULL, NULL, NULL, plaintext, NULL);
786 		error = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
787 	}
788 
789 	/* Release the hold done in kcf_new_ctx() during init step. */
790 	KCF_CONTEXT_COND_RELEASE(error, kcf_ctx);
791 	return (error);
792 }
793 
794 /*
795  * See comments for crypto_encrypt_update().
796  */
797 int
798 crypto_encrypt_single(crypto_context_t context, crypto_data_t *plaintext,
799     crypto_data_t *ciphertext, crypto_call_req_t *cr)
800 {
801 	crypto_ctx_t *ctx = (crypto_ctx_t *)context;
802 	kcf_context_t *kcf_ctx;
803 	kcf_provider_desc_t *pd;
804 	int error;
805 	kcf_req_params_t params;
806 
807 	if ((ctx == NULL) ||
808 	    ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
809 	    ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
810 		return (CRYPTO_INVALID_CONTEXT);
811 	}
812 
813 
814 	/* The fast path for SW providers. */
815 	if (CHECK_FASTPATH(cr, pd)) {
816 		error = KCF_PROV_ENCRYPT(pd, ctx, plaintext,
817 		    ciphertext, NULL);
818 		KCF_PROV_INCRSTATS(pd, error);
819 	} else {
820 		KCF_WRAP_ENCRYPT_OPS_PARAMS(&params, KCF_OP_SINGLE, pd->pd_sid,
821 		    NULL, NULL, plaintext, ciphertext, NULL);
822 		error = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
823 	}
824 
825 	/* Release the hold done in kcf_new_ctx() during init step. */
826 	KCF_CONTEXT_COND_RELEASE(error, kcf_ctx);
827 	return (error);
828 }
829 
830 /*
831  * See comments for crypto_decrypt_update().
832  */
833 int
834 crypto_decrypt_single(crypto_context_t context, crypto_data_t *ciphertext,
835     crypto_data_t *plaintext, crypto_call_req_t *cr)
836 {
837 	crypto_ctx_t *ctx = (crypto_ctx_t *)context;
838 	kcf_context_t *kcf_ctx;
839 	kcf_provider_desc_t *pd;
840 	int error;
841 	kcf_req_params_t params;
842 
843 	if ((ctx == NULL) ||
844 	    ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
845 	    ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
846 		return (CRYPTO_INVALID_CONTEXT);
847 	}
848 
849 
850 	/* The fast path for SW providers. */
851 	if (CHECK_FASTPATH(cr, pd)) {
852 		error = KCF_PROV_DECRYPT(pd, ctx, ciphertext,
853 		    plaintext, NULL);
854 		KCF_PROV_INCRSTATS(pd, error);
855 	} else {
856 		KCF_WRAP_DECRYPT_OPS_PARAMS(&params, KCF_OP_SINGLE, pd->pd_sid,
857 		    NULL, NULL, ciphertext, plaintext, NULL);
858 		error = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
859 	}
860 
861 	/* Release the hold done in kcf_new_ctx() during init step. */
862 	KCF_CONTEXT_COND_RELEASE(error, kcf_ctx);
863 	return (error);
864 }
865