(root)/
libxcrypt-4.4.36/
lib/
crypt-yescrypt.c
       1  /* Copyright (C) 2018 vt@altlinux.org
       2   *
       3   * Redistribution and use in source and binary forms, with or without
       4   * modification, are permitted.
       5   *
       6   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
       7   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       8   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
       9   * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      10   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      11   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      12   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      13   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      14   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      15   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      16   * SUCH DAMAGE.
      17   */
      18  
      19  #include "crypt-port.h"
      20  #include "alg-yescrypt.h"
      21  
      22  #include <errno.h>
      23  
      24  #if INCLUDE_yescrypt || INCLUDE_scrypt
      25  
      26  /* For use in scratch space by crypt_yescrypt_rn().  */
      27  typedef struct
      28  {
      29    yescrypt_local_t local;
      30    uint8_t outbuf[CRYPT_OUTPUT_SIZE];
      31    uint8_t *retval;
      32  } crypt_yescrypt_internal_t;
      33  
      34  static_assert (sizeof (crypt_yescrypt_internal_t) <= ALG_SPECIFIC_SIZE,
      35                 "ALG_SPECIFIC_SIZE is too small for YESCRYPT.");
      36  
      37  void
      38  crypt_yescrypt_rn (const char *phrase, size_t phr_size,
      39                     const char *setting, size_t set_size,
      40                     uint8_t *output, size_t o_size,
      41                     void *scratch, size_t s_size)
      42  {
      43  #if !INCLUDE_scrypt
      44  
      45    /* If scrypt is disabled fail when called with its prefix.  */
      46    if (!strncmp (setting, "$7$", 3))
      47      {
      48        errno = EINVAL;
      49        return;
      50      }
      51  
      52  #endif /* !INCLUDE_scrypt */
      53  
      54  #if !INCLUDE_yescrypt
      55  
      56    /* If yescrypt is disabled fail when called with its prefix.  */
      57    if (!strncmp (setting, "$y$", 3))
      58      {
      59        errno = EINVAL;
      60        return;
      61      }
      62  
      63  #endif /* !INCLUDE_yescrypt */
      64  
      65    if (o_size < set_size + 1 + 43 + 1 ||
      66        CRYPT_OUTPUT_SIZE < set_size + 1 + 43 + 1 ||
      67        s_size < sizeof (crypt_yescrypt_internal_t))
      68      {
      69        errno = ERANGE;
      70        return;
      71      }
      72  
      73    crypt_yescrypt_internal_t *intbuf = scratch;
      74  
      75    if (yescrypt_init_local (&intbuf->local))
      76      return;
      77  
      78    intbuf->retval = yescrypt_r (NULL, &intbuf->local,
      79                                 (const uint8_t *)phrase, phr_size,
      80                                 (const uint8_t *)setting, NULL,
      81                                 intbuf->outbuf, o_size);
      82  
      83    if (!intbuf->retval)
      84      errno = EINVAL;
      85  
      86    if (yescrypt_free_local (&intbuf->local) || !intbuf->retval)
      87      return;
      88  
      89    strcpy_or_abort (output, o_size, intbuf->outbuf);
      90    return;
      91  }
      92  
      93  #endif /* INCLUDE_yescrypt || INCLUDE_scrypt */
      94  
      95  #if INCLUDE_gost_yescrypt || INCLUDE_yescrypt
      96  
      97  /*
      98   * As OUTPUT is initialized with a failure token before gensalt_yescrypt_rn
      99   * is called, in case of an error we could just set an appropriate errno
     100   * and return.
     101   * Since O_SIZE is guaranteed to be greater than 2, we may fill OUTPUT
     102   * with a short failure token when need.
     103   */
     104  void
     105  gensalt_yescrypt_rn (unsigned long count,
     106                       const uint8_t *rbytes, size_t nrbytes,
     107                       uint8_t *output, size_t o_size)
     108  {
     109    /* Up to 512 bits (64 bytes) of entropy for computing the salt portion
     110       of the MCF-setting are supported.  */
     111    nrbytes = (nrbytes > 64 ? 64 : nrbytes);
     112  
     113    if (o_size < 3 + 8 * 6 + 1 + BASE64_LEN (nrbytes) + 1 ||
     114        CRYPT_GENSALT_OUTPUT_SIZE < 3 + 8 * 6 + 1 + BASE64_LEN (nrbytes) + 1)
     115      {
     116        errno = ERANGE;
     117        return;
     118      }
     119  
     120    if (count > 11 || nrbytes < 16)
     121      {
     122        errno = EINVAL;
     123        return;
     124      }
     125  
     126    /* Temporary buffer for operation.  The buffer is guaranteed to be
     127       large enough to hold the maximum size of the generated salt.  */
     128    uint8_t outbuf[CRYPT_GENSALT_OUTPUT_SIZE];
     129  
     130    yescrypt_params_t params =
     131    {
     132      .flags = YESCRYPT_DEFAULTS,
     133      .p = 1,
     134    };
     135  
     136    /* Valid cost parameters are from 1 to 11.  The default is 5.
     137       These are used to set yescrypt's 'N' and 'r' parameters as
     138       follows:
     139       N (block count) is specified in units of r (block size,
     140       adjustable in steps of 128 bytes).
     141  
     142       128 bytes * r = size of each memory block
     143  
     144       128 bytes * r * N = total amount of memory used for hashing
     145                           in N blocks of r * 128 bytes.
     146  
     147       The author of yescrypt recommends in the documentation to use
     148       r=8 (a block size of 1 KiB) for total sizes of 2 MiB and less,
     149       and r=32 (a block size of 4KiB) above that.
     150       This has to do with the typical per-core last-level cache sizes
     151       of current CPUs.  */
     152  
     153    if (count == 0)
     154      count = 5;
     155  
     156    if (count < 3)
     157      {
     158        params.r = 8;                   // N in 1KiB
     159        params.N = 1ULL << (count + 9); // 1 -> 1024, 2 -> 2048
     160      }
     161    else
     162      {
     163        params.r = 32;                  // N in 4KiB
     164        params.N = 1ULL << (count + 7); // 3 -> 1024, 4 -> 2048, ... 11 -> 262144
     165      }
     166  
     167    if (!yescrypt_encode_params_r (&params, rbytes, nrbytes, outbuf, o_size))
     168      {
     169        errno = ERANGE;
     170        return;
     171      }
     172  
     173    strcpy_or_abort (output, o_size, outbuf);
     174    return;
     175  }
     176  
     177  #endif /* INCLUDE_gost_yescrypt || INCLUDE_yescrypt */