blob: 824e24e190b139c6b19c36f60b3f2fdd71b255ce [file] [log] [blame]
Steffen Jaeckel878c91b2021-07-08 15:57:34 +02001// SPDX-License-Identifier: CC0-1.0
2/* Based on libxcrypt v4.4.17-0-g6b110bc */
Steffen Jaeckel229bd512021-07-08 15:57:33 +02003/* 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.
Steffen Jaeckel878c91b2021-07-08 15:57:34 +02009 * 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.
Steffen Jaeckel229bd512021-07-08 15:57:33 +020012 * 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
Steffen Jaeckel878c91b2021-07-08 15:57:34 +020027#include <linux/errno.h>
Steffen Jaeckel229bd512021-07-08 15:57:33 +020028#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
Steffen Jaeckel878c91b2021-07-08 15:57:34 +020075/* Use this instead of including errno.h */
76static int errno;
77
78void crypt_sha256crypt_rn(const char *phrase, size_t phr_size,
79 const char *setting, size_t ARG_UNUSED(set_size),
80 uint8_t *output, size_t out_size, void *scratch,
81 size_t scr_size);
82
83int crypt_sha256crypt_rn_wrapped(const char *phrase, size_t phr_size,
84 const char *setting, size_t set_size,
85 u8 *output, size_t out_size, void *scratch,
86 size_t scr_size)
87{
88 errno = 0;
89 crypt_sha256crypt_rn(phrase, phr_size, setting, set_size, output,
90 out_size, scratch, scr_size);
91 return -errno;
92}
93
Steffen Jaeckel229bd512021-07-08 15:57:33 +020094/* Feed CTX with LEN bytes of a virtual byte sequence consisting of
95 BLOCK repeated over and over indefinitely. */
96static void
97SHA256_Update_recycled (SHA256_CTX *ctx,
98 unsigned char block[32], size_t len)
99{
100 size_t cnt;
101 for (cnt = len; cnt >= 32; cnt -= 32)
102 SHA256_Update (ctx, block, 32);
103 SHA256_Update (ctx, block, cnt);
104}
105
106void
107crypt_sha256crypt_rn (const char *phrase, size_t phr_size,
108 const char *setting, size_t ARG_UNUSED (set_size),
109 uint8_t *output, size_t out_size,
110 void *scratch, size_t scr_size)
111{
112 /* This shouldn't ever happen, but... */
113 if (out_size < SHA256_HASH_LENGTH
114 || scr_size < sizeof (struct sha256_buffer))
115 {
116 errno = ERANGE;
117 return;
118 }
119
120 struct sha256_buffer *buf = scratch;
121 SHA256_CTX *ctx = &buf->ctx;
122 uint8_t *result = buf->result;
123 uint8_t *p_bytes = buf->p_bytes;
124 uint8_t *s_bytes = buf->s_bytes;
125 char *cp = (char *)output;
126 const char *salt = setting;
127
128 size_t salt_size;
129 size_t cnt;
130 /* Default number of rounds. */
131 size_t rounds = ROUNDS_DEFAULT;
132 bool rounds_custom = false;
133
134 /* Find beginning of salt string. The prefix should normally always
135 be present. Just in case it is not. */
136 if (strncmp (sha256_salt_prefix, salt, sizeof (sha256_salt_prefix) - 1) == 0)
137 /* Skip salt prefix. */
138 salt += sizeof (sha256_salt_prefix) - 1;
139
140 if (strncmp (salt, sha256_rounds_prefix, sizeof (sha256_rounds_prefix) - 1)
141 == 0)
142 {
143 const char *num = salt + sizeof (sha256_rounds_prefix) - 1;
144 /* Do not allow an explicit setting of zero rounds, nor of the
145 default number of rounds, nor leading zeroes on the rounds. */
146 if (!(*num >= '1' && *num <= '9'))
147 {
148 errno = EINVAL;
149 return;
150 }
151
152 errno = 0;
153 char *endp;
154 rounds = strtoul (num, &endp, 10);
155 if (endp == num || *endp != '$'
156 || rounds < ROUNDS_MIN
157 || rounds > ROUNDS_MAX
158 || errno)
159 {
160 errno = EINVAL;
161 return;
162 }
163 salt = endp + 1;
164 rounds_custom = true;
165 }
166
167 /* The salt ends at the next '$' or the end of the string.
168 Ensure ':' does not appear in the salt (it is used as a separator in /etc/passwd).
169 Also check for '\n', as in /etc/passwd the whole parameters of the user data must
170 be on a single line. */
171 salt_size = strcspn (salt, "$:\n");
172 if (!(salt[salt_size] == '$' || !salt[salt_size]))
173 {
174 errno = EINVAL;
175 return;
176 }
177
178 /* Ensure we do not use more salt than SALT_LEN_MAX. */
179 if (salt_size > SALT_LEN_MAX)
180 salt_size = SALT_LEN_MAX;
181
182 /* Compute alternate SHA256 sum with input PHRASE, SALT, and PHRASE. The
183 final result will be added to the first context. */
184 SHA256_Init (ctx);
185
186 /* Add phrase. */
187 SHA256_Update (ctx, phrase, phr_size);
188
189 /* Add salt. */
190 SHA256_Update (ctx, salt, salt_size);
191
192 /* Add phrase again. */
193 SHA256_Update (ctx, phrase, phr_size);
194
195 /* Now get result of this (32 bytes). */
196 SHA256_Final (result, ctx);
197
198 /* Prepare for the real work. */
199 SHA256_Init (ctx);
200
201 /* Add the phrase string. */
202 SHA256_Update (ctx, phrase, phr_size);
203
204 /* The last part is the salt string. This must be at most 8
205 characters and it ends at the first `$' character (for
206 compatibility with existing implementations). */
207 SHA256_Update (ctx, salt, salt_size);
208
209 /* Add for any character in the phrase one byte of the alternate sum. */
210 for (cnt = phr_size; cnt > 32; cnt -= 32)
211 SHA256_Update (ctx, result, 32);
212 SHA256_Update (ctx, result, cnt);
213
214 /* Take the binary representation of the length of the phrase and for every
215 1 add the alternate sum, for every 0 the phrase. */
216 for (cnt = phr_size; cnt > 0; cnt >>= 1)
217 if ((cnt & 1) != 0)
218 SHA256_Update (ctx, result, 32);
219 else
220 SHA256_Update (ctx, phrase, phr_size);
221
222 /* Create intermediate result. */
223 SHA256_Final (result, ctx);
224
225 /* Start computation of P byte sequence. */
226 SHA256_Init (ctx);
227
228 /* For every character in the password add the entire password. */
229 for (cnt = 0; cnt < phr_size; ++cnt)
230 SHA256_Update (ctx, phrase, phr_size);
231
232 /* Finish the digest. */
233 SHA256_Final (p_bytes, ctx);
234
235 /* Start computation of S byte sequence. */
236 SHA256_Init (ctx);
237
238 /* For every character in the password add the entire password. */
239 for (cnt = 0; cnt < (size_t) 16 + (size_t) result[0]; ++cnt)
240 SHA256_Update (ctx, salt, salt_size);
241
242 /* Finish the digest. */
243 SHA256_Final (s_bytes, ctx);
244
245 /* Repeatedly run the collected hash value through SHA256 to burn
246 CPU cycles. */
247 for (cnt = 0; cnt < rounds; ++cnt)
248 {
249 /* New context. */
250 SHA256_Init (ctx);
251
252 /* Add phrase or last result. */
253 if ((cnt & 1) != 0)
254 SHA256_Update_recycled (ctx, p_bytes, phr_size);
255 else
256 SHA256_Update (ctx, result, 32);
257
258 /* Add salt for numbers not divisible by 3. */
259 if (cnt % 3 != 0)
260 SHA256_Update_recycled (ctx, s_bytes, salt_size);
261
262 /* Add phrase for numbers not divisible by 7. */
263 if (cnt % 7 != 0)
264 SHA256_Update_recycled (ctx, p_bytes, phr_size);
265
266 /* Add phrase or last result. */
267 if ((cnt & 1) != 0)
268 SHA256_Update (ctx, result, 32);
269 else
270 SHA256_Update_recycled (ctx, p_bytes, phr_size);
271
272 /* Create intermediate result. */
273 SHA256_Final (result, ctx);
274 }
275
276 /* Now we can construct the result string. It consists of four
277 parts, one of which is optional. We already know that there
278 is sufficient space at CP for the longest possible result string. */
279 memcpy (cp, sha256_salt_prefix, sizeof (sha256_salt_prefix) - 1);
280 cp += sizeof (sha256_salt_prefix) - 1;
281
282 if (rounds_custom)
283 {
284 int n = snprintf (cp,
285 SHA256_HASH_LENGTH - (sizeof (sha256_salt_prefix) - 1),
286 "%s%zu$", sha256_rounds_prefix, rounds);
287 cp += n;
288 }
289
290 memcpy (cp, salt, salt_size);
291 cp += salt_size;
292 *cp++ = '$';
293
294#define b64_from_24bit(B2, B1, B0, N) \
295 do { \
296 unsigned int w = ((((unsigned int)(B2)) << 16) | \
297 (((unsigned int)(B1)) << 8) | \
298 ((unsigned int)(B0))); \
299 int n = (N); \
300 while (n-- > 0) \
301 { \
302 *cp++ = b64t[w & 0x3f]; \
303 w >>= 6; \
304 } \
305 } while (0)
306
307 b64_from_24bit (result[0], result[10], result[20], 4);
308 b64_from_24bit (result[21], result[1], result[11], 4);
309 b64_from_24bit (result[12], result[22], result[2], 4);
310 b64_from_24bit (result[3], result[13], result[23], 4);
311 b64_from_24bit (result[24], result[4], result[14], 4);
312 b64_from_24bit (result[15], result[25], result[5], 4);
313 b64_from_24bit (result[6], result[16], result[26], 4);
314 b64_from_24bit (result[27], result[7], result[17], 4);
315 b64_from_24bit (result[18], result[28], result[8], 4);
316 b64_from_24bit (result[9], result[19], result[29], 4);
317 b64_from_24bit (0, result[31], result[30], 3);
318
319 *cp = '\0';
320}
321
322#ifndef NO_GENSALT
323
324void
325gensalt_sha256crypt_rn (unsigned long count,
326 const uint8_t *rbytes, size_t nrbytes,
327 uint8_t *output, size_t output_size)
328{
329 gensalt_sha_rn ('5', SALT_LEN_MAX, ROUNDS_DEFAULT, ROUNDS_MIN, ROUNDS_MAX,
330 count, rbytes, nrbytes, output, output_size);
331}
332
333#endif
334
335#endif