]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - zfs/module/icp/api/kcf_cipher.c
UBUNTU: SAUCE: Update zfs to e02aaf17f15ad274fa1f24c9c826f1477911ea3f
[mirror_ubuntu-zesty-kernel.git] / zfs / module / icp / api / kcf_cipher.c
1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <sys/zfs_context.h>
27 #include <sys/crypto/common.h>
28 #include <sys/crypto/impl.h>
29 #include <sys/crypto/api.h>
30 #include <sys/crypto/spi.h>
31 #include <sys/crypto/sched_impl.h>
32
33 #define CRYPTO_OPS_OFFSET(f) offsetof(crypto_ops_t, co_##f)
34 #define CRYPTO_CIPHER_OFFSET(f) offsetof(crypto_cipher_ops_t, f)
35
36 /*
37 * Encryption and decryption routines.
38 */
39
40 /*
41 * The following are the possible returned values common to all the routines
42 * below. The applicability of some of these return values depends on the
43 * presence of the arguments.
44 *
45 * CRYPTO_SUCCESS: The operation completed successfully.
46 * CRYPTO_QUEUED: A request was submitted successfully. The callback
47 * routine will be called when the operation is done.
48 * CRYPTO_INVALID_MECH_NUMBER, CRYPTO_INVALID_MECH_PARAM, or
49 * CRYPTO_INVALID_MECH for problems with the 'mech'.
50 * CRYPTO_INVALID_DATA for bogus 'data'
51 * CRYPTO_HOST_MEMORY for failure to allocate memory to handle this work.
52 * CRYPTO_INVALID_CONTEXT: Not a valid context.
53 * CRYPTO_BUSY: Cannot process the request now. Schedule a
54 * crypto_bufcall(), or try later.
55 * CRYPTO_NOT_SUPPORTED and CRYPTO_MECH_NOT_SUPPORTED: No provider is
56 * capable of a function or a mechanism.
57 * CRYPTO_INVALID_KEY: bogus 'key' argument.
58 * CRYPTO_INVALID_PLAINTEXT: bogus 'plaintext' argument.
59 * CRYPTO_INVALID_CIPHERTEXT: bogus 'ciphertext' argument.
60 */
61
62 /*
63 * crypto_cipher_init_prov()
64 *
65 * Arguments:
66 *
67 * pd: provider descriptor
68 * sid: session id
69 * mech: crypto_mechanism_t pointer.
70 * mech_type is a valid value previously returned by
71 * crypto_mech2id();
72 * When the mech's parameter is not NULL, its definition depends
73 * on the standard definition of the mechanism.
74 * key: pointer to a crypto_key_t structure.
75 * tmpl: a crypto_ctx_template_t, opaque template of a context of an
76 * encryption or decryption with the 'mech' using 'key'.
77 * 'tmpl' is created by a previous call to
78 * crypto_create_ctx_template().
79 * ctxp: Pointer to a crypto_context_t.
80 * func: CRYPTO_FG_ENCRYPT or CRYPTO_FG_DECRYPT.
81 * cr: crypto_call_req_t calling conditions and call back info.
82 *
83 * Description:
84 * This is a common function invoked internally by both
85 * crypto_encrypt_init() and crypto_decrypt_init().
86 * Asynchronously submits a request for, or synchronously performs the
87 * initialization of an encryption or a decryption operation.
88 * When possible and applicable, will internally use the pre-expanded key
89 * schedule from the context template, tmpl.
90 * When complete and successful, 'ctxp' will contain a crypto_context_t
91 * valid for later calls to encrypt_update() and encrypt_final(), or
92 * decrypt_update() and decrypt_final().
93 * The caller should hold a reference on the specified provider
94 * descriptor before calling this function.
95 *
96 * Context:
97 * Process or interrupt, according to the semantics dictated by the 'cr'.
98 *
99 * Returns:
100 * See comment in the beginning of the file.
101 */
102 static int
103 crypto_cipher_init_prov(crypto_provider_t provider, crypto_session_id_t sid,
104 crypto_mechanism_t *mech, crypto_key_t *key,
105 crypto_spi_ctx_template_t tmpl, crypto_context_t *ctxp,
106 crypto_call_req_t *crq, crypto_func_group_t func)
107 {
108 int error;
109 crypto_ctx_t *ctx;
110 kcf_req_params_t params;
111 kcf_provider_desc_t *pd = provider;
112 kcf_provider_desc_t *real_provider = pd;
113
114 ASSERT(KCF_PROV_REFHELD(pd));
115
116 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
117 if (func == CRYPTO_FG_ENCRYPT) {
118 error = kcf_get_hardware_provider(mech->cm_type,
119 CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd,
120 &real_provider, CRYPTO_FG_ENCRYPT);
121 } else {
122 error = kcf_get_hardware_provider(mech->cm_type,
123 CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd,
124 &real_provider, CRYPTO_FG_DECRYPT);
125 }
126
127 if (error != CRYPTO_SUCCESS)
128 return (error);
129 }
130
131 /* Allocate and initialize the canonical context */
132 if ((ctx = kcf_new_ctx(crq, real_provider, sid)) == NULL) {
133 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
134 KCF_PROV_REFRELE(real_provider);
135 return (CRYPTO_HOST_MEMORY);
136 }
137
138 /* The fast path for SW providers. */
139 if (CHECK_FASTPATH(crq, pd)) {
140 crypto_mechanism_t lmech;
141
142 lmech = *mech;
143 KCF_SET_PROVIDER_MECHNUM(mech->cm_type, real_provider, &lmech);
144
145 if (func == CRYPTO_FG_ENCRYPT)
146 error = KCF_PROV_ENCRYPT_INIT(real_provider, ctx,
147 &lmech, key, tmpl, KCF_SWFP_RHNDL(crq));
148 else {
149 ASSERT(func == CRYPTO_FG_DECRYPT);
150
151 error = KCF_PROV_DECRYPT_INIT(real_provider, ctx,
152 &lmech, key, tmpl, KCF_SWFP_RHNDL(crq));
153 }
154 KCF_PROV_INCRSTATS(pd, error);
155
156 goto done;
157 }
158
159 /* Check if context sharing is possible */
160 if (pd->pd_prov_type == CRYPTO_HW_PROVIDER &&
161 key->ck_format == CRYPTO_KEY_RAW &&
162 KCF_CAN_SHARE_OPSTATE(pd, mech->cm_type)) {
163 kcf_context_t *tctxp = (kcf_context_t *)ctx;
164 kcf_provider_desc_t *tpd = NULL;
165 crypto_mech_info_t *sinfo;
166
167 if ((kcf_get_sw_prov(mech->cm_type, &tpd, &tctxp->kc_mech,
168 B_FALSE) == CRYPTO_SUCCESS)) {
169 int tlen;
170
171 sinfo = &(KCF_TO_PROV_MECHINFO(tpd, mech->cm_type));
172 /*
173 * key->ck_length from the consumer is always in bits.
174 * We convert it to be in the same unit registered by
175 * the provider in order to do a comparison.
176 */
177 if (sinfo->cm_mech_flags & CRYPTO_KEYSIZE_UNIT_IN_BYTES)
178 tlen = key->ck_length >> 3;
179 else
180 tlen = key->ck_length;
181 /*
182 * Check if the software provider can support context
183 * sharing and support this key length.
184 */
185 if ((sinfo->cm_mech_flags & CRYPTO_CAN_SHARE_OPSTATE) &&
186 (tlen >= sinfo->cm_min_key_length) &&
187 (tlen <= sinfo->cm_max_key_length)) {
188 ctx->cc_flags = CRYPTO_INIT_OPSTATE;
189 tctxp->kc_sw_prov_desc = tpd;
190 } else
191 KCF_PROV_REFRELE(tpd);
192 }
193 }
194
195 if (func == CRYPTO_FG_ENCRYPT) {
196 KCF_WRAP_ENCRYPT_OPS_PARAMS(&params, KCF_OP_INIT, sid,
197 mech, key, NULL, NULL, tmpl);
198 } else {
199 ASSERT(func == CRYPTO_FG_DECRYPT);
200 KCF_WRAP_DECRYPT_OPS_PARAMS(&params, KCF_OP_INIT, sid,
201 mech, key, NULL, NULL, tmpl);
202 }
203
204 error = kcf_submit_request(real_provider, ctx, crq, &params,
205 B_FALSE);
206
207 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
208 KCF_PROV_REFRELE(real_provider);
209
210 done:
211 if ((error == CRYPTO_SUCCESS) || (error == CRYPTO_QUEUED))
212 *ctxp = (crypto_context_t)ctx;
213 else {
214 /* Release the hold done in kcf_new_ctx(). */
215 KCF_CONTEXT_REFRELE((kcf_context_t *)ctx->cc_framework_private);
216 }
217
218 return (error);
219 }
220
221 /*
222 * Same as crypto_cipher_init_prov(), but relies on the scheduler to pick
223 * an appropriate provider. See crypto_cipher_init_prov() comments for more
224 * details.
225 */
226 static int
227 crypto_cipher_init(crypto_mechanism_t *mech, crypto_key_t *key,
228 crypto_ctx_template_t tmpl, crypto_context_t *ctxp,
229 crypto_call_req_t *crq, crypto_func_group_t func)
230 {
231 int error;
232 kcf_mech_entry_t *me;
233 kcf_provider_desc_t *pd;
234 kcf_ctx_template_t *ctx_tmpl;
235 crypto_spi_ctx_template_t spi_ctx_tmpl = NULL;
236 kcf_prov_tried_t *list = NULL;
237
238 retry:
239 /* pd is returned held */
240 if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error,
241 list, func, CHECK_RESTRICT(crq), 0)) == NULL) {
242 if (list != NULL)
243 kcf_free_triedlist(list);
244 return (error);
245 }
246
247 /*
248 * For SW providers, check the validity of the context template
249 * It is very rare that the generation number mis-matches, so
250 * is acceptable to fail here, and let the consumer recover by
251 * freeing this tmpl and create a new one for the key and new SW
252 * provider
253 */
254 if ((pd->pd_prov_type == CRYPTO_SW_PROVIDER) &&
255 ((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) {
256 if (ctx_tmpl->ct_generation != me->me_gen_swprov) {
257 if (list != NULL)
258 kcf_free_triedlist(list);
259 KCF_PROV_REFRELE(pd);
260 return (CRYPTO_OLD_CTX_TEMPLATE);
261 } else {
262 spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl;
263 }
264 }
265
266 error = crypto_cipher_init_prov(pd, pd->pd_sid, mech, key,
267 spi_ctx_tmpl, ctxp, crq, func);
268 if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED &&
269 IS_RECOVERABLE(error)) {
270 /* Add pd to the linked list of providers tried. */
271 if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL)
272 goto retry;
273 }
274
275 if (list != NULL)
276 kcf_free_triedlist(list);
277
278 KCF_PROV_REFRELE(pd);
279 return (error);
280 }
281
282 /*
283 * crypto_encrypt_prov()
284 *
285 * Arguments:
286 * pd: provider descriptor
287 * sid: session id
288 * mech: crypto_mechanism_t pointer.
289 * mech_type is a valid value previously returned by
290 * crypto_mech2id();
291 * When the mech's parameter is not NULL, its definition depends
292 * on the standard definition of the mechanism.
293 * key: pointer to a crypto_key_t structure.
294 * plaintext: The message to be encrypted
295 * ciphertext: Storage for the encrypted message. The length needed
296 * depends on the mechanism, and the plaintext's size.
297 * tmpl: a crypto_ctx_template_t, opaque template of a context of an
298 * encryption with the 'mech' using 'key'. 'tmpl' is created by
299 * a previous call to crypto_create_ctx_template().
300 * cr: crypto_call_req_t calling conditions and call back info.
301 *
302 * Description:
303 * Asynchronously submits a request for, or synchronously performs a
304 * single-part encryption of 'plaintext' with the mechanism 'mech', using
305 * the key 'key'.
306 * When complete and successful, 'ciphertext' will contain the encrypted
307 * message.
308 *
309 * Context:
310 * Process or interrupt, according to the semantics dictated by the 'cr'.
311 *
312 * Returns:
313 * See comment in the beginning of the file.
314 */
315 int
316 crypto_encrypt_prov(crypto_provider_t provider, crypto_session_id_t sid,
317 crypto_mechanism_t *mech, crypto_data_t *plaintext, crypto_key_t *key,
318 crypto_ctx_template_t tmpl, crypto_data_t *ciphertext,
319 crypto_call_req_t *crq)
320 {
321 kcf_req_params_t params;
322 kcf_provider_desc_t *pd = provider;
323 kcf_provider_desc_t *real_provider = pd;
324 int error;
325
326 ASSERT(KCF_PROV_REFHELD(pd));
327
328 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
329 error = kcf_get_hardware_provider(mech->cm_type,
330 CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd,
331 &real_provider, CRYPTO_FG_ENCRYPT_ATOMIC);
332
333 if (error != CRYPTO_SUCCESS)
334 return (error);
335 }
336
337 KCF_WRAP_ENCRYPT_OPS_PARAMS(&params, KCF_OP_ATOMIC, sid, mech, key,
338 plaintext, ciphertext, tmpl);
339
340 error = kcf_submit_request(real_provider, NULL, crq, &params, B_FALSE);
341 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
342 KCF_PROV_REFRELE(real_provider);
343
344 return (error);
345 }
346
347 /*
348 * Same as crypto_encrypt_prov(), but relies on the scheduler to pick
349 * a provider. See crypto_encrypt_prov() for more details.
350 */
351 int
352 crypto_encrypt(crypto_mechanism_t *mech, crypto_data_t *plaintext,
353 crypto_key_t *key, crypto_ctx_template_t tmpl, crypto_data_t *ciphertext,
354 crypto_call_req_t *crq)
355 {
356 int error;
357 kcf_mech_entry_t *me;
358 kcf_req_params_t params;
359 kcf_provider_desc_t *pd;
360 kcf_ctx_template_t *ctx_tmpl;
361 crypto_spi_ctx_template_t spi_ctx_tmpl = NULL;
362 kcf_prov_tried_t *list = NULL;
363
364 retry:
365 /* pd is returned held */
366 if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error,
367 list, CRYPTO_FG_ENCRYPT_ATOMIC, CHECK_RESTRICT(crq),
368 plaintext->cd_length)) == NULL) {
369 if (list != NULL)
370 kcf_free_triedlist(list);
371 return (error);
372 }
373
374 /*
375 * For SW providers, check the validity of the context template
376 * It is very rare that the generation number mis-matches, so
377 * is acceptable to fail here, and let the consumer recover by
378 * freeing this tmpl and create a new one for the key and new SW
379 * provider
380 */
381 if ((pd->pd_prov_type == CRYPTO_SW_PROVIDER) &&
382 ((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) {
383 if (ctx_tmpl->ct_generation != me->me_gen_swprov) {
384 if (list != NULL)
385 kcf_free_triedlist(list);
386 KCF_PROV_REFRELE(pd);
387 return (CRYPTO_OLD_CTX_TEMPLATE);
388 } else {
389 spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl;
390 }
391 }
392
393 /* The fast path for SW providers. */
394 if (CHECK_FASTPATH(crq, pd)) {
395 crypto_mechanism_t lmech;
396
397 lmech = *mech;
398 KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, &lmech);
399
400 error = KCF_PROV_ENCRYPT_ATOMIC(pd, pd->pd_sid, &lmech, key,
401 plaintext, ciphertext, spi_ctx_tmpl, KCF_SWFP_RHNDL(crq));
402 KCF_PROV_INCRSTATS(pd, error);
403 } else {
404 KCF_WRAP_ENCRYPT_OPS_PARAMS(&params, KCF_OP_ATOMIC, pd->pd_sid,
405 mech, key, plaintext, ciphertext, spi_ctx_tmpl);
406 error = kcf_submit_request(pd, NULL, crq, &params, B_FALSE);
407 }
408
409 if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED &&
410 IS_RECOVERABLE(error)) {
411 /* Add pd to the linked list of providers tried. */
412 if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL)
413 goto retry;
414 }
415
416 if (list != NULL)
417 kcf_free_triedlist(list);
418
419 KCF_PROV_REFRELE(pd);
420 return (error);
421 }
422
423 /*
424 * crypto_encrypt_init_prov()
425 *
426 * Calls crypto_cipher_init_prov() to initialize an encryption operation.
427 */
428 int
429 crypto_encrypt_init_prov(crypto_provider_t pd, crypto_session_id_t sid,
430 crypto_mechanism_t *mech, crypto_key_t *key,
431 crypto_ctx_template_t tmpl, crypto_context_t *ctxp,
432 crypto_call_req_t *crq)
433 {
434 return (crypto_cipher_init_prov(pd, sid, mech, key, tmpl, ctxp, crq,
435 CRYPTO_FG_ENCRYPT));
436 }
437
438 /*
439 * crypto_encrypt_init()
440 *
441 * Calls crypto_cipher_init() to initialize an encryption operation
442 */
443 int
444 crypto_encrypt_init(crypto_mechanism_t *mech, crypto_key_t *key,
445 crypto_ctx_template_t tmpl, crypto_context_t *ctxp,
446 crypto_call_req_t *crq)
447 {
448 return (crypto_cipher_init(mech, key, tmpl, ctxp, crq,
449 CRYPTO_FG_ENCRYPT));
450 }
451
452 /*
453 * crypto_encrypt_update()
454 *
455 * Arguments:
456 * context: A crypto_context_t initialized by encrypt_init().
457 * plaintext: The message part to be encrypted
458 * ciphertext: Storage for the encrypted message part.
459 * cr: crypto_call_req_t calling conditions and call back info.
460 *
461 * Description:
462 * Asynchronously submits a request for, or synchronously performs a
463 * part of an encryption operation.
464 *
465 * Context:
466 * Process or interrupt, according to the semantics dictated by the 'cr'.
467 *
468 * Returns:
469 * See comment in the beginning of the file.
470 */
471 int
472 crypto_encrypt_update(crypto_context_t context, crypto_data_t *plaintext,
473 crypto_data_t *ciphertext, crypto_call_req_t *cr)
474 {
475 crypto_ctx_t *ctx = (crypto_ctx_t *)context;
476 kcf_context_t *kcf_ctx;
477 kcf_provider_desc_t *pd;
478 int error;
479 kcf_req_params_t params;
480
481 if ((ctx == NULL) ||
482 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
483 ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
484 return (CRYPTO_INVALID_CONTEXT);
485 }
486
487 ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
488
489 /* The fast path for SW providers. */
490 if (CHECK_FASTPATH(cr, pd)) {
491 error = KCF_PROV_ENCRYPT_UPDATE(pd, ctx, plaintext,
492 ciphertext, NULL);
493 KCF_PROV_INCRSTATS(pd, error);
494 return (error);
495 }
496
497 /* Check if we should use a software provider for small jobs */
498 if ((ctx->cc_flags & CRYPTO_USE_OPSTATE) && cr == NULL) {
499 if (plaintext->cd_length < kcf_ctx->kc_mech->me_threshold &&
500 kcf_ctx->kc_sw_prov_desc != NULL &&
501 KCF_IS_PROV_USABLE(kcf_ctx->kc_sw_prov_desc)) {
502 pd = kcf_ctx->kc_sw_prov_desc;
503 }
504 }
505
506 KCF_WRAP_ENCRYPT_OPS_PARAMS(&params, KCF_OP_UPDATE,
507 ctx->cc_session, NULL, NULL, plaintext, ciphertext, NULL);
508 error = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
509
510 return (error);
511 }
512
513 /*
514 * crypto_encrypt_final()
515 *
516 * Arguments:
517 * context: A crypto_context_t initialized by encrypt_init().
518 * ciphertext: Storage for the last part of encrypted message
519 * cr: crypto_call_req_t calling conditions and call back info.
520 *
521 * Description:
522 * Asynchronously submits a request for, or synchronously performs the
523 * final part of an encryption operation.
524 *
525 * Context:
526 * Process or interrupt, according to the semantics dictated by the 'cr'.
527 *
528 * Returns:
529 * See comment in the beginning of the file.
530 */
531 int
532 crypto_encrypt_final(crypto_context_t context, crypto_data_t *ciphertext,
533 crypto_call_req_t *cr)
534 {
535 crypto_ctx_t *ctx = (crypto_ctx_t *)context;
536 kcf_context_t *kcf_ctx;
537 kcf_provider_desc_t *pd;
538 int error;
539 kcf_req_params_t params;
540
541 if ((ctx == NULL) ||
542 ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
543 ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
544 return (CRYPTO_INVALID_CONTEXT);
545 }
546
547 ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
548
549 /* The fast path for SW providers. */
550 if (CHECK_FASTPATH(cr, pd)) {
551 error = KCF_PROV_ENCRYPT_FINAL(pd, ctx, ciphertext, NULL);
552 KCF_PROV_INCRSTATS(pd, error);
553 } else {
554 KCF_WRAP_ENCRYPT_OPS_PARAMS(&params, KCF_OP_FINAL,
555 ctx->cc_session, NULL, NULL, NULL, ciphertext, NULL);
556 error = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
557 }
558
559 /* Release the hold done in kcf_new_ctx() during init step. */
560 KCF_CONTEXT_COND_RELEASE(error, kcf_ctx);
561 return (error);
562 }
563
564 /*
565 * crypto_decrypt_prov()
566 *
567 * Arguments:
568 * pd: provider descriptor
569 * sid: session id
570 * mech: crypto_mechanism_t pointer.
571 * mech_type is a valid value previously returned by
572 * crypto_mech2id();
573 * When the mech's parameter is not NULL, its definition depends
574 * on the standard definition of the mechanism.
575 * key: pointer to a crypto_key_t structure.
576 * ciphertext: The message to be encrypted
577 * plaintext: Storage for the encrypted message. The length needed
578 * depends on the mechanism, and the plaintext's size.
579 * tmpl: a crypto_ctx_template_t, opaque template of a context of an
580 * encryption with the 'mech' using 'key'. 'tmpl' is created by
581 * a previous call to crypto_create_ctx_template().
582 * cr: crypto_call_req_t calling conditions and call back info.
583 *
584 * Description:
585 * Asynchronously submits a request for, or synchronously performs a
586 * single-part decryption of 'ciphertext' with the mechanism 'mech', using
587 * the key 'key'.
588 * When complete and successful, 'plaintext' will contain the decrypted
589 * message.
590 *
591 * Context:
592 * Process or interrupt, according to the semantics dictated by the 'cr'.
593 *
594 * Returns:
595 * See comment in the beginning of the file.
596 */
597 int
598 crypto_decrypt_prov(crypto_provider_t provider, crypto_session_id_t sid,
599 crypto_mechanism_t *mech, crypto_data_t *ciphertext, crypto_key_t *key,
600 crypto_ctx_template_t tmpl, crypto_data_t *plaintext,
601 crypto_call_req_t *crq)
602 {
603 kcf_req_params_t params;
604 kcf_provider_desc_t *pd = provider;
605 kcf_provider_desc_t *real_provider = pd;
606 int rv;
607
608 ASSERT(KCF_PROV_REFHELD(pd));
609
610 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
611 rv = kcf_get_hardware_provider(mech->cm_type,
612 CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd,
613 &real_provider, CRYPTO_FG_DECRYPT_ATOMIC);
614
615 if (rv != CRYPTO_SUCCESS)
616 return (rv);
617 }
618
619 KCF_WRAP_DECRYPT_OPS_PARAMS(&params, KCF_OP_ATOMIC, sid, mech, key,
620 ciphertext, plaintext, tmpl);
621
622 rv = kcf_submit_request(real_provider, NULL, crq, &params, B_FALSE);
623 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
624 KCF_PROV_REFRELE(real_provider);
625
626 return (rv);
627 }
628
629 /*
630 * Same as crypto_decrypt_prov(), but relies on the KCF scheduler to
631 * choose a provider. See crypto_decrypt_prov() comments for more
632 * information.
633 */
634 int
635 crypto_decrypt(crypto_mechanism_t *mech, crypto_data_t *ciphertext,
636 crypto_key_t *key, crypto_ctx_template_t tmpl, crypto_data_t *plaintext,
637 crypto_call_req_t *crq)
638 {
639 int error;
640 kcf_mech_entry_t *me;
641 kcf_req_params_t params;
642 kcf_provider_desc_t *pd;
643 kcf_ctx_template_t *ctx_tmpl;
644 crypto_spi_ctx_template_t spi_ctx_tmpl = NULL;
645 kcf_prov_tried_t *list = NULL;
646
647 retry:
648 /* pd is returned held */
649 if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error,
650 list, CRYPTO_FG_DECRYPT_ATOMIC, CHECK_RESTRICT(crq),
651 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
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
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
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
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
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
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
918 #if defined(_KERNEL) && defined(HAVE_SPL)
919 EXPORT_SYMBOL(crypto_cipher_init_prov);
920 EXPORT_SYMBOL(crypto_cipher_init);
921 EXPORT_SYMBOL(crypto_encrypt_prov);
922 EXPORT_SYMBOL(crypto_encrypt);
923 EXPORT_SYMBOL(crypto_encrypt_init_prov);
924 EXPORT_SYMBOL(crypto_encrypt_init);
925 EXPORT_SYMBOL(crypto_encrypt_update);
926 EXPORT_SYMBOL(crypto_encrypt_final);
927 EXPORT_SYMBOL(crypto_decrypt_prov);
928 EXPORT_SYMBOL(crypto_decrypt);
929 EXPORT_SYMBOL(crypto_decrypt_init_prov);
930 EXPORT_SYMBOL(crypto_decrypt_init);
931 EXPORT_SYMBOL(crypto_decrypt_update);
932 EXPORT_SYMBOL(crypto_decrypt_final);
933 EXPORT_SYMBOL(crypto_encrypt_single);
934 EXPORT_SYMBOL(crypto_decrypt_single);
935 #endif