Blame crypt.c

Packit 13e0ca
/* High-level libcrypt interfaces.
Packit 13e0ca
Packit 13e0ca
   Copyright 2007-2017 Thorsten Kukuk and Zack Weinberg
Packit 13e0ca
Packit 13e0ca
   This library is free software; you can redistribute it and/or
Packit 13e0ca
   modify it under the terms of the GNU Lesser General Public License
Packit 13e0ca
   as published by the Free Software Foundation; either version 2.1 of
Packit 13e0ca
   the License, or (at your option) any later version.
Packit 13e0ca
Packit 13e0ca
   This library is distributed in the hope that it will be useful,
Packit 13e0ca
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 13e0ca
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 13e0ca
   GNU Lesser General Public License for more details.
Packit 13e0ca
Packit 13e0ca
   You should have received a copy of the GNU Lesser General Public
Packit 13e0ca
   License along with this library; if not, see
Packit 13e0ca
   <https://www.gnu.org/licenses/>.  */
Packit 13e0ca
Packit 13e0ca
#include "crypt-port.h"
Packit 13e0ca
#include "crypt-private.h"
Packit 13e0ca
Packit 13e0ca
#include <errno.h>
Packit 13e0ca
#include <stdlib.h>
Packit 13e0ca
#include <limits.h>
Packit 13e0ca
Packit 13e0ca
/* The internal storage area within struct crypt_data is used as
Packit 13e0ca
   follows.  We don't know what alignment the algorithm modules will
Packit 13e0ca
   need for their scratch data, so give it the maximum natural
Packit 13e0ca
   alignment.  Note that the C11 alignas() specifier can't be applied
Packit 13e0ca
   directly to a struct type, but it can be applied to the first field
Packit 13e0ca
   of a struct, which effectively forces alignment of the entire
Packit 13e0ca
   struct, since the first field must always have offset 0.  */
Packit 13e0ca
struct crypt_internal
Packit 13e0ca
{
Packit 13e0ca
  char alignas (max_align_t) alg_specific[ALG_SPECIFIC_SIZE];
Packit 13e0ca
};
Packit 13e0ca
Packit 13e0ca
static_assert(sizeof (struct crypt_internal) + alignof (struct crypt_internal)
Packit 13e0ca
              <= CRYPT_DATA_INTERNAL_SIZE,
Packit 13e0ca
              "crypt_data.internal is too small for crypt_internal");
Packit 13e0ca
Packit 13e0ca
/* struct crypt_data is allocated by application code and contains
Packit 13e0ca
   only char-typed fields, so its 'internal' field may not be
Packit 13e0ca
   sufficiently aligned.  */
Packit 13e0ca
static inline struct crypt_internal *
Packit 13e0ca
get_internal (struct crypt_data *data)
Packit 13e0ca
{
Packit 13e0ca
  uintptr_t internalp = (uintptr_t) data->internal;
Packit 13e0ca
  const uintptr_t align = alignof (struct crypt_internal);
Packit 13e0ca
  internalp = (internalp + align - 1) & ~(align - 1);
Packit 13e0ca
  return (struct crypt_internal *)internalp;
Packit 13e0ca
}
Packit 13e0ca
Packit 13e0ca
typedef void (*crypt_fn) (const char *phrase, size_t phr_size,
Packit 13e0ca
                          const char *setting, size_t set_size,
Packit 13e0ca
                          uint8_t *output, size_t out_size,
Packit 13e0ca
                          void *scratch, size_t scr_size);
Packit 13e0ca
Packit 13e0ca
typedef void (*gensalt_fn) (unsigned long count,
Packit 13e0ca
                            const uint8_t *rbytes, size_t nrbytes,
Packit 13e0ca
                            uint8_t *output, size_t output_size);
