Blame crypt/sha256-crypt.c

Packit Service 82fcde
/* One way encryption based on SHA256 sum.
Packit Service 82fcde
   Copyright (C) 2007-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
   Contributed by Ulrich Drepper <drepper@redhat.com>, 2007.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#include <assert.h>
Packit Service 82fcde
#include <errno.h>
Packit Service 82fcde
#include <stdbool.h>
Packit Service 82fcde
#include <stdlib.h>
Packit Service 82fcde
#include <string.h>
Packit Service 82fcde
#include <stdint.h>
Packit Service 82fcde
#include <sys/param.h>
Packit Service 82fcde
Packit Service 82fcde
#include "sha256.h"
Packit Service 82fcde
#include "crypt-private.h"
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
#ifdef USE_NSS
Packit Service 82fcde
typedef int PRBool;
Packit Service 82fcde
# include <hasht.h>
Packit Service 82fcde
# include <nsslowhash.h>
Packit Service 82fcde
Packit Service 82fcde
# define sha256_init_ctx(ctxp, nss_ctxp) \
Packit Service 82fcde
  do									      \
Packit Service 82fcde
    {									      \
Packit Service 82fcde
      if (((nss_ctxp = NSSLOWHASH_NewContext (nss_ictx, HASH_AlgSHA256))      \
Packit Service 82fcde
	   == NULL))							      \
Packit Service 82fcde
	{								      \
Packit Service 82fcde
	  if (nss_ctx != NULL)						      \
Packit Service 82fcde
	    NSSLOWHASH_Destroy (nss_ctx);				      \
Packit Service 82fcde
	  if (nss_alt_ctx != NULL)					      \
Packit Service 82fcde
	    NSSLOWHASH_Destroy (nss_alt_ctx);				      \
Packit Service 82fcde
	  return NULL;							      \
Packit Service 82fcde
	}								      \
Packit Service 82fcde
      NSSLOWHASH_Begin (nss_ctxp);					      \
Packit Service 82fcde
    }									      \
Packit Service 82fcde
  while (0)
Packit Service 82fcde
Packit Service 82fcde
# define sha256_process_bytes(buf, len, ctxp, nss_ctxp) \
Packit Service 82fcde
  NSSLOWHASH_Update (nss_ctxp, (const unsigned char *) buf, len)
Packit Service 82fcde
Packit Service 82fcde
# define sha256_finish_ctx(ctxp, nss_ctxp, result) \
Packit Service 82fcde
  do									      \
Packit Service 82fcde
    {									      \
Packit Service 82fcde
      unsigned int ret;							      \
Packit Service 82fcde
      NSSLOWHASH_End (nss_ctxp, result, &ret, sizeof (result));		      \
Packit Service 82fcde
      assert (ret == sizeof (result));					      \
Packit Service 82fcde
      NSSLOWHASH_Destroy (nss_ctxp);					      \
Packit Service 82fcde
      nss_ctxp = NULL;							      \
Packit Service 82fcde
    }									      \
Packit Service 82fcde
  while (0)
Packit Service 82fcde
#else
Packit Service 82fcde
# define sha256_init_ctx(ctxp, nss_ctxp) \
Packit Service 82fcde
  __sha256_init_ctx (ctxp)
Packit Service 82fcde
Packit Service 82fcde
# define sha256_process_bytes(buf, len, ctxp, nss_ctxp) \
Packit Service 82fcde
  __sha256_process_bytes(buf, len, ctxp)
Packit Service 82fcde
Packit Service 82fcde
# define sha256_finish_ctx(ctxp, nss_ctxp, result) \
Packit Service 82fcde
  __sha256_finish_ctx (ctxp, result)
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Define our magic string to mark salt for SHA256 "encryption"
Packit Service 82fcde
   replacement.  */
