Regenerate configure.
[glibc.git] / crypt / sha512-crypt.c
blob9deb31ce99fbdc58e31a47b0788e2d58a8c8966b
1 /* One way encryption based on SHA512 sum.
2 Copyright (C) 2007-2023 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 #include <assert.h>
20 #include <errno.h>
21 #include <stdbool.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdint.h>
25 #include <sys/param.h>
27 #include "sha512.h"
28 #include "crypt-private.h"
31 #ifdef USE_NSS
32 typedef int PRBool;
33 # include <hasht.h>
34 # include <nsslowhash.h>
36 # define sha512_init_ctx(ctxp, nss_ctxp) \
37 do \
38 { \
39 if (((nss_ctxp = NSSLOWHASH_NewContext (nss_ictx, HASH_AlgSHA512)) \
40 == NULL)) \
41 { \
42 if (nss_ctx != NULL) \
43 NSSLOWHASH_Destroy (nss_ctx); \
44 if (nss_alt_ctx != NULL) \
45 NSSLOWHASH_Destroy (nss_alt_ctx); \
46 return NULL; \
47 } \
48 NSSLOWHASH_Begin (nss_ctxp); \
49 } \
50 while (0)
52 # define sha512_process_bytes(buf, len, ctxp, nss_ctxp) \
53 NSSLOWHASH_Update (nss_ctxp, (const unsigned char *) buf, len)
55 # define sha512_finish_ctx(ctxp, nss_ctxp, result) \
56 do \
57 { \
58 unsigned int ret; \
59 NSSLOWHASH_End (nss_ctxp, result, &ret, sizeof (result)); \
60 assert (ret == sizeof (result)); \
61 NSSLOWHASH_Destroy (nss_ctxp); \
62 nss_ctxp = NULL; \
63 } \
64 while (0)
65 #else
66 # define sha512_init_ctx(ctxp, nss_ctxp) \
67 __sha512_init_ctx (ctxp)
69 # define sha512_process_bytes(buf, len, ctxp, nss_ctxp) \
70 __sha512_process_bytes(buf, len, ctxp)
72 # define sha512_finish_ctx(ctxp, nss_ctxp, result) \
73 __sha512_finish_ctx (ctxp, result)
74 #endif
77 /* Define our magic string to mark salt for SHA512 "encryption"
78 replacement. */
79 static const char sha512_salt_prefix[] = "$6$";
81 /* Prefix for optional rounds specification. */
82 static const char sha512_rounds_prefix[] = "rounds=";
84 /* Maximum salt string length. */
85 #define SALT_LEN_MAX 16
86 /* Default number of rounds if not explicitly specified. */
87 #define ROUNDS_DEFAULT 5000
88 /* Minimum number of rounds. */
89 #define ROUNDS_MIN 1000
90 /* Maximum number of rounds. */
91 #define ROUNDS_MAX 999999999
94 /* Prototypes for local functions. */
95 extern char *__sha512_crypt_r (const char *key, const char *salt,
96 char *buffer, int buflen);
97 extern char *__sha512_crypt (const char *key, const char *salt);
100 char *
101 __sha512_crypt_r (const char *key, const char *salt, char *buffer, int buflen)
103 unsigned char alt_result[64]
104 __attribute__ ((__aligned__ (__alignof__ (uint64_t))));
105 unsigned char temp_result[64]
106 __attribute__ ((__aligned__ (__alignof__ (uint64_t))));
107 size_t salt_len;
108 size_t key_len;
109 size_t cnt;
110 char *cp;
111 char *copied_key = NULL;
112 char *copied_salt = NULL;
113 char *p_bytes;
114 char *s_bytes;
115 /* Default number of rounds. */
116 size_t rounds = ROUNDS_DEFAULT;
117 bool rounds_custom = false;
118 size_t alloca_used = 0;
119 char *free_key = NULL;
120 char *free_pbytes = NULL;
122 /* Find beginning of salt string. The prefix should normally always
123 be present. Just in case it is not. */
124 if (strncmp (sha512_salt_prefix, salt, sizeof (sha512_salt_prefix) - 1) == 0)
125 /* Skip salt prefix. */
126 salt += sizeof (sha512_salt_prefix) - 1;
128 if (strncmp (salt, sha512_rounds_prefix, sizeof (sha512_rounds_prefix) - 1)
129 == 0)
131 const char *num = salt + sizeof (sha512_rounds_prefix) - 1;
132 char *endp;
133 unsigned long int srounds = strtoul (num, &endp, 10);
134 if (*endp == '$')
136 salt = endp + 1;
137 rounds = MAX (ROUNDS_MIN, MIN (srounds, ROUNDS_MAX));
138 rounds_custom = true;
142 salt_len = MIN (strcspn (salt, "$"), SALT_LEN_MAX);
143 key_len = strlen (key);
145 if ((key - (char *) 0) % __alignof__ (uint64_t) != 0)
147 char *tmp;
149 if (__libc_use_alloca (alloca_used + key_len + __alignof__ (uint64_t)))
150 tmp = alloca_account (key_len + __alignof__ (uint64_t), alloca_used);
151 else
153 free_key = tmp = (char *) malloc (key_len + __alignof__ (uint64_t));
154 if (tmp == NULL)
155 return NULL;
158 key = copied_key =
159 memcpy (tmp + __alignof__ (uint64_t)
160 - (tmp - (char *) 0) % __alignof__ (uint64_t),
161 key, key_len);
162 assert ((key - (char *) 0) % __alignof__ (uint64_t) == 0);
165 if ((salt - (char *) 0) % __alignof__ (uint64_t) != 0)
167 char *tmp = (char *) alloca (salt_len + __alignof__ (uint64_t));
168 salt = copied_salt =
169 memcpy (tmp + __alignof__ (uint64_t)
170 - (tmp - (char *) 0) % __alignof__ (uint64_t),
171 salt, salt_len);
172 assert ((salt - (char *) 0) % __alignof__ (uint64_t) == 0);
175 #ifdef USE_NSS
176 /* Initialize libfreebl3. */
177 NSSLOWInitContext *nss_ictx = NSSLOW_Init ();
178 if (nss_ictx == NULL)
180 free (free_key);
181 return NULL;
183 NSSLOWHASHContext *nss_ctx = NULL;
184 NSSLOWHASHContext *nss_alt_ctx = NULL;
185 #else
186 struct sha512_ctx ctx;
187 struct sha512_ctx alt_ctx;
188 #endif
190 /* Prepare for the real work. */
191 sha512_init_ctx (&ctx, nss_ctx);
193 /* Add the key string. */
194 sha512_process_bytes (key, key_len, &ctx, nss_ctx);
196 /* The last part is the salt string. This must be at most 16
197 characters and it ends at the first `$' character. */
198 sha512_process_bytes (salt, salt_len, &ctx, nss_ctx);
201 /* Compute alternate SHA512 sum with input KEY, SALT, and KEY. The
202 final result will be added to the first context. */
203 sha512_init_ctx (&alt_ctx, nss_alt_ctx);
205 /* Add key. */
206 sha512_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
208 /* Add salt. */
209 sha512_process_bytes (salt, salt_len, &alt_ctx, nss_alt_ctx);
211 /* Add key again. */
212 sha512_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
214 /* Now get result of this (64 bytes) and add it to the other
215 context. */
216 sha512_finish_ctx (&alt_ctx, nss_alt_ctx, alt_result);
218 /* Add for any character in the key one byte of the alternate sum. */
219 for (cnt = key_len; cnt > 64; cnt -= 64)
220 sha512_process_bytes (alt_result, 64, &ctx, nss_ctx);
221 sha512_process_bytes (alt_result, cnt, &ctx, nss_ctx);
223 /* Take the binary representation of the length of the key and for every
224 1 add the alternate sum, for every 0 the key. */
225 for (cnt = key_len; cnt > 0; cnt >>= 1)
226 if ((cnt & 1) != 0)
227 sha512_process_bytes (alt_result, 64, &ctx, nss_ctx);
228 else
229 sha512_process_bytes (key, key_len, &ctx, nss_ctx);
231 /* Create intermediate result. */
232 sha512_finish_ctx (&ctx, nss_ctx, alt_result);
234 /* Start computation of P byte sequence. */
235 sha512_init_ctx (&alt_ctx, nss_alt_ctx);
237 /* For every character in the password add the entire password. */
238 for (cnt = 0; cnt < key_len; ++cnt)
239 sha512_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
241 /* Finish the digest. */
242 sha512_finish_ctx (&alt_ctx, nss_alt_ctx, temp_result);
244 /* Create byte sequence P. */
245 if (__libc_use_alloca (alloca_used + key_len))
246 cp = p_bytes = (char *) alloca (key_len);
247 else
249 free_pbytes = cp = p_bytes = (char *)malloc (key_len);
250 if (free_pbytes == NULL)
252 free (free_key);
253 return NULL;
257 for (cnt = key_len; cnt >= 64; cnt -= 64)
258 cp = mempcpy (cp, temp_result, 64);
259 memcpy (cp, temp_result, cnt);
261 /* Start computation of S byte sequence. */
262 sha512_init_ctx (&alt_ctx, nss_alt_ctx);
264 /* For every character in the password add the entire password. */
265 for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt)
266 sha512_process_bytes (salt, salt_len, &alt_ctx, nss_alt_ctx);
268 /* Finish the digest. */
269 sha512_finish_ctx (&alt_ctx, nss_alt_ctx, temp_result);
271 /* Create byte sequence S. */
272 cp = s_bytes = alloca (salt_len);
273 for (cnt = salt_len; cnt >= 64; cnt -= 64)
274 cp = mempcpy (cp, temp_result, 64);
275 memcpy (cp, temp_result, cnt);
277 /* Repeatedly run the collected hash value through SHA512 to burn
278 CPU cycles. */
279 for (cnt = 0; cnt < rounds; ++cnt)
281 /* New context. */
282 sha512_init_ctx (&ctx, nss_ctx);
284 /* Add key or last result. */
285 if ((cnt & 1) != 0)
286 sha512_process_bytes (p_bytes, key_len, &ctx, nss_ctx);
287 else
288 sha512_process_bytes (alt_result, 64, &ctx, nss_ctx);
290 /* Add salt for numbers not divisible by 3. */
291 if (cnt % 3 != 0)
292 sha512_process_bytes (s_bytes, salt_len, &ctx, nss_ctx);
294 /* Add key for numbers not divisible by 7. */
295 if (cnt % 7 != 0)
296 sha512_process_bytes (p_bytes, key_len, &ctx, nss_ctx);
298 /* Add key or last result. */
299 if ((cnt & 1) != 0)
300 sha512_process_bytes (alt_result, 64, &ctx, nss_ctx);
301 else
302 sha512_process_bytes (p_bytes, key_len, &ctx, nss_ctx);
304 /* Create intermediate result. */
305 sha512_finish_ctx (&ctx, nss_ctx, alt_result);
308 #ifdef USE_NSS
309 /* Free libfreebl3 resources. */
310 NSSLOW_Shutdown (nss_ictx);
311 #endif
313 /* Now we can construct the result string. It consists of three
314 parts. */
315 cp = __stpncpy (buffer, sha512_salt_prefix, MAX (0, buflen));
316 buflen -= sizeof (sha512_salt_prefix) - 1;
318 if (rounds_custom)
320 int n = __snprintf (cp, MAX (0, buflen), "%s%zu$",
321 sha512_rounds_prefix, rounds);
322 cp += n;
323 buflen -= n;
326 cp = __stpncpy (cp, salt, MIN ((size_t) MAX (0, buflen), salt_len));
327 buflen -= MIN ((size_t) MAX (0, buflen), salt_len);
329 if (buflen > 0)
331 *cp++ = '$';
332 --buflen;
335 __b64_from_24bit (&cp, &buflen,
336 alt_result[0], alt_result[21], alt_result[42], 4);
337 __b64_from_24bit (&cp, &buflen,
338 alt_result[22], alt_result[43], alt_result[1], 4);
339 __b64_from_24bit (&cp, &buflen,
340 alt_result[44], alt_result[2], alt_result[23], 4);
341 __b64_from_24bit (&cp, &buflen,
342 alt_result[3], alt_result[24], alt_result[45], 4);
343 __b64_from_24bit (&cp, &buflen,
344 alt_result[25], alt_result[46], alt_result[4], 4);
345 __b64_from_24bit (&cp, &buflen,
346 alt_result[47], alt_result[5], alt_result[26], 4);
347 __b64_from_24bit (&cp, &buflen,
348 alt_result[6], alt_result[27], alt_result[48], 4);
349 __b64_from_24bit (&cp, &buflen,
350 alt_result[28], alt_result[49], alt_result[7], 4);
351 __b64_from_24bit (&cp, &buflen,
352 alt_result[50], alt_result[8], alt_result[29], 4);
353 __b64_from_24bit (&cp, &buflen,
354 alt_result[9], alt_result[30], alt_result[51], 4);
355 __b64_from_24bit (&cp, &buflen,
356 alt_result[31], alt_result[52], alt_result[10], 4);
357 __b64_from_24bit (&cp, &buflen,
358 alt_result[53], alt_result[11], alt_result[32], 4);
359 __b64_from_24bit (&cp, &buflen,
360 alt_result[12], alt_result[33], alt_result[54], 4);
361 __b64_from_24bit (&cp, &buflen,
362 alt_result[34], alt_result[55], alt_result[13], 4);
363 __b64_from_24bit (&cp, &buflen,
364 alt_result[56], alt_result[14], alt_result[35], 4);
365 __b64_from_24bit (&cp, &buflen,
366 alt_result[15], alt_result[36], alt_result[57], 4);
367 __b64_from_24bit (&cp, &buflen,
368 alt_result[37], alt_result[58], alt_result[16], 4);
369 __b64_from_24bit (&cp, &buflen,
370 alt_result[59], alt_result[17], alt_result[38], 4);
371 __b64_from_24bit (&cp, &buflen,
372 alt_result[18], alt_result[39], alt_result[60], 4);
373 __b64_from_24bit (&cp, &buflen,
374 alt_result[40], alt_result[61], alt_result[19], 4);
375 __b64_from_24bit (&cp, &buflen,
376 alt_result[62], alt_result[20], alt_result[41], 4);
377 __b64_from_24bit (&cp, &buflen,
378 0, 0, alt_result[63], 2);
380 if (buflen <= 0)
382 __set_errno (ERANGE);
383 buffer = NULL;
385 else
386 *cp = '\0'; /* Terminate the string. */
388 /* Clear the buffer for the intermediate result so that people
389 attaching to processes or reading core dumps cannot get any
390 information. We do it in this way to clear correct_words[]
391 inside the SHA512 implementation as well. */
392 #ifndef USE_NSS
393 __sha512_init_ctx (&ctx);
394 __sha512_finish_ctx (&ctx, alt_result);
395 explicit_bzero (&ctx, sizeof (ctx));
396 explicit_bzero (&alt_ctx, sizeof (alt_ctx));
397 #endif
398 explicit_bzero (temp_result, sizeof (temp_result));
399 explicit_bzero (p_bytes, key_len);
400 explicit_bzero (s_bytes, salt_len);
401 if (copied_key != NULL)
402 explicit_bzero (copied_key, key_len);
403 if (copied_salt != NULL)
404 explicit_bzero (copied_salt, salt_len);
406 free (free_key);
407 free (free_pbytes);
408 return buffer;
411 #ifndef _LIBC
412 # define libc_freeres_ptr(decl) decl
413 #endif
414 libc_freeres_ptr (static char *buffer);
416 /* This entry point is equivalent to the `crypt' function in Unix
417 libcs. */
418 char *
419 __sha512_crypt (const char *key, const char *salt)
421 /* We don't want to have an arbitrary limit in the size of the
422 password. We can compute an upper bound for the size of the
423 result in advance and so we can prepare the buffer we pass to
424 `sha512_crypt_r'. */
425 static int buflen;
426 int needed = (sizeof (sha512_salt_prefix) - 1
427 + sizeof (sha512_rounds_prefix) + 9 + 1
428 + strlen (salt) + 1 + 86 + 1);
430 if (buflen < needed)
432 char *new_buffer = (char *) realloc (buffer, needed);
433 if (new_buffer == NULL)
434 return NULL;
436 buffer = new_buffer;
437 buflen = needed;
440 return __sha512_crypt_r (key, salt, buffer, buflen);
443 #ifndef _LIBC
444 static void
445 __attribute__ ((__destructor__))
446 free_mem (void)
448 free (buffer);
450 #endif