Blame crypt-des.c

Packit 13e0ca
/*
Packit 13e0ca
 * FreeSec: libcrypt for NetBSD
Packit 13e0ca
 *
Packit 13e0ca
 * Copyright (c) 1994 David Burren
Packit 13e0ca
 * All rights reserved.
Packit 13e0ca
 *
Packit 13e0ca
 * Adapted for FreeBSD-2.0 by Geoffrey M. Rehmet
Packit 13e0ca
 *	this file should now *only* export crypt(), in order to make
Packit 13e0ca
 *	binaries of libcrypt exportable from the USA
Packit 13e0ca
 *
Packit 13e0ca
 * Adapted for FreeBSD-4.0 by Mark R V Murray
Packit 13e0ca
 *	this file should now *only* export crypt_des(), in order to make
Packit 13e0ca
 *	a module that can be optionally included in libcrypt.
Packit 13e0ca
 *
Packit 13e0ca
 * Adapted for libxcrypt by Zack Weinberg, 2017
Packit 13e0ca
 *	see notes in des.c
Packit 13e0ca
 *
Packit 13e0ca
 * Redistribution and use in source and binary forms, with or without
Packit 13e0ca
 * modification, are permitted provided that the following conditions
Packit 13e0ca
 * are met:
Packit 13e0ca
 * 1. Redistributions of source code must retain the above copyright
Packit 13e0ca
 *    notice, this list of conditions and the following disclaimer.
Packit 13e0ca
 * 2. Redistributions in binary form must reproduce the above copyright
Packit 13e0ca
 *    notice, this list of conditions and the following disclaimer in the
Packit 13e0ca
 *    documentation and/or other materials provided with the distribution.
Packit 13e0ca
 * 3. Neither the name of the author nor the names of other contributors
Packit 13e0ca
 *    may be used to endorse or promote products derived from this software
Packit 13e0ca
 *    without specific prior written permission.
Packit 13e0ca
 *
Packit 13e0ca
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
Packit 13e0ca
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit 13e0ca
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit 13e0ca
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
Packit 13e0ca
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit 13e0ca
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
Packit 13e0ca
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
Packit 13e0ca
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
Packit 13e0ca
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
Packit 13e0ca
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
Packit 13e0ca
 * SUCH DAMAGE.
Packit 13e0ca
 *
Packit 13e0ca
 * This is an original implementation of the DES and the crypt(3) interfaces
Packit 13e0ca
 * by David Burren <davidb@werj.com.au>.
Packit 13e0ca
 */
Packit 13e0ca
Packit 13e0ca
#include "crypt-port.h"
Packit 13e0ca
#include "crypt-private.h"
Packit 13e0ca
#include "alg-des.h"
Packit 13e0ca
Packit 13e0ca
#include <errno.h>
Packit 13e0ca
Packit 13e0ca
#if INCLUDE_des || INCLUDE_des_xbsd || INCLUDE_des_big
Packit 13e0ca
Packit 13e0ca
#define DES_TRD_OUTPUT_LEN 14                /* SShhhhhhhhhhh0 */
Packit 13e0ca
#define DES_EXT_OUTPUT_LEN 21                /* _CCCCSSSShhhhhhhhhhh0 */
Packit 13e0ca
#define DES_BIG_OUTPUT_LEN ((16*11) + 2 + 1) /* SS (hhhhhhhhhhh){1,16} 0 */
Packit 13e0ca
Packit 13e0ca
#define DES_MAX_OUTPUT_LEN \
Packit 13e0ca
  MAX (DES_TRD_OUTPUT_LEN, MAX (DES_EXT_OUTPUT_LEN, DES_BIG_OUTPUT_LEN))
Packit 13e0ca
Packit 13e0ca
static_assert (DES_MAX_OUTPUT_LEN <= CRYPT_OUTPUT_SIZE,
Packit 13e0ca
               "CRYPT_OUTPUT_SIZE is too small for DES");
Packit 13e0ca
Packit 13e0ca
/* A des_buffer holds all of the sensitive intermediate data used by
Packit 13e0ca
   crypt_des_*.  */