Packit Service 82fcde
static const char sha256_salt_prefix[] = "$5$";
Packit Service 82fcde
Packit Service 82fcde
/* Prefix for optional rounds specification.  */
Packit Service 82fcde
static const char sha256_rounds_prefix[] = "rounds=";
Packit Service 82fcde
Packit Service 82fcde
/* Maximum salt string length.  */
Packit Service 82fcde
#define SALT_LEN_MAX 16
Packit Service 82fcde
/* Default number of rounds if not explicitly specified.  */
Packit Service 82fcde
#define ROUNDS_DEFAULT 5000
Packit Service 82fcde
/* Minimum number of rounds.  */
Packit Service 82fcde
#define ROUNDS_MIN 1000
Packit Service 82fcde
/* Maximum number of rounds.  */
Packit Service 82fcde
#define ROUNDS_MAX 999999999
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Prototypes for local functions.  */
Packit Service 82fcde
extern char *__sha256_crypt_r (const char *key, const char *salt,
Packit Service 82fcde
			       char *buffer, int buflen);
Packit Service 82fcde
extern char *__sha256_crypt (const char *key, const char *salt);
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
char *
Packit Service 82fcde
__sha256_crypt_r (const char *key, const char *salt, char *buffer, int buflen)
Packit Service 82fcde
{
Packit Service 82fcde
  unsigned char alt_result[32]
Packit Service 82fcde
    __attribute__ ((__aligned__ (__alignof__ (uint32_t))));
Packit Service 82fcde
  unsigned char temp_result[32]
Packit Service 82fcde
    __attribute__ ((__aligned__ (__alignof__ (uint32_t))));
Packit Service 82fcde
  size_t salt_len;
Packit Service 82fcde
  size_t key_len;
Packit Service 82fcde
  size_t cnt;
Packit Service 82fcde
  char *cp;
Packit Service 82fcde
  char *copied_key = NULL;
Packit Service 82fcde
  char *copied_salt = NULL;
Packit Service 82fcde
  char *p_bytes;
Packit Service 82fcde
  char *s_bytes;
Packit Service 82fcde
  /* Default number of rounds.  */
Packit Service 82fcde
  size_t rounds = ROUNDS_DEFAULT;
Packit Service 82fcde
  bool rounds_custom = false;
Packit Service 82fcde
  size_t alloca_used = 0;
Packit Service 82fcde
  char *free_key = NULL;
Packit Service 82fcde
  char *free_pbytes = NULL;
Packit Service 82fcde
Packit Service 82fcde
  /* Find beginning of salt string.  The prefix should normally always
Packit Service 82fcde
     be present.  Just in case it is not.  */
Packit Service 82fcde
  if (strncmp (sha256_salt_prefix, salt, sizeof (sha256_salt_prefix) - 1) == 0)
Packit Service 82fcde
    /* Skip salt prefix.  */
Packit Service 82fcde
    salt += sizeof (sha256_salt_prefix) - 1;
Packit Service 82fcde
Packit Service 82fcde
  if (strncmp (salt, sha256_rounds_prefix, sizeof (sha256_rounds_prefix) - 1)
Packit Service 82fcde
      == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      const char *num = salt + sizeof (sha256_rounds_prefix) - 1;
Packit Service 82fcde
      char *endp;
Packit Service 82fcde
      unsigned long int srounds = strtoul (num, &endp, 10);
Packit Service 82fcde
      if (*endp == '$')
Packit Service 82fcde
	{
Packit Service 82fcde
	  salt = endp + 1;
Packit Service 82fcde
	  rounds = MAX (ROUNDS_MIN, MIN (srounds, ROUNDS_MAX));
Packit Service 82fcde
	  rounds_custom = true;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  salt_len = MIN (strcspn (salt, "$"), SALT_LEN_MAX);
Packit Service 82fcde
  key_len = strlen (key);
Packit Service 82fcde
Packit Service 82fcde
  if ((key - (char *) 0) % __alignof__ (uint32_t) != 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      char *tmp;
Packit Service 82fcde
Packit Service 82fcde
      if (__libc_use_alloca (alloca_used + key_len + __alignof__ (uint32_t)))
Packit Service 82fcde
	tmp = alloca_account (key_len + __alignof__ (uint32_t), alloca_used);
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  free_key = tmp = (char *) malloc (key_len + __alignof__ (uint32_t));
Packit Service 82fcde
	  if (tmp == NULL)
Packit Service 82fcde
	    return NULL;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      key = copied_key =
Packit Service 82fcde
	memcpy (tmp + __alignof__ (uint32_t)
Packit Service 82fcde
		- (tmp - (char *) 0) % __alignof__ (uint32_t),
Packit Service 82fcde
		key, key_len);
Packit Service 82fcde
      assert ((key - (char *) 0) % __alignof__ (uint32_t) == 0);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if ((salt - (char *) 0) % __alignof__ (uint32_t) != 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      char *tmp = (char *) alloca (salt_len + __alignof__ (uint32_t));
Packit Service 82fcde
      alloca_used += salt_len + __alignof__ (uint32_t);
Packit Service 82fcde
      salt = copied_salt =
Packit Service 82fcde
	memcpy (tmp + __alignof__ (uint32_t)
Packit Service 82fcde
		- (tmp - (char *) 0) % __alignof__ (uint32_t),
Packit Service 82fcde
		salt, salt_len);
Packit Service 82fcde
      assert ((salt - (char *) 0) % __alignof__ (uint32_t) == 0);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
#ifdef USE_NSS
Packit Service 82fcde
  /* Initialize libfreebl3.  */
Packit Service 82fcde
  NSSLOWInitContext *nss_ictx = NSSLOW_Init ();
Packit Service 82fcde
  if (nss_ictx == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      free (free_key);
Packit Service 82fcde
      return NULL;
Packit Service 82fcde
    }
Packit Service 82fcde
  NSSLOWHASHContext *nss_ctx = NULL;
Packit Service 82fcde
  NSSLOWHASHContext *nss_alt_ctx = NULL;
Packit Service 82fcde
#else
Packit Service 82fcde
  struct sha256_ctx ctx;
Packit Service 82fcde
  struct sha256_ctx alt_ctx;
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
  /* Prepare for the real work.  */
Packit Service 82fcde
  sha256_init_ctx (&ctx, nss_ctx);
Packit Service 82fcde
Packit Service 82fcde
  /* Add the key string.  */
Packit Service 82fcde
  sha256_process_bytes (key, key_len, &ctx, nss_ctx);
Packit Service 82fcde
Packit Service 82fcde
  /* The last part is the salt string.  This must be at most 16
Packit Service 82fcde
     characters and it ends at the first `$' character.  */
Packit Service 82fcde
  sha256_process_bytes (salt, salt_len, &ctx, nss_ctx);
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
  /* Compute alternate SHA256 sum with input KEY, SALT, and KEY.  The
Packit Service 82fcde
     final result will be added to the first context.  */
Packit Service 82fcde
  sha256_init_ctx (&alt_ctx, nss_alt_ctx);
Packit Service 82fcde
Packit Service 82fcde
  /* Add key.  */
Packit Service 82fcde
  sha256_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
Packit Service 82fcde
Packit Service 82fcde
  /* Add salt.  */
Packit Service 82fcde
  sha256_process_bytes (salt, salt_len, &alt_ctx, nss_alt_ctx);
Packit Service 82fcde
Packit Service 82fcde
  /* Add key again.  */
Packit Service 82fcde
  sha256_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
Packit Service 82fcde
Packit Service 82fcde
  /* Now get result of this (32 bytes) and add it to the other
Packit Service 82fcde
     context.  */
Packit Service 82fcde
  sha256_finish_ctx (&alt_ctx, nss_alt_ctx, alt_result);
Packit Service 82fcde
Packit Service 82fcde
  /* Add for any character in the key one byte of the alternate sum.  */
Packit Service 82fcde
  for (cnt = key_len; cnt > 32; cnt -= 32)
Packit Service 82fcde
    sha256_process_bytes (alt_result, 32, &ctx, nss_ctx);
Packit Service 82fcde
  sha256_process_bytes (alt_result, cnt, &ctx, nss_ctx);
Packit Service 82fcde
Packit Service 82fcde
  /* Take the binary representation of the length of the key and for every
Packit Service 82fcde
     1 add the alternate sum, for every 0 the key.  */
Packit Service 82fcde
  for (cnt = key_len; cnt > 0; cnt >>= 1)
Packit Service 82fcde
    if ((cnt & 1) != 0)
Packit Service 82fcde
      sha256_process_bytes (alt_result, 32, &ctx, nss_ctx);
Packit Service 82fcde
    else
Packit Service 82fcde
      sha256_process_bytes (key, key_len, &ctx, nss_ctx);
Packit Service 82fcde
Packit Service 82fcde
  /* Create intermediate result.  */
Packit Service 82fcde
  sha256_finish_ctx (&ctx, nss_ctx, alt_result);
Packit Service 82fcde
Packit Service 82fcde
  /* Start computation of P byte sequence.  */
Packit Service 82fcde
  sha256_init_ctx (&alt_ctx, nss_alt_ctx);
Packit Service 82fcde
Packit Service 82fcde
  /* For every character in the password add the entire password.  */
Packit Service 82fcde
  for (cnt = 0; cnt < key_len; ++cnt)
Packit Service 82fcde
    sha256_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
Packit Service 82fcde
Packit Service 82fcde
  /* Finish the digest.  */
Packit Service 82fcde
  sha256_finish_ctx (&alt_ctx, nss_alt_ctx, temp_result);
Packit Service 82fcde
Packit Service 82fcde
  /* Create byte sequence P.  */
Packit Service 82fcde
  if (__libc_use_alloca (alloca_used + key_len))
Packit Service 82fcde
    cp = p_bytes = (char *) alloca (key_len);
Packit Service 82fcde
  else
Packit Service 82fcde
    {
Packit Service 82fcde
      free_pbytes = cp = p_bytes = (char *)malloc (key_len);
Packit Service 82fcde
      if (free_pbytes == NULL)
Packit Service 82fcde
	{
Packit Service 82fcde
	  free (free_key);
Packit Service 82fcde
	  return NULL;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  for (cnt = key_len; cnt >= 32; cnt -= 32)
Packit Service 82fcde
    cp = mempcpy (cp, temp_result, 32);
Packit Service 82fcde
  memcpy (cp, temp_result, cnt);
Packit Service 82fcde
Packit Service 82fcde
  /* Start computation of S byte sequence.  */
Packit Service 82fcde
  sha256_init_ctx (&alt_ctx, nss_alt_ctx);
Packit Service 82fcde
Packit Service 82fcde
  /* For every character in the password add the entire password.  */
Packit Service 82fcde
  for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt)
Packit Service 82fcde
    sha256_process_bytes (salt, salt_len, &alt_ctx, nss_alt_ctx);
Packit Service 82fcde
Packit Service 82fcde
  /* Finish the digest.  */
Packit Service 82fcde
  sha256_finish_ctx (&alt_ctx, nss_alt_ctx, temp_result);
Packit Service 82fcde
Packit Service 82fcde
  /* Create byte sequence S.  */
Packit Service 82fcde
  cp = s_bytes = alloca (salt_len);
Packit Service 82fcde
  for (cnt = salt_len; cnt >= 32; cnt -= 32)
Packit Service 82fcde
    cp = mempcpy (cp, temp_result, 32);
Packit Service 82fcde
  memcpy (cp, temp_result, cnt);
Packit Service 82fcde
Packit Service 82fcde
  /* Repeatedly run the collected hash value through SHA256 to burn
Packit Service 82fcde
     CPU cycles.  */
Packit Service 82fcde
  for (cnt = 0; cnt < rounds; ++cnt)
Packit Service 82fcde
    {
Packit Service 82fcde
      /* New context.  */
Packit Service 82fcde
      sha256_init_ctx (&ctx, nss_ctx);
Packit Service 82fcde
Packit Service 82fcde
      /* Add key or last result.  */
Packit Service 82fcde
      if ((cnt & 1) != 0)
Packit Service 82fcde
	sha256_process_bytes (p_bytes, key_len, &ctx, nss_ctx);
Packit Service 82fcde
      else
Packit Service 82fcde
	sha256_process_bytes (alt_result, 32, &ctx, nss_ctx);
Packit Service 82fcde
Packit Service 82fcde
      /* Add salt for numbers not divisible by 3.  */
Packit Service 82fcde
      if (cnt % 3 != 0)
Packit Service 82fcde
	sha256_process_bytes (s_bytes, salt_len, &ctx, nss_ctx);
Packit Service 82fcde
Packit Service 82fcde
      /* Add key for numbers not divisible by 7.  */
Packit Service 82fcde
      if (cnt % 7 != 0)
Packit Service 82fcde
	sha256_process_bytes (p_bytes, key_len, &ctx, nss_ctx);
Packit Service 82fcde
Packit Service 82fcde
      /* Add key or last result.  */
Packit Service 82fcde
      if ((cnt & 1) != 0)
Packit Service 82fcde
	sha256_process_bytes (alt_result, 32, &ctx, nss_ctx);
Packit Service 82fcde
      else
Packit Service 82fcde
	sha256_process_bytes (p_bytes, key_len, &ctx, nss_ctx);
Packit Service 82fcde
Packit Service 82fcde
      /* Create intermediate result.  */
Packit Service 82fcde
      sha256_finish_ctx (&ctx, nss_ctx, alt_result);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
#ifdef USE_NSS
Packit Service 82fcde
  /* Free libfreebl3 resources. */
Packit Service 82fcde
  NSSLOW_Shutdown (nss_ictx);
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
  /* Now we can construct the result string.  It consists of three
Packit Service 82fcde
     parts.  */
Packit Service 82fcde
  cp = __stpncpy (buffer, sha256_salt_prefix, MAX (0, buflen));
Packit Service 82fcde
  buflen -= sizeof (sha256_salt_prefix) - 1;
Packit Service 82fcde
Packit Service 82fcde
  if (rounds_custom)
Packit Service 82fcde
    {
Packit Service 82fcde
      int n = __snprintf (cp, MAX (0, buflen), "%s%zu$",
Packit Service 82fcde
			  sha256_rounds_prefix, rounds);
Packit Service 82fcde
      cp += n;
Packit Service 82fcde
      buflen -= n;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  cp = __stpncpy (cp, salt, MIN ((size_t) MAX (0, buflen), salt_len));
Packit Service 82fcde
  buflen -= MIN ((size_t) MAX (0, buflen), salt_len);
Packit Service 82fcde
Packit Service 82fcde
  if (buflen > 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      *cp++ = '$';
Packit Service 82fcde
      --buflen;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  __b64_from_24bit (&cp, &buflen,
Packit Service 82fcde
		    alt_result[0], alt_result[10], alt_result[20], 4);
Packit Service 82fcde
  __b64_from_24bit (&cp, &buflen,
Packit Service 82fcde
		    alt_result[21], alt_result[1], alt_result[11], 4);
Packit Service 82fcde
  __b64_from_24bit (&cp, &buflen,
Packit Service 82fcde
		    alt_result[12], alt_result[22], alt_result[2], 4);
Packit Service 82fcde
  __b64_from_24bit (&cp, &buflen,
Packit Service 82fcde
		    alt_result[3], alt_result[13], alt_result[23], 4);
Packit Service 82fcde
  __b64_from_24bit (&cp, &buflen,
Packit Service 82fcde
		    alt_result[24], alt_result[4], alt_result[14], 4);
Packit Service 82fcde
  __b64_from_24bit (&cp, &buflen,
Packit Service 82fcde
		    alt_result[15], alt_result[25], alt_result[5], 4);
Packit Service 82fcde
  __b64_from_24bit (&cp, &buflen,
Packit Service 82fcde
		    alt_result[6], alt_result[16], alt_result[26], 4);
Packit Service 82fcde
  __b64_from_24bit (&cp, &buflen,
Packit Service 82fcde
		    alt_result[27], alt_result[7], alt_result[17], 4);
Packit Service 82fcde
  __b64_from_24bit (&cp, &buflen,
Packit Service 82fcde
		    alt_result[18], alt_result[28], alt_result[8], 4);
Packit Service 82fcde
  __b64_from_24bit (&cp, &buflen,
Packit Service 82fcde
		    alt_result[9], alt_result[19], alt_result[29], 4);
Packit Service 82fcde
  __b64_from_24bit (&cp, &buflen,
Packit Service 82fcde
		    0, alt_result[31], alt_result[30], 3);
Packit Service 82fcde
  if (buflen <= 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      __set_errno (ERANGE);
Packit Service 82fcde
      buffer = NULL;
Packit Service 82fcde
    }
Packit Service 82fcde
  else
Packit Service 82fcde
    *cp = '\0';		/* Terminate the string.  */
Packit Service 82fcde
Packit Service 82fcde
  /* Clear the buffer for the intermediate result so that people
Packit Service 82fcde
     attaching to processes or reading core dumps cannot get any
Packit Service 82fcde
     information.  We do it in this way to clear correct_words[]
Packit Service 82fcde
     inside the SHA256 implementation as well.  */
Packit Service 82fcde
#ifndef USE_NSS
Packit Service 82fcde
  __sha256_init_ctx (&ctx;;
Packit Service 82fcde
  __sha256_finish_ctx (&ctx, alt_result);
Packit Service 82fcde
  explicit_bzero (&ctx, sizeof (ctx));
Packit Service 82fcde
  explicit_bzero (&alt_ctx, sizeof (alt_ctx));
Packit Service 82fcde
#endif
Packit Service 82fcde
  explicit_bzero (temp_result, sizeof (temp_result));
Packit Service 82fcde
  explicit_bzero (p_bytes, key_len);
Packit Service 82fcde
  explicit_bzero (s_bytes, salt_len);
Packit Service 82fcde
  if (copied_key != NULL)
Packit Service 82fcde
    explicit_bzero (copied_key, key_len);
Packit Service 82fcde
  if (copied_salt != NULL)
Packit Service 82fcde
    explicit_bzero (copied_salt, salt_len);
Packit Service 82fcde
Packit Service 82fcde
  free (free_key);
Packit Service 82fcde
  free (free_pbytes);
Packit Service 82fcde
  return buffer;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#ifndef _LIBC
Packit Service 82fcde
# define libc_freeres_ptr(decl) decl
Packit Service 82fcde
#endif
Packit Service 82fcde
libc_freeres_ptr (static char *buffer);
Packit Service 82fcde
Packit Service 82fcde
/* This entry point is equivalent to the `crypt' function in Unix
Packit Service 82fcde
   libcs.  */
Packit Service 82fcde
char *
Packit Service 82fcde
__sha256_crypt (const char *key, const char *salt)
Packit Service 82fcde
{
Packit Service 82fcde
  /* We don't want to have an arbitrary limit in the size of the
Packit Service 82fcde
     password.  We can compute an upper bound for the size of the
Packit Service 82fcde
     result in advance and so we can prepare the buffer we pass to
Packit Service 82fcde
     `sha256_crypt_r'.  */
Packit Service 82fcde
  static int buflen;
Packit Service 82fcde
  int needed = (sizeof (sha256_salt_prefix) - 1
Packit Service 82fcde
		+ sizeof (sha256_rounds_prefix) + 9 + 1
Packit Service 82fcde
		+ strlen (salt) + 1 + 43 + 1);
Packit Service 82fcde
Packit Service 82fcde
  if (buflen < needed)
Packit Service 82fcde
    {
Packit Service 82fcde
      char *new_buffer = (char *) realloc (buffer, needed);
Packit Service 82fcde
      if (new_buffer == NULL)
Packit Service 82fcde
	return NULL;
Packit Service 82fcde
Packit Service 82fcde
      buffer = new_buffer;
Packit Service 82fcde
      buflen = needed;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return __sha256_crypt_r (key, salt, buffer, buflen);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#ifndef _LIBC
Packit Service 82fcde
static void
Packit Service 82fcde
__attribute__ ((__destructor__))
Packit Service 82fcde
free_mem (void)
Packit Service 82fcde
{
Packit Service 82fcde
  free (buffer);
Packit Service 82fcde
}
Packit Service 82fcde
#endif