"Fossies" - the Fresh Open Source Software Archive

Member "cryptsetup-2.4.3/lib/utils_pbkdf.c" (13 Jan 2022, 9304 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 "utils_pbkdf.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2.3.6_vs_2.4.0.

    1 /*
    2  * utils_pbkdf - PBKDF settings for libcryptsetup
    3  *
    4  * Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
    5  * Copyright (C) 2009-2021 Milan Broz
    6  *
    7  * This program is free software; you can redistribute it and/or
    8  * modify it under the terms of the GNU General Public License
    9  * as published by the Free Software Foundation; either version 2
   10  * of the License, or (at your option) any later version.
   11  *
   12  * This program 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
   15  * GNU General Public License for more details.
   16  *
   17  * You should have received a copy of the GNU General Public License
   18  * along with this program; if not, write to the Free Software
   19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   20  */
   21 
   22 #include <stdlib.h>
   23 #include <errno.h>
   24 
   25 #include "internal.h"
   26 
   27 const struct crypt_pbkdf_type default_pbkdf2 = {
   28     .type = CRYPT_KDF_PBKDF2,
   29     .hash = DEFAULT_LUKS1_HASH,
   30     .time_ms = DEFAULT_LUKS1_ITER_TIME
   31 };
   32 
   33 const struct crypt_pbkdf_type default_argon2i = {
   34     .type = CRYPT_KDF_ARGON2I,
   35     .hash = DEFAULT_LUKS1_HASH,
   36     .time_ms = DEFAULT_LUKS2_ITER_TIME,
   37     .max_memory_kb = DEFAULT_LUKS2_MEMORY_KB,
   38     .parallel_threads = DEFAULT_LUKS2_PARALLEL_THREADS
   39 };
   40 
   41 const struct crypt_pbkdf_type default_argon2id = {
   42     .type = CRYPT_KDF_ARGON2ID,
   43     .hash = DEFAULT_LUKS1_HASH,
   44     .time_ms = DEFAULT_LUKS2_ITER_TIME,
   45     .max_memory_kb = DEFAULT_LUKS2_MEMORY_KB,
   46     .parallel_threads = DEFAULT_LUKS2_PARALLEL_THREADS
   47 };
   48 
   49 const struct crypt_pbkdf_type *crypt_get_pbkdf_type_params(const char *pbkdf_type)
   50 {
   51     if (!pbkdf_type)
   52         return NULL;
   53 
   54     if (!strcmp(pbkdf_type, CRYPT_KDF_PBKDF2))
   55         return &default_pbkdf2;
   56     else if (!strcmp(pbkdf_type, CRYPT_KDF_ARGON2I))
   57         return &default_argon2i;
   58     else if (!strcmp(pbkdf_type, CRYPT_KDF_ARGON2ID))
   59         return &default_argon2id;
   60 
   61     return NULL;
   62 }
   63 
   64 static uint32_t adjusted_phys_memory(void)
   65 {
   66     uint64_t memory_kb = crypt_getphysmemory_kb();
   67 
   68     /* Ignore bogus value */
   69     if (memory_kb < (128 * 1024) || memory_kb > UINT32_MAX)
   70         return DEFAULT_LUKS2_MEMORY_KB;
   71 
   72     /*
   73      * Never use more than half of physical memory.
   74      * OOM killer is too clever...
   75      */
   76     memory_kb /= 2;
   77 
   78     return memory_kb;
   79 }
   80 
   81 /*
   82  * PBKDF configuration interface
   83  */
   84 int verify_pbkdf_params(struct crypt_device *cd,
   85             const struct crypt_pbkdf_type *pbkdf)
   86 {
   87     struct crypt_pbkdf_limits pbkdf_limits;
   88     const char *pbkdf_type;
   89     int r;
   90 
   91     r = init_crypto(cd);
   92     if (r < 0)
   93         return r;
   94 
   95     if (!pbkdf || !pbkdf->type ||
   96         (!pbkdf->hash && !strcmp(pbkdf->type, "pbkdf2")))
   97         return -EINVAL;
   98 
   99     if (!pbkdf->time_ms && !(pbkdf->flags & CRYPT_PBKDF_NO_BENCHMARK)) {
  100         log_err(cd, _("Requested PBKDF target time cannot be zero."));
  101         return -EINVAL;
  102     }
  103 
  104     r = crypt_parse_pbkdf(pbkdf->type, &pbkdf_type);
  105     if (r < 0) {
  106         log_err(cd, _("Unknown PBKDF type %s."), pbkdf->type);
  107         return r;
  108     }
  109 
  110     if (pbkdf->hash && crypt_hash_size(pbkdf->hash) < 0) {
  111         log_err(cd, _("Requested hash %s is not supported."), pbkdf->hash);
  112         return -EINVAL;
  113     }
  114 
  115     r = crypt_pbkdf_get_limits(pbkdf->type, &pbkdf_limits);
  116     if (r < 0)
  117         return r;
  118 
  119     if (crypt_get_type(cd) &&
  120         !strcmp(crypt_get_type(cd), CRYPT_LUKS1) &&
  121         strcmp(pbkdf_type, CRYPT_KDF_PBKDF2)) {
  122         log_err(cd, _("Requested PBKDF type is not supported for LUKS1."));
  123         return -EINVAL;
  124     }
  125 
  126     if (!strcmp(pbkdf_type, CRYPT_KDF_PBKDF2)) {
  127         if (pbkdf->max_memory_kb || pbkdf->parallel_threads) {
  128             log_err(cd, _("PBKDF max memory or parallel threads must not be set with pbkdf2."));
  129             return -EINVAL;
  130         }
  131         if (pbkdf->flags & CRYPT_PBKDF_NO_BENCHMARK &&
  132             pbkdf->iterations < pbkdf_limits.min_iterations) {
  133             log_err(cd, _("Forced iteration count is too low for %s (minimum is %u)."),
  134                 pbkdf_type, pbkdf_limits.min_iterations);
  135             return -EINVAL;
  136         }
  137         return 0;
  138     }
  139 
  140     /* TODO: properly define minimal iterations and also minimal memory values */
  141     if (pbkdf->flags & CRYPT_PBKDF_NO_BENCHMARK) {
  142         if (pbkdf->iterations < pbkdf_limits.min_iterations) {
  143             log_err(cd, _("Forced iteration count is too low for %s (minimum is %u)."),
  144                 pbkdf_type, pbkdf_limits.min_iterations);
  145             r = -EINVAL;
  146         }
  147         if (pbkdf->max_memory_kb < pbkdf_limits.min_memory) {
  148             log_err(cd, _("Forced memory cost is too low for %s (minimum is %u kilobytes)."),
  149                 pbkdf_type, pbkdf_limits.min_memory);
  150             r = -EINVAL;
  151         }
  152     }
  153 
  154     if (pbkdf->max_memory_kb > pbkdf_limits.max_memory) {
  155         log_err(cd, _("Requested maximum PBKDF memory cost is too high (maximum is %d kilobytes)."),
  156             pbkdf_limits.max_memory);
  157         r = -EINVAL;
  158     }
  159     if (!pbkdf->max_memory_kb) {
  160         log_err(cd, _("Requested maximum PBKDF memory cannot be zero."));
  161         r = -EINVAL;
  162     }
  163     if (!pbkdf->parallel_threads) {
  164         log_err(cd, _("Requested PBKDF parallel threads cannot be zero."));
  165         r = -EINVAL;
  166     }
  167 
  168     return r;
  169 }
  170 
  171 int init_pbkdf_type(struct crypt_device *cd,
  172             const struct crypt_pbkdf_type *pbkdf,
  173             const char *dev_type)
  174 {
  175     struct crypt_pbkdf_type *cd_pbkdf = crypt_get_pbkdf(cd);
  176     struct crypt_pbkdf_limits pbkdf_limits;
  177     const char *hash, *type;
  178     unsigned cpus;
  179     uint32_t old_flags, memory_kb;
  180     int r;
  181 
  182     if (crypt_fips_mode()) {
  183         if (pbkdf && strcmp(pbkdf->type, CRYPT_KDF_PBKDF2)) {
  184             log_err(cd, _("Only PBKDF2 is supported in FIPS mode."));
  185             return -EINVAL;
  186         }
  187         if (!pbkdf)
  188             pbkdf = crypt_get_pbkdf_type_params(CRYPT_KDF_PBKDF2);
  189     }
  190 
  191     if (!pbkdf && dev_type && !strcmp(dev_type, CRYPT_LUKS2))
  192         pbkdf = crypt_get_pbkdf_type_params(DEFAULT_LUKS2_PBKDF);
  193     else if (!pbkdf)
  194         pbkdf = crypt_get_pbkdf_type_params(CRYPT_KDF_PBKDF2);
  195 
  196     r = verify_pbkdf_params(cd, pbkdf);
  197     if (r)
  198         return r;
  199 
  200     r = crypt_pbkdf_get_limits(pbkdf->type, &pbkdf_limits);
  201     if (r < 0)
  202         return r;
  203 
  204     type = strdup(pbkdf->type);
  205     hash = pbkdf->hash ? strdup(pbkdf->hash) : NULL;
  206 
  207     if (!type || (!hash && pbkdf->hash)) {
  208         free(CONST_CAST(void*)type);
  209         free(CONST_CAST(void*)hash);
  210         return -ENOMEM;
  211     }
  212 
  213     free(CONST_CAST(void*)cd_pbkdf->type);
  214     free(CONST_CAST(void*)cd_pbkdf->hash);
  215     cd_pbkdf->type = type;
  216     cd_pbkdf->hash = hash;
  217 
  218     old_flags = cd_pbkdf->flags;
  219     cd_pbkdf->flags = pbkdf->flags;
  220 
  221     /* Reset iteration count so benchmark must run again. */
  222     if (cd_pbkdf->flags & CRYPT_PBKDF_NO_BENCHMARK)
  223         cd_pbkdf->iterations = pbkdf->iterations;
  224     else
  225         cd_pbkdf->iterations = 0;
  226 
  227     if (old_flags & CRYPT_PBKDF_ITER_TIME_SET)
  228         cd_pbkdf->flags |= CRYPT_PBKDF_ITER_TIME_SET;
  229     else
  230         cd_pbkdf->time_ms = pbkdf->time_ms;
  231 
  232     cd_pbkdf->max_memory_kb = pbkdf->max_memory_kb;
  233     cd_pbkdf->parallel_threads = pbkdf->parallel_threads;
  234 
  235     if (cd_pbkdf->parallel_threads > pbkdf_limits.max_parallel) {
  236         log_dbg(cd, "Maximum PBKDF threads is %d (requested %d).",
  237             pbkdf_limits.max_parallel, cd_pbkdf->parallel_threads);
  238         cd_pbkdf->parallel_threads = pbkdf_limits.max_parallel;
  239     }
  240 
  241     if (cd_pbkdf->parallel_threads) {
  242         cpus = crypt_cpusonline();
  243         if (cd_pbkdf->parallel_threads > cpus) {
  244             log_dbg(cd, "Only %u active CPUs detected, "
  245                 "PBKDF threads decreased from %d to %d.",
  246                 cpus, cd_pbkdf->parallel_threads, cpus);
  247             cd_pbkdf->parallel_threads = cpus;
  248         }
  249     }
  250 
  251     if (cd_pbkdf->max_memory_kb) {
  252         memory_kb = adjusted_phys_memory();
  253         if (cd_pbkdf->max_memory_kb > memory_kb) {
  254             log_dbg(cd, "Not enough physical memory detected, "
  255                 "PBKDF max memory decreased from %dkB to %dkB.",
  256                 cd_pbkdf->max_memory_kb, memory_kb);
  257             cd_pbkdf->max_memory_kb = memory_kb;
  258         }
  259     }
  260 
  261     if (!strcmp(pbkdf->type, CRYPT_KDF_PBKDF2))
  262         log_dbg(cd, "PBKDF %s-%s, time_ms %u (iterations %u).",
  263             cd_pbkdf->type, cd_pbkdf->hash, cd_pbkdf->time_ms, cd_pbkdf->iterations);
  264     else
  265         log_dbg(cd, "PBKDF %s, time_ms %u (iterations %u), max_memory_kb %u, parallel_threads %u.",
  266             cd_pbkdf->type, cd_pbkdf->time_ms, cd_pbkdf->iterations,
  267             cd_pbkdf->max_memory_kb, cd_pbkdf->parallel_threads);
  268 
  269     return 0;
  270 }
  271 
  272 /* Libcryptsetup API */
  273 
  274 int crypt_set_pbkdf_type(struct crypt_device *cd, const struct crypt_pbkdf_type *pbkdf)
  275 {
  276     if (!cd)
  277         return -EINVAL;
  278 
  279     if (!pbkdf)
  280         log_dbg(cd, "Resetting pbkdf type to default");
  281 
  282     crypt_get_pbkdf(cd)->flags = 0;
  283 
  284     return init_pbkdf_type(cd, pbkdf, crypt_get_type(cd));
  285 }
  286 
  287 const struct crypt_pbkdf_type *crypt_get_pbkdf_type(struct crypt_device *cd)
  288 {
  289     if (!cd)
  290         return NULL;
  291 
  292     return crypt_get_pbkdf(cd)->type ? crypt_get_pbkdf(cd) : NULL;
  293 }
  294 
  295 const struct crypt_pbkdf_type *crypt_get_pbkdf_default(const char *type)
  296 {
  297     if (!type)
  298         return NULL;
  299 
  300     if (!strcmp(type, CRYPT_LUKS1) || crypt_fips_mode())
  301         return crypt_get_pbkdf_type_params(CRYPT_KDF_PBKDF2);
  302     else if (!strcmp(type, CRYPT_LUKS2))
  303         return crypt_get_pbkdf_type_params(DEFAULT_LUKS2_PBKDF);
  304 
  305     return NULL;
  306 }
  307 
  308 void crypt_set_iteration_time(struct crypt_device *cd, uint64_t iteration_time_ms)
  309 {
  310     struct crypt_pbkdf_type *pbkdf;
  311     uint32_t old_time_ms;
  312 
  313     if (!cd || iteration_time_ms > UINT32_MAX)
  314         return;
  315 
  316     pbkdf = crypt_get_pbkdf(cd);
  317     old_time_ms = pbkdf->time_ms;
  318     pbkdf->time_ms = (uint32_t)iteration_time_ms;
  319 
  320     if (pbkdf->type && verify_pbkdf_params(cd, pbkdf)) {
  321         pbkdf->time_ms = old_time_ms;
  322         log_dbg(cd, "Invalid iteration time.");
  323         return;
  324     }
  325 
  326     pbkdf->flags |= CRYPT_PBKDF_ITER_TIME_SET;
  327 
  328     /* iterations must be benchmarked now */
  329     pbkdf->flags &= ~(CRYPT_PBKDF_NO_BENCHMARK);
  330     pbkdf->iterations = 0;
  331 
  332     log_dbg(cd, "Iteration time set to %" PRIu64 " milliseconds.", iteration_time_ms);
  333 }