Packit 13e0ca
Packit 13e0ca
struct des_buffer
Packit 13e0ca
{
Packit 13e0ca
  struct des_ctx ctx;
Packit 13e0ca
  uint8_t keybuf[8];
Packit 13e0ca
  uint8_t pkbuf[8];
Packit 13e0ca
};
Packit 13e0ca
Packit 13e0ca
static_assert (sizeof (struct des_buffer) <= ALG_SPECIFIC_SIZE,
Packit 13e0ca
               "ALG_SPECIFIC_SIZE is too small for DES");
Packit 13e0ca
Packit 13e0ca
Packit 13e0ca
static const uint8_t ascii64[] =
Packit 13e0ca
  "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
Packit 13e0ca
/* 0000000000111111111122222222223333333333444444444455555555556666 */
Packit 13e0ca
/* 0123456789012345678901234567890123456789012345678901234567890123 */
Packit 13e0ca
Packit 13e0ca
static inline int
Packit 13e0ca
ascii_to_bin(char ch)
Packit 13e0ca
{
Packit 13e0ca
  if (ch > 'z')
Packit 13e0ca
    return -1;
Packit 13e0ca
  if (ch >= 'a')
Packit 13e0ca
    return ch - 'a' + 38;
Packit 13e0ca
  if (ch > 'Z')
Packit 13e0ca
    return -1;
Packit 13e0ca
  if (ch >= 'A')
Packit 13e0ca
    return ch - 'A' + 12;
Packit 13e0ca
  if (ch > '9')
Packit 13e0ca
    return -1;
Packit 13e0ca
  if (ch >= '.')
Packit 13e0ca
    return ch - '.';
Packit 13e0ca
  return -1;
Packit 13e0ca
}
Packit 13e0ca
Packit 13e0ca
/* Generate an 11-character DES password hash into the buffer at
Packit 13e0ca
   OUTPUT, and nul-terminate it.  The salt and key have already been
Packit 13e0ca
   set.  The plaintext is 64 bits of zeroes, and the raw ciphertext is
Packit 13e0ca
   written to cbuf[].  */
Packit 13e0ca
static void
Packit 13e0ca
des_gen_hash (struct des_ctx *ctx, uint32_t count, uint8_t *output,
Packit 13e0ca
              uint8_t cbuf[8])
Packit 13e0ca
{
Packit 13e0ca
  uint8_t plaintext[8];
Packit 13e0ca
  XCRYPT_SECURE_MEMSET (plaintext, 8);
Packit 13e0ca
  des_crypt_block (ctx, cbuf, plaintext, count, false);
Packit 13e0ca
Packit 13e0ca
  /* Now encode the result.  */
Packit 13e0ca
  const uint8_t *sptr = cbuf;
Packit 13e0ca
  const uint8_t *end = sptr + 8;
Packit 13e0ca
  unsigned int c1, c2;
Packit 13e0ca
Packit 13e0ca
  do
Packit 13e0ca
    {
Packit 13e0ca
      c1 = *sptr++;
Packit 13e0ca
      *output++ = ascii64[c1 >> 2];
Packit 13e0ca
      c1 = (c1 & 0x03) << 4;
Packit 13e0ca
      if (sptr >= end)
Packit 13e0ca
        {
Packit 13e0ca
          *output++ = ascii64[c1];
Packit 13e0ca
          break;
Packit 13e0ca
        }
Packit 13e0ca
Packit 13e0ca
      c2 = *sptr++;
Packit 13e0ca
      c1 |= c2 >> 4;
Packit 13e0ca
      *output++ = ascii64[c1];
Packit 13e0ca
      c1 = (c2 & 0x0f) << 2;
Packit 13e0ca
      if (sptr >= end)
Packit 13e0ca
        {
Packit 13e0ca
          *output++ = ascii64[c1];
Packit 13e0ca
          break;
Packit 13e0ca
        }
Packit 13e0ca
Packit 13e0ca
      c2 = *sptr++;
Packit 13e0ca
      c1 |= c2 >> 6;
Packit 13e0ca
      *output++ = ascii64[c1];
Packit 13e0ca
      *output++ = ascii64[c2 & 0x3f];
Packit 13e0ca
    }
Packit 13e0ca
  while (sptr < end);
Packit 13e0ca
  *output = '\0';
Packit 13e0ca
}
Packit 13e0ca
#endif
Packit 13e0ca
Packit 13e0ca
#if INCLUDE_des
Packit 13e0ca
/* The original UNIX DES-based password hash, no extensions.  */
Packit 13e0ca
void
Packit 13e0ca
crypt_des_rn (const char *phrase, size_t ARG_UNUSED (phr_size),
Packit 13e0ca
              const char *setting, size_t ARG_UNUSED (set_size),
Packit 13e0ca
              uint8_t *output, size_t out_size,
Packit 13e0ca
              void *scratch, size_t scr_size)
