xref: /titanic_50/usr/src/uts/common/crypto/api/kcf_cipher.c (revision 9b009fc1b553084f6003dcd46b171890049de0ff)
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  */
104 static int
crypto_cipher_init_prov(crypto_provider_t provider,crypto_session_id_t sid,crypto_mechanism_t * mech,crypto_key_t * key,crypto_spi_ctx_template_t tmpl,crypto_context_t * ctxp,crypto_call_req_t * crq,crypto_func_group_t func)105 crypto_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 
212 done:
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  */
228 static int
crypto_cipher_init(crypto_mechanism_t * mech,crypto_key_t * key,crypto_ctx_template_t tmpl,crypto_context_t * ctxp,crypto_call_req_t * crq,crypto_func_group_t func)229 crypto_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 
240 retry:
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  */
317 int
crypto_encrypt_prov(crypto_provider_t provider,crypto_session_id_t sid,crypto_mechanism_t * mech,crypto_data_t * plaintext,crypto_key_t * key,crypto_ctx_template_t tmpl,crypto_data_t * ciphertext,crypto_call_req_t * crq)318 crypto_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  */
353 int
crypto_encrypt(crypto_mechanism_t * mech,crypto_data_t * plaintext,crypto_key_t * key,crypto_ctx_template_t tmpl,crypto_data_t * ciphertext,crypto_call_req_t * crq)354 crypto_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 
366 retry:
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  */
429 int
crypto_encrypt_init_prov(crypto_provider_t pd,crypto_session_id_t sid,crypto_mechanism_t * mech,crypto_key_t * key,crypto_ctx_template_t tmpl,crypto_context_t * ctxp,crypto_call_req_t * crq)430 crypto_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  */
444 int
crypto_encrypt_init(crypto_mechanism_t * mech,crypto_key_t * key,crypto_ctx_template_t tmpl,crypto_context_t * ctxp,crypto_call_req_t * crq)445 crypto_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  */
472 int
crypto_encrypt_update(crypto_context_t context,crypto_data_t * plaintext,crypto_data_t * ciphertext,crypto_call_req_t * cr)473 crypto_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  */
532 int
crypto_encrypt_final(crypto_context_t context,crypto_data_t * ciphertext,crypto_call_req_t * cr)533 crypto_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  */
598 int
crypto_decrypt_prov(crypto_provider_t provider,crypto_session_id_t sid,crypto_mechanism_t * mech,crypto_data_t * ciphertext,crypto_key_t * key,crypto_ctx_template_t tmpl,crypto_data_t * plaintext,crypto_call_req_t * crq)599 crypto_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  */
635 int
crypto_decrypt(crypto_mechanism_t * mech,crypto_data_t * ciphertext,crypto_key_t * key,crypto_ctx_template_t tmpl,crypto_data_t * plaintext,crypto_call_req_t * crq)636 crypto_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 
648 retry:
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  */
711 int
crypto_decrypt_init_prov(crypto_provider_t pd,crypto_session_id_t sid,crypto_mechanism_t * mech,crypto_key_t * key,crypto_ctx_template_t tmpl,crypto_context_t * ctxp,crypto_call_req_t * crq)712 crypto_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  */
726 int
crypto_decrypt_init(crypto_mechanism_t * mech,crypto_key_t * key,crypto_ctx_template_t tmpl,crypto_context_t * ctxp,crypto_call_req_t * crq)727 crypto_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  */
754 int
crypto_decrypt_update(crypto_context_t context,crypto_data_t * ciphertext,crypto_data_t * plaintext,crypto_call_req_t * cr)755 crypto_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  */
814 int
crypto_decrypt_final(crypto_context_t context,crypto_data_t * plaintext,crypto_call_req_t * cr)815 crypto_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  */
851 int
crypto_encrypt_single(crypto_context_t context,crypto_data_t * plaintext,crypto_data_t * ciphertext,crypto_call_req_t * cr)852 crypto_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  */
886 int
crypto_decrypt_single(crypto_context_t context,crypto_data_t * ciphertext,crypto_data_t * plaintext,crypto_call_req_t * cr)887 crypto_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