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