The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/openzfs/module/icp/api/kcf_mac.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 https://opensource.org/licenses/CDDL-1.0.
   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  * Message authentication codes 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_INVALID_MECH_NUMBER, CRYPTO_INVALID_MECH_PARAM, or
   44  *      CRYPTO_INVALID_MECH for problems with the 'mech'.
   45  *      CRYPTO_INVALID_DATA for bogus 'data'
   46  *      CRYPTO_HOST_MEMORY for failure to allocate memory to handle this work.
   47  *      CRYPTO_INVALID_CONTEXT: Not a valid context.
   48  *      CRYPTO_BUSY:    Cannot process the request now. Try later.
   49  *      CRYPTO_NOT_SUPPORTED and CRYPTO_MECH_NOT_SUPPORTED: No provider is
   50  *                      capable of a function or a mechanism.
   51  *      CRYPTO_INVALID_KEY: bogus 'key' argument.
   52  *      CRYPTO_INVALID_MAC: bogus 'mac' argument.
   53  */
   54 
   55 /*
   56  * crypto_mac_prov()
   57  *
   58  * Arguments:
   59  *      mech:   crypto_mechanism_t pointer.
   60  *              mech_type is a valid value previously returned by
   61  *              crypto_mech2id();
   62  *              When the mech's parameter is not NULL, its definition depends
   63  *              on the standard definition of the mechanism.
   64  *      key:    pointer to a crypto_key_t structure.
   65  *      data:   The message to compute the MAC for.
   66  *      mac: Storage for the MAC. The length needed depends on the mechanism.
   67  *      tmpl:   a crypto_ctx_template_t, opaque template of a context of a
   68  *              MAC with the 'mech' using 'key'. 'tmpl' is created by
   69  *              a previous call to crypto_create_ctx_template().
   70  *
   71  * Description:
   72  *      Asynchronously submits a request for, or synchronously performs a
   73  *      single-part message authentication of 'data' with the mechanism
   74  *      'mech', using * the key 'key', on the specified provider with
   75  *      the specified session id.
   76  *      When complete and successful, 'mac' will contain the message
   77  *      authentication code.
   78  *      Relies on the KCF scheduler to choose a provider.
   79  *
   80  * Returns:
   81  *      See comment in the beginning of the file.
   82  */
   83 int
   84 crypto_mac(crypto_mechanism_t *mech, crypto_data_t *data,
   85     crypto_key_t *key, crypto_ctx_template_t tmpl, crypto_data_t *mac)
   86 {
   87         int error;
   88         kcf_mech_entry_t *me;
   89         kcf_provider_desc_t *pd;
   90         kcf_ctx_template_t *ctx_tmpl;
   91         crypto_spi_ctx_template_t spi_ctx_tmpl = NULL;
   92         kcf_prov_tried_t *list = NULL;
   93 
   94 retry:
   95         /* The pd is returned held */
   96         if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error,
   97             list, CRYPTO_FG_MAC_ATOMIC)) == NULL) {
   98                 if (list != NULL)
   99                         kcf_free_triedlist(list);
  100                 return (error);
  101         }
  102 
  103         if (((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL))
  104                 spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl;
  105 
  106         crypto_mechanism_t lmech = *mech;
  107         KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, &lmech);
  108         error = KCF_PROV_MAC_ATOMIC(pd, &lmech, key, data,
  109             mac, spi_ctx_tmpl);
  110 
  111         if (error != CRYPTO_SUCCESS && IS_RECOVERABLE(error)) {
  112                 /* Add pd to the linked list of providers tried. */
  113                 if (kcf_insert_triedlist(&list, pd, KM_SLEEP) != NULL)
  114                         goto retry;
  115         }
  116 
  117         if (list != NULL)
  118                 kcf_free_triedlist(list);
  119 
  120         KCF_PROV_REFRELE(pd);
  121         return (error);
  122 }
  123 
  124 /*
  125  * crypto_mac_init_prov()
  126  *
  127  * Arguments:
  128  *      pd:     pointer to the descriptor of the provider to use for this
  129  *              operation.
  130  *      mech:   crypto_mechanism_t pointer.
  131  *              mech_type is a valid value previously returned by
  132  *              crypto_mech2id();
  133  *              When the mech's parameter is not NULL, its definition depends
  134  *              on the standard definition of the mechanism.
  135  *      key:    pointer to a crypto_key_t structure.
  136  *      tmpl:   a crypto_ctx_template_t, opaque template of a context of a
  137  *              MAC with the 'mech' using 'key'. 'tmpl' is created by
  138  *              a previous call to crypto_create_ctx_template().
  139  *      ctxp:   Pointer to a crypto_context_t.
  140  *
  141  * Description:
  142  *      Asynchronously submits a request for, or synchronously performs the
  143  *      initialization of a MAC operation on the specified provider with
  144  *      the specified session.
  145  *      When possible and applicable, will internally use the pre-computed MAC
  146  *      context from the context template, tmpl.
  147  *      When complete and successful, 'ctxp' will contain a crypto_context_t
  148  *      valid for later calls to mac_update() and mac_final().
  149  *      The caller should hold a reference on the specified provider
  150  *      descriptor before calling this function.
  151  *
  152  * Returns:
  153  *      See comment in the beginning of the file.
  154  */
  155 static int
  156 crypto_mac_init_prov(kcf_provider_desc_t *pd,
  157     crypto_mechanism_t *mech, crypto_key_t *key, crypto_spi_ctx_template_t tmpl,
  158     crypto_context_t *ctxp)
  159 {
  160         int rv;
  161         crypto_ctx_t *ctx;
  162         kcf_provider_desc_t *real_provider = pd;
  163 
  164         ASSERT(KCF_PROV_REFHELD(pd));
  165 
  166         /* Allocate and initialize the canonical context */
  167         if ((ctx = kcf_new_ctx(real_provider)) == NULL)
  168                 return (CRYPTO_HOST_MEMORY);
  169 
  170         crypto_mechanism_t lmech = *mech;
  171         KCF_SET_PROVIDER_MECHNUM(mech->cm_type, real_provider, &lmech);
  172         rv = KCF_PROV_MAC_INIT(real_provider, ctx, &lmech, key, tmpl);
  173 
  174         if (rv == CRYPTO_SUCCESS)
  175                 *ctxp = (crypto_context_t)ctx;
  176         else {
  177                 /* Release the hold done in kcf_new_ctx(). */
  178                 KCF_CONTEXT_REFRELE((kcf_context_t *)ctx->cc_framework_private);
  179         }
  180 
  181         return (rv);
  182 }
  183 
  184 /*
  185  * Same as crypto_mac_init_prov(), but relies on the KCF scheduler to
  186  * choose a provider. See crypto_mac_init_prov() comments for more
  187  * information.
  188  */
  189 int
  190 crypto_mac_init(crypto_mechanism_t *mech, crypto_key_t *key,
  191     crypto_ctx_template_t tmpl, crypto_context_t *ctxp)
  192 {
  193         int error;
  194         kcf_mech_entry_t *me;
  195         kcf_provider_desc_t *pd;
  196         kcf_ctx_template_t *ctx_tmpl;
  197         crypto_spi_ctx_template_t spi_ctx_tmpl = NULL;
  198         kcf_prov_tried_t *list = NULL;
  199 
  200 retry:
  201         /* The pd is returned held */
  202         if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error,
  203             list, CRYPTO_FG_MAC)) == NULL) {
  204                 if (list != NULL)
  205                         kcf_free_triedlist(list);
  206                 return (error);
  207         }
  208 
  209         /*
  210          * Check the validity of the context template
  211          * It is very rare that the generation number mis-matches, so
  212          * is acceptable to fail here, and let the consumer recover by
  213          * freeing this tmpl and create a new one for the key and new provider
  214          */
  215 
  216         if (((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL))
  217                 spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl;
  218 
  219         error = crypto_mac_init_prov(pd, mech, key,
  220             spi_ctx_tmpl, ctxp);
  221         if (error != CRYPTO_SUCCESS && IS_RECOVERABLE(error)) {
  222                 /* Add pd to the linked list of providers tried. */
  223                 if (kcf_insert_triedlist(&list, pd, KM_SLEEP) != NULL)
  224                         goto retry;
  225         }
  226 
  227         if (list != NULL)
  228                 kcf_free_triedlist(list);
  229 
  230         KCF_PROV_REFRELE(pd);
  231         return (error);
  232 }
  233 
  234 /*
  235  * crypto_mac_update()
  236  *
  237  * Arguments:
  238  *      context: A crypto_context_t initialized by mac_init().
  239  *      data: The message part to be MAC'ed
  240  *
  241  * Description:
  242  *      Synchronously performs a part of a MAC operation.
  243  *
  244  * Returns:
  245  *      See comment in the beginning of the file.
  246  */
  247 int
  248 crypto_mac_update(crypto_context_t context, crypto_data_t *data)
  249 {
  250         crypto_ctx_t *ctx = (crypto_ctx_t *)context;
  251         kcf_context_t *kcf_ctx;
  252         kcf_provider_desc_t *pd;
  253 
  254         if ((ctx == NULL) ||
  255             ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
  256             ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
  257                 return (CRYPTO_INVALID_CONTEXT);
  258         }
  259 
  260         return (KCF_PROV_MAC_UPDATE(pd, ctx, data));
  261 }
  262 
  263 /*
  264  * crypto_mac_final()
  265  *
  266  * Arguments:
  267  *      context: A crypto_context_t initialized by mac_init().
  268  *      mac: Storage for the message authentication code.
  269  *
  270  * Description:
  271  *      Synchronously performs a part of a message authentication operation.
  272  *
  273  * Returns:
  274  *      See comment in the beginning of the file.
  275  */
  276 int
  277 crypto_mac_final(crypto_context_t context, crypto_data_t *mac)
  278 {
  279         crypto_ctx_t *ctx = (crypto_ctx_t *)context;
  280         kcf_context_t *kcf_ctx;
  281         kcf_provider_desc_t *pd;
  282 
  283         if ((ctx == NULL) ||
  284             ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
  285             ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
  286                 return (CRYPTO_INVALID_CONTEXT);
  287         }
  288 
  289         int rv = KCF_PROV_MAC_FINAL(pd, ctx, mac);
  290 
  291         /* Release the hold done in kcf_new_ctx() during init step. */
  292         KCF_CONTEXT_COND_RELEASE(rv, kcf_ctx);
  293         return (rv);
  294 }
  295 
  296 #if defined(_KERNEL)
  297 EXPORT_SYMBOL(crypto_mac);
  298 EXPORT_SYMBOL(crypto_mac_init);
  299 EXPORT_SYMBOL(crypto_mac_update);
  300 EXPORT_SYMBOL(crypto_mac_final);
  301 #endif

Cache object: e9519b137b1b2d6a171885f17ae4e57f


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.