1/* One way encryption based on SHA512 sum.
2 Copyright (C) 2007-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
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.
9
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.
14
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/>. */
18
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>
26
27#include "sha512.h"
28#include "crypt-private.h"
29
30
31#ifdef USE_NSS
32typedef int PRBool;
33# include <hasht.h>
34# include <nsslowhash.h>
35
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)
51
52# define sha512_process_bytes(buf, len, ctxp, nss_ctxp) \
53 NSSLOWHASH_Update (nss_ctxp, (const unsigned char *) buf, len)
54
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)
68
69# define sha512_process_bytes(buf, len, ctxp, nss_ctxp) \
70 __sha512_process_bytes(buf, len, ctxp)
71
72# define sha512_finish_ctx(ctxp, nss_ctxp, result) \
73 __sha512_finish_ctx (ctxp, result)
74#endif
75
76
77/* Define our magic string to mark salt for SHA512 "encryption"
78 replacement. */
79static const char sha512_salt_prefix[] = "$6$";
80
81/* Prefix for optional rounds specification. */
82static const char sha512_rounds_prefix[] = "rounds=";
83
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
92
93
94/* Prototypes for local functions. */
95extern char *__sha512_crypt_r (const char *key, const char *salt,
96 char *buffer, int buflen);
97extern char *__sha512_crypt (const char *key, const char *salt);
98
99
100char *
101__sha512_crypt_r (const char *key, const char *salt, char *buffer, int buflen)
102{
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;
121
122 /* Find beginning of salt string. The prefix should normally always
123 be present. Just in case it is not. */
124 if (strncmp (s1: sha512_salt_prefix, s2: salt, n: sizeof (sha512_salt_prefix) - 1) == 0)
125 /* Skip salt prefix. */
126 salt += sizeof (sha512_salt_prefix) - 1;
127
128 if (strncmp (s1: salt, s2: sha512_rounds_prefix, n: sizeof (sha512_rounds_prefix) - 1)
129 == 0)
130 {
131 const char *num = salt + sizeof (sha512_rounds_prefix) - 1;
132 char *endp;
133 unsigned long int srounds = strtoul (nptr: num, endptr: &endp, base: 10);
134 if (*endp == '$')
135 {
136 salt = endp + 1;
137 rounds = MAX (ROUNDS_MIN, MIN (srounds, ROUNDS_MAX));
138 rounds_custom = true;
139 }
140 }
141
142 salt_len = MIN (strcspn (salt, "$"), SALT_LEN_MAX);
143 key_len = strlen (s: key);
144
145 if ((key - (char *) 0) % __alignof__ (uint64_t) != 0)
146 {
147 char *tmp;
148
149 if (__libc_use_alloca (size: alloca_used + key_len + __alignof__ (uint64_t)))
150 tmp = alloca_account (key_len + __alignof__ (uint64_t), alloca_used);
151 else
152 {
153 free_key = tmp = (char *) malloc (size: key_len + __alignof__ (uint64_t));
154 if (tmp == NULL)
155 return NULL;
156 }
157
158 key = copied_key =
159 memcpy (dest: tmp + __alignof__ (uint64_t)
160 - (tmp - (char *) 0) % __alignof__ (uint64_t),
161 src: key, n: key_len);
162 assert ((key - (char *) 0) % __alignof__ (uint64_t) == 0);
163 }
164
165 if ((salt - (char *) 0) % __alignof__ (uint64_t) != 0)
166 {
167 char *tmp = (char *) alloca (salt_len + __alignof__ (uint64_t));
168 salt = copied_salt =
169 memcpy (dest: tmp + __alignof__ (uint64_t)
170 - (tmp - (char *) 0) % __alignof__ (uint64_t),
171 src: salt, n: salt_len);
172 assert ((salt - (char *) 0) % __alignof__ (uint64_t) == 0);
173 }
174
175#ifdef USE_NSS
176 /* Initialize libfreebl3. */
177 NSSLOWInitContext *nss_ictx = NSSLOW_Init ();
178 if (nss_ictx == NULL)
179 {
180 free (free_key);
181 return NULL;
182 }
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
189
190 /* Prepare for the real work. */
191 sha512_init_ctx (&ctx, nss_ctx);
192
193 /* Add the key string. */
194 sha512_process_bytes (key, key_len, &ctx, nss_ctx);
195
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);
199
200
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);
204
205 /* Add key. */
206 sha512_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
207
208 /* Add salt. */
209 sha512_process_bytes (salt, salt_len, &alt_ctx, nss_alt_ctx);
210
211 /* Add key again. */
212 sha512_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
213
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);
217
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);
222
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);
230
231 /* Create intermediate result. */
232 sha512_finish_ctx (&ctx, nss_ctx, alt_result);
233
234 /* Start computation of P byte sequence. */
235 sha512_init_ctx (&alt_ctx, nss_alt_ctx);
236
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);
240
241 /* Finish the digest. */
242 sha512_finish_ctx (&alt_ctx, nss_alt_ctx, temp_result);
243
244 /* Create byte sequence P. */
245 if (__libc_use_alloca (size: alloca_used + key_len))
246 cp = p_bytes = (char *) alloca (key_len);
247 else
248 {
249 free_pbytes = cp = p_bytes = (char *)malloc (size: key_len);
250 if (free_pbytes == NULL)
251 {
252 free (ptr: free_key);
253 return NULL;
254 }
255 }
256
257 for (cnt = key_len; cnt >= 64; cnt -= 64)
258 cp = mempcpy (cp, temp_result, 64);
259 memcpy (dest: cp, src: temp_result, n: cnt);
260
261 /* Start computation of S byte sequence. */
262 sha512_init_ctx (&alt_ctx, nss_alt_ctx);
263
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);
267
268 /* Finish the digest. */
269 sha512_finish_ctx (&alt_ctx, nss_alt_ctx, temp_result);
270
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 (dest: cp, src: temp_result, n: cnt);
276
277 /* Repeatedly run the collected hash value through SHA512 to burn
278 CPU cycles. */
279 for (cnt = 0; cnt < rounds; ++cnt)
280 {
281 /* New context. */
282 sha512_init_ctx (&ctx, nss_ctx);
283
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);
289
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);
293
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);
297
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);
303
304 /* Create intermediate result. */
305 sha512_finish_ctx (&ctx, nss_ctx, alt_result);
306 }
307
308#ifdef USE_NSS
309 /* Free libfreebl3 resources. */
310 NSSLOW_Shutdown (nss_ictx);
311#endif
312
313 /* Now we can construct the result string. It consists of three
314 parts. */
315 cp = __stpncpy (dest: buffer, src: sha512_salt_prefix, MAX (0, buflen));
316 buflen -= sizeof (sha512_salt_prefix) - 1;
317
318 if (rounds_custom)
319 {
320 int n = __snprintf (s: cp, MAX (0, buflen), format: "%s%zu$",
321 sha512_rounds_prefix, rounds);
322 cp += n;
323 buflen -= n;
324 }
325
326 cp = __stpncpy (dest: cp, src: salt, MIN ((size_t) MAX (0, buflen), salt_len));
327 buflen -= MIN ((size_t) MAX (0, buflen), salt_len);
328
329 if (buflen > 0)
330 {
331 *cp++ = '$';
332 --buflen;
333 }
334
335 __b64_from_24bit (cp: &cp, buflen: &buflen,
336 b2: alt_result[0], b1: alt_result[21], b0: alt_result[42], n: 4);
337 __b64_from_24bit (cp: &cp, buflen: &buflen,
338 b2: alt_result[22], b1: alt_result[43], b0: alt_result[1], n: 4);
339 __b64_from_24bit (cp: &cp, buflen: &buflen,
340 b2: alt_result[44], b1: alt_result[2], b0: alt_result[23], n: 4);
341 __b64_from_24bit (cp: &cp, buflen: &buflen,
342 b2: alt_result[3], b1: alt_result[24], b0: alt_result[45], n: 4);
343 __b64_from_24bit (cp: &cp, buflen: &buflen,
344 b2: alt_result[25], b1: alt_result[46], b0: alt_result[4], n: 4);
345 __b64_from_24bit (cp: &cp, buflen: &buflen,
346 b2: alt_result[47], b1: alt_result[5], b0: alt_result[26], n: 4);
347 __b64_from_24bit (cp: &cp, buflen: &buflen,
348 b2: alt_result[6], b1: alt_result[27], b0: alt_result[48], n: 4);
349 __b64_from_24bit (cp: &cp, buflen: &buflen,
350 b2: alt_result[28], b1: alt_result[49], b0: alt_result[7], n: 4);
351 __b64_from_24bit (cp: &cp, buflen: &buflen,
352 b2: alt_result[50], b1: alt_result[8], b0: alt_result[29], n: 4);
353 __b64_from_24bit (cp: &cp, buflen: &buflen,
354 b2: alt_result[9], b1: alt_result[30], b0: alt_result[51], n: 4);
355 __b64_from_24bit (cp: &cp, buflen: &buflen,
356 b2: alt_result[31], b1: alt_result[52], b0: alt_result[10], n: 4);
357 __b64_from_24bit (cp: &cp, buflen: &buflen,
358 b2: alt_result[53], b1: alt_result[11], b0: alt_result[32], n: 4);
359 __b64_from_24bit (cp: &cp, buflen: &buflen,
360 b2: alt_result[12], b1: alt_result[33], b0: alt_result[54], n: 4);
361 __b64_from_24bit (cp: &cp, buflen: &buflen,
362 b2: alt_result[34], b1: alt_result[55], b0: alt_result[13], n: 4);
363 __b64_from_24bit (cp: &cp, buflen: &buflen,
364 b2: alt_result[56], b1: alt_result[14], b0: alt_result[35], n: 4);
365 __b64_from_24bit (cp: &cp, buflen: &buflen,
366 b2: alt_result[15], b1: alt_result[36], b0: alt_result[57], n: 4);
367 __b64_from_24bit (cp: &cp, buflen: &buflen,
368 b2: alt_result[37], b1: alt_result[58], b0: alt_result[16], n: 4);
369 __b64_from_24bit (cp: &cp, buflen: &buflen,
370 b2: alt_result[59], b1: alt_result[17], b0: alt_result[38], n: 4);
371 __b64_from_24bit (cp: &cp, buflen: &buflen,
372 b2: alt_result[18], b1: alt_result[39], b0: alt_result[60], n: 4);
373 __b64_from_24bit (cp: &cp, buflen: &buflen,
374 b2: alt_result[40], b1: alt_result[61], b0: alt_result[19], n: 4);
375 __b64_from_24bit (cp: &cp, buflen: &buflen,
376 b2: alt_result[62], b1: alt_result[20], b0: alt_result[41], n: 4);
377 __b64_from_24bit (cp: &cp, buflen: &buflen,
378 b2: 0, b1: 0, b0: alt_result[63], n: 2);
379
380 if (buflen <= 0)
381 {
382 __set_errno (ERANGE);
383 buffer = NULL;
384 }
385 else
386 *cp = '\0'; /* Terminate the string. */
387
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: &ctx);
394 __sha512_finish_ctx (ctx: &ctx, resbuf: 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);
405
406 free (ptr: free_key);
407 free (ptr: free_pbytes);
408 return buffer;
409}
410
411#ifndef _LIBC
412# define libc_freeres_ptr(decl) decl
413#endif
414libc_freeres_ptr (static char *buffer);
415
416/* This entry point is equivalent to the `crypt' function in Unix
417 libcs. */
418char *
419__sha512_crypt (const char *key, const char *salt)
420{
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 (s: salt) + 1 + 86 + 1);
429
430 if (buflen < needed)
431 {
432 char *new_buffer = (char *) realloc (ptr: buffer, size: needed);
433 if (new_buffer == NULL)
434 return NULL;
435
436 buffer = new_buffer;
437 buflen = needed;
438 }
439
440 return __sha512_crypt_r (key, salt, buffer, buflen);
441}
442
443#ifndef _LIBC
444static void
445__attribute__ ((__destructor__))
446free_mem (void)
447{
448 free (buffer);
449}
450#endif
451

source code of glibc/crypt/sha512-crypt.c