Packit 13e0ca
Packit 13e0ca
struct hashfn
Packit 13e0ca
{
Packit 13e0ca
  const char *prefix;
Packit 13e0ca
  size_t plen;
Packit 13e0ca
  crypt_fn crypt;
Packit 13e0ca
  gensalt_fn gensalt;
Packit 13e0ca
  /* The type of this field is unsigned char to ensure that it cannot
Packit 13e0ca
     be set larger than the size of an internal buffer in crypt_gensalt_rn.  */
Packit 13e0ca
  unsigned char nrbytes;
Packit 13e0ca
};
Packit 13e0ca
Packit 13e0ca
static const struct hashfn hash_algorithms[] =
Packit 13e0ca
{
Packit 13e0ca
  HASH_ALGORITHM_TABLE_ENTRIES
Packit 13e0ca
};
Packit 13e0ca
Packit 13e0ca
#if INCLUDE_des || INCLUDE_des_big
Packit 13e0ca
static int
Packit 13e0ca
is_des_salt_char (char c)
Packit 13e0ca
{
Packit 13e0ca
  return ((c >= 'a' && c <= 'z') ||
Packit 13e0ca
          (c >= 'A' && c <= 'Z') ||
Packit 13e0ca
          (c >= '0' && c <= '9') ||
Packit 13e0ca
          c == '.' || c == '/');
Packit 13e0ca
}
Packit 13e0ca
#endif
Packit 13e0ca
Packit 13e0ca
static const struct hashfn *
Packit 13e0ca
get_hashfn (const char *setting)
Packit 13e0ca
{
Packit 13e0ca
  const struct hashfn *h;
Packit 13e0ca
  for (h = hash_algorithms; h->prefix; h++)
Packit 13e0ca
    {
Packit 13e0ca
      if (h->plen > 0)
Packit 13e0ca
        {
Packit 13e0ca
          if (!strncmp (setting, h->prefix, h->plen))
Packit 13e0ca
            return h;
Packit 13e0ca
        }
Packit 13e0ca
#if INCLUDE_des || INCLUDE_des_big
Packit 13e0ca
      else
Packit 13e0ca
        {
Packit 13e0ca
          if (setting[0] == '\0' ||
Packit 13e0ca
              (is_des_salt_char (setting[0]) && is_des_salt_char (setting[1])))
Packit 13e0ca
            return h;
Packit 13e0ca
        }
Packit 13e0ca
#endif
Packit 13e0ca
    }
Packit 13e0ca
  return 0;
Packit 13e0ca
}
Packit 13e0ca
Packit 13e0ca
/* For historical reasons, crypt and crypt_r are not expected ever to
Packit 13e0ca
   return 0, and for internal implementation reasons (see
Packit 13e0ca
   call_crypt_fn, below), it is simpler if the individual algorithms'
Packit 13e0ca
   crypt and gensalt functions return nothing.
Packit 13e0ca
Packit 13e0ca
   This function generates a "failure token" in the output buffer,
Packit 13e0ca
   which is guaranteed not to be equal to any valid password hash or
Packit 13e0ca
   setting string, nor to the setting(+hash) string that was passed
Packit 13e0ca
   in; thus, a subsequent blind attempt to authenticate someone by
Packit 13e0ca
   comparing the output to a previously recorded hash string will
Packit 13e0ca
   fail, even if that string is itself one of these "failure tokens".
Packit 13e0ca
Packit 13e0ca
   We always call this function on the output buffer as the first
Packit 13e0ca
   step.  If the individual algorithm's crypt or gensalt function
Packit 13e0ca
   succeeds, it overwrites the failure token with real output;
Packit 13e0ca
   otherwise the token is left intact, and the API functions that
Packit 13e0ca
   _can_ return 0 on error notice it.  */
