]> granicus.if.org Git - zfs/blob - module/icp/api/kcf_cipher.c
Illumos Crypto Port module added to enable native encryption in zfs
[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