Packit 13e0ca
{
Packit 13e0ca
  /* This shouldn't ever happen, but...  */
Packit 13e0ca
  if (out_size < DES_TRD_OUTPUT_LEN || scr_size < sizeof (struct des_buffer))
Packit 13e0ca
    {
Packit 13e0ca
      errno = ERANGE;
Packit 13e0ca
      return;
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  struct des_buffer *buf = scratch;
Packit 13e0ca
  struct des_ctx *ctx = &buf->ctx;
Packit 13e0ca
  uint32_t salt = 0;
Packit 13e0ca
  uint8_t *keybuf = buf->keybuf, *pkbuf = buf->pkbuf;
Packit 13e0ca
  uint8_t *cp = output;
Packit 13e0ca
  int i;
Packit 13e0ca
Packit 13e0ca
  /* "old"-style: setting - 2 bytes of salt, phrase - up to 8 characters.
Packit 13e0ca
     Note: ascii_to_bin maps all byte values outside the ascii64
Packit 13e0ca
     alphabet to -1.  Do not read past the end of the string.  */
Packit 13e0ca
  i = ascii_to_bin (setting[0]);
Packit 13e0ca
  if (i < 0)
Packit 13e0ca
    {
Packit 13e0ca
      errno = EINVAL;
Packit 13e0ca
      return;
Packit 13e0ca
    }
Packit 13e0ca
  salt = (unsigned int)i;
Packit 13e0ca
  i = ascii_to_bin (setting[1]);
Packit 13e0ca
  if (i < 0)
Packit 13e0ca
    {
Packit 13e0ca
      errno = EINVAL;
Packit 13e0ca
      return;
Packit 13e0ca
    }
Packit 13e0ca
  salt |= ((unsigned int)i << 6);
Packit 13e0ca
Packit 13e0ca
  /* Write the canonical form of the salt to the output buffer.  We do
Packit 13e0ca
     this instead of copying from the setting because the setting
Packit 13e0ca
     might be catastrophically malformed (e.g. a 0- or 1-byte string;
Packit 13e0ca
     this could plausibly happen if e.g. login(8) doesn't special-case
Packit 13e0ca
     "*" or "!" in the password database).  */
Packit 13e0ca
  *cp++ = ascii64[salt & 0x3f];
Packit 13e0ca
  *cp++ = ascii64[(salt >> 6) & 0x3f];
Packit 13e0ca
Packit 13e0ca
  /* Copy the first 8 characters of the password into keybuf, shifting
Packit 13e0ca
     each character up by 1 bit and padding on the right with zeroes.  */
Packit 13e0ca
  for (i = 0; i < 8; i++)
Packit 13e0ca
    {
Packit 13e0ca
      keybuf[i] = (uint8_t)(*phrase << 1);
Packit 13e0ca
      if (*phrase)
Packit 13e0ca
        phrase++;
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  des_set_key (ctx, keybuf);
Packit 13e0ca
  des_set_salt (ctx, salt);
Packit 13e0ca
  des_gen_hash (ctx, 25, cp, pkbuf);
Packit 13e0ca
}
Packit 13e0ca
#endif
Packit 13e0ca
Packit 13e0ca
#if INCLUDE_des_big
Packit 13e0ca
/* This algorithm is algorithm 0 (default) shipped with the C2 secure
Packit 13e0ca
   implementation of Digital UNIX.
Packit 13e0ca
Packit 13e0ca
   Disclaimer: This work is not based on the source code to Digital
Packit 13e0ca
   UNIX, nor am I (Andy Phillips) connected to Digital Equipment Corp,
Packit 13e0ca
   in any way other than as a customer. This code is based on
Packit 13e0ca
   published interfaces and reasonable guesswork.
Packit 13e0ca
Packit 13e0ca
   Description: The cleartext is divided into blocks of 8 characters
Packit 13e0ca
   or less. Each block is encrypted using the standard UNIX libc crypt
Packit 13e0ca
   function. The result of the encryption for one block provides the
Packit 13e0ca
   salt for the suceeding block.  The output is simply the
Packit 13e0ca
   concatenation of all the blocks.  Up to 16 blocks are supported
Packit 13e0ca
   (that is, the password can be no more than 128 characters long).
Packit 13e0ca
Packit 13e0ca
   Andy Phillips <atp@mssl.ucl.ac.uk>  */
Packit 13e0ca
void
Packit 13e0ca
crypt_des_big_rn (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
#if INCLUDE_des
Packit 13e0ca
  /* For backward compatibility, if the setting string is short enough
Packit 13e0ca
     to have been generated by the traditional DES algorithm, forward
Packit 13e0ca
     to traditional DES (which means that only the first 8 characters
Packit 13e0ca
     of 'phrase' are significant).  */
Packit 13e0ca
  if (strlen (setting) <= 13)
Packit 13e0ca
    {
Packit 13e0ca
      crypt_des_rn (phrase, phr_size, setting, set_size,
Packit 13e0ca
                    output, out_size, scratch, scr_size);
Packit 13e0ca
      return;
Packit 13e0ca
    }
Packit 13e0ca
#endif
Packit 13e0ca
Packit 13e0ca
  /* This shouldn't ever happen, but...  */
Packit 13e0ca
  if (out_size < DES_BIG_OUTPUT_LEN || scr_size < sizeof (struct des_buffer))
Packit 13e0ca
    {
Packit 13e0ca
      errno = ERANGE;
Packit 13e0ca
      return;
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  struct des_buffer *buf = scratch;
Packit 13e0ca
  struct des_ctx *ctx = &buf->ctx;
Packit 13e0ca
  uint32_t salt = 0;
Packit 13e0ca
  uint8_t *keybuf = buf->keybuf, *pkbuf = buf->pkbuf;
Packit 13e0ca
  uint8_t *cp = output;
Packit 13e0ca
  int i, seg;
Packit 13e0ca
Packit 13e0ca
  /* The setting string is exactly the same as for a traditional DES
Packit 13e0ca
     hash.  */
Packit 13e0ca
  i = ascii_to_bin (setting[0]);
Packit 13e0ca
  if (i < 0)
Packit 13e0ca
    {
Packit 13e0ca
      errno = EINVAL;
Packit 13e0ca
      return;
Packit 13e0ca
    }
Packit 13e0ca
  salt = (unsigned int)i;
Packit 13e0ca
  i = ascii_to_bin (setting[1]);
Packit 13e0ca
  if (i < 0)
Packit 13e0ca
    {
Packit 13e0ca
      errno = EINVAL;
Packit 13e0ca
      return;
Packit 13e0ca
    }
Packit 13e0ca
  salt |= ((unsigned int)i << 6);
Packit 13e0ca
Packit 13e0ca
  *cp++ = ascii64[salt & 0x3f];
Packit 13e0ca
  *cp++ = ascii64[(salt >> 6) & 0x3f];
Packit 13e0ca
Packit 13e0ca
  for (seg = 0; seg < 16; seg++)
Packit 13e0ca
    {
Packit 13e0ca
      /* Copy and shift each block as for the traditional DES.  */
Packit 13e0ca
      for (i = 0; i < 8; i++)
Packit 13e0ca
        {
Packit 13e0ca
          keybuf[i] = (uint8_t)(*phrase << 1);
Packit 13e0ca
          if (*phrase)
Packit 13e0ca
            phrase++;
Packit 13e0ca
        }
Packit 13e0ca
Packit 13e0ca
      des_set_key (ctx, keybuf);
Packit 13e0ca
      des_set_salt (ctx, salt);
Packit 13e0ca
      des_gen_hash (ctx, 25, cp, pkbuf);
Packit 13e0ca
Packit 13e0ca
      if (*phrase == 0)
Packit 13e0ca
        break;
Packit 13e0ca
Packit 13e0ca
      /* change the salt (1st 2 chars of previous block) - this was found
Packit 13e0ca
         by dowsing - no need to check for invalid characters here */
Packit 13e0ca
      salt = (unsigned int)ascii_to_bin ((char)cp[0]);
Packit 13e0ca
      salt |= (unsigned int)ascii_to_bin ((char)cp[1]) << 6;
Packit 13e0ca
      cp += 11;
Packit 13e0ca
    }
Packit 13e0ca
}
Packit 13e0ca
#endif
Packit 13e0ca
Packit 13e0ca
#if INCLUDE_des_xbsd
Packit 13e0ca
/* crypt_rn() entry point for BSD-style extended DES hashes.  These
Packit 13e0ca
   permit long passwords and have more salt and a controllable iteration
Packit 13e0ca
   count, but are still unacceptably weak by modern standards.  */
Packit 13e0ca
void
Packit 13e0ca
crypt_des_xbsd_rn (const char *phrase, size_t ARG_UNUSED (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
  /* This shouldn't ever happen, but...  */
Packit 13e0ca
  if (out_size < DES_EXT_OUTPUT_LEN || scr_size < sizeof (struct des_buffer))
Packit 13e0ca
    {
Packit 13e0ca
      errno = ERANGE;
Packit 13e0ca
      return;
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  /* If this is true, this function shouldn't have been called.
Packit 13e0ca
     Setting must be at least 9 bytes long, byte 10+ is ignored.  */
Packit 13e0ca
  if (*setting != '_' || set_size < 9)
Packit 13e0ca
    {
Packit 13e0ca
      errno = EINVAL;
Packit 13e0ca
      return;
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  struct des_buffer *buf = scratch;
Packit 13e0ca
  struct des_ctx *ctx = &buf->ctx;
Packit 13e0ca
  uint32_t count = 0, salt = 0;
Packit 13e0ca
  uint8_t *keybuf = buf->keybuf, *pkbuf = buf->pkbuf;
Packit 13e0ca
  uint8_t *cp = output;
Packit 13e0ca
  int i, x;
Packit 13e0ca
Packit 13e0ca
  /* "new"-style DES hash:
Packit 13e0ca
   	setting - underscore, 4 bytes of count, 4 bytes of salt
Packit 13e0ca
   	phrase - unlimited characters
Packit 13e0ca
   */
Packit 13e0ca
  for (i = 1; i < 5; i++)
Packit 13e0ca
    {
Packit 13e0ca
      x = ascii_to_bin(setting[i]);
Packit 13e0ca
      if (x < 0)
Packit 13e0ca
        {
Packit 13e0ca
          errno = EINVAL;
Packit 13e0ca
          return;
Packit 13e0ca
        }
Packit 13e0ca
      count |= (unsigned int)x << ((i - 1) * 6);
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  for (i = 5; i < 9; i++)
Packit 13e0ca
    {
Packit 13e0ca
      x = ascii_to_bin(setting[i]);
Packit 13e0ca
      if (x < 0)
Packit 13e0ca
        {
Packit 13e0ca
          errno = EINVAL;
Packit 13e0ca
          return;
Packit 13e0ca
        }
Packit 13e0ca
      salt |= (unsigned int)x << ((i - 5) * 6);
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  memcpy (cp, setting, 9);
Packit 13e0ca
  cp += 9;
Packit 13e0ca
Packit 13e0ca
  /* Fold passwords longer than 8 bytes into a single DES key using a
Packit 13e0ca
     procedure similar to a Merkle-Dåmgard hash construction.  Each
Packit 13e0ca
     block is shifted and padded, as for the traditional hash, then
Packit 13e0ca
     XORed with the output of the previous round (IV all bits zero),
Packit 13e0ca
     set as the DES key, and encrypted to produce the round output.
Packit 13e0ca
     The salt is zero throughout this procedure.  */
Packit 13e0ca
  des_set_salt (ctx, 0);
Packit 13e0ca
  XCRYPT_SECURE_MEMSET (pkbuf, 8);
Packit 13e0ca
  for (;;)
Packit 13e0ca
    {
Packit 13e0ca
      for (i = 0; i < 8; i++)
Packit 13e0ca
        {
Packit 13e0ca
          keybuf[i] = (uint8_t)(pkbuf[i] ^ (*phrase << 1));
Packit 13e0ca
          if (*phrase)
Packit 13e0ca
            phrase++;
Packit 13e0ca
        }
Packit 13e0ca
      des_set_key (ctx, keybuf);
Packit 13e0ca
      if (*phrase == 0)
Packit 13e0ca
        break;
Packit 13e0ca
      des_crypt_block (ctx, pkbuf, keybuf, 1, false);
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  /* Proceed as for the traditional DES hash.  */
Packit 13e0ca
  des_set_salt (ctx, salt);
Packit 13e0ca
  des_gen_hash (ctx, count, cp, pkbuf);
Packit 13e0ca
}
Packit 13e0ca
#endif
Packit 13e0ca
Packit 13e0ca
#if INCLUDE_des || INCLUDE_des_big
Packit 13e0ca
void
Packit 13e0ca
gensalt_des_rn (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
  if (output_size < 3)
Packit 13e0ca
    {
Packit 13e0ca
      errno = ERANGE;
Packit 13e0ca
      return;
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  if (nrbytes < 2 || (count != 0 && count != 25))
Packit 13e0ca
    {
Packit 13e0ca
      errno = EINVAL;
Packit 13e0ca
      return;
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  output[0] = ascii64[(unsigned int) rbytes[0] & 0x3f];
Packit 13e0ca
  output[1] = ascii64[(unsigned int) rbytes[1] & 0x3f];
Packit 13e0ca
  output[2] = '\0';
Packit 13e0ca
}
Packit 13e0ca
#if INCLUDE_des_big
Packit 13e0ca
strong_alias (gensalt_des_rn, gensalt_des_big_rn);
Packit 13e0ca
#endif
Packit 13e0ca
#endif
Packit 13e0ca
Packit 13e0ca
#if INCLUDE_des_xbsd
Packit 13e0ca
void
Packit 13e0ca
gensalt_des_xbsd_rn (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
  if (output_size < 1 + 4 + 4 + 1)
Packit 13e0ca
    {
Packit 13e0ca
      errno = ERANGE;
Packit 13e0ca
      return;
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  if (count == 0)
Packit 13e0ca
    count = 725;
Packit 13e0ca
Packit 13e0ca
  /* Even iteration counts make it easier to detect weak DES keys from a look
Packit 13e0ca
     at the hash, so they should be avoided.  */
Packit 13e0ca
  if (nrbytes < 3 || count > 0xffffff || count % 2 == 0)
Packit 13e0ca
    {
Packit 13e0ca
      errno = EINVAL;
Packit 13e0ca
      return;
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  unsigned long value =
Packit 13e0ca
    ((unsigned long) (unsigned char) rbytes[0] <<  0) |
Packit 13e0ca
    ((unsigned long) (unsigned char) rbytes[1] <<  8) |
Packit 13e0ca
    ((unsigned long) (unsigned char) rbytes[2] << 16);
Packit 13e0ca
Packit 13e0ca
  output[0] = '_';
Packit 13e0ca
Packit 13e0ca
  output[1] = ascii64[(count >>  0) & 0x3f];
Packit 13e0ca
  output[2] = ascii64[(count >>  6) & 0x3f];
Packit 13e0ca
  output[3] = ascii64[(count >> 12) & 0x3f];
Packit 13e0ca
  output[4] = ascii64[(count >> 18) & 0x3f];
Packit 13e0ca
Packit 13e0ca
  output[5] = ascii64[(value >>  0) & 0x3f];
Packit 13e0ca
  output[6] = ascii64[(value >>  6) & 0x3f];
Packit 13e0ca
  output[7] = ascii64[(value >> 12) & 0x3f];
Packit 13e0ca
  output[8] = ascii64[(value >> 18) & 0x3f];
Packit 13e0ca
Packit 13e0ca
  output[9] = '\0';
Packit 13e0ca
}
Packit 13e0ca
#endif