Packit 13e0ca
Packit 13e0ca
static void
Packit 13e0ca
make_failure_token (const char *setting, char *output, int size)
Packit 13e0ca
{
Packit 13e0ca
  if (size >= 3)
Packit 13e0ca
    {
Packit 13e0ca
      output[0] = '*';
Packit 13e0ca
      output[1] = '0';
Packit 13e0ca
      output[2] = '\0';
Packit 13e0ca
Packit 13e0ca
      if (setting && setting[0] == '*' && setting[1] == '0')
Packit 13e0ca
        output[1] = '1';
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  /* If there's not enough space for the full failure token, do the
Packit 13e0ca
     best we can.  */
Packit 13e0ca
  else if (size == 2)
Packit 13e0ca
    {
Packit 13e0ca
      output[0] = '*';
Packit 13e0ca
      output[1] = '\0';
Packit 13e0ca
    }
Packit 13e0ca
  else if (size == 1)
Packit 13e0ca
    {
Packit 13e0ca
      output[0] = '\0';
Packit 13e0ca
    }
Packit 13e0ca
}
Packit 13e0ca
Packit 13e0ca
static void
Packit 13e0ca
do_crypt (const char *phrase, const char *setting, struct crypt_data *data)
Packit 13e0ca
{
Packit 13e0ca
  if (!phrase || !setting)
Packit 13e0ca
    {
Packit 13e0ca
      errno = EINVAL;
Packit 13e0ca
      return;
Packit 13e0ca
    }
Packit 13e0ca
  /* Do these strlen() calls before reading prefixes of either
Packit 13e0ca
     'phrase' or 'setting', so we get a predictable crash if they are
Packit 13e0ca
     not valid strings.  */
Packit 13e0ca
  size_t phr_size = strlen (phrase);
Packit 13e0ca
  size_t set_size = strlen (setting);
Packit 13e0ca
  const struct hashfn *h = get_hashfn (setting);
Packit 13e0ca
  if (!h)
Packit 13e0ca
    {
Packit 13e0ca
      /* Unrecognized hash algorithm */
Packit 13e0ca
      errno = EINVAL;
Packit 13e0ca
      return;
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  struct crypt_internal *cint = get_internal (data);
Packit 13e0ca
  h->crypt (phrase, phr_size, setting, set_size,
Packit 13e0ca
            (unsigned char *)data->output, sizeof data->output,
Packit 13e0ca
            cint->alg_specific, sizeof cint->alg_specific);
Packit 13e0ca
Packit 13e0ca
  XCRYPT_SECURE_MEMSET (data->internal, sizeof data->internal);
Packit 13e0ca
}
Packit 13e0ca
Packit 13e0ca
#if INCLUDE_crypt_rn
Packit 13e0ca
char *
Packit 13e0ca
crypt_rn (const char *phrase, const char *setting, void *data, int size)
Packit 13e0ca
{
Packit 13e0ca
  make_failure_token (setting, data, MIN (size, CRYPT_OUTPUT_SIZE));
Packit 13e0ca
  if (size < 0 || (size_t)size < sizeof (struct crypt_data))
Packit 13e0ca
    {
Packit 13e0ca
      errno = ERANGE;
Packit 13e0ca
      return 0;
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  struct crypt_data *p = data;
Packit 13e0ca
  do_crypt (phrase, setting, p);
Packit 13e0ca
  return p->output[0] == '*' ? 0 : p->output;
Packit 13e0ca
}
Packit 13e0ca
SYMVER_crypt_rn;
Packit 13e0ca
#endif
Packit 13e0ca
Packit 13e0ca
#if INCLUDE_crypt_ra
Packit 13e0ca
char *
Packit 13e0ca
crypt_ra (const char *phrase, const char *setting, void **data, int *size)
Packit 13e0ca
{
Packit 13e0ca
  if (!*data)
Packit 13e0ca
    {
Packit 13e0ca
      *data = malloc (sizeof (struct crypt_data));
Packit 13e0ca
      if (!*data)
Packit 13e0ca
        return 0;
Packit 13e0ca
      *size = sizeof (struct crypt_data);
Packit 13e0ca
    }
Packit 13e0ca
  if (*size < 0 || (size_t)*size < sizeof (struct crypt_data))
Packit 13e0ca
    {
Packit 13e0ca
      void *rdata = realloc (*data, sizeof (struct crypt_data));
Packit 13e0ca
      if (!rdata)
Packit 13e0ca
        return 0;
Packit 13e0ca
      *data = rdata;
Packit 13e0ca
      *size = sizeof (struct crypt_data);
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  struct crypt_data *p = *data;
Packit 13e0ca
  make_failure_token (setting, p->output, sizeof p->output);
Packit 13e0ca
  do_crypt (phrase, setting, p);
Packit 13e0ca
  return p->output[0] == '*' ? 0 : p->output;
Packit 13e0ca
}
Packit 13e0ca
SYMVER_crypt_ra;
Packit 13e0ca
#endif
Packit 13e0ca
Packit 13e0ca
#if INCLUDE_crypt_r
Packit 13e0ca
char *
Packit 13e0ca
crypt_r (const char *phrase, const char *setting, struct crypt_data *data)
Packit 13e0ca
{
Packit 13e0ca
  make_failure_token (setting, data->output, sizeof data->output);
Packit 13e0ca
  do_crypt (phrase, setting, data);
Packit Service 0b5db0
#if ENABLE_FAILURE_TOKENS
Packit 13e0ca
  return data->output;
Packit Service 0b5db0
#else
Packit Service 0b5db0
  return data->output[0] == '*' ? 0 : data->output;
Packit Service 0b5db0
#endif
Packit 13e0ca
}
Packit 13e0ca
SYMVER_crypt_r;
Packit 13e0ca
#endif
Packit 13e0ca
Packit 13e0ca
#if INCLUDE_crypt_gensalt_rn
Packit 13e0ca
char *
Packit 13e0ca
crypt_gensalt_rn (const char *prefix, unsigned long count,
Packit 13e0ca
                  const char *rbytes, int nrbytes, char *output,
Packit 13e0ca
                  int output_size)
Packit 13e0ca
{
Packit 13e0ca
  make_failure_token ("", output, output_size);
Packit 13e0ca
Packit 13e0ca
  /* Individual gensalt functions will check for adequate space for
Packit 13e0ca
     their own breed of setting, but the shortest possible one is
Packit 13e0ca
     three bytes (DES two-character salt + NUL terminator) and we
Packit 13e0ca
     also want to rule out negative numbers early.  */
Packit 13e0ca
  if (output_size < 3)
Packit 13e0ca
    {
Packit 13e0ca
      errno = ERANGE;
Packit 13e0ca
      return 0;
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  /* If the prefix is 0, that means to use the current best default.
Packit 13e0ca
     Note that this is different from the behavior when the prefix is
Packit 13e0ca
     "", which selects DES.  HASH_ALGORITHM_DEFAULT is null when the
Packit 13e0ca
     current default algorithm was disabled at configure time.  */
Packit 13e0ca
  if (!prefix)
Packit 13e0ca
    prefix = HASH_ALGORITHM_DEFAULT;
Packit 13e0ca
  if (!prefix)
Packit 13e0ca
    {
Packit 13e0ca
      errno = EINVAL;
Packit 13e0ca
      return 0;
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  const struct hashfn *h = get_hashfn (prefix);
Packit 13e0ca
  if (!h)
Packit 13e0ca
    {
Packit 13e0ca
      errno = EINVAL;
Packit 13e0ca
      return 0;
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  char internal_rbytes[UCHAR_MAX];
Packit 13e0ca
  /* typeof (internal_nrbytes) == typeof (h->nrbytes).  */
Packit 13e0ca
  unsigned char internal_nrbytes = 0;
Packit 13e0ca
Packit 13e0ca
  /* If rbytes is 0, read random bytes from the operating system if
Packit 13e0ca
     possible.  */
Packit 13e0ca
  if (!rbytes)
Packit 13e0ca
    {
Packit 13e0ca
      if (!get_random_bytes (internal_rbytes, h->nrbytes))
Packit 13e0ca
        return 0;
Packit 13e0ca
Packit 13e0ca
      rbytes = internal_rbytes;
Packit 13e0ca
      nrbytes = internal_nrbytes = h->nrbytes;
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  /* Individual gensalt functions will check for sufficient random bits
Packit 13e0ca
     for their own breed of setting, but the shortest possible one has
Packit 13e0ca
     64**2 = 4096 possibilities, which requires two bytes of input.  */
Packit 13e0ca
  if (nrbytes < 2)
Packit 13e0ca
    {
Packit 13e0ca
      errno = EINVAL;
Packit 13e0ca
      return 0;
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  h->gensalt (count,
Packit 13e0ca
              (const unsigned char *)rbytes, (size_t)nrbytes,
Packit 13e0ca
              (unsigned char *)output, (size_t)output_size);
Packit 13e0ca
Packit 13e0ca
  if (internal_nrbytes)
Packit 13e0ca
    XCRYPT_SECURE_MEMSET (internal_rbytes, internal_nrbytes);
Packit 13e0ca
Packit 13e0ca
  return output[0] == '*' ? 0 : output;
Packit 13e0ca
}
Packit 13e0ca
SYMVER_crypt_gensalt_rn;
Packit 13e0ca
#endif
Packit 13e0ca
Packit 13e0ca
#if INCLUDE_crypt_gensalt_ra
Packit 13e0ca
char *
Packit 13e0ca
crypt_gensalt_ra (const char *prefix, unsigned long count,
Packit 13e0ca
                  const char *rbytes, int nrbytes)
Packit 13e0ca
{
Packit 13e0ca
  char *output = malloc (CRYPT_GENSALT_OUTPUT_SIZE);
Packit 13e0ca
  if (!output)
Packit 13e0ca
    return 0;
Packit 13e0ca
Packit 13e0ca
  char *result = crypt_gensalt_rn (prefix, count, rbytes, nrbytes, output,
Packit 13e0ca
                                   CRYPT_GENSALT_OUTPUT_SIZE);
Packit 13e0ca
  if (result == 0)
Packit 13e0ca
    free (output);
Packit 13e0ca
  return result;
Packit 13e0ca
}
Packit 13e0ca
SYMVER_crypt_gensalt_ra;
Packit 13e0ca
#endif