xref: /illumos-gate/usr/src/uts/common/crypto/api/kcf_cipher.c (revision 8b80e8cb6855118d46f605e91b5ed4ce83417395)
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 
161 		goto done;
162 	}
163 
164 	/* Check if context sharing is possible */
165 	if (pd->pd_prov_type == CRYPTO_HW_PROVIDER &&
166 	    key->ck_format == CRYPTO_KEY_RAW &&
167 	    KCF_CAN_SHARE_OPSTATE(pd, mech->cm_type)) {
168 		kcf_context_t *tctxp = (kcf_context_t *)ctx;
169 		kcf_provider_desc_t *tpd = NULL;
170 		crypto_mech_info_t *sinfo;
171 
172 		if ((kcf_get_sw_prov(mech->cm_type, &tpd, &tctxp->kc_mech,
173 		    B_FALSE) == CRYPTO_SUCCESS)) {
174 			int tlen;
175 
176 			sinfo = &(KCF_TO_PROV_MECHINFO(tpd, mech->cm_type));
177 			/*
178 			 * key->ck_length from the consumer is always in bits.
179 			 * We convert it to be in the same unit registered by
180 			 * the provider in order to do a comparison.
181 			 */
182 			if (sinfo->cm_mech_flags & CRYPTO_KEYSIZE_UNIT_IN_BYTES)
183 				tlen = key->ck_length >> 3;
184 			else
185 				tlen = key->ck_length;
186 			/*
187 			 * Check if the software provider can support context
188 			 * sharing and support this key length.
189 			 */
190 			if ((sinfo->cm_mech_flags & CRYPTO_CAN_SHARE_OPSTATE) &&
191 			    (tlen >= sinfo->cm_min_key_length) &&
192 			    (tlen <= sinfo->cm_max_key_length)) {
193 				ctx->cc_flags = CRYPTO_INIT_OPSTATE;
194 				tctxp->kc_sw_prov_desc = tpd;
195 			} else
196 				KCF_PROV_REFRELE(tpd);
197 		}
198 	}
199 
200 	if (func == CRYPTO_FG_ENCRYPT) {
201 		KCF_WRAP_ENCRYPT_OPS_PARAMS(&params, KCF_OP_INIT, sid,
202 		    mech, key, NULL, NULL, tmpl);
203 	} else {
204 		ASSERT(func == CRYPTO_FG_DECRYPT);
205 		KCF_WRAP_DECRYPT_OPS_PARAMS(&params, KCF_OP_INIT, sid,
206 		    mech, key, NULL, NULL, tmpl);
207 	}
208 
209 	error = kcf_submit_request(real_provider, ctx, crq, &params,
210 	    B_FALSE);
211 
212 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
213 		KCF_PROV_REFRELE(real_provider);
214 
215 done:
216 	if ((error == CRYPTO_SUCCESS) || (error == CRYPTO_QUEUED))
217 		*ctxp = (crypto_context_t)ctx;
218 	else {
219 		/* Release the hold done in kcf_new_ctx(). */
220 		KCF_CONTEXT_REFRELE((kcf_context_t *)ctx->cc_framework_private);
221 	}
222 
223 	return (error);
224 }
225 
226 /*
227  * Same as crypto_cipher_init_prov(), but relies on the scheduler to pick
228  * an appropriate provider. See crypto_cipher_init_prov() comments for more
229  * details.
230  */
231 static int
232 crypto_cipher_init(crypto_mechanism_t *mech, crypto_key_t *key,
233     crypto_ctx_template_t tmpl, crypto_context_t *ctxp,
234     crypto_call_req_t *crq, crypto_func_group_t func)
235 {
236 	int error;
237 	kcf_mech_entry_t *me;
238 	kcf_provider_desc_t *pd;
239 	kcf_ctx_template_t *ctx_tmpl;
240 	crypto_spi_ctx_template_t spi_ctx_tmpl = NULL;
241 	kcf_prov_tried_t *list = NULL;
242 
243 retry:
244 	/* pd is returned held */
245 	if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error,
246 	    list, func, CHECK_RESTRICT(crq), 0)) == NULL) {
247 		if (list != NULL)
248 			kcf_free_triedlist(list);
249 		return (error);
250 	}
251 
252 	/*
253 	 * For SW providers, check the validity of the context template
254 	 * It is very rare that the generation number mis-matches, so
255 	 * is acceptable to fail here, and let the consumer recover by
256 	 * freeing this tmpl and create a new one for the key and new SW
257 	 * provider
258 	 */
259 	if ((pd->pd_prov_type == CRYPTO_SW_PROVIDER) &&
260 	    ((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) {
261 		if (ctx_tmpl->ct_generation != me->me_gen_swprov) {
262 			if (list != NULL)
263 				kcf_free_triedlist(list);
264 			KCF_PROV_REFRELE(pd);
265 			return (CRYPTO_OLD_CTX_TEMPLATE);
266 		} else {
267 			spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl;
268 		}
269 	}
270 
271 	error = crypto_cipher_init_prov(pd, pd->pd_sid, mech, key,
272 	    spi_ctx_tmpl, ctxp, crq, func);
273 	if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED &&
274 	    IS_RECOVERABLE(error)) {
275 		/* Add pd to the linked list of providers tried. */
276 		if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL)
277 			goto retry;
278 	}
279 
280 	if (list != NULL)
281 		kcf_free_triedlist(list);
282 
283 	KCF_PROV_REFRELE(pd);
284 	return (error);
285 }
286 
287 /*
288  * crypto_encrypt_prov()
289  *
290  * Arguments:
291  *	pd:	provider descriptor
292  *	sid:	session id
293  *	mech:	crypto_mechanism_t pointer.
294  *		mech_type is a valid value previously returned by
295  *		crypto_mech2id();
296  *		When the mech's parameter is not NULL, its definition depends
297  *		on the standard definition of the mechanism.
298  *	key:	pointer to a crypto_key_t structure.
299  *	plaintext: The message to be encrypted
300  *	ciphertext: Storage for the encrypted message. The length needed
301  *		depends on the mechanism, and the plaintext's size.
302  *	tmpl:	a crypto_ctx_template_t, opaque template of a context of an
303  *		encryption with the 'mech' using 'key'. 'tmpl' is created by
304  *		a previous call to crypto_create_ctx_template().
305  *	cr:	crypto_call_req_t calling conditions and call back info.
306  *
307  * Description:
308  *	Asynchronously submits a request for, or synchronously performs a
309  *	single-part encryption of 'plaintext' with the mechanism 'mech', using
310  *	the key 'key'.
311  *	When complete and successful, 'ciphertext' will contain the encrypted
312  *	message.
313  *
314  * Context:
315  *	Process or interrupt, according to the semantics dictated by the 'cr'.
316  *
317  * Returns:
318  *	See comment in the beginning of the file.
319  */
320 int
321 crypto_encrypt_prov(crypto_provider_t provider, crypto_session_id_t sid,
322     crypto_mechanism_t *mech, crypto_data_t *plaintext, crypto_key_t *key,
323     crypto_ctx_template_t tmpl, crypto_data_t *ciphertext,
324     crypto_call_req_t *crq)
325 {
326 	kcf_req_params_t params;
327 	kcf_provider_desc_t *pd = provider;
328 	kcf_provider_desc_t *real_provider = pd;
329 	int error;
330 
331 	ASSERT(KCF_PROV_REFHELD(pd));
332 
333 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
334 		error = kcf_get_hardware_provider(mech->cm_type,
335 		    CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd,
336 		    &real_provider, CRYPTO_FG_ENCRYPT_ATOMIC);
337 
338 		if (error != CRYPTO_SUCCESS)
339 			return (error);
340 	}
341 
342 	KCF_WRAP_ENCRYPT_OPS_PARAMS(&params, KCF_OP_ATOMIC, sid, mech, key,
343 	    plaintext, ciphertext, tmpl);
344 
345 	error = kcf_submit_request(real_provider, NULL, crq, &params, B_FALSE);
346 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
347 		KCF_PROV_REFRELE(real_provider);
348 
349 	return (error);
350 }
351 
352 /*
353  * Same as crypto_encrypt_prov(), but relies on the scheduler to pick
354  * a provider. See crypto_encrypt_prov() for more details.
355  */
356 int
357 crypto_encrypt(crypto_mechanism_t *mech, crypto_data_t *plaintext,
358     crypto_key_t *key, crypto_ctx_template_t tmpl, crypto_data_t *ciphertext,
359     crypto_call_req_t *crq)
360 {
361 	int error;
362 	kcf_mech_entry_t *me;
363 	kcf_req_params_t params;
364 	kcf_provider_desc_t *pd;
365 	kcf_ctx_template_t *ctx_tmpl;
366 	crypto_spi_ctx_template_t spi_ctx_tmpl = NULL;
367 	kcf_prov_tried_t *list = NULL;
368 
369 retry:
370 	/* pd is returned held */
371 	if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error,
372 	    list, CRYPTO_FG_ENCRYPT_ATOMIC, CHECK_RESTRICT(crq),
373 	    plaintext->cd_length)) == NULL) {
374 		if (list != NULL)
375 			kcf_free_triedlist(list);
376 		return (error);
377 	}
378 
379 	/*
380 	 * For SW providers, check the validity of the context template
381 	 * It is very rare that the generation number mis-matches, so
382 	 * is acceptable to fail here, and let the consumer recover by
383 	 * freeing this tmpl and create a new one for the key and new SW
384 	 * provider
385 	 */
386 	if ((pd->pd_prov_type == CRYPTO_SW_PROVIDER) &&
387 	    ((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) {
388 		if (ctx_tmpl->ct_generation != me->me_gen_swprov) {
389 			if (list != NULL)
390 				kcf_free_triedlist(list);
391 			KCF_PROV_REFRELE(pd);
392 			return (CRYPTO_OLD_CTX_TEMPLATE);
393 		} else {
394 			spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl;
395 		}
396 	}
397 
398 	/* The fast path for SW providers. */
399 	if (CHECK_FASTPATH(crq, pd)) {
400 		crypto_mechanism_t lmech;
401 
402 		lmech = *mech;
403 		KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, &lmech);
404 
405 		error = KCF_PROV_ENCRYPT_ATOMIC(pd, pd->pd_sid, &lmech, key,
406 		    plaintext, ciphertext, spi_ctx_tmpl, KCF_SWFP_RHNDL(crq));
407 		KCF_PROV_INCRSTATS(pd, error);
408 	} else {
409 		KCF_WRAP_ENCRYPT_OPS_PARAMS(&params, KCF_OP_ATOMIC, pd->pd_sid,
410 		    mech, key, plaintext, ciphertext, spi_ctx_tmpl);
411 		error = kcf_submit_request(pd, NULL, crq, &params, B_FALSE);
412 	}
413 
414 	if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED &&
415 	    IS_RECOVERABLE(error)) {
416 		/* Add pd to the linked list of providers tried. */
417 		if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL)
418 			goto retry;
419 	}
420 
421 	if (list != NULL)
422 		kcf_free_triedlist(list);
423 
424 	KCF_PROV_REFRELE(pd);
425 	return (error);
426 }
427 
428 /*
429  * crypto_encrypt_init_prov()
430  *
431  * Calls crypto_cipher_init_prov() to initialize an encryption operation.
432  */
433 int
434 crypto_encrypt_init_prov(crypto_provider_t pd, crypto_session_id_t sid,
435     crypto_mechanism_t *mech, crypto_key_t *key,
436     crypto_ctx_template_t tmpl, crypto_context_t *ctxp,
437     crypto_call_req_t *crq)
438 {
439 	return (crypto_cipher_init_prov(pd, sid, mech, key, tmpl, ctxp, crq,
440 	    CRYPTO_FG_ENCRYPT));
441 }
442 
443 /*
444  * crypto_encrypt_init()
445  *
446  * Calls crypto_cipher_init() to initialize an encryption operation
447  */
448 int
449 crypto_encrypt_init(crypto_mechanism_t *mech, crypto_key_t *key,
450     crypto_ctx_template_t tmpl, crypto_context_t *ctxp,
451     crypto_call_req_t *crq)
452 {
453 	return (crypto_cipher_init(mech, key, tmpl, ctxp, crq,
454 	    CRYPTO_FG_ENCRYPT));
455 }
456 
457 /*
458  * crypto_encrypt_update()
459  *
460  * Arguments:
461  *	context: A crypto_context_t initialized by encrypt_init().
462  *	plaintext: The message part to be encrypted
463  *	ciphertext: Storage for the encrypted message part.
464  *	cr:	crypto_call_req_t calling conditions and call back info.
465  *
466  * Description:
467  *	Asynchronously submits a request for, or synchronously performs a
468  *	part of an encryption operation.
469  *
470  * Context:
471  *	Process or interrupt, according to the semantics dictated by the 'cr'.
472  *
473  * Returns:
474  *	See comment in the beginning of the file.
475  */
476 int
477 crypto_encrypt_update(crypto_context_t context, crypto_data_t *plaintext,
478     crypto_data_t *ciphertext, crypto_call_req_t *cr)
479 {
480 	crypto_ctx_t *ctx = (crypto_ctx_t *)context;
481 	kcf_context_t *kcf_ctx;
482 	kcf_provider_desc_t *pd;
483 	int error;
484 	kcf_req_params_t params;
485 
486 	if ((ctx == NULL) ||
487 	    ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
488 	    ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
489 		return (CRYPTO_INVALID_CONTEXT);
490 	}
491 
492 	ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
493 
494 	/* The fast path for SW providers. */
495 	if (CHECK_FASTPATH(cr, pd)) {
496 		error = KCF_PROV_ENCRYPT_UPDATE(pd, ctx, plaintext,
497 		    ciphertext, NULL);
498 		KCF_PROV_INCRSTATS(pd, error);
499 		return (error);
500 	}
501 
502 	/* Check if we should use a software provider for small jobs */
503 	if ((ctx->cc_flags & CRYPTO_USE_OPSTATE) && cr == NULL) {
504 		if (plaintext->cd_length < kcf_ctx->kc_mech->me_threshold &&
505 		    kcf_ctx->kc_sw_prov_desc != NULL &&
506 		    KCF_IS_PROV_USABLE(kcf_ctx->kc_sw_prov_desc)) {
507 			pd = kcf_ctx->kc_sw_prov_desc;
508 		}
509 	}
510 
511 	KCF_WRAP_ENCRYPT_OPS_PARAMS(&params, KCF_OP_UPDATE,
512 	    ctx->cc_session, NULL, NULL, plaintext, ciphertext, NULL);
513 	error = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
514 
515 	return (error);
516 }
517 
518 /*
519  * crypto_encrypt_final()
520  *
521  * Arguments:
522  *	context: A crypto_context_t initialized by encrypt_init().
523  *	ciphertext: Storage for the last part of encrypted message
524  *	cr:	crypto_call_req_t calling conditions and call back info.
525  *
526  * Description:
527  *	Asynchronously submits a request for, or synchronously performs the
528  *	final part of an encryption operation.
529  *
530  * Context:
531  *	Process or interrupt, according to the semantics dictated by the 'cr'.
532  *
533  * Returns:
534  *	See comment in the beginning of the file.
535  */
536 int
537 crypto_encrypt_final(crypto_context_t context, crypto_data_t *ciphertext,
538     crypto_call_req_t *cr)
539 {
540 	crypto_ctx_t *ctx = (crypto_ctx_t *)context;
541 	kcf_context_t *kcf_ctx;
542 	kcf_provider_desc_t *pd;
543 	int error;
544 	kcf_req_params_t params;
545 
546 	if ((ctx == NULL) ||
547 	    ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
548 	    ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
549 		return (CRYPTO_INVALID_CONTEXT);
550 	}
551 
552 	ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
553 
554 	/* The fast path for SW providers. */
555 	if (CHECK_FASTPATH(cr, pd)) {
556 		error = KCF_PROV_ENCRYPT_FINAL(pd, ctx, ciphertext, NULL);
557 		KCF_PROV_INCRSTATS(pd, error);
558 	} else {
559 		KCF_WRAP_ENCRYPT_OPS_PARAMS(&params, KCF_OP_FINAL,
560 		    ctx->cc_session, NULL, NULL, NULL, ciphertext, NULL);
561 		error = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
562 	}
563 
564 	/* Release the hold done in kcf_new_ctx() during init step. */
565 	KCF_CONTEXT_COND_RELEASE(error, kcf_ctx);
566 	return (error);
567 }
568 
569 /*
570  * crypto_decrypt_prov()
571  *
572  * Arguments:
573  *	pd:	provider descriptor
574  *	sid:	session id
575  *	mech:	crypto_mechanism_t pointer.
576  *		mech_type is a valid value previously returned by
577  *		crypto_mech2id();
578  *		When the mech's parameter is not NULL, its definition depends
579  *		on the standard definition of the mechanism.
580  *	key:	pointer to a crypto_key_t structure.
581  *	ciphertext: The message to be encrypted
582  *	plaintext: Storage for the encrypted message. The length needed
583  *		depends on the mechanism, and the plaintext's size.
584  *	tmpl:	a crypto_ctx_template_t, opaque template of a context of an
585  *		encryption with the 'mech' using 'key'. 'tmpl' is created by
586  *		a previous call to crypto_create_ctx_template().
587  *	cr:	crypto_call_req_t calling conditions and call back info.
588  *
589  * Description:
590  *	Asynchronously submits a request for, or synchronously performs a
591  *	single-part decryption of 'ciphertext' with the mechanism 'mech', using
592  *	the key 'key'.
593  *	When complete and successful, 'plaintext' will contain the decrypted
594  *	message.
595  *
596  * Context:
597  *	Process or interrupt, according to the semantics dictated by the 'cr'.
598  *
599  * Returns:
600  *	See comment in the beginning of the file.
601  */
602 int
603 crypto_decrypt_prov(crypto_provider_t provider, crypto_session_id_t sid,
604     crypto_mechanism_t *mech, crypto_data_t *ciphertext, crypto_key_t *key,
605     crypto_ctx_template_t tmpl, crypto_data_t *plaintext,
606     crypto_call_req_t *crq)
607 {
608 	kcf_req_params_t params;
609 	kcf_provider_desc_t *pd = provider;
610 	kcf_provider_desc_t *real_provider = pd;
611 	int rv;
612 
613 	ASSERT(KCF_PROV_REFHELD(pd));
614 
615 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
616 		rv = kcf_get_hardware_provider(mech->cm_type,
617 		    CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd,
618 		    &real_provider, CRYPTO_FG_DECRYPT_ATOMIC);
619 
620 		if (rv != CRYPTO_SUCCESS)
621 			return (rv);
622 	}
623 
624 	KCF_WRAP_DECRYPT_OPS_PARAMS(&params, KCF_OP_ATOMIC, sid, mech, key,
625 	    ciphertext, plaintext, tmpl);
626 
627 	rv = kcf_submit_request(real_provider, NULL, crq, &params, B_FALSE);
628 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
629 		KCF_PROV_REFRELE(real_provider);
630 
631 	return (rv);
632 }
633 
634 /*
635  * Same as crypto_decrypt_prov(), but relies on the KCF scheduler to
636  * choose a provider. See crypto_decrypt_prov() comments for more
637  * information.
638  */
639 int
640 crypto_decrypt(crypto_mechanism_t *mech, crypto_data_t *ciphertext,
641     crypto_key_t *key, crypto_ctx_template_t tmpl, crypto_data_t *plaintext,
642     crypto_call_req_t *crq)
643 {
644 	int error;
645 	kcf_mech_entry_t *me;
646 	kcf_req_params_t params;
647 	kcf_provider_desc_t *pd;
648 	kcf_ctx_template_t *ctx_tmpl;
649 	crypto_spi_ctx_template_t spi_ctx_tmpl = NULL;
650 	kcf_prov_tried_t *list = NULL;
651 
652 retry:
653 	/* pd is returned held */
654 	if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error,
655 	    list, CRYPTO_FG_DECRYPT_ATOMIC, CHECK_RESTRICT(crq),
656 	    ciphertext->cd_length)) == NULL) {
657 		if (list != NULL)
658 			kcf_free_triedlist(list);
659 		return (error);
660 	}
661 
662 	/*
663 	 * For SW providers, check the validity of the context template
664 	 * It is very rare that the generation number mis-matches, so
665 	 * is acceptable to fail here, and let the consumer recover by
666 	 * freeing this tmpl and create a new one for the key and new SW
667 	 * provider
668 	 */
669 	if ((pd->pd_prov_type == CRYPTO_SW_PROVIDER) &&
670 	    ((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) {
671 		if (ctx_tmpl->ct_generation != me->me_gen_swprov) {
672 			if (list != NULL)
673 				kcf_free_triedlist(list);
674 			KCF_PROV_REFRELE(pd);
675 			return (CRYPTO_OLD_CTX_TEMPLATE);
676 		} else {
677 			spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl;
678 		}
679 	}
680 
681 	/* The fast path for SW providers. */
682 	if (CHECK_FASTPATH(crq, pd)) {
683 		crypto_mechanism_t lmech;
684 
685 		lmech = *mech;
686 		KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, &lmech);
687 
688 		error = KCF_PROV_DECRYPT_ATOMIC(pd, pd->pd_sid, &lmech, key,
689 		    ciphertext, plaintext, spi_ctx_tmpl, KCF_SWFP_RHNDL(crq));
690 		KCF_PROV_INCRSTATS(pd, error);
691 	} else {
692 		KCF_WRAP_DECRYPT_OPS_PARAMS(&params, KCF_OP_ATOMIC, pd->pd_sid,
693 		    mech, key, ciphertext, plaintext, spi_ctx_tmpl);
694 		error = kcf_submit_request(pd, NULL, crq, &params, B_FALSE);
695 	}
696 
697 	if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED &&
698 	    IS_RECOVERABLE(error)) {
699 		/* Add pd to the linked list of providers tried. */
700 		if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL)
701 			goto retry;
702 	}
703 
704 	if (list != NULL)
705 		kcf_free_triedlist(list);
706 
707 	KCF_PROV_REFRELE(pd);
708 	return (error);
709 }
710 
711 /*
712  * crypto_decrypt_init_prov()
713  *
714  * Calls crypto_cipher_init_prov() to initialize a decryption operation
715  */
716 int
717 crypto_decrypt_init_prov(crypto_provider_t pd, crypto_session_id_t sid,
718     crypto_mechanism_t *mech, crypto_key_t *key,
719     crypto_ctx_template_t tmpl, crypto_context_t *ctxp,
720     crypto_call_req_t *crq)
721 {
722 	return (crypto_cipher_init_prov(pd, sid, mech, key, tmpl, ctxp, crq,
723 	    CRYPTO_FG_DECRYPT));
724 }
725 
726 /*
727  * crypto_decrypt_init()
728  *
729  * Calls crypto_cipher_init() to initialize a decryption operation
730  */
731 int
732 crypto_decrypt_init(crypto_mechanism_t *mech, crypto_key_t *key,
733     crypto_ctx_template_t tmpl, crypto_context_t *ctxp,
734     crypto_call_req_t *crq)
735 {
736 	return (crypto_cipher_init(mech, key, tmpl, ctxp, crq,
737 	    CRYPTO_FG_DECRYPT));
738 }
739 
740 /*
741  * crypto_decrypt_update()
742  *
743  * Arguments:
744  *	context: A crypto_context_t initialized by decrypt_init().
745  *	ciphertext: The message part to be decrypted
746  *	plaintext: Storage for the decrypted message part.
747  *	cr:	crypto_call_req_t calling conditions and call back info.
748  *
749  * Description:
750  *	Asynchronously submits a request for, or synchronously performs a
751  *	part of an decryption operation.
752  *
753  * Context:
754  *	Process or interrupt, according to the semantics dictated by the 'cr'.
755  *
756  * Returns:
757  *	See comment in the beginning of the file.
758  */
759 int
760 crypto_decrypt_update(crypto_context_t context, crypto_data_t *ciphertext,
761     crypto_data_t *plaintext, crypto_call_req_t *cr)
762 {
763 	crypto_ctx_t *ctx = (crypto_ctx_t *)context;
764 	kcf_context_t *kcf_ctx;
765 	kcf_provider_desc_t *pd;
766 	int error;
767 	kcf_req_params_t params;
768 
769 	if ((ctx == NULL) ||
770 	    ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
771 	    ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
772 		return (CRYPTO_INVALID_CONTEXT);
773 	}
774 
775 	ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
776 
777 	/* The fast path for SW providers. */
778 	if (CHECK_FASTPATH(cr, pd)) {
779 		error = KCF_PROV_DECRYPT_UPDATE(pd, ctx, ciphertext,
780 		    plaintext, NULL);
781 		KCF_PROV_INCRSTATS(pd, error);
782 		return (error);
783 	}
784 
785 	/* Check if we should use a software provider for small jobs */
786 	if ((ctx->cc_flags & CRYPTO_USE_OPSTATE) && cr == NULL) {
787 		if (ciphertext->cd_length < kcf_ctx->kc_mech->me_threshold &&
788 		    kcf_ctx->kc_sw_prov_desc != NULL &&
789 		    KCF_IS_PROV_USABLE(kcf_ctx->kc_sw_prov_desc)) {
790 			pd = kcf_ctx->kc_sw_prov_desc;
791 		}
792 	}
793 
794 	KCF_WRAP_DECRYPT_OPS_PARAMS(&params, KCF_OP_UPDATE,
795 	    ctx->cc_session, NULL, NULL, ciphertext, plaintext, NULL);
796 	error = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
797 
798 	return (error);
799 }
800 
801 /*
802  * crypto_decrypt_final()
803  *
804  * Arguments:
805  *	context: A crypto_context_t initialized by decrypt_init().
806  *	plaintext: Storage for the last part of the decrypted message
807  *	cr:	crypto_call_req_t calling conditions and call back info.
808  *
809  * Description:
810  *	Asynchronously submits a request for, or synchronously performs the
811  *	final part of a decryption operation.
812  *
813  * Context:
814  *	Process or interrupt, according to the semantics dictated by the 'cr'.
815  *
816  * Returns:
817  *	See comment in the beginning of the file.
818  */
819 int
820 crypto_decrypt_final(crypto_context_t context, crypto_data_t *plaintext,
821     crypto_call_req_t *cr)
822 {
823 	crypto_ctx_t *ctx = (crypto_ctx_t *)context;
824 	kcf_context_t *kcf_ctx;
825 	kcf_provider_desc_t *pd;
826 	int error;
827 	kcf_req_params_t params;
828 
829 	if ((ctx == NULL) ||
830 	    ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
831 	    ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
832 		return (CRYPTO_INVALID_CONTEXT);
833 	}
834 
835 	ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
836 
837 	/* The fast path for SW providers. */
838 	if (CHECK_FASTPATH(cr, pd)) {
839 		error = KCF_PROV_DECRYPT_FINAL(pd, ctx, plaintext,
840 		    NULL);
841 		KCF_PROV_INCRSTATS(pd, error);
842 	} else {
843 		KCF_WRAP_DECRYPT_OPS_PARAMS(&params, KCF_OP_FINAL,
844 		    ctx->cc_session, NULL, NULL, NULL, plaintext, NULL);
845 		error = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
846 	}
847 
848 	/* Release the hold done in kcf_new_ctx() during init step. */
849 	KCF_CONTEXT_COND_RELEASE(error, kcf_ctx);
850 	return (error);
851 }
852 
853 /*
854  * See comments for crypto_encrypt_update().
855  */
856 int
857 crypto_encrypt_single(crypto_context_t context, crypto_data_t *plaintext,
858     crypto_data_t *ciphertext, crypto_call_req_t *cr)
859 {
860 	crypto_ctx_t *ctx = (crypto_ctx_t *)context;
861 	kcf_context_t *kcf_ctx;
862 	kcf_provider_desc_t *pd;
863 	int error;
864 	kcf_req_params_t params;
865 
866 	if ((ctx == NULL) ||
867 	    ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
868 	    ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
869 		return (CRYPTO_INVALID_CONTEXT);
870 	}
871 
872 	/* The fast path for SW providers. */
873 	if (CHECK_FASTPATH(cr, pd)) {
874 		error = KCF_PROV_ENCRYPT(pd, ctx, plaintext,
875 		    ciphertext, NULL);
876 		KCF_PROV_INCRSTATS(pd, error);
877 	} else {
878 		KCF_WRAP_ENCRYPT_OPS_PARAMS(&params, KCF_OP_SINGLE, pd->pd_sid,
879 		    NULL, NULL, plaintext, ciphertext, NULL);
880 		error = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
881 	}
882 
883 	/* Release the hold done in kcf_new_ctx() during init step. */
884 	KCF_CONTEXT_COND_RELEASE(error, kcf_ctx);
885 	return (error);
886 }
887 
888 /*
889  * See comments for crypto_decrypt_update().
890  */
891 int
892 crypto_decrypt_single(crypto_context_t context, crypto_data_t *ciphertext,
893     crypto_data_t *plaintext, crypto_call_req_t *cr)
894 {
895 	crypto_ctx_t *ctx = (crypto_ctx_t *)context;
896 	kcf_context_t *kcf_ctx;
897 	kcf_provider_desc_t *pd;
898 	int error;
899 	kcf_req_params_t params;
900 
901 	if ((ctx == NULL) ||
902 	    ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
903 	    ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
904 		return (CRYPTO_INVALID_CONTEXT);
905 	}
906 
907 	/* The fast path for SW providers. */
908 	if (CHECK_FASTPATH(cr, pd)) {
909 		error = KCF_PROV_DECRYPT(pd, ctx, ciphertext,
910 		    plaintext, NULL);
911 		KCF_PROV_INCRSTATS(pd, error);
912 	} else {
913 		KCF_WRAP_DECRYPT_OPS_PARAMS(&params, KCF_OP_SINGLE, pd->pd_sid,
914 		    NULL, NULL, ciphertext, plaintext, NULL);
915 		error = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
916 	}
917 
918 	/* Release the hold done in kcf_new_ctx() during init step. */
919 	KCF_CONTEXT_COND_RELEASE(error, kcf_ctx);
920 	return (error);
921 }
922