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