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