blob: 335c8880d816f3da25c1897e7a067cb818f77765 [file] [log] [blame]
Steffen Jaeckel29bbe712021-07-08 15:57:34 +02001// SPDX-License-Identifier: CC0-1.0
2/* Based on libxcrypt v4.4.17-0-g6b110bc */
Steffen Jaeckel26dd9932021-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 Jaeckel29bbe712021-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 Jaeckel26dd9932021-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 Jaeckel29bbe712021-07-08 15:57:34 +020027#include <linux/errno.h>
Steffen Jaeckel26dd9932021-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
75
Steffen Jaeckel29bbe712021-07-08 15:57:34 +020076/* 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
Steffen Jaeckel26dd9932021-07-08 15:57:33 +020095/* 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