"Fossies" - the Fresh Open Source Software Archive

Member "cryptsetup-2.4.3/lib/crypto_backend/pbkdf2_generic.c" (13 Jan 2022, 6849 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 "pbkdf2_generic.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Implementation of Password-Based Cryptography as per PKCS#5
    3  * Copyright (C) 2002,2003 Simon Josefsson
    4  * Copyright (C) 2004 Free Software Foundation
    5  *
    6  * cryptsetup related changes
    7  * Copyright (C) 2012-2021 Red Hat, Inc. All rights reserved.
    8  * Copyright (C) 2012-2021 Milan Broz
    9  *
   10  * This file is free software; you can redistribute it and/or
   11  * modify it under the terms of the GNU Lesser General Public
   12  * License as published by the Free Software Foundation; either
   13  * version 2.1 of the License, or (at your option) any later version.
   14  *
   15  * This file is distributed in the hope that it will be useful,
   16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   18  * Lesser General Public License for more details.
   19  *
   20  * You should have received a copy of the GNU Lesser General Public
   21  * License along with this file; if not, write to the Free Software
   22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   23  *
   24  */
   25 
   26 #include <errno.h>
   27 #include <alloca.h>
   28 #include "crypto_backend_internal.h"
   29 
   30 static int hash_buf(const char *src, size_t src_len,
   31             char *dst, size_t dst_len,
   32             const char *hash_name)
   33 {
   34     struct crypt_hash *hd = NULL;
   35     int r;
   36 
   37     if (crypt_hash_init(&hd, hash_name))
   38         return -EINVAL;
   39 
   40     r = crypt_hash_write(hd, src, src_len);
   41 
   42     if (!r)
   43         r = crypt_hash_final(hd, dst, dst_len);
   44 
   45     crypt_hash_destroy(hd);
   46     return r;
   47 }
   48 
   49 /*
   50  * 5.2 PBKDF2
   51  *
   52  *  PBKDF2 applies a pseudorandom function (see Appendix B.1 for an
   53  *  example) to derive keys. The length of the derived key is essentially
   54  *  unbounded. (However, the maximum effective search space for the
   55  *  derived key may be limited by the structure of the underlying
   56  *  pseudorandom function. See Appendix B.1 for further discussion.)
   57  *  PBKDF2 is recommended for new applications.
   58  *
   59  *  PBKDF2 (P, S, c, dkLen)
   60  *
   61  *  Options:        PRF        underlying pseudorandom function (hLen
   62  *                             denotes the length in octets of the
   63  *                             pseudorandom function output)
   64  *
   65  *  Input:          P          password, an octet string (ASCII or UTF-8)
   66  *                  S          salt, an octet string
   67  *                  c          iteration count, a positive integer
   68  *                  dkLen      intended length in octets of the derived
   69  *                             key, a positive integer, at most
   70  *                             (2^32 - 1) * hLen
   71  *
   72  *  Output:         DK         derived key, a dkLen-octet string
   73  */
   74 
   75 /*
   76  * if hash_block_size is not zero, the HMAC key is pre-hashed
   77  * inside this function.
   78  * This prevents situation when crypto backend doesn't support
   79  * long HMAC keys or it tries hash long key in every iteration
   80  * (because of crypt_final() cannot do simple key reset.
   81  */
   82 
   83 #define MAX_PRF_BLOCK_LEN 80
   84 
   85 int pkcs5_pbkdf2(const char *hash,
   86             const char *P, size_t Plen,
   87             const char *S, size_t Slen,
   88             unsigned int c, unsigned int dkLen,
   89             char *DK, unsigned int hash_block_size)
   90 {
   91     struct crypt_hmac *hmac;
   92     char U[MAX_PRF_BLOCK_LEN];
   93     char T[MAX_PRF_BLOCK_LEN];
   94     char P_hash[MAX_PRF_BLOCK_LEN];
   95     int i, k, rc = -EINVAL;
   96     unsigned int u, hLen, l, r;
   97     size_t tmplen = Slen + 4;
   98     char *tmp;
   99 
  100     tmp = alloca(tmplen);
  101     if (tmp == NULL)
  102         return -ENOMEM;
  103 
  104     hLen = crypt_hmac_size(hash);
  105     if (hLen == 0 || hLen > MAX_PRF_BLOCK_LEN)
  106         return -EINVAL;
  107 
  108     if (c == 0)
  109         return -EINVAL;
  110 
  111     if (dkLen == 0)
  112         return -EINVAL;
  113 
  114     /*
  115      *
  116      *  Steps:
  117      *
  118      *     1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and
  119      *        stop.
  120      */
  121 
  122     if (dkLen > 4294967295U)
  123         return -EINVAL;
  124 
  125     /*
  126      *     2. Let l be the number of hLen-octet blocks in the derived key,
  127      *        rounding up, and let r be the number of octets in the last
  128      *        block:
  129      *
  130      *                  l = CEIL (dkLen / hLen) ,
  131      *                  r = dkLen - (l - 1) * hLen .
  132      *
  133      *        Here, CEIL (x) is the "ceiling" function, i.e. the smallest
  134      *        integer greater than, or equal to, x.
  135      */
  136 
  137     l = dkLen / hLen;
  138     if (dkLen % hLen)
  139         l++;
  140     r = dkLen - (l - 1) * hLen;
  141 
  142     /*
  143      *     3. For each block of the derived key apply the function F defined
  144      *        below to the password P, the salt S, the iteration count c, and
  145      *        the block index to compute the block:
  146      *
  147      *                  T_1 = F (P, S, c, 1) ,
  148      *                  T_2 = F (P, S, c, 2) ,
  149      *                  ...
  150      *                  T_l = F (P, S, c, l) ,
  151      *
  152      *        where the function F is defined as the exclusive-or sum of the
  153      *        first c iterates of the underlying pseudorandom function PRF
  154      *        applied to the password P and the concatenation of the salt S
  155      *        and the block index i:
  156      *
  157      *                  F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c
  158      *
  159      *        where
  160      *
  161      *                  U_1 = PRF (P, S || INT (i)) ,
  162      *                  U_2 = PRF (P, U_1) ,
  163      *                  ...
  164      *                  U_c = PRF (P, U_{c-1}) .
  165      *
  166      *        Here, INT (i) is a four-octet encoding of the integer i, most
  167      *        significant octet first.
  168      *
  169      *     4. Concatenate the blocks and extract the first dkLen octets to
  170      *        produce a derived key DK:
  171      *
  172      *                  DK = T_1 || T_2 ||  ...  || T_l<0..r-1>
  173      *
  174      *     5. Output the derived key DK.
  175      *
  176      *  Note. The construction of the function F follows a "belt-and-
  177      *  suspenders" approach. The iterates U_i are computed recursively to
  178      *  remove a degree of parallelism from an opponent; they are exclusive-
  179      *  ored together to reduce concerns about the recursion degenerating
  180      *  into a small set of values.
  181      *
  182      */
  183 
  184     /* If hash_block_size is provided, hash password in advance. */
  185     if (hash_block_size > 0 && Plen > hash_block_size) {
  186         if (hash_buf(P, Plen, P_hash, hLen, hash))
  187             return -EINVAL;
  188 
  189         if (crypt_hmac_init(&hmac, hash, P_hash, hLen))
  190             return -EINVAL;
  191         crypt_backend_memzero(P_hash, sizeof(P_hash));
  192     } else {
  193         if (crypt_hmac_init(&hmac, hash, P, Plen))
  194             return -EINVAL;
  195     }
  196 
  197     for (i = 1; (unsigned int) i <= l; i++) {
  198         memset(T, 0, hLen);
  199 
  200         for (u = 1; u <= c ; u++) {
  201             if (u == 1) {
  202                 memcpy(tmp, S, Slen);
  203                 tmp[Slen + 0] = (i & 0xff000000) >> 24;
  204                 tmp[Slen + 1] = (i & 0x00ff0000) >> 16;
  205                 tmp[Slen + 2] = (i & 0x0000ff00) >> 8;
  206                 tmp[Slen + 3] = (i & 0x000000ff) >> 0;
  207 
  208                 if (crypt_hmac_write(hmac, tmp, tmplen))
  209                     goto out;
  210             } else {
  211                 if (crypt_hmac_write(hmac, U, hLen))
  212                     goto out;
  213             }
  214 
  215             if (crypt_hmac_final(hmac, U, hLen))
  216                 goto out;
  217 
  218             for (k = 0; (unsigned int) k < hLen; k++)
  219                 T[k] ^= U[k];
  220         }
  221 
  222         memcpy(DK + (i - 1) * hLen, T, (unsigned int) i == l ? r : hLen);
  223     }
  224     rc = 0;
  225 out:
  226     crypt_hmac_destroy(hmac);
  227     crypt_backend_memzero(U, sizeof(U));
  228     crypt_backend_memzero(T, sizeof(T));
  229     crypt_backend_memzero(tmp, tmplen);
  230 
  231     return rc;
  232 }