(root)/
glibc-2.38/
crypt/
sha256-crypt.c
       1  /* One way encryption based on SHA256 sum.
       2     Copyright (C) 2007-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <assert.h>
      20  #include <errno.h>
      21  #include <stdbool.h>
      22  #include <stdlib.h>
      23  #include <string.h>
      24  #include <stdint.h>
      25  #include <sys/param.h>
      26  
      27  #include "sha256.h"
      28  #include "crypt-private.h"
      29  
      30  
      31  #ifdef USE_NSS
      32  typedef int PRBool;
      33  # include <hasht.h>
      34  # include <nsslowhash.h>
      35  
      36  # define sha256_init_ctx(ctxp, nss_ctxp) \
      37    do									      \
      38      {									      \
      39        if (((nss_ctxp = NSSLOWHASH_NewContext (nss_ictx, HASH_AlgSHA256))      \
      40  	   == NULL))							      \
      41  	{								      \
      42  	  if (nss_ctx != NULL)						      \
      43  	    NSSLOWHASH_Destroy (nss_ctx);				      \
      44  	  if (nss_alt_ctx != NULL)					      \
      45  	    NSSLOWHASH_Destroy (nss_alt_ctx);				      \
      46  	  return NULL;							      \
      47  	}								      \
      48        NSSLOWHASH_Begin (nss_ctxp);					      \
      49      }									      \
      50    while (0)
      51  
      52  # define sha256_process_bytes(buf, len, ctxp, nss_ctxp) \
      53    NSSLOWHASH_Update (nss_ctxp, (const unsigned char *) buf, len)
      54  
      55  # define sha256_finish_ctx(ctxp, nss_ctxp, result) \
      56    do									      \
      57      {									      \
      58        unsigned int ret;							      \
      59        NSSLOWHASH_End (nss_ctxp, result, &ret, sizeof (result));		      \
      60        assert (ret == sizeof (result));					      \
      61        NSSLOWHASH_Destroy (nss_ctxp);					      \
      62        nss_ctxp = NULL;							      \
      63      }									      \
      64    while (0)
      65  #else
      66  # define sha256_init_ctx(ctxp, nss_ctxp) \
      67    __sha256_init_ctx (ctxp)
      68  
      69  # define sha256_process_bytes(buf, len, ctxp, nss_ctxp) \
      70    __sha256_process_bytes(buf, len, ctxp)
      71  
      72  # define sha256_finish_ctx(ctxp, nss_ctxp, result) \
      73    __sha256_finish_ctx (ctxp, result)
      74  #endif
      75  
      76  
      77  /* Define our magic string to mark salt for SHA256 "encryption"
      78     replacement.  */
      79  static const char sha256_salt_prefix[] = "$5$";
      80  
      81  /* Prefix for optional rounds specification.  */
      82  static const char sha256_rounds_prefix[] = "rounds=";
      83  
      84  /* Maximum salt string length.  */
      85  #define SALT_LEN_MAX 16
      86  /* Default number of rounds if not explicitly specified.  */
      87  #define ROUNDS_DEFAULT 5000
      88  /* Minimum number of rounds.  */
      89  #define ROUNDS_MIN 1000
      90  /* Maximum number of rounds.  */
      91  #define ROUNDS_MAX 999999999
      92  
      93  
      94  /* Prototypes for local functions.  */
      95  extern char *__sha256_crypt_r (const char *key, const char *salt,
      96  			       char *buffer, int buflen);
      97  extern char *__sha256_crypt (const char *key, const char *salt);
      98  
      99  
     100  char *
     101  __sha256_crypt_r (const char *key, const char *salt, char *buffer, int buflen)
     102  {
     103    unsigned char alt_result[32]
     104      __attribute__ ((__aligned__ (__alignof__ (uint32_t))));
     105    unsigned char temp_result[32]
     106      __attribute__ ((__aligned__ (__alignof__ (uint32_t))));
     107    size_t salt_len;
     108    size_t key_len;
     109    size_t cnt;
     110    char *cp;
     111    char *copied_key = NULL;
     112    char *copied_salt = NULL;
     113    char *p_bytes;
     114    char *s_bytes;
     115    /* Default number of rounds.  */
     116    size_t rounds = ROUNDS_DEFAULT;
     117    bool rounds_custom = false;
     118    size_t alloca_used = 0;
     119    char *free_key = NULL;
     120    char *free_pbytes = NULL;
     121  
     122    /* Find beginning of salt string.  The prefix should normally always
     123       be present.  Just in case it is not.  */
     124    if (strncmp (sha256_salt_prefix, salt, sizeof (sha256_salt_prefix) - 1) == 0)
     125      /* Skip salt prefix.  */
     126      salt += sizeof (sha256_salt_prefix) - 1;
     127  
     128    if (strncmp (salt, sha256_rounds_prefix, sizeof (sha256_rounds_prefix) - 1)
     129        == 0)
     130      {
     131        const char *num = salt + sizeof (sha256_rounds_prefix) - 1;
     132        char *endp;
     133        unsigned long int srounds = strtoul (num, &endp, 10);
     134        if (*endp == '$')
     135  	{
     136  	  salt = endp + 1;
     137  	  rounds = MAX (ROUNDS_MIN, MIN (srounds, ROUNDS_MAX));
     138  	  rounds_custom = true;
     139  	}
     140      }
     141  
     142    salt_len = MIN (strcspn (salt, "$"), SALT_LEN_MAX);
     143    key_len = strlen (key);
     144  
     145    if (((uintptr_t) key) % __alignof__ (uint32_t) != 0)
     146      {
     147        char *tmp;
     148  
     149        if (__libc_use_alloca (alloca_used + key_len + __alignof__ (uint32_t)))
     150  	tmp = alloca_account (key_len + __alignof__ (uint32_t), alloca_used);
     151        else
     152  	{
     153  	  free_key = tmp = (char *) malloc (key_len + __alignof__ (uint32_t));
     154  	  if (tmp == NULL)
     155  	    return NULL;
     156  	}
     157  
     158        key = copied_key =
     159  	memcpy (tmp + __alignof__ (uint32_t)
     160  		- ((uintptr_t) tmp) % __alignof__ (uint32_t),
     161  		key, key_len);
     162        assert (((uintptr_t) key) % __alignof__ (uint32_t) == 0);
     163      }
     164  
     165    if (((uintptr_t) salt) % __alignof__ (uint32_t) != 0)
     166      {
     167        char *tmp = (char *) alloca (salt_len + __alignof__ (uint32_t));
     168        alloca_used += salt_len + __alignof__ (uint32_t);
     169        salt = copied_salt =
     170  	memcpy (tmp + __alignof__ (uint32_t)
     171  		- ((uintptr_t) tmp) % __alignof__ (uint32_t),
     172  		salt, salt_len);
     173        assert (((uintptr_t) salt) % __alignof__ (uint32_t) == 0);
     174      }
     175  
     176  #ifdef USE_NSS
     177    /* Initialize libfreebl3.  */
     178    NSSLOWInitContext *nss_ictx = NSSLOW_Init ();
     179    if (nss_ictx == NULL)
     180      {
     181        free (free_key);
     182        return NULL;
     183      }
     184    NSSLOWHASHContext *nss_ctx = NULL;
     185    NSSLOWHASHContext *nss_alt_ctx = NULL;
     186  #else
     187    struct sha256_ctx ctx;
     188    struct sha256_ctx alt_ctx;
     189  #endif
     190  
     191    /* Prepare for the real work.  */
     192    sha256_init_ctx (&ctx, nss_ctx);
     193  
     194    /* Add the key string.  */
     195    sha256_process_bytes (key, key_len, &ctx, nss_ctx);
     196  
     197    /* The last part is the salt string.  This must be at most 16
     198       characters and it ends at the first `$' character.  */
     199    sha256_process_bytes (salt, salt_len, &ctx, nss_ctx);
     200  
     201  
     202    /* Compute alternate SHA256 sum with input KEY, SALT, and KEY.  The
     203       final result will be added to the first context.  */
     204    sha256_init_ctx (&alt_ctx, nss_alt_ctx);
     205  
     206    /* Add key.  */
     207    sha256_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
     208  
     209    /* Add salt.  */
     210    sha256_process_bytes (salt, salt_len, &alt_ctx, nss_alt_ctx);
     211  
     212    /* Add key again.  */
     213    sha256_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
     214  
     215    /* Now get result of this (32 bytes) and add it to the other
     216       context.  */
     217    sha256_finish_ctx (&alt_ctx, nss_alt_ctx, alt_result);
     218  
     219    /* Add for any character in the key one byte of the alternate sum.  */
     220    for (cnt = key_len; cnt > 32; cnt -= 32)
     221      sha256_process_bytes (alt_result, 32, &ctx, nss_ctx);
     222    sha256_process_bytes (alt_result, cnt, &ctx, nss_ctx);
     223  
     224    /* Take the binary representation of the length of the key and for every
     225       1 add the alternate sum, for every 0 the key.  */
     226    for (cnt = key_len; cnt > 0; cnt >>= 1)
     227      if ((cnt & 1) != 0)
     228        sha256_process_bytes (alt_result, 32, &ctx, nss_ctx);
     229      else
     230        sha256_process_bytes (key, key_len, &ctx, nss_ctx);
     231  
     232    /* Create intermediate result.  */
     233    sha256_finish_ctx (&ctx, nss_ctx, alt_result);
     234  
     235    /* Start computation of P byte sequence.  */
     236    sha256_init_ctx (&alt_ctx, nss_alt_ctx);
     237  
     238    /* For every character in the password add the entire password.  */
     239    for (cnt = 0; cnt < key_len; ++cnt)
     240      sha256_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
     241  
     242    /* Finish the digest.  */
     243    sha256_finish_ctx (&alt_ctx, nss_alt_ctx, temp_result);
     244  
     245    /* Create byte sequence P.  */
     246    if (__libc_use_alloca (alloca_used + key_len))
     247      cp = p_bytes = (char *) alloca (key_len);
     248    else
     249      {
     250        free_pbytes = cp = p_bytes = (char *)malloc (key_len);
     251        if (free_pbytes == NULL)
     252  	{
     253  	  free (free_key);
     254  	  return NULL;
     255  	}
     256      }
     257  
     258    for (cnt = key_len; cnt >= 32; cnt -= 32)
     259      cp = mempcpy (cp, temp_result, 32);
     260    memcpy (cp, temp_result, cnt);
     261  
     262    /* Start computation of S byte sequence.  */
     263    sha256_init_ctx (&alt_ctx, nss_alt_ctx);
     264  
     265    /* For every character in the password add the entire password.  */
     266    for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt)
     267      sha256_process_bytes (salt, salt_len, &alt_ctx, nss_alt_ctx);
     268  
     269    /* Finish the digest.  */
     270    sha256_finish_ctx (&alt_ctx, nss_alt_ctx, temp_result);
     271  
     272    /* Create byte sequence S.  */
     273    cp = s_bytes = alloca (salt_len);
     274    for (cnt = salt_len; cnt >= 32; cnt -= 32)
     275      cp = mempcpy (cp, temp_result, 32);
     276    memcpy (cp, temp_result, cnt);
     277  
     278    /* Repeatedly run the collected hash value through SHA256 to burn
     279       CPU cycles.  */
     280    for (cnt = 0; cnt < rounds; ++cnt)
     281      {
     282        /* New context.  */
     283        sha256_init_ctx (&ctx, nss_ctx);
     284  
     285        /* Add key or last result.  */
     286        if ((cnt & 1) != 0)
     287  	sha256_process_bytes (p_bytes, key_len, &ctx, nss_ctx);
     288        else
     289  	sha256_process_bytes (alt_result, 32, &ctx, nss_ctx);
     290  
     291        /* Add salt for numbers not divisible by 3.  */
     292        if (cnt % 3 != 0)
     293  	sha256_process_bytes (s_bytes, salt_len, &ctx, nss_ctx);
     294  
     295        /* Add key for numbers not divisible by 7.  */
     296        if (cnt % 7 != 0)
     297  	sha256_process_bytes (p_bytes, key_len, &ctx, nss_ctx);
     298  
     299        /* Add key or last result.  */
     300        if ((cnt & 1) != 0)
     301  	sha256_process_bytes (alt_result, 32, &ctx, nss_ctx);
     302        else
     303  	sha256_process_bytes (p_bytes, key_len, &ctx, nss_ctx);
     304  
     305        /* Create intermediate result.  */
     306        sha256_finish_ctx (&ctx, nss_ctx, alt_result);
     307      }
     308  
     309  #ifdef USE_NSS
     310    /* Free libfreebl3 resources. */
     311    NSSLOW_Shutdown (nss_ictx);
     312  #endif
     313  
     314    /* Now we can construct the result string.  It consists of three
     315       parts.  */
     316    cp = __stpncpy (buffer, sha256_salt_prefix, MAX (0, buflen));
     317    buflen -= sizeof (sha256_salt_prefix) - 1;
     318  
     319    if (rounds_custom)
     320      {
     321        int n = __snprintf (cp, MAX (0, buflen), "%s%zu$",
     322  			  sha256_rounds_prefix, rounds);
     323        cp += n;
     324        buflen -= n;
     325      }
     326  
     327    cp = __stpncpy (cp, salt, MIN ((size_t) MAX (0, buflen), salt_len));
     328    buflen -= MIN ((size_t) MAX (0, buflen), salt_len);
     329  
     330    if (buflen > 0)
     331      {
     332        *cp++ = '$';
     333        --buflen;
     334      }
     335  
     336    __b64_from_24bit (&cp, &buflen,
     337  		    alt_result[0], alt_result[10], alt_result[20], 4);
     338    __b64_from_24bit (&cp, &buflen,
     339  		    alt_result[21], alt_result[1], alt_result[11], 4);
     340    __b64_from_24bit (&cp, &buflen,
     341  		    alt_result[12], alt_result[22], alt_result[2], 4);
     342    __b64_from_24bit (&cp, &buflen,
     343  		    alt_result[3], alt_result[13], alt_result[23], 4);
     344    __b64_from_24bit (&cp, &buflen,
     345  		    alt_result[24], alt_result[4], alt_result[14], 4);
     346    __b64_from_24bit (&cp, &buflen,
     347  		    alt_result[15], alt_result[25], alt_result[5], 4);
     348    __b64_from_24bit (&cp, &buflen,
     349  		    alt_result[6], alt_result[16], alt_result[26], 4);
     350    __b64_from_24bit (&cp, &buflen,
     351  		    alt_result[27], alt_result[7], alt_result[17], 4);
     352    __b64_from_24bit (&cp, &buflen,
     353  		    alt_result[18], alt_result[28], alt_result[8], 4);
     354    __b64_from_24bit (&cp, &buflen,
     355  		    alt_result[9], alt_result[19], alt_result[29], 4);
     356    __b64_from_24bit (&cp, &buflen,
     357  		    0, alt_result[31], alt_result[30], 3);
     358    if (buflen <= 0)
     359      {
     360        __set_errno (ERANGE);
     361        buffer = NULL;
     362      }
     363    else
     364      *cp = '\0';		/* Terminate the string.  */
     365  
     366    /* Clear the buffer for the intermediate result so that people
     367       attaching to processes or reading core dumps cannot get any
     368       information.  We do it in this way to clear correct_words[]
     369       inside the SHA256 implementation as well.  */
     370  #ifndef USE_NSS
     371    __sha256_init_ctx (&ctx);
     372    __sha256_finish_ctx (&ctx, alt_result);
     373    explicit_bzero (&ctx, sizeof (ctx));
     374    explicit_bzero (&alt_ctx, sizeof (alt_ctx));
     375  #endif
     376    explicit_bzero (temp_result, sizeof (temp_result));
     377    explicit_bzero (p_bytes, key_len);
     378    explicit_bzero (s_bytes, salt_len);
     379    if (copied_key != NULL)
     380      explicit_bzero (copied_key, key_len);
     381    if (copied_salt != NULL)
     382      explicit_bzero (copied_salt, salt_len);
     383  
     384    free (free_key);
     385    free (free_pbytes);
     386    return buffer;
     387  }
     388  
     389  static char *buffer;
     390  
     391  /* This entry point is equivalent to the `crypt' function in Unix
     392     libcs.  */
     393  char *
     394  __sha256_crypt (const char *key, const char *salt)
     395  {
     396    /* We don't want to have an arbitrary limit in the size of the
     397       password.  We can compute an upper bound for the size of the
     398       result in advance and so we can prepare the buffer we pass to
     399       `sha256_crypt_r'.  */
     400    static int buflen;
     401    int needed = (sizeof (sha256_salt_prefix) - 1
     402  		+ sizeof (sha256_rounds_prefix) + 9 + 1
     403  		+ strlen (salt) + 1 + 43 + 1);
     404  
     405    if (buflen < needed)
     406      {
     407        char *new_buffer = (char *) realloc (buffer, needed);
     408        if (new_buffer == NULL)
     409  	return NULL;
     410  
     411        buffer = new_buffer;
     412        buflen = needed;
     413      }
     414  
     415    return __sha256_crypt_r (key, salt, buffer, buflen);
     416  }
     417  
     418  static void
     419  __attribute__ ((__destructor__))
     420  free_mem (void)
     421  {
     422    free (buffer);
     423  }