1// SPDX-License-Identifier: CC0-1.0
2/* Based on libxcrypt v4.4.17-0-g6b110bc */
3/* One way encryption based on the SHA256-based Unix crypt implementation.
4 *
5 * Written by Ulrich Drepper <drepper at redhat.com> in 2007 [1].
6 * Modified by Zack Weinberg <zackw at panix.com> in 2017, 2018.
7 * Composed by Bj��rn Esser <besser82 at fedoraproject.org> in 2018.
8 * Modified by Bj��rn Esser <besser82 at fedoraproject.org> in 2020.
9 * Modified by Steffen Jaeckel <jaeckel-floss at eyet-services.de> in 2021
10 * for U-Boot, instead of using the global errno to use a static one
11 * inside this file.
12 * To the extent possible under law, the named authors have waived all
13 * copyright and related or neighboring rights to this work.
14 *
15 * See https://creativecommons.org/publicdomain/zero/1.0/ for further
16 * details.
17 *
18 * This file is a modified except from [2], lines 648 up to 909.
19 *
20 * [1]  https://www.akkadia.org/drepper/sha-crypt.html
21 * [2]  https://www.akkadia.org/drepper/SHA-crypt.txt
22 */
23
24#include "crypt-port.h"
25#include "alg-sha256.h"
26
27#include <linux/errno.h>
28#include <stdio.h>
29#include <stdlib.h>
30
31#if INCLUDE_sha256crypt
32
33/* Define our magic string to mark salt for SHA256 "encryption"
34   replacement.  */
35static const char sha256_salt_prefix[] = "$5$";
36
37/* Prefix for optional rounds specification.  */
38static const char sha256_rounds_prefix[] = "rounds=";
39
40/* Maximum salt string length.  */
41#define SALT_LEN_MAX 16
42/* Default number of rounds if not explicitly specified.  */
43#define ROUNDS_DEFAULT 5000
44/* Minimum number of rounds.  */
45#define ROUNDS_MIN 1000
46/* Maximum number of rounds.  */
47#define ROUNDS_MAX 999999999
48
49/* The maximum possible length of a SHA256-hashed password string,
50   including the terminating NUL character.  Prefix (including its NUL)
51   + rounds tag ("rounds=$" = "rounds=\0") + strlen(ROUNDS_MAX)
52   + salt (up to SALT_LEN_MAX chars) + '$' + hash (43 chars).  */
53
54#define LENGTH_OF_NUMBER(n) (sizeof #n - 1)
55
56#define SHA256_HASH_LENGTH \
57  (sizeof (sha256_salt_prefix) + sizeof (sha256_rounds_prefix) + \
58   LENGTH_OF_NUMBER (ROUNDS_MAX) + SALT_LEN_MAX + 1 + 43)
59
60static_assert (SHA256_HASH_LENGTH <= CRYPT_OUTPUT_SIZE,
61               "CRYPT_OUTPUT_SIZE is too small for SHA256");
62
63/* A sha256_buffer holds all of the sensitive intermediate data.  */
64struct sha256_buffer
65{
66  SHA256_CTX ctx;
67  uint8_t result[32];
68  uint8_t p_bytes[32];
69  uint8_t s_bytes[32];
70};
71
72static_assert (sizeof (struct sha256_buffer) <= ALG_SPECIFIC_SIZE,
73               "ALG_SPECIFIC_SIZE is too small for SHA256");
74
75
76/* Use this instead of including errno.h */
77static int errno;
78
79void crypt_sha256crypt_rn(const char *phrase, size_t phr_size,
80			  const char *setting, size_t ARG_UNUSED(set_size),
81			  uint8_t *output, size_t out_size, void *scratch,
82			  size_t scr_size);
83
84int crypt_sha256crypt_rn_wrapped(const char *phrase, size_t phr_size,
85				 const char *setting, size_t set_size,
86				 u8 *output, size_t out_size, void *scratch,
87				 size_t scr_size)
88{
89	errno = 0;
90	crypt_sha256crypt_rn(phrase, phr_size, setting, set_size, output,
91			     out_size, scratch, scr_size);
92	return -errno;
93}
94
95/* Feed CTX with LEN bytes of a virtual byte sequence consisting of
96   BLOCK repeated over and over indefinitely.  */
97static void
98SHA256_Update_recycled (SHA256_CTX *ctx,
99                        unsigned char block[32], size_t len)
100{
101  size_t cnt;
102  for (cnt = len; cnt >= 32; cnt -= 32)
103    SHA256_Update (ctx, block, 32);
104  SHA256_Update (ctx, block, cnt);
105}
106
107void
108crypt_sha256crypt_rn (const char *phrase, size_t phr_size,
109                      const char *setting, size_t ARG_UNUSED (set_size),
110                      uint8_t *output, size_t out_size,
111                      void *scratch, size_t scr_size)
112{
113  /* This shouldn't ever happen, but...  */
114  if (out_size < SHA256_HASH_LENGTH
115      || scr_size < sizeof (struct sha256_buffer))
116    {
117      errno = ERANGE;
118      return;
119    }
120
121  struct sha256_buffer *buf = scratch;
122  SHA256_CTX *ctx = &buf->ctx;
123  uint8_t *result = buf->result;
124  uint8_t *p_bytes = buf->p_bytes;
125  uint8_t *s_bytes = buf->s_bytes;
126  char *cp = (char *)output;
127  const char *salt = setting;
128
129  size_t salt_size;
130  size_t cnt;
131  /* Default number of rounds.  */
132  size_t rounds = ROUNDS_DEFAULT;
133  bool rounds_custom = false;
134
135  /* Find beginning of salt string.  The prefix should normally always
136     be present.  Just in case it is not.  */
137  if (strncmp (sha256_salt_prefix, salt, sizeof (sha256_salt_prefix) - 1) == 0)
138    /* Skip salt prefix.  */
139    salt += sizeof (sha256_salt_prefix) - 1;
140
141  if (strncmp (salt, sha256_rounds_prefix, sizeof (sha256_rounds_prefix) - 1)
142      == 0)
143    {
144      const char *num = salt + sizeof (sha256_rounds_prefix) - 1;
145      /* Do not allow an explicit setting of zero rounds, nor of the
146         default number of rounds, nor leading zeroes on the rounds.  */
147      if (!(*num >= '1' && *num <= '9'))
148        {
149          errno = EINVAL;
150          return;
151        }
152
153      errno = 0;
154      char *endp;
155      rounds = strtoul (num, &endp, 10);
156      if (endp == num || *endp != '$'
157          || rounds < ROUNDS_MIN
158          || rounds > ROUNDS_MAX
159          || errno)
160        {
161          errno = EINVAL;
162          return;
163        }
164      salt = endp + 1;
165      rounds_custom = true;
166    }
167
168  /* The salt ends at the next '$' or the end of the string.
169     Ensure ':' does not appear in the salt (it is used as a separator in /etc/passwd).
170     Also check for '\n', as in /etc/passwd the whole parameters of the user data must
171     be on a single line. */
172  salt_size = strcspn (salt, "$:\n");
173  if (!(salt[salt_size] == '$' || !salt[salt_size]))
174    {
175      errno = EINVAL;
176      return;
177    }
178
179  /* Ensure we do not use more salt than SALT_LEN_MAX. */
180  if (salt_size > SALT_LEN_MAX)
181    salt_size = SALT_LEN_MAX;
182
183  /* Compute alternate SHA256 sum with input PHRASE, SALT, and PHRASE.  The
184     final result will be added to the first context.  */
185  SHA256_Init (ctx);
186
187  /* Add phrase.  */
188  SHA256_Update (ctx, phrase, phr_size);
189
190  /* Add salt.  */
191  SHA256_Update (ctx, salt, salt_size);
192
193  /* Add phrase again.  */
194  SHA256_Update (ctx, phrase, phr_size);
195
196  /* Now get result of this (32 bytes).  */
197  SHA256_Final (result, ctx);
198
199  /* Prepare for the real work.  */
200  SHA256_Init (ctx);
201
202  /* Add the phrase string.  */
203  SHA256_Update (ctx, phrase, phr_size);
204
205  /* The last part is the salt string.  This must be at most 8
206     characters and it ends at the first `$' character (for
207     compatibility with existing implementations).  */
208  SHA256_Update (ctx, salt, salt_size);
209
210  /* Add for any character in the phrase one byte of the alternate sum.  */
211  for (cnt = phr_size; cnt > 32; cnt -= 32)
212    SHA256_Update (ctx, result, 32);
213  SHA256_Update (ctx, result, cnt);
214
215  /* Take the binary representation of the length of the phrase and for every
216     1 add the alternate sum, for every 0 the phrase.  */
217  for (cnt = phr_size; cnt > 0; cnt >>= 1)
218    if ((cnt & 1) != 0)
219      SHA256_Update (ctx, result, 32);
220    else
221      SHA256_Update (ctx, phrase, phr_size);
222
223  /* Create intermediate result.  */
224  SHA256_Final (result, ctx);
225
226  /* Start computation of P byte sequence.  */
227  SHA256_Init (ctx);
228
229  /* For every character in the password add the entire password.  */
230  for (cnt = 0; cnt < phr_size; ++cnt)
231    SHA256_Update (ctx, phrase, phr_size);
232
233  /* Finish the digest.  */
234  SHA256_Final (p_bytes, ctx);
235
236  /* Start computation of S byte sequence.  */
237  SHA256_Init (ctx);
238
239  /* For every character in the password add the entire password.  */
240  for (cnt = 0; cnt < (size_t) 16 + (size_t) result[0]; ++cnt)
241    SHA256_Update (ctx, salt, salt_size);
242
243  /* Finish the digest.  */
244  SHA256_Final (s_bytes, ctx);
245
246  /* Repeatedly run the collected hash value through SHA256 to burn
247     CPU cycles.  */
248  for (cnt = 0; cnt < rounds; ++cnt)
249    {
250      /* New context.  */
251      SHA256_Init (ctx);
252
253      /* Add phrase or last result.  */
254      if ((cnt & 1) != 0)
255        SHA256_Update_recycled (ctx, p_bytes, phr_size);
256      else
257        SHA256_Update (ctx, result, 32);
258
259      /* Add salt for numbers not divisible by 3.  */
260      if (cnt % 3 != 0)
261        SHA256_Update_recycled (ctx, s_bytes, salt_size);
262
263      /* Add phrase for numbers not divisible by 7.  */
264      if (cnt % 7 != 0)
265        SHA256_Update_recycled (ctx, p_bytes, phr_size);
266
267      /* Add phrase or last result.  */
268      if ((cnt & 1) != 0)
269        SHA256_Update (ctx, result, 32);
270      else
271        SHA256_Update_recycled (ctx, p_bytes, phr_size);
272
273      /* Create intermediate result.  */
274      SHA256_Final (result, ctx);
275    }
276
277  /* Now we can construct the result string.  It consists of four
278     parts, one of which is optional.  We already know that there
279     is sufficient space at CP for the longest possible result string.  */
280  memcpy (cp, sha256_salt_prefix, sizeof (sha256_salt_prefix) - 1);
281  cp += sizeof (sha256_salt_prefix) - 1;
282
283  if (rounds_custom)
284    {
285      int n = snprintf (cp,
286                        SHA256_HASH_LENGTH - (sizeof (sha256_salt_prefix) - 1),
287                        "%s%zu$", sha256_rounds_prefix, rounds);
288      cp += n;
289    }
290
291  memcpy (cp, salt, salt_size);
292  cp += salt_size;
293  *cp++ = '$';
294
295#define b64_from_24bit(B2, B1, B0, N)                   \
296  do {                                                  \
297    unsigned int w = ((((unsigned int)(B2)) << 16) |    \
298                      (((unsigned int)(B1)) << 8) |     \
299                      ((unsigned int)(B0)));            \
300    int n = (N);                                        \
301    while (n-- > 0)                                     \
302      {                                                 \
303        *cp++ = b64t[w & 0x3f];                         \
304        w >>= 6;                                        \
305      }                                                 \
306  } while (0)
307
308  b64_from_24bit (result[0], result[10], result[20], 4);
309  b64_from_24bit (result[21], result[1], result[11], 4);
310  b64_from_24bit (result[12], result[22], result[2], 4);
311  b64_from_24bit (result[3], result[13], result[23], 4);
312  b64_from_24bit (result[24], result[4], result[14], 4);
313  b64_from_24bit (result[15], result[25], result[5], 4);
314  b64_from_24bit (result[6], result[16], result[26], 4);
315  b64_from_24bit (result[27], result[7], result[17], 4);
316  b64_from_24bit (result[18], result[28], result[8], 4);
317  b64_from_24bit (result[9], result[19], result[29], 4);
318  b64_from_24bit (0, result[31], result[30], 3);
319
320  *cp = '\0';
321}
322
323#ifndef NO_GENSALT
324
325void
326gensalt_sha256crypt_rn (unsigned long count,
327                        const uint8_t *rbytes, size_t nrbytes,
328                        uint8_t *output, size_t output_size)
329{
330  gensalt_sha_rn ('5', SALT_LEN_MAX, ROUNDS_DEFAULT, ROUNDS_MIN, ROUNDS_MAX,
331                  count, rbytes, nrbytes, output, output_size);
332}
333
334#endif
335
336#endif
337