]> Git Repo - J-u-boot.git/blob - lib/crypt/crypt-sha256.c
efi_loader: efi_dp_from_lo() should skip VenMedia node
[J-u-boot.git] / lib / crypt / crypt-sha256.c
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
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
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
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
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
This page took 0.04432 seconds and 4 git commands to generate.