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