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.  */
35 static const char sha256_salt_prefix[] = "$5$";
36 
37 /* Prefix for optional rounds specification.  */
38 static 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 
60 static_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.  */
64 struct 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 
72 static_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 */
77 static int errno;
78 
79 void 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 
crypt_sha256crypt_rn_wrapped(const char * phrase,size_t phr_size,const char * setting,size_t set_size,u8 * output,size_t out_size,void * scratch,size_t scr_size)84 int 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.  */
97 static void
SHA256_Update_recycled(SHA256_CTX * ctx,unsigned char block[32],size_t len)98 SHA256_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 
107 void
crypt_sha256crypt_rn(const char * phrase,size_t phr_size,const char * setting,size_t ARG_UNUSED (set_size),uint8_t * output,size_t out_size,void * scratch,size_t scr_size)108 crypt_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 
325 void
gensalt_sha256crypt_rn(unsigned long count,const uint8_t * rbytes,size_t nrbytes,uint8_t * output,size_t output_size)326 gensalt_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