"Fossies" - the Fresh Open Source Software Archive

Member "cryptsetup-2.4.3/lib/crypto_backend/crypto_gcrypt.c" (13 Jan 2022, 12325 Bytes) of package /linux/misc/cryptsetup-2.4.3.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "crypto_gcrypt.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2.4.0_vs_2.4.1.

    1 /*
    2  * GCRYPT crypto backend implementation
    3  *
    4  * Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
    5  * Copyright (C) 2010-2021 Milan Broz
    6  *
    7  * This file is free software; you can redistribute it and/or
    8  * modify it under the terms of the GNU Lesser General Public
    9  * License as published by the Free Software Foundation; either
   10  * version 2.1 of the License, or (at your option) any later version.
   11  *
   12  * This file is distributed in the hope that it will be useful,
   13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   15  * Lesser General Public License for more details.
   16  *
   17  * You should have received a copy of the GNU Lesser General Public
   18  * License along with this file; if not, write to the Free Software
   19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   20  */
   21 
   22 #include <string.h>
   23 #include <stdio.h>
   24 #include <errno.h>
   25 #include <assert.h>
   26 #include <gcrypt.h>
   27 #include "crypto_backend_internal.h"
   28 
   29 static int crypto_backend_initialised = 0;
   30 static int crypto_backend_secmem = 1;
   31 static int crypto_backend_whirlpool_bug = -1;
   32 static char version[64];
   33 
   34 struct crypt_hash {
   35     gcry_md_hd_t hd;
   36     int hash_id;
   37     int hash_len;
   38 };
   39 
   40 struct crypt_hmac {
   41     gcry_md_hd_t hd;
   42     int hash_id;
   43     int hash_len;
   44 };
   45 
   46 struct crypt_cipher {
   47     bool use_kernel;
   48     union {
   49     struct crypt_cipher_kernel kernel;
   50     gcry_cipher_hd_t hd;
   51     } u;
   52 };
   53 
   54 struct hash_alg {
   55     const char *name;
   56     const char *gcrypt_name;
   57 };
   58 
   59 /*
   60  * Test for wrong Whirlpool variant,
   61  * Ref: https://lists.gnupg.org/pipermail/gcrypt-devel/2014-January/002889.html
   62  */
   63 static void crypt_hash_test_whirlpool_bug(void)
   64 {
   65     struct crypt_hash *h;
   66     char buf[2] = "\0\0", hash_out1[64], hash_out2[64];
   67     int r;
   68 
   69     if (crypto_backend_whirlpool_bug >= 0)
   70         return;
   71 
   72     crypto_backend_whirlpool_bug = 0;
   73     if (crypt_hash_init(&h, "whirlpool"))
   74         return;
   75 
   76     /* One shot */
   77     if ((r = crypt_hash_write(h, &buf[0], 2)) ||
   78         (r = crypt_hash_final(h, hash_out1, 64))) {
   79         crypt_hash_destroy(h);
   80         return;
   81     }
   82 
   83     /* Split buf (crypt_hash_final resets hash state) */
   84     if ((r = crypt_hash_write(h, &buf[0], 1)) ||
   85         (r = crypt_hash_write(h, &buf[1], 1)) ||
   86         (r = crypt_hash_final(h, hash_out2, 64))) {
   87         crypt_hash_destroy(h);
   88         return;
   89     }
   90 
   91     crypt_hash_destroy(h);
   92 
   93     if (memcmp(hash_out1, hash_out2, 64))
   94         crypto_backend_whirlpool_bug = 1;
   95 }
   96 
   97 int crypt_backend_init(bool fips __attribute__((unused)))
   98 {
   99     int r;
  100 
  101     if (crypto_backend_initialised)
  102         return 0;
  103 
  104     if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P)) {
  105         if (!gcry_check_version (GCRYPT_REQ_VERSION)) {
  106             return -ENOSYS;
  107         }
  108 
  109 /* If gcrypt compiled to support POSIX 1003.1e capabilities,
  110  * it drops all privileges during secure memory initialisation.
  111  * For now, the only workaround is to disable secure memory in gcrypt.
  112  * cryptsetup always need at least cap_sys_admin privilege for dm-ioctl
  113  * and it locks its memory space anyway.
  114  */
  115 #if 0
  116         gcry_control (GCRYCTL_DISABLE_SECMEM);
  117         crypto_backend_secmem = 0;
  118 #else
  119 
  120         gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
  121         gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
  122         gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
  123 #endif
  124         gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
  125     }
  126 
  127     crypto_backend_initialised = 1;
  128     crypt_hash_test_whirlpool_bug();
  129 
  130     r = snprintf(version, sizeof(version), "gcrypt %s%s%s",
  131          gcry_check_version(NULL),
  132          crypto_backend_secmem ? "" : ", secmem disabled",
  133          crypto_backend_whirlpool_bug > 0 ? ", flawed whirlpool" : "");
  134     if (r < 0 || (size_t)r >= sizeof(version))
  135         return -EINVAL;
  136 
  137     return 0;
  138 }
  139 
  140 void crypt_backend_destroy(void)
  141 {
  142     if (crypto_backend_initialised)
  143         gcry_control(GCRYCTL_TERM_SECMEM);
  144 
  145     crypto_backend_initialised = 0;
  146 }
  147 
  148 const char *crypt_backend_version(void)
  149 {
  150     return crypto_backend_initialised ? version : "";
  151 }
  152 
  153 uint32_t crypt_backend_flags(void)
  154 {
  155     return 0;
  156 }
  157 
  158 static const char *crypt_hash_compat_name(const char *name, unsigned int *flags)
  159 {
  160     const char *hash_name = name;
  161     int i;
  162     static struct hash_alg hash_algs[] = {
  163     { "blake2b-160", "blake2b_160" },
  164     { "blake2b-256", "blake2b_256" },
  165     { "blake2b-384", "blake2b_384" },
  166     { "blake2b-512", "blake2b_512" },
  167     { "blake2s-128", "blake2s_128" },
  168     { "blake2s-160", "blake2s_160" },
  169     { "blake2s-224", "blake2s_224" },
  170     { "blake2s-256", "blake2s_256" },
  171     { NULL,          NULL,         }};
  172 
  173     if (!name)
  174         return NULL;
  175 
  176     /* "whirlpool_gcryptbug" is out shortcut to flawed whirlpool
  177      * in libgcrypt < 1.6.0 */
  178     if (!strcasecmp(name, "whirlpool_gcryptbug")) {
  179 #if GCRYPT_VERSION_NUMBER >= 0x010601
  180         if (flags)
  181             *flags |= GCRY_MD_FLAG_BUGEMU1;
  182 #endif
  183         hash_name = "whirlpool";
  184     }
  185 
  186     i = 0;
  187     while (hash_algs[i].name) {
  188         if (!strcasecmp(name, hash_algs[i].name)) {
  189             hash_name =  hash_algs[i].gcrypt_name;
  190             break;
  191         }
  192         i++;
  193     }
  194 
  195     return hash_name;
  196 }
  197 
  198 /* HASH */
  199 int crypt_hash_size(const char *name)
  200 {
  201     int hash_id;
  202 
  203     assert(crypto_backend_initialised);
  204 
  205     hash_id = gcry_md_map_name(crypt_hash_compat_name(name, NULL));
  206     if (!hash_id)
  207         return -EINVAL;
  208 
  209     return gcry_md_get_algo_dlen(hash_id);
  210 }
  211 
  212 int crypt_hash_init(struct crypt_hash **ctx, const char *name)
  213 {
  214     struct crypt_hash *h;
  215     unsigned int flags = 0;
  216 
  217     assert(crypto_backend_initialised);
  218 
  219     h = malloc(sizeof(*h));
  220     if (!h)
  221         return -ENOMEM;
  222 
  223     h->hash_id = gcry_md_map_name(crypt_hash_compat_name(name, &flags));
  224     if (!h->hash_id) {
  225         free(h);
  226         return -EINVAL;
  227     }
  228 
  229     if (gcry_md_open(&h->hd, h->hash_id, flags)) {
  230         free(h);
  231         return -EINVAL;
  232     }
  233 
  234     h->hash_len = gcry_md_get_algo_dlen(h->hash_id);
  235     *ctx = h;
  236     return 0;
  237 }
  238 
  239 static void crypt_hash_restart(struct crypt_hash *ctx)
  240 {
  241     gcry_md_reset(ctx->hd);
  242 }
  243 
  244 int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length)
  245 {
  246     gcry_md_write(ctx->hd, buffer, length);
  247     return 0;
  248 }
  249 
  250 int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
  251 {
  252     unsigned char *hash;
  253 
  254     if (length > (size_t)ctx->hash_len)
  255         return -EINVAL;
  256 
  257     hash = gcry_md_read(ctx->hd, ctx->hash_id);
  258     if (!hash)
  259         return -EINVAL;
  260 
  261     memcpy(buffer, hash, length);
  262     crypt_hash_restart(ctx);
  263 
  264     return 0;
  265 }
  266 
  267 void crypt_hash_destroy(struct crypt_hash *ctx)
  268 {
  269     gcry_md_close(ctx->hd);
  270     memset(ctx, 0, sizeof(*ctx));
  271     free(ctx);
  272 }
  273 
  274 /* HMAC */
  275 int crypt_hmac_size(const char *name)
  276 {
  277     return crypt_hash_size(name);
  278 }
  279 
  280 int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
  281             const void *key, size_t key_length)
  282 {
  283     struct crypt_hmac *h;
  284     unsigned int flags = GCRY_MD_FLAG_HMAC;
  285 
  286     assert(crypto_backend_initialised);
  287 
  288     h = malloc(sizeof(*h));
  289     if (!h)
  290         return -ENOMEM;
  291 
  292     h->hash_id = gcry_md_map_name(crypt_hash_compat_name(name, &flags));
  293     if (!h->hash_id) {
  294         free(h);
  295         return -EINVAL;
  296     }
  297 
  298     if (gcry_md_open(&h->hd, h->hash_id, flags)) {
  299         free(h);
  300         return -EINVAL;
  301     }
  302 
  303     if (gcry_md_setkey(h->hd, key, key_length)) {
  304         gcry_md_close(h->hd);
  305         free(h);
  306         return -EINVAL;
  307     }
  308 
  309     h->hash_len = gcry_md_get_algo_dlen(h->hash_id);
  310     *ctx = h;
  311     return 0;
  312 }
  313 
  314 static void crypt_hmac_restart(struct crypt_hmac *ctx)
  315 {
  316     gcry_md_reset(ctx->hd);
  317 }
  318 
  319 int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
  320 {
  321     gcry_md_write(ctx->hd, buffer, length);
  322     return 0;
  323 }
  324 
  325 int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
  326 {
  327     unsigned char *hash;
  328 
  329     if (length > (size_t)ctx->hash_len)
  330         return -EINVAL;
  331 
  332     hash = gcry_md_read(ctx->hd, ctx->hash_id);
  333     if (!hash)
  334         return -EINVAL;
  335 
  336     memcpy(buffer, hash, length);
  337     crypt_hmac_restart(ctx);
  338 
  339     return 0;
  340 }
  341 
  342 void crypt_hmac_destroy(struct crypt_hmac *ctx)
  343 {
  344     gcry_md_close(ctx->hd);
  345     memset(ctx, 0, sizeof(*ctx));
  346     free(ctx);
  347 }
  348 
  349 /* RNG */
  350 int crypt_backend_rng(char *buffer, size_t length, int quality, int fips __attribute__((unused)))
  351 {
  352     switch(quality) {
  353     case CRYPT_RND_NORMAL:
  354         gcry_randomize(buffer, length, GCRY_STRONG_RANDOM);
  355         break;
  356     case CRYPT_RND_SALT:
  357     case CRYPT_RND_KEY:
  358     default:
  359         gcry_randomize(buffer, length, GCRY_VERY_STRONG_RANDOM);
  360         break;
  361     }
  362     return 0;
  363 }
  364 
  365 static int pbkdf2(const char *hash,
  366           const char *password, size_t password_length,
  367           const char *salt, size_t salt_length,
  368           char *key, size_t key_length,
  369           uint32_t iterations)
  370 {
  371     const char *hash_name = crypt_hash_compat_name(hash, NULL);
  372 
  373 #if USE_INTERNAL_PBKDF2
  374     return pkcs5_pbkdf2(hash_name, password, password_length, salt, salt_length,
  375                 iterations, key_length, key, 0);
  376 #else /* USE_INTERNAL_PBKDF2 */
  377     int hash_id = gcry_md_map_name(hash_name);
  378 
  379     if (!hash_id)
  380         return -EINVAL;
  381 
  382     if (gcry_kdf_derive(password, password_length, GCRY_KDF_PBKDF2, hash_id,
  383         salt, salt_length, iterations, key_length, key))
  384         return -EINVAL;
  385 
  386     return 0;
  387 #endif /* USE_INTERNAL_PBKDF2 */
  388 }
  389 
  390 /* PBKDF */
  391 int crypt_pbkdf(const char *kdf, const char *hash,
  392         const char *password, size_t password_length,
  393         const char *salt, size_t salt_length,
  394         char *key, size_t key_length,
  395         uint32_t iterations, uint32_t memory, uint32_t parallel)
  396 {
  397     if (!kdf)
  398         return -EINVAL;
  399 
  400     if (!strcmp(kdf, "pbkdf2"))
  401         return pbkdf2(hash, password, password_length, salt, salt_length,
  402                   key, key_length, iterations);
  403     else if (!strncmp(kdf, "argon2", 6))
  404         return argon2(kdf, password, password_length, salt, salt_length,
  405                   key, key_length, iterations, memory, parallel);
  406     return -EINVAL;
  407 }
  408 
  409 /* Block ciphers */
  410 static int _cipher_init(gcry_cipher_hd_t *hd, const char *name,
  411             const char *mode, const void *buffer, size_t length)
  412 {
  413     int cipher_id, mode_id;
  414 
  415     cipher_id = gcry_cipher_map_name(name);
  416     if (cipher_id == GCRY_CIPHER_MODE_NONE)
  417         return -ENOENT;
  418 
  419     if (!strcmp(mode, "ecb"))
  420         mode_id = GCRY_CIPHER_MODE_ECB;
  421     else if (!strcmp(mode, "cbc"))
  422         mode_id = GCRY_CIPHER_MODE_CBC;
  423 #if HAVE_DECL_GCRY_CIPHER_MODE_XTS
  424     else if (!strcmp(mode, "xts"))
  425         mode_id = GCRY_CIPHER_MODE_XTS;
  426 #endif
  427     else
  428         return -ENOENT;
  429 
  430     if (gcry_cipher_open(hd, cipher_id, mode_id, 0))
  431         return -EINVAL;
  432 
  433     if (gcry_cipher_setkey(*hd, buffer, length)) {
  434         gcry_cipher_close(*hd);
  435         return -EINVAL;
  436     }
  437 
  438     return 0;
  439 }
  440 
  441 int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
  442             const char *mode, const void *key, size_t key_length)
  443 {
  444     struct crypt_cipher *h;
  445     int r;
  446 
  447     h = malloc(sizeof(*h));
  448     if (!h)
  449         return -ENOMEM;
  450 
  451     if (!_cipher_init(&h->u.hd, name, mode, key, key_length)) {
  452         h->use_kernel = false;
  453         *ctx = h;
  454         return 0;
  455     }
  456 
  457     r = crypt_cipher_init_kernel(&h->u.kernel, name, mode, key, key_length);
  458     if (r < 0) {
  459         free(h);
  460         return r;
  461     }
  462 
  463     h->use_kernel = true;
  464     *ctx = h;
  465     return 0;
  466 }
  467 
  468 void crypt_cipher_destroy(struct crypt_cipher *ctx)
  469 {
  470     if (ctx->use_kernel)
  471         crypt_cipher_destroy_kernel(&ctx->u.kernel);
  472     else
  473         gcry_cipher_close(ctx->u.hd);
  474     free(ctx);
  475 }
  476 
  477 int crypt_cipher_encrypt(struct crypt_cipher *ctx,
  478              const char *in, char *out, size_t length,
  479              const char *iv, size_t iv_length)
  480 {
  481     if (ctx->use_kernel)
  482         return crypt_cipher_encrypt_kernel(&ctx->u.kernel, in, out, length, iv, iv_length);
  483 
  484     if (iv && gcry_cipher_setiv(ctx->u.hd, iv, iv_length))
  485         return -EINVAL;
  486 
  487     if (gcry_cipher_encrypt(ctx->u.hd, out, length, in, length))
  488         return -EINVAL;
  489 
  490     return 0;
  491 }
  492 
  493 int crypt_cipher_decrypt(struct crypt_cipher *ctx,
  494              const char *in, char *out, size_t length,
  495              const char *iv, size_t iv_length)
  496 {
  497     if (ctx->use_kernel)
  498         return crypt_cipher_decrypt_kernel(&ctx->u.kernel, in, out, length, iv, iv_length);
  499 
  500     if (iv && gcry_cipher_setiv(ctx->u.hd, iv, iv_length))
  501         return -EINVAL;
  502 
  503     if (gcry_cipher_decrypt(ctx->u.hd, out, length, in, length))
  504         return -EINVAL;
  505 
  506     return 0;
  507 }
  508 
  509 bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
  510 {
  511     return ctx->use_kernel;
  512 }
  513 
  514 int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
  515                 const char *in, char *out, size_t length,
  516                 const char *iv, size_t iv_length,
  517                 const char *tag, size_t tag_length)
  518 {
  519 #ifdef GCRY_CCM_BLOCK_LEN
  520     gcry_cipher_hd_t hd;
  521     uint64_t l[3];
  522     int r = -EINVAL;
  523 
  524     if (gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, 0))
  525         return -EINVAL;
  526 
  527     if (gcry_cipher_setkey(hd, key, key_length))
  528         goto out;
  529 
  530     if (gcry_cipher_setiv(hd, iv, iv_length))
  531         goto out;
  532 
  533     l[0] = length;
  534     l[1] = 0;
  535     l[2] = tag_length;
  536     if (gcry_cipher_ctl(hd, GCRYCTL_SET_CCM_LENGTHS, l, sizeof(l)))
  537         goto out;
  538 
  539     if (gcry_cipher_decrypt(hd, out, length, in, length))
  540         goto out;
  541 
  542     if (gcry_cipher_checktag(hd, tag, tag_length))
  543         goto out;
  544 
  545     r = 0;
  546 out:
  547     gcry_cipher_close(hd);
  548     return r;
  549 #else
  550     return -ENOTSUP;
  551 #endif
  552 }