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/os/freebsd/zfs/crypto_os.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  * Copyright (c) 2005-2010 Pawel Jakub Dawidek <pjd@FreeBSD.org>
    3  * Copyright (c) 2018 Sean Eric Fagan <sef@ixsystems.com>
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  * Portions of this file are derived from sys/geom/eli/g_eli_hmac.c
   28  */
   29 
   30 #include <sys/cdefs.h>
   31 __FBSDID("$FreeBSD$");
   32 
   33 #include <sys/types.h>
   34 #include <sys/errno.h>
   35 
   36 #ifdef _KERNEL
   37 #include <sys/libkern.h>
   38 #include <sys/malloc.h>
   39 #include <sys/sysctl.h>
   40 #include <opencrypto/cryptodev.h>
   41 #include <opencrypto/xform.h>
   42 #endif
   43 
   44 #include <sys/zio_crypt.h>
   45 #include <sys/fs/zfs.h>
   46 #include <sys/zio.h>
   47 
   48 #include <sys/freebsd_crypto.h>
   49 
   50 #define SHA512_HMAC_BLOCK_SIZE  128
   51 
   52 static int crypt_sessions = 0;
   53 SYSCTL_DECL(_vfs_zfs);
   54 SYSCTL_INT(_vfs_zfs, OID_AUTO, crypt_sessions, CTLFLAG_RD,
   55         &crypt_sessions, 0, "Number of cryptographic sessions created");
   56 
   57 void
   58 crypto_mac_init(struct hmac_ctx *ctx, const crypto_key_t *c_key)
   59 {
   60         uint8_t k_ipad[SHA512_HMAC_BLOCK_SIZE],
   61             k_opad[SHA512_HMAC_BLOCK_SIZE],
   62             key[SHA512_HMAC_BLOCK_SIZE];
   63         SHA512_CTX lctx;
   64         int i;
   65         size_t cl_bytes = CRYPTO_BITS2BYTES(c_key->ck_length);
   66 
   67         /*
   68          * This code is based on the similar code in geom/eli/g_eli_hmac.c
   69          */
   70         memset(key, 0, sizeof (key));
   71         if (c_key->ck_length  == 0)
   72                 /* do nothing */;
   73         else if (cl_bytes <= SHA512_HMAC_BLOCK_SIZE)
   74                 memcpy(key, c_key->ck_data, cl_bytes);
   75         else {
   76                 /*
   77                  * If key is longer than 128 bytes reset it to
   78                  * key = SHA512(key).
   79                  */
   80                 SHA512_Init(&lctx);
   81                 SHA512_Update(&lctx, c_key->ck_data, cl_bytes);
   82                 SHA512_Final(key, &lctx);
   83         }
   84 
   85         /* XOR key with ipad and opad values. */
   86         for (i = 0; i < sizeof (key); i++) {
   87                 k_ipad[i] = key[i] ^ 0x36;
   88                 k_opad[i] = key[i] ^ 0x5c;
   89         }
   90         memset(key, 0, sizeof (key));
   91 
   92         /* Start inner SHA512. */
   93         SHA512_Init(&ctx->innerctx);
   94         SHA512_Update(&ctx->innerctx, k_ipad, sizeof (k_ipad));
   95         memset(k_ipad, 0, sizeof (k_ipad));
   96         /* Start outer SHA512. */
   97         SHA512_Init(&ctx->outerctx);
   98         SHA512_Update(&ctx->outerctx, k_opad, sizeof (k_opad));
   99         memset(k_opad, 0, sizeof (k_opad));
  100 }
  101 
  102 void
  103 crypto_mac_update(struct hmac_ctx *ctx, const void *data, size_t datasize)
  104 {
  105         SHA512_Update(&ctx->innerctx, data, datasize);
  106 }
  107 
  108 void
  109 crypto_mac_final(struct hmac_ctx *ctx, void *md, size_t mdsize)
  110 {
  111         uint8_t digest[SHA512_DIGEST_LENGTH];
  112 
  113         /* Complete inner hash */
  114         SHA512_Final(digest, &ctx->innerctx);
  115 
  116         /* Complete outer hash */
  117         SHA512_Update(&ctx->outerctx, digest, sizeof (digest));
  118         SHA512_Final(digest, &ctx->outerctx);
  119 
  120         memset(ctx, 0, sizeof (*ctx));
  121         /* mdsize == 0 means "Give me the whole hash!" */
  122         if (mdsize == 0)
  123                 mdsize = SHA512_DIGEST_LENGTH;
  124         memcpy(md, digest, mdsize);
  125         memset(digest, 0, sizeof (digest));
  126 }
  127 
  128 void
  129 crypto_mac(const crypto_key_t *key, const void *in_data, size_t in_data_size,
  130     void *out_data, size_t out_data_size)
  131 {
  132         struct hmac_ctx ctx;
  133 
  134         crypto_mac_init(&ctx, key);
  135         crypto_mac_update(&ctx, in_data, in_data_size);
  136         crypto_mac_final(&ctx, out_data, out_data_size);
  137 }
  138 
  139 static int
  140 freebsd_zfs_crypt_done(struct cryptop *crp)
  141 {
  142         freebsd_crypt_session_t *ses;
  143 
  144         ses = crp->crp_opaque;
  145         mtx_lock(&ses->fs_lock);
  146         ses->fs_done = true;
  147         mtx_unlock(&ses->fs_lock);
  148         wakeup(crp);
  149         return (0);
  150 }
  151 
  152 static int
  153 freebsd_zfs_crypt_done_sync(struct cryptop *crp)
  154 {
  155 
  156         return (0);
  157 }
  158 
  159 void
  160 freebsd_crypt_freesession(freebsd_crypt_session_t *sess)
  161 {
  162         mtx_destroy(&sess->fs_lock);
  163         crypto_freesession(sess->fs_sid);
  164         memset(sess, 0, sizeof (*sess));
  165 }
  166 
  167 static int
  168 zfs_crypto_dispatch(freebsd_crypt_session_t *session, struct cryptop *crp)
  169 {
  170         int error;
  171 
  172         crp->crp_opaque = session;
  173         for (;;) {
  174 #if __FreeBSD_version < 1400004
  175                 boolean_t async = ((crypto_ses2caps(crp->crp_session) &
  176                     CRYPTOCAP_F_SYNC) == 0);
  177 #else
  178                 boolean_t async = !CRYPTO_SESS_SYNC(crp->crp_session);
  179 #endif
  180                 crp->crp_callback = async ? freebsd_zfs_crypt_done :
  181                     freebsd_zfs_crypt_done_sync;
  182                 error = crypto_dispatch(crp);
  183                 if (error == 0) {
  184                         if (async) {
  185                                 mtx_lock(&session->fs_lock);
  186                                 while (session->fs_done == false) {
  187                                         msleep(crp, &session->fs_lock, 0,
  188                                             "zfs_crypto", 0);
  189                                 }
  190                                 mtx_unlock(&session->fs_lock);
  191                         }
  192                         error = crp->crp_etype;
  193                 }
  194 
  195                 if (error == ENOMEM) {
  196                         pause("zcrnomem", 1);
  197                 } else if (error != EAGAIN) {
  198                         break;
  199                 }
  200                 crp->crp_etype = 0;
  201                 crp->crp_flags &= ~CRYPTO_F_DONE;
  202                 session->fs_done = false;
  203 #if __FreeBSD_version < 1300087
  204                 /*
  205                  * Session ID changed, so we should record that,
  206                  * and try again
  207                  */
  208                 session->fs_sid = crp->crp_session;
  209 #endif
  210         }
  211         return (error);
  212 }
  213 static void
  214 freebsd_crypt_uio_debug_log(boolean_t encrypt,
  215     freebsd_crypt_session_t *input_sessionp,
  216     const struct zio_crypt_info *c_info,
  217     zfs_uio_t *data_uio,
  218     crypto_key_t *key,
  219     uint8_t *ivbuf,
  220     size_t datalen,
  221     size_t auth_len)
  222 {
  223 #ifdef FCRYPTO_DEBUG
  224         struct cryptodesc *crd;
  225         uint8_t *p = NULL;
  226         size_t total = 0;
  227 
  228         printf("%s(%s, %p, { %s, %d, %d, %s }, %p, { %p, %u }, "
  229             "%p, %u, %u)\n",
  230             __FUNCTION__, encrypt ? "encrypt" : "decrypt", input_sessionp,
  231             c_info->ci_algname, c_info->ci_crypt_type,
  232             (unsigned int)c_info->ci_keylen, c_info->ci_name,
  233             data_uio, key->ck_data,
  234             (unsigned int)key->ck_length,
  235             ivbuf, (unsigned int)datalen, (unsigned int)auth_len);
  236         printf("\tkey = { ");
  237         for (int i = 0; i < key->ck_length / 8; i++) {
  238                 uint8_t *b = (uint8_t *)key->ck_data;
  239                 printf("%02x ", b[i]);
  240         }
  241         printf("}\n");
  242         for (int i = 0; i < zfs_uio_iovcnt(data_uio); i++) {
  243                 printf("\tiovec #%d: <%p, %u>\n", i,
  244                     zfs_uio_iovbase(data_uio, i),
  245                     (unsigned int)zfs_uio_iovlen(data_uio, i));
  246                 total += zfs_uio_iovlen(data_uio, i);
  247         }
  248         zfs_uio_resid(data_uio) = total;
  249 #endif
  250 }
  251 /*
  252  * Create a new cryptographic session.  This should
  253  * happen every time the key changes (including when
  254  * it's first loaded).
  255  */
  256 #if __FreeBSD_version >= 1300087
  257 int
  258 freebsd_crypt_newsession(freebsd_crypt_session_t *sessp,
  259     const struct zio_crypt_info *c_info, crypto_key_t *key)
  260 {
  261         struct crypto_session_params csp = {0};
  262         int error = 0;
  263 
  264 #ifdef FCRYPTO_DEBUG
  265         printf("%s(%p, { %s, %d, %d, %s }, { %p, %u })\n",
  266             __FUNCTION__, sessp,
  267             c_info->ci_algname, c_info->ci_crypt_type,
  268             (unsigned int)c_info->ci_keylen, c_info->ci_name,
  269             key->ck_data, (unsigned int)key->ck_length);
  270         printf("\tkey = { ");
  271         for (int i = 0; i < key->ck_length / 8; i++) {
  272                 uint8_t *b = (uint8_t *)key->ck_data;
  273                 printf("%02x ", b[i]);
  274         }
  275         printf("}\n");
  276 #endif
  277         csp.csp_mode = CSP_MODE_AEAD;
  278         csp.csp_cipher_key = key->ck_data;
  279         csp.csp_cipher_klen = key->ck_length / 8;
  280         switch (c_info->ci_crypt_type) {
  281                 case ZC_TYPE_GCM:
  282                 csp.csp_cipher_alg = CRYPTO_AES_NIST_GCM_16;
  283                 csp.csp_ivlen = AES_GCM_IV_LEN;
  284                 switch (key->ck_length/8) {
  285                 case AES_128_GMAC_KEY_LEN:
  286                 case AES_192_GMAC_KEY_LEN:
  287                 case AES_256_GMAC_KEY_LEN:
  288                         break;
  289                 default:
  290                         error = EINVAL;
  291                         goto bad;
  292                 }
  293                 break;
  294         case ZC_TYPE_CCM:
  295                 csp.csp_cipher_alg = CRYPTO_AES_CCM_16;
  296                 csp.csp_ivlen = AES_CCM_IV_LEN;
  297                 switch (key->ck_length/8) {
  298                 case AES_128_CBC_MAC_KEY_LEN:
  299                 case AES_192_CBC_MAC_KEY_LEN:
  300                 case AES_256_CBC_MAC_KEY_LEN:
  301                         break;
  302                 default:
  303                         error = EINVAL;
  304                         goto bad;
  305                         break;
  306                 }
  307                 break;
  308         default:
  309                 error = ENOTSUP;
  310                 goto bad;
  311         }
  312 
  313         /*
  314          * Disable the use of hardware drivers on FreeBSD 13 and later since
  315          * common crypto offload drivers impose constraints on AES-GCM AAD
  316          * lengths that make them unusable for ZFS, and we currently do not have
  317          * a mechanism to fall back to a software driver for requests not
  318          * handled by a hardware driver.
  319          *
  320          * On 12 we continue to permit the use of hardware drivers since
  321          * CPU-accelerated drivers such as aesni(4) register themselves as
  322          * hardware drivers.
  323          */
  324         error = crypto_newsession(&sessp->fs_sid, &csp, CRYPTOCAP_F_SOFTWARE);
  325         mtx_init(&sessp->fs_lock, "FreeBSD Cryptographic Session Lock",
  326             NULL, MTX_DEF);
  327         crypt_sessions++;
  328 bad:
  329 #ifdef FCRYPTO_DEBUG
  330         if (error)
  331                 printf("%s: returning error %d\n", __FUNCTION__, error);
  332 #endif
  333         return (error);
  334 }
  335 
  336 int
  337 freebsd_crypt_uio(boolean_t encrypt,
  338     freebsd_crypt_session_t *input_sessionp,
  339     const struct zio_crypt_info *c_info,
  340     zfs_uio_t *data_uio,
  341     crypto_key_t *key,
  342     uint8_t *ivbuf,
  343     size_t datalen,
  344     size_t auth_len)
  345 {
  346         struct cryptop *crp;
  347         freebsd_crypt_session_t *session = NULL;
  348         int error = 0;
  349         size_t total = 0;
  350 
  351         freebsd_crypt_uio_debug_log(encrypt, input_sessionp, c_info, data_uio,
  352             key, ivbuf, datalen, auth_len);
  353         for (int i = 0; i < zfs_uio_iovcnt(data_uio); i++)
  354                 total += zfs_uio_iovlen(data_uio, i);
  355         zfs_uio_resid(data_uio) = total;
  356         if (input_sessionp == NULL) {
  357                 session = kmem_zalloc(sizeof (*session), KM_SLEEP);
  358                 error = freebsd_crypt_newsession(session, c_info, key);
  359                 if (error)
  360                         goto out;
  361         } else
  362                 session = input_sessionp;
  363 
  364         crp = crypto_getreq(session->fs_sid, M_WAITOK);
  365         if (encrypt) {
  366                 crp->crp_op = CRYPTO_OP_ENCRYPT |
  367                     CRYPTO_OP_COMPUTE_DIGEST;
  368         } else {
  369                 crp->crp_op = CRYPTO_OP_DECRYPT |
  370                     CRYPTO_OP_VERIFY_DIGEST;
  371         }
  372         crp->crp_flags = CRYPTO_F_CBIFSYNC | CRYPTO_F_IV_SEPARATE;
  373         crypto_use_uio(crp, GET_UIO_STRUCT(data_uio));
  374 
  375         crp->crp_aad_start = 0;
  376         crp->crp_aad_length = auth_len;
  377         crp->crp_payload_start = auth_len;
  378         crp->crp_payload_length = datalen;
  379         crp->crp_digest_start = auth_len + datalen;
  380 
  381         memcpy(crp->crp_iv, ivbuf, ZIO_DATA_IV_LEN);
  382         error = zfs_crypto_dispatch(session, crp);
  383         crypto_freereq(crp);
  384 out:
  385 #ifdef FCRYPTO_DEBUG
  386         if (error)
  387                 printf("%s: returning error %d\n", __FUNCTION__, error);
  388 #endif
  389         if (input_sessionp == NULL) {
  390                 freebsd_crypt_freesession(session);
  391                 kmem_free(session, sizeof (*session));
  392         }
  393         return (error);
  394 }
  395 
  396 #else
  397 int
  398 freebsd_crypt_newsession(freebsd_crypt_session_t *sessp,
  399     const struct zio_crypt_info *c_info, crypto_key_t *key)
  400 {
  401         struct cryptoini cria = {0}, crie = {0}, *crip;
  402         struct enc_xform *xform;
  403         struct auth_hash *xauth;
  404         int error = 0;
  405         crypto_session_t sid;
  406 
  407 #ifdef FCRYPTO_DEBUG
  408         printf("%s(%p, { %s, %d, %d, %s }, { %p, %u })\n",
  409             __FUNCTION__, sessp,
  410             c_info->ci_algname, c_info->ci_crypt_type,
  411             (unsigned int)c_info->ci_keylen, c_info->ci_name,
  412             key->ck_data, (unsigned int)key->ck_length);
  413         printf("\tkey = { ");
  414         for (int i = 0; i < key->ck_length / 8; i++) {
  415                 uint8_t *b = (uint8_t *)key->ck_data;
  416                 printf("%02x ", b[i]);
  417         }
  418         printf("}\n");
  419 #endif
  420         switch (c_info->ci_crypt_type) {
  421         case ZC_TYPE_GCM:
  422                 xform = &enc_xform_aes_nist_gcm;
  423                 switch (key->ck_length/8) {
  424                 case AES_128_GMAC_KEY_LEN:
  425                         xauth = &auth_hash_nist_gmac_aes_128;
  426                         break;
  427                 case AES_192_GMAC_KEY_LEN:
  428                         xauth = &auth_hash_nist_gmac_aes_192;
  429                         break;
  430                 case AES_256_GMAC_KEY_LEN:
  431                         xauth = &auth_hash_nist_gmac_aes_256;
  432                         break;
  433                 default:
  434                         error = EINVAL;
  435                         goto bad;
  436                 }
  437                 break;
  438         case ZC_TYPE_CCM:
  439                 xform = &enc_xform_ccm;
  440                 switch (key->ck_length/8) {
  441                 case AES_128_CBC_MAC_KEY_LEN:
  442                         xauth = &auth_hash_ccm_cbc_mac_128;
  443                         break;
  444                 case AES_192_CBC_MAC_KEY_LEN:
  445                         xauth = &auth_hash_ccm_cbc_mac_192;
  446                         break;
  447                 case AES_256_CBC_MAC_KEY_LEN:
  448                         xauth = &auth_hash_ccm_cbc_mac_256;
  449                         break;
  450                 default:
  451                         error = EINVAL;
  452                         goto bad;
  453                         break;
  454                 }
  455                 break;
  456         default:
  457                 error = ENOTSUP;
  458                 goto bad;
  459         }
  460 #ifdef FCRYPTO_DEBUG
  461         printf("%s(%d): Using crypt %s (key length %u [%u bytes]), "
  462             "auth %s (key length %d)\n",
  463             __FUNCTION__, __LINE__,
  464             xform->name, (unsigned int)key->ck_length,
  465             (unsigned int)key->ck_length/8,
  466             xauth->name, xauth->keysize);
  467 #endif
  468 
  469         crie.cri_alg = xform->type;
  470         crie.cri_key = key->ck_data;
  471         crie.cri_klen = key->ck_length;
  472 
  473         cria.cri_alg = xauth->type;
  474         cria.cri_key = key->ck_data;
  475         cria.cri_klen = key->ck_length;
  476 
  477         cria.cri_next = &crie;
  478         crie.cri_next = NULL;
  479         crip = &cria;
  480         // Everything else is zero-initialised
  481 
  482         error = crypto_newsession(&sid, crip,
  483             CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE);
  484         if (error != 0) {
  485                 printf("%s(%d):  crypto_newsession failed with %d\n",
  486                     __FUNCTION__, __LINE__, error);
  487                 goto bad;
  488         }
  489         sessp->fs_sid = sid;
  490         mtx_init(&sessp->fs_lock, "FreeBSD Cryptographic Session Lock",
  491             NULL, MTX_DEF);
  492         crypt_sessions++;
  493 bad:
  494         return (error);
  495 }
  496 
  497 /*
  498  * The meat of encryption/decryption.
  499  * If sessp is NULL, then it will create a
  500  * temporary cryptographic session, and release
  501  * it when done.
  502  */
  503 int
  504 freebsd_crypt_uio(boolean_t encrypt,
  505     freebsd_crypt_session_t *input_sessionp,
  506     const struct zio_crypt_info *c_info,
  507     zfs_uio_t *data_uio,
  508     crypto_key_t *key,
  509     uint8_t *ivbuf,
  510     size_t datalen,
  511     size_t auth_len)
  512 {
  513         struct cryptop *crp;
  514         struct cryptodesc *enc_desc, *auth_desc;
  515         struct enc_xform *xform;
  516         struct auth_hash *xauth;
  517         freebsd_crypt_session_t *session = NULL;
  518         int error;
  519 
  520         freebsd_crypt_uio_debug_log(encrypt, input_sessionp, c_info, data_uio,
  521             key, ivbuf, datalen, auth_len);
  522         switch (c_info->ci_crypt_type) {
  523         case ZC_TYPE_GCM:
  524                 xform = &enc_xform_aes_nist_gcm;
  525                 switch (key->ck_length/8) {
  526                 case AES_128_GMAC_KEY_LEN:
  527                         xauth = &auth_hash_nist_gmac_aes_128;
  528                         break;
  529                 case AES_192_GMAC_KEY_LEN:
  530                         xauth = &auth_hash_nist_gmac_aes_192;
  531                         break;
  532                 case AES_256_GMAC_KEY_LEN:
  533                         xauth = &auth_hash_nist_gmac_aes_256;
  534                         break;
  535                 default:
  536                         error = EINVAL;
  537                         goto bad;
  538                 }
  539                 break;
  540         case ZC_TYPE_CCM:
  541                 xform = &enc_xform_ccm;
  542                 switch (key->ck_length/8) {
  543                 case AES_128_CBC_MAC_KEY_LEN:
  544                         xauth = &auth_hash_ccm_cbc_mac_128;
  545                         break;
  546                 case AES_192_CBC_MAC_KEY_LEN:
  547                         xauth = &auth_hash_ccm_cbc_mac_192;
  548                         break;
  549                 case AES_256_CBC_MAC_KEY_LEN:
  550                         xauth = &auth_hash_ccm_cbc_mac_256;
  551                         break;
  552                 default:
  553                         error = EINVAL;
  554                         goto bad;
  555                         break;
  556                 }
  557                 break;
  558         default:
  559                 error = ENOTSUP;
  560                 goto bad;
  561         }
  562 
  563 #ifdef FCRYPTO_DEBUG
  564         printf("%s(%d): Using crypt %s (key length %u [%u bytes]), "
  565             "auth %s (key length %d)\n",
  566             __FUNCTION__, __LINE__,
  567             xform->name, (unsigned int)key->ck_length,
  568             (unsigned int)key->ck_length/8,
  569             xauth->name, xauth->keysize);
  570 #endif
  571 
  572         if (input_sessionp == NULL) {
  573                 session = kmem_zalloc(sizeof (*session), KM_SLEEP);
  574                 error = freebsd_crypt_newsession(session, c_info, key);
  575                 if (error)
  576                         goto out;
  577         } else
  578                 session = input_sessionp;
  579 
  580         crp = crypto_getreq(2);
  581         if (crp == NULL) {
  582                 error = ENOMEM;
  583                 goto bad;
  584         }
  585 
  586         auth_desc = crp->crp_desc;
  587         enc_desc = auth_desc->crd_next;
  588 
  589         crp->crp_session = session->fs_sid;
  590         crp->crp_ilen = auth_len + datalen;
  591         crp->crp_buf = (void*)GET_UIO_STRUCT(data_uio);
  592         crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIFSYNC;
  593 
  594         auth_desc->crd_skip = 0;
  595         auth_desc->crd_len = auth_len;
  596         auth_desc->crd_inject = auth_len + datalen;
  597         auth_desc->crd_alg = xauth->type;
  598 #ifdef FCRYPTO_DEBUG
  599         printf("%s: auth: skip = %u, len = %u, inject = %u\n",
  600             __FUNCTION__, auth_desc->crd_skip, auth_desc->crd_len,
  601             auth_desc->crd_inject);
  602 #endif
  603 
  604         enc_desc->crd_skip = auth_len;
  605         enc_desc->crd_len = datalen;
  606         enc_desc->crd_inject = auth_len;
  607         enc_desc->crd_alg = xform->type;
  608         enc_desc->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
  609         memcpy(enc_desc->crd_iv, ivbuf, ZIO_DATA_IV_LEN);
  610         enc_desc->crd_next = NULL;
  611 
  612 #ifdef FCRYPTO_DEBUG
  613         printf("%s: enc: skip = %u, len = %u, inject = %u\n",
  614             __FUNCTION__, enc_desc->crd_skip, enc_desc->crd_len,
  615             enc_desc->crd_inject);
  616 #endif
  617 
  618         if (encrypt)
  619                 enc_desc->crd_flags |= CRD_F_ENCRYPT;
  620 
  621         error = zfs_crypto_dispatch(session, crp);
  622         crypto_freereq(crp);
  623 out:
  624         if (input_sessionp == NULL) {
  625                 freebsd_crypt_freesession(session);
  626                 kmem_free(session, sizeof (*session));
  627         }
  628 bad:
  629 #ifdef FCRYPTO_DEBUG
  630         if (error)
  631                 printf("%s: returning error %d\n", __FUNCTION__, error);
  632 #endif
  633         return (error);
  634 }
  635 #endif

Cache object: 3ee4c37a5abface208112ac0e3cef324


[ 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.