Assemble via ELF, to enable future linking
[syslinux.git] / com32 / libutil / sha512crypt.c
blob9553ec1e026cf751b77fe7faea3e2c3d2e0f0c59
1 /* SHA512-based Unix crypt implementation.
2 Released into the Public Domain by Ulrich Drepper <drepper@redhat.com>. */
4 #include <alloca.h>
5 #include <endian.h>
6 #include <errno.h>
7 #include <limits.h>
8 #include <stdbool.h>
9 #include <stdint.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <minmax.h>
14 #include <sys/types.h>
16 #include "xcrypt.h"
18 #define MIN(x,y) min(x,y)
19 #define MAX(x,y) max(x,y)
21 /* Structure to save state of computation between the single steps. */
22 struct sha512_ctx
24 uint64_t H[8];
26 uint64_t total[2];
27 uint64_t buflen;
28 char buffer[256]; /* NB: always correctly aligned for uint64_t. */
32 #if __BYTE_ORDER == __LITTLE_ENDIAN
33 # define SWAP(n) \
34 (((n) << 56) \
35 | (((n) & 0xff00) << 40) \
36 | (((n) & 0xff0000) << 24) \
37 | (((n) & 0xff000000) << 8) \
38 | (((n) >> 8) & 0xff000000) \
39 | (((n) >> 24) & 0xff0000) \
40 | (((n) >> 40) & 0xff00) \
41 | ((n) >> 56))
42 #else
43 # define SWAP(n) (n)
44 #endif
47 /* This array contains the bytes used to pad the buffer to the next
48 64-byte boundary. (FIPS 180-2:5.1.2) */
49 static const unsigned char fillbuf[128] = { 0x80, 0 /* , 0, 0, ... */ };
52 /* Constants for SHA512 from FIPS 180-2:4.2.3. */
53 static const uint64_t K[80] =
55 UINT64_C (0x428a2f98d728ae22), UINT64_C (0x7137449123ef65cd),
56 UINT64_C (0xb5c0fbcfec4d3b2f), UINT64_C (0xe9b5dba58189dbbc),
57 UINT64_C (0x3956c25bf348b538), UINT64_C (0x59f111f1b605d019),
58 UINT64_C (0x923f82a4af194f9b), UINT64_C (0xab1c5ed5da6d8118),
59 UINT64_C (0xd807aa98a3030242), UINT64_C (0x12835b0145706fbe),
60 UINT64_C (0x243185be4ee4b28c), UINT64_C (0x550c7dc3d5ffb4e2),
61 UINT64_C (0x72be5d74f27b896f), UINT64_C (0x80deb1fe3b1696b1),
62 UINT64_C (0x9bdc06a725c71235), UINT64_C (0xc19bf174cf692694),
63 UINT64_C (0xe49b69c19ef14ad2), UINT64_C (0xefbe4786384f25e3),
64 UINT64_C (0x0fc19dc68b8cd5b5), UINT64_C (0x240ca1cc77ac9c65),
65 UINT64_C (0x2de92c6f592b0275), UINT64_C (0x4a7484aa6ea6e483),
66 UINT64_C (0x5cb0a9dcbd41fbd4), UINT64_C (0x76f988da831153b5),
67 UINT64_C (0x983e5152ee66dfab), UINT64_C (0xa831c66d2db43210),
68 UINT64_C (0xb00327c898fb213f), UINT64_C (0xbf597fc7beef0ee4),
69 UINT64_C (0xc6e00bf33da88fc2), UINT64_C (0xd5a79147930aa725),
70 UINT64_C (0x06ca6351e003826f), UINT64_C (0x142929670a0e6e70),
71 UINT64_C (0x27b70a8546d22ffc), UINT64_C (0x2e1b21385c26c926),
72 UINT64_C (0x4d2c6dfc5ac42aed), UINT64_C (0x53380d139d95b3df),
73 UINT64_C (0x650a73548baf63de), UINT64_C (0x766a0abb3c77b2a8),
74 UINT64_C (0x81c2c92e47edaee6), UINT64_C (0x92722c851482353b),
75 UINT64_C (0xa2bfe8a14cf10364), UINT64_C (0xa81a664bbc423001),
76 UINT64_C (0xc24b8b70d0f89791), UINT64_C (0xc76c51a30654be30),
77 UINT64_C (0xd192e819d6ef5218), UINT64_C (0xd69906245565a910),
78 UINT64_C (0xf40e35855771202a), UINT64_C (0x106aa07032bbd1b8),
79 UINT64_C (0x19a4c116b8d2d0c8), UINT64_C (0x1e376c085141ab53),
80 UINT64_C (0x2748774cdf8eeb99), UINT64_C (0x34b0bcb5e19b48a8),
81 UINT64_C (0x391c0cb3c5c95a63), UINT64_C (0x4ed8aa4ae3418acb),
82 UINT64_C (0x5b9cca4f7763e373), UINT64_C (0x682e6ff3d6b2b8a3),
83 UINT64_C (0x748f82ee5defb2fc), UINT64_C (0x78a5636f43172f60),
84 UINT64_C (0x84c87814a1f0ab72), UINT64_C (0x8cc702081a6439ec),
85 UINT64_C (0x90befffa23631e28), UINT64_C (0xa4506cebde82bde9),
86 UINT64_C (0xbef9a3f7b2c67915), UINT64_C (0xc67178f2e372532b),
87 UINT64_C (0xca273eceea26619c), UINT64_C (0xd186b8c721c0c207),
88 UINT64_C (0xeada7dd6cde0eb1e), UINT64_C (0xf57d4f7fee6ed178),
89 UINT64_C (0x06f067aa72176fba), UINT64_C (0x0a637dc5a2c898a6),
90 UINT64_C (0x113f9804bef90dae), UINT64_C (0x1b710b35131c471b),
91 UINT64_C (0x28db77f523047d84), UINT64_C (0x32caab7b40c72493),
92 UINT64_C (0x3c9ebe0a15c9bebc), UINT64_C (0x431d67c49c100d4c),
93 UINT64_C (0x4cc5d4becb3e42b6), UINT64_C (0x597f299cfc657e2a),
94 UINT64_C (0x5fcb6fab3ad6faec), UINT64_C (0x6c44198c4a475817)
98 /* Process LEN bytes of BUFFER, accumulating context into CTX.
99 It is assumed that LEN % 128 == 0. */
100 static void
101 sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx)
103 unsigned int t;
104 const uint64_t *words = buffer;
105 size_t nwords = len / sizeof (uint64_t);
106 uint64_t a = ctx->H[0];
107 uint64_t b = ctx->H[1];
108 uint64_t c = ctx->H[2];
109 uint64_t d = ctx->H[3];
110 uint64_t e = ctx->H[4];
111 uint64_t f = ctx->H[5];
112 uint64_t g = ctx->H[6];
113 uint64_t h = ctx->H[7];
115 /* First increment the byte count. FIPS 180-2 specifies the possible
116 length of the file up to 2^128 bits. Here we only compute the
117 number of bytes. Do a double word increment. */
118 ctx->total[0] += len;
119 if (ctx->total[0] < len)
120 ++ctx->total[1];
122 /* Process all bytes in the buffer with 128 bytes in each round of
123 the loop. */
124 while (nwords > 0)
126 uint64_t W[80];
127 uint64_t a_save = a;
128 uint64_t b_save = b;
129 uint64_t c_save = c;
130 uint64_t d_save = d;
131 uint64_t e_save = e;
132 uint64_t f_save = f;
133 uint64_t g_save = g;
134 uint64_t h_save = h;
136 /* Operators defined in FIPS 180-2:4.1.2. */
137 #define Ch(x, y, z) ((x & y) ^ (~x & z))
138 #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
139 #define S0(x) (CYCLIC (x, 28) ^ CYCLIC (x, 34) ^ CYCLIC (x, 39))
140 #define S1(x) (CYCLIC (x, 14) ^ CYCLIC (x, 18) ^ CYCLIC (x, 41))
141 #define R0(x) (CYCLIC (x, 1) ^ CYCLIC (x, 8) ^ (x >> 7))
142 #define R1(x) (CYCLIC (x, 19) ^ CYCLIC (x, 61) ^ (x >> 6))
144 /* It is unfortunate that C does not provide an operator for
145 cyclic rotation. Hope the C compiler is smart enough. */
146 #define CYCLIC(w, s) ((w >> s) | (w << (64 - s)))
148 /* Compute the message schedule according to FIPS 180-2:6.3.2 step 2. */
149 for (t = 0; t < 16; ++t)
151 W[t] = SWAP (*words);
152 ++words;
154 for (t = 16; t < 80; ++t)
155 W[t] = R1 (W[t - 2]) + W[t - 7] + R0 (W[t - 15]) + W[t - 16];
157 /* The actual computation according to FIPS 180-2:6.3.2 step 3. */
158 for (t = 0; t < 80; ++t)
160 uint64_t T1 = h + S1 (e) + Ch (e, f, g) + K[t] + W[t];
161 uint64_t T2 = S0 (a) + Maj (a, b, c);
162 h = g;
163 g = f;
164 f = e;
165 e = d + T1;
166 d = c;
167 c = b;
168 b = a;
169 a = T1 + T2;
172 /* Add the starting values of the context according to FIPS 180-2:6.3.2
173 step 4. */
174 a += a_save;
175 b += b_save;
176 c += c_save;
177 d += d_save;
178 e += e_save;
179 f += f_save;
180 g += g_save;
181 h += h_save;
183 /* Prepare for the next round. */
184 nwords -= 16;
187 /* Put checksum in context given as argument. */
188 ctx->H[0] = a;
189 ctx->H[1] = b;
190 ctx->H[2] = c;
191 ctx->H[3] = d;
192 ctx->H[4] = e;
193 ctx->H[5] = f;
194 ctx->H[6] = g;
195 ctx->H[7] = h;
199 /* Initialize structure containing state of computation.
200 (FIPS 180-2:5.3.3) */
201 static void
202 sha512_init_ctx (struct sha512_ctx *ctx)
204 ctx->H[0] = UINT64_C (0x6a09e667f3bcc908);
205 ctx->H[1] = UINT64_C (0xbb67ae8584caa73b);
206 ctx->H[2] = UINT64_C (0x3c6ef372fe94f82b);
207 ctx->H[3] = UINT64_C (0xa54ff53a5f1d36f1);
208 ctx->H[4] = UINT64_C (0x510e527fade682d1);
209 ctx->H[5] = UINT64_C (0x9b05688c2b3e6c1f);
210 ctx->H[6] = UINT64_C (0x1f83d9abfb41bd6b);
211 ctx->H[7] = UINT64_C (0x5be0cd19137e2179);
213 ctx->total[0] = ctx->total[1] = 0;
214 ctx->buflen = 0;
218 /* Process the remaining bytes in the internal buffer and the usual
219 prolog according to the standard and write the result to RESBUF.
221 IMPORTANT: On some systems it is required that RESBUF is correctly
222 aligned for a 32 bits value. */
223 static void *
224 sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf)
226 unsigned int i;
227 /* Take yet unprocessed bytes into account. */
228 uint64_t bytes = ctx->buflen;
229 size_t pad;
231 /* Now count remaining bytes. */
232 ctx->total[0] += bytes;
233 if (ctx->total[0] < bytes)
234 ++ctx->total[1];
236 pad = bytes >= 112 ? 128 + 112 - bytes : 112 - bytes;
237 memcpy (&ctx->buffer[bytes], fillbuf, pad);
239 /* Put the 128-bit file length in *bits* at the end of the buffer. */
240 *(uint64_t *) &ctx->buffer[bytes + pad + 8] = SWAP (ctx->total[0] << 3);
241 *(uint64_t *) &ctx->buffer[bytes + pad] = SWAP ((ctx->total[1] << 3) |
242 (ctx->total[0] >> 61));
244 /* Process last bytes. */
245 sha512_process_block (ctx->buffer, bytes + pad + 16, ctx);
247 /* Put result from CTX in first 64 bytes following RESBUF. */
248 for (i = 0; i < 8; ++i)
249 ((uint64_t *) resbuf)[i] = SWAP (ctx->H[i]);
251 return resbuf;
255 static void
256 sha512_process_bytes (const void *buffer, size_t len, struct sha512_ctx *ctx)
258 /* When we already have some bits in our internal buffer concatenate
259 both inputs first. */
260 if (ctx->buflen != 0)
262 size_t left_over = ctx->buflen;
263 size_t add = 256 - left_over > len ? len : 256 - left_over;
265 memcpy (&ctx->buffer[left_over], buffer, add);
266 ctx->buflen += add;
268 if (ctx->buflen > 128)
270 sha512_process_block (ctx->buffer, ctx->buflen & ~127, ctx);
272 ctx->buflen &= 127;
273 /* The regions in the following copy operation cannot overlap. */
274 memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~127],
275 ctx->buflen);
278 buffer = (const char *) buffer + add;
279 len -= add;
282 /* Process available complete blocks. */
283 if (len >= 128)
285 #if !_STRING_ARCH_unaligned
286 /* To check alignment gcc has an appropriate operator. Other
287 compilers don't. */
288 # if __GNUC__ >= 2
289 # define UNALIGNED_P(p) (((uintptr_t) p) % __alignof__ (uint64_t) != 0)
290 # else
291 # define UNALIGNED_P(p) (((uintptr_t) p) % sizeof (uint64_t) != 0)
292 # endif
293 if (UNALIGNED_P (buffer))
294 while (len > 128)
296 sha512_process_block (memcpy (ctx->buffer, buffer, 128), 128,
297 ctx);
298 buffer = (const char *) buffer + 128;
299 len -= 128;
301 else
302 #endif
304 sha512_process_block (buffer, len & ~127, ctx);
305 buffer = (const char *) buffer + (len & ~127);
306 len &= 127;
310 /* Move remaining bytes into internal buffer. */
311 if (len > 0)
313 size_t left_over = ctx->buflen;
315 memcpy (&ctx->buffer[left_over], buffer, len);
316 left_over += len;
317 if (left_over >= 128)
319 sha512_process_block (ctx->buffer, 128, ctx);
320 left_over -= 128;
321 memcpy (ctx->buffer, &ctx->buffer[128], left_over);
323 ctx->buflen = left_over;
328 /* Define our magic string to mark salt for SHA512 "encryption"
329 replacement. */
330 static const char sha512_salt_prefix[] = "$6$";
332 /* Prefix for optional rounds specification. */
333 static const char sha512_rounds_prefix[] = "rounds=";
335 /* Maximum salt string length. */
336 #define SALT_LEN_MAX 16
337 /* Default number of rounds if not explicitly specified. */
338 #define ROUNDS_DEFAULT 5000
339 /* Minimum number of rounds. */
340 #define ROUNDS_MIN 1000
341 /* Maximum number of rounds. */
342 #define ROUNDS_MAX 999999999
344 /* Table with characters for base64 transformation. */
345 static const char b64t[64] =
346 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
349 static char *
350 sha512_crypt_r (const char *key, const char *salt, char *buffer, int buflen)
352 unsigned char alt_result[64]
353 __attribute__ ((__aligned__ (__alignof__ (uint64_t))));
354 unsigned char temp_result[64]
355 __attribute__ ((__aligned__ (__alignof__ (uint64_t))));
356 struct sha512_ctx ctx;
357 struct sha512_ctx alt_ctx;
358 size_t salt_len;
359 size_t key_len;
360 size_t cnt;
361 char *cp;
362 char *copied_key = NULL;
363 char *copied_salt = NULL;
364 char *p_bytes;
365 char *s_bytes;
366 /* Default number of rounds. */
367 size_t rounds = ROUNDS_DEFAULT;
368 bool rounds_custom = false;
370 /* Find beginning of salt string. The prefix should normally always
371 be present. Just in case it is not. */
372 if (strncmp (sha512_salt_prefix, salt, sizeof (sha512_salt_prefix) - 1) == 0)
373 /* Skip salt prefix. */
374 salt += sizeof (sha512_salt_prefix) - 1;
376 if (strncmp (salt, sha512_rounds_prefix, sizeof (sha512_rounds_prefix) - 1)
377 == 0)
379 const char *num = salt + sizeof (sha512_rounds_prefix) - 1;
380 char *endp;
381 unsigned long int srounds = strtoul (num, &endp, 10);
382 if (*endp == '$')
384 salt = endp + 1;
385 rounds = MAX (ROUNDS_MIN, MIN (srounds, ROUNDS_MAX));
386 rounds_custom = true;
390 salt_len = MIN (strcspn (salt, "$"), SALT_LEN_MAX);
391 key_len = strlen (key);
393 if ((key - (char *) 0) % __alignof__ (uint64_t) != 0)
395 char *tmp = (char *) alloca (key_len + __alignof__ (uint64_t));
396 key = copied_key =
397 memcpy (tmp + __alignof__ (uint64_t)
398 - (tmp - (char *) 0) % __alignof__ (uint64_t),
399 key, key_len);
402 if ((salt - (char *) 0) % __alignof__ (uint64_t) != 0)
404 char *tmp = (char *) alloca (salt_len + __alignof__ (uint64_t));
405 salt = copied_salt =
406 memcpy (tmp + __alignof__ (uint64_t)
407 - (tmp - (char *) 0) % __alignof__ (uint64_t),
408 salt, salt_len);
411 /* Prepare for the real work. */
412 sha512_init_ctx (&ctx);
414 /* Add the key string. */
415 sha512_process_bytes (key, key_len, &ctx);
417 /* The last part is the salt string. This must be at most 8
418 characters and it ends at the first `$' character (for
419 compatibility with existing implementations). */
420 sha512_process_bytes (salt, salt_len, &ctx);
423 /* Compute alternate SHA512 sum with input KEY, SALT, and KEY. The
424 final result will be added to the first context. */
425 sha512_init_ctx (&alt_ctx);
427 /* Add key. */
428 sha512_process_bytes (key, key_len, &alt_ctx);
430 /* Add salt. */
431 sha512_process_bytes (salt, salt_len, &alt_ctx);
433 /* Add key again. */
434 sha512_process_bytes (key, key_len, &alt_ctx);
436 /* Now get result of this (64 bytes) and add it to the other
437 context. */
438 sha512_finish_ctx (&alt_ctx, alt_result);
440 /* Add for any character in the key one byte of the alternate sum. */
441 for (cnt = key_len; cnt > 64; cnt -= 64)
442 sha512_process_bytes (alt_result, 64, &ctx);
443 sha512_process_bytes (alt_result, cnt, &ctx);
445 /* Take the binary representation of the length of the key and for every
446 1 add the alternate sum, for every 0 the key. */
447 for (cnt = key_len; cnt > 0; cnt >>= 1)
448 if ((cnt & 1) != 0)
449 sha512_process_bytes (alt_result, 64, &ctx);
450 else
451 sha512_process_bytes (key, key_len, &ctx);
453 /* Create intermediate result. */
454 sha512_finish_ctx (&ctx, alt_result);
456 /* Start computation of P byte sequence. */
457 sha512_init_ctx (&alt_ctx);
459 /* For every character in the password add the entire password. */
460 for (cnt = 0; cnt < key_len; ++cnt)
461 sha512_process_bytes (key, key_len, &alt_ctx);
463 /* Finish the digest. */
464 sha512_finish_ctx (&alt_ctx, temp_result);
466 /* Create byte sequence P. */
467 cp = p_bytes = alloca (key_len);
468 for (cnt = key_len; cnt >= 64; cnt -= 64)
469 cp = mempcpy (cp, temp_result, 64);
470 memcpy (cp, temp_result, cnt);
472 /* Start computation of S byte sequence. */
473 sha512_init_ctx (&alt_ctx);
475 /* For every character in the password add the entire password. */
476 for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt)
477 sha512_process_bytes (salt, salt_len, &alt_ctx);
479 /* Finish the digest. */
480 sha512_finish_ctx (&alt_ctx, temp_result);
482 /* Create byte sequence S. */
483 cp = s_bytes = alloca (salt_len);
484 for (cnt = salt_len; cnt >= 64; cnt -= 64)
485 cp = mempcpy (cp, temp_result, 64);
486 memcpy (cp, temp_result, cnt);
488 /* Repeatedly run the collected hash value through SHA512 to burn
489 CPU cycles. */
490 for (cnt = 0; cnt < rounds; ++cnt)
492 /* New context. */
493 sha512_init_ctx (&ctx);
495 /* Add key or last result. */
496 if ((cnt & 1) != 0)
497 sha512_process_bytes (p_bytes, key_len, &ctx);
498 else
499 sha512_process_bytes (alt_result, 64, &ctx);
501 /* Add salt for numbers not divisible by 3. */
502 if (cnt % 3 != 0)
503 sha512_process_bytes (s_bytes, salt_len, &ctx);
505 /* Add key for numbers not divisible by 7. */
506 if (cnt % 7 != 0)
507 sha512_process_bytes (p_bytes, key_len, &ctx);
509 /* Add key or last result. */
510 if ((cnt & 1) != 0)
511 sha512_process_bytes (alt_result, 64, &ctx);
512 else
513 sha512_process_bytes (p_bytes, key_len, &ctx);
515 /* Create intermediate result. */
516 sha512_finish_ctx (&ctx, alt_result);
519 /* Now we can construct the result string. It consists of three
520 parts. */
521 cp = stpncpy (buffer, sha512_salt_prefix, MAX (0, buflen));
522 buflen -= sizeof (sha512_salt_prefix) - 1;
524 if (rounds_custom)
526 int n = snprintf (cp, MAX (0, buflen), "%s%zu$",
527 sha512_rounds_prefix, rounds);
528 cp += n;
529 buflen -= n;
532 cp = stpncpy (cp, salt, MIN ((size_t) MAX (0, buflen), salt_len));
533 buflen -= MIN ((size_t) MAX (0, buflen), salt_len);
535 if (buflen > 0)
537 *cp++ = '$';
538 --buflen;
541 #define b64_from_24bit(B2, B1, B0, N) \
542 do { \
543 unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \
544 int n = (N); \
545 while (n-- > 0 && buflen > 0) \
547 *cp++ = b64t[w & 0x3f]; \
548 --buflen; \
549 w >>= 6; \
551 } while (0)
553 b64_from_24bit (alt_result[0], alt_result[21], alt_result[42], 4);
554 b64_from_24bit (alt_result[22], alt_result[43], alt_result[1], 4);
555 b64_from_24bit (alt_result[44], alt_result[2], alt_result[23], 4);
556 b64_from_24bit (alt_result[3], alt_result[24], alt_result[45], 4);
557 b64_from_24bit (alt_result[25], alt_result[46], alt_result[4], 4);
558 b64_from_24bit (alt_result[47], alt_result[5], alt_result[26], 4);
559 b64_from_24bit (alt_result[6], alt_result[27], alt_result[48], 4);
560 b64_from_24bit (alt_result[28], alt_result[49], alt_result[7], 4);
561 b64_from_24bit (alt_result[50], alt_result[8], alt_result[29], 4);
562 b64_from_24bit (alt_result[9], alt_result[30], alt_result[51], 4);
563 b64_from_24bit (alt_result[31], alt_result[52], alt_result[10], 4);
564 b64_from_24bit (alt_result[53], alt_result[11], alt_result[32], 4);
565 b64_from_24bit (alt_result[12], alt_result[33], alt_result[54], 4);
566 b64_from_24bit (alt_result[34], alt_result[55], alt_result[13], 4);
567 b64_from_24bit (alt_result[56], alt_result[14], alt_result[35], 4);
568 b64_from_24bit (alt_result[15], alt_result[36], alt_result[57], 4);
569 b64_from_24bit (alt_result[37], alt_result[58], alt_result[16], 4);
570 b64_from_24bit (alt_result[59], alt_result[17], alt_result[38], 4);
571 b64_from_24bit (alt_result[18], alt_result[39], alt_result[60], 4);
572 b64_from_24bit (alt_result[40], alt_result[61], alt_result[19], 4);
573 b64_from_24bit (alt_result[62], alt_result[20], alt_result[41], 4);
574 b64_from_24bit (0, 0, alt_result[63], 2);
576 if (buflen <= 0)
578 errno = ERANGE;
579 buffer = NULL;
581 else
582 *cp = '\0'; /* Terminate the string. */
584 /* Clear the buffer for the intermediate result so that people
585 attaching to processes or reading core dumps cannot get any
586 information. We do it in this way to clear correct_words[]
587 inside the SHA512 implementation as well. */
588 sha512_init_ctx (&ctx);
589 sha512_finish_ctx (&ctx, alt_result);
590 memset (temp_result, '\0', sizeof (temp_result));
591 memset (p_bytes, '\0', key_len);
592 memset (s_bytes, '\0', salt_len);
593 memset (&ctx, '\0', sizeof (ctx));
594 memset (&alt_ctx, '\0', sizeof (alt_ctx));
595 if (copied_key != NULL)
596 memset (copied_key, '\0', key_len);
597 if (copied_salt != NULL)
598 memset (copied_salt, '\0', salt_len);
600 return buffer;
604 /* This entry point is equivalent to the `crypt' function in Unix
605 libcs. */
606 char *
607 sha512_crypt (const char *key, const char *salt)
609 /* We don't want to have an arbitrary limit in the size of the
610 password. We can compute an upper bound for the size of the
611 result in advance and so we can prepare the buffer we pass to
612 `sha512_crypt_r'. */
613 static char *buffer;
614 static int buflen;
615 int needed = (sizeof (sha512_salt_prefix) - 1
616 + sizeof (sha512_rounds_prefix) + 9 + 1
617 + strlen (salt) + 1 + 86 + 1);
619 if (buflen < needed)
621 char *new_buffer = (char *) realloc (buffer, needed);
622 if (new_buffer == NULL)
623 return NULL;
625 buffer = new_buffer;
626 buflen = needed;
629 return sha512_crypt_r (key, salt, buffer, buflen);
633 #ifdef TEST
634 static const struct
636 const char *input;
637 const char result[64];
638 } tests[] =
640 /* Test vectors from FIPS 180-2: appendix C.1. */
641 { "abc",
642 "\xdd\xaf\x35\xa1\x93\x61\x7a\xba\xcc\x41\x73\x49\xae\x20\x41\x31"
643 "\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2\x0a\x9e\xee\xe6\x4b\x55\xd3\x9a"
644 "\x21\x92\x99\x2a\x27\x4f\xc1\xa8\x36\xba\x3c\x23\xa3\xfe\xeb\xbd"
645 "\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a\x9a\xc9\x4f\xa5\x4c\xa4\x9f" },
646 /* Test vectors from FIPS 180-2: appendix C.2. */
647 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
648 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
649 "\x8e\x95\x9b\x75\xda\xe3\x13\xda\x8c\xf4\xf7\x28\x14\xfc\x14\x3f"
650 "\x8f\x77\x79\xc6\xeb\x9f\x7f\xa1\x72\x99\xae\xad\xb6\x88\x90\x18"
651 "\x50\x1d\x28\x9e\x49\x00\xf7\xe4\x33\x1b\x99\xde\xc4\xb5\x43\x3a"
652 "\xc7\xd3\x29\xee\xb6\xdd\x26\x54\x5e\x96\xe5\x5b\x87\x4b\xe9\x09" },
653 /* Test vectors from the NESSIE project. */
654 { "",
655 "\xcf\x83\xe1\x35\x7e\xef\xb8\xbd\xf1\x54\x28\x50\xd6\x6d\x80\x07"
656 "\xd6\x20\xe4\x05\x0b\x57\x15\xdc\x83\xf4\xa9\x21\xd3\x6c\xe9\xce"
657 "\x47\xd0\xd1\x3c\x5d\x85\xf2\xb0\xff\x83\x18\xd2\x87\x7e\xec\x2f"
658 "\x63\xb9\x31\xbd\x47\x41\x7a\x81\xa5\x38\x32\x7a\xf9\x27\xda\x3e" },
659 { "a",
660 "\x1f\x40\xfc\x92\xda\x24\x16\x94\x75\x09\x79\xee\x6c\xf5\x82\xf2"
661 "\xd5\xd7\xd2\x8e\x18\x33\x5d\xe0\x5a\xbc\x54\xd0\x56\x0e\x0f\x53"
662 "\x02\x86\x0c\x65\x2b\xf0\x8d\x56\x02\x52\xaa\x5e\x74\x21\x05\x46"
663 "\xf3\x69\xfb\xbb\xce\x8c\x12\xcf\xc7\x95\x7b\x26\x52\xfe\x9a\x75" },
664 { "message digest",
665 "\x10\x7d\xbf\x38\x9d\x9e\x9f\x71\xa3\xa9\x5f\x6c\x05\x5b\x92\x51"
666 "\xbc\x52\x68\xc2\xbe\x16\xd6\xc1\x34\x92\xea\x45\xb0\x19\x9f\x33"
667 "\x09\xe1\x64\x55\xab\x1e\x96\x11\x8e\x8a\x90\x5d\x55\x97\xb7\x20"
668 "\x38\xdd\xb3\x72\xa8\x98\x26\x04\x6d\xe6\x66\x87\xbb\x42\x0e\x7c" },
669 { "abcdefghijklmnopqrstuvwxyz",
670 "\x4d\xbf\xf8\x6c\xc2\xca\x1b\xae\x1e\x16\x46\x8a\x05\xcb\x98\x81"
671 "\xc9\x7f\x17\x53\xbc\xe3\x61\x90\x34\x89\x8f\xaa\x1a\xab\xe4\x29"
672 "\x95\x5a\x1b\xf8\xec\x48\x3d\x74\x21\xfe\x3c\x16\x46\x61\x3a\x59"
673 "\xed\x54\x41\xfb\x0f\x32\x13\x89\xf7\x7f\x48\xa8\x79\xc7\xb1\xf1" },
674 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
675 "\x20\x4a\x8f\xc6\xdd\xa8\x2f\x0a\x0c\xed\x7b\xeb\x8e\x08\xa4\x16"
676 "\x57\xc1\x6e\xf4\x68\xb2\x28\xa8\x27\x9b\xe3\x31\xa7\x03\xc3\x35"
677 "\x96\xfd\x15\xc1\x3b\x1b\x07\xf9\xaa\x1d\x3b\xea\x57\x78\x9c\xa0"
678 "\x31\xad\x85\xc7\xa7\x1d\xd7\x03\x54\xec\x63\x12\x38\xca\x34\x45" },
679 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
680 "\x1e\x07\xbe\x23\xc2\x6a\x86\xea\x37\xea\x81\x0c\x8e\xc7\x80\x93"
681 "\x52\x51\x5a\x97\x0e\x92\x53\xc2\x6f\x53\x6c\xfc\x7a\x99\x96\xc4"
682 "\x5c\x83\x70\x58\x3e\x0a\x78\xfa\x4a\x90\x04\x1d\x71\xa4\xce\xab"
683 "\x74\x23\xf1\x9c\x71\xb9\xd5\xa3\xe0\x12\x49\xf0\xbe\xbd\x58\x94" },
684 { "123456789012345678901234567890123456789012345678901234567890"
685 "12345678901234567890",
686 "\x72\xec\x1e\xf1\x12\x4a\x45\xb0\x47\xe8\xb7\xc7\x5a\x93\x21\x95"
687 "\x13\x5b\xb6\x1d\xe2\x4e\xc0\xd1\x91\x40\x42\x24\x6e\x0a\xec\x3a"
688 "\x23\x54\xe0\x93\xd7\x6f\x30\x48\xb4\x56\x76\x43\x46\x90\x0c\xb1"
689 "\x30\xd2\xa4\xfd\x5d\xd1\x6a\xbb\x5e\x30\xbc\xb8\x50\xde\xe8\x43" }
691 #define ntests (sizeof (tests) / sizeof (tests[0]))
694 static const struct
696 const char *salt;
697 const char *input;
698 const char *expected;
699 } tests2[] =
701 { "$6$saltstring", "Hello world!",
702 "$6$saltstring$svn8UoSVapNtMuq1ukKS4tPQd8iKwSMHWjl/O817G3uBnIFNjnQJu"
703 "esI68u4OTLiBFdcbYEdFCoEOfaS35inz1" },
704 { "$6$rounds=10000$saltstringsaltstring", "Hello world!",
705 "$6$rounds=10000$saltstringsaltst$OW1/O6BYHV6BcXZu8QVeXbDWra3Oeqh0sb"
706 "HbbMCVNSnCM/UrjmM0Dp8vOuZeHBy/YTBmSK6H9qs/y3RnOaw5v." },
707 { "$6$rounds=5000$toolongsaltstring", "This is just a test",
708 "$6$rounds=5000$toolongsaltstrin$lQ8jolhgVRVhY4b5pZKaysCLi0QBxGoNeKQ"
709 "zQ3glMhwllF7oGDZxUhx1yxdYcz/e1JSbq3y6JMxxl8audkUEm0" },
710 { "$6$rounds=1400$anotherlongsaltstring",
711 "a very much longer text to encrypt. This one even stretches over more"
712 "than one line.",
713 "$6$rounds=1400$anotherlongsalts$POfYwTEok97VWcjxIiSOjiykti.o/pQs.wP"
714 "vMxQ6Fm7I6IoYN3CmLs66x9t0oSwbtEW7o7UmJEiDwGqd8p4ur1" },
715 { "$6$rounds=77777$short",
716 "we have a short salt string but not a short password",
717 "$6$rounds=77777$short$WuQyW2YR.hBNpjjRhpYD/ifIw05xdfeEyQoMxIXbkvr0g"
718 "ge1a1x3yRULJ5CCaUeOxFmtlcGZelFl5CxtgfiAc0" },
719 { "$6$rounds=123456$asaltof16chars..", "a short string",
720 "$6$rounds=123456$asaltof16chars..$BtCwjqMJGx5hrJhZywWvt0RLE8uZ4oPwc"
721 "elCjmw2kSYu.Ec6ycULevoBK25fs2xXgMNrCzIMVcgEJAstJeonj1" },
722 { "$6$rounds=10$roundstoolow", "the minimum number is still observed",
723 "$6$rounds=1000$roundstoolow$kUMsbe306n21p9R.FRkW3IGn.S9NPN0x50YhH1x"
724 "hLsPuWGsUSklZt58jaTfF4ZEQpyUNGc0dqbpBYYBaHHrsX." },
726 #define ntests2 (sizeof (tests2) / sizeof (tests2[0]))
730 main (void)
732 struct sha512_ctx ctx;
733 char sum[64];
734 int result = 0;
735 int cnt;
737 for (cnt = 0; cnt < (int) ntests; ++cnt)
739 sha512_init_ctx (&ctx);
740 sha512_process_bytes (tests[cnt].input, strlen (tests[cnt].input), &ctx);
741 sha512_finish_ctx (&ctx, sum);
742 if (memcmp (tests[cnt].result, sum, 64) != 0)
744 printf ("test %d run %d failed\n", cnt, 1);
745 result = 1;
748 sha512_init_ctx (&ctx);
749 for (int i = 0; tests[cnt].input[i] != '\0'; ++i)
750 sha512_process_bytes (&tests[cnt].input[i], 1, &ctx);
751 sha512_finish_ctx (&ctx, sum);
752 if (memcmp (tests[cnt].result, sum, 64) != 0)
754 printf ("test %d run %d failed\n", cnt, 2);
755 result = 1;
759 /* Test vector from FIPS 180-2: appendix C.3. */
760 char buf[1000];
761 memset (buf, 'a', sizeof (buf));
762 sha512_init_ctx (&ctx);
763 for (int i = 0; i < 1000; ++i)
764 sha512_process_bytes (buf, sizeof (buf), &ctx);
765 sha512_finish_ctx (&ctx, sum);
766 static const char expected[64] =
767 "\xe7\x18\x48\x3d\x0c\xe7\x69\x64\x4e\x2e\x42\xc7\xbc\x15\xb4\x63"
768 "\x8e\x1f\x98\xb1\x3b\x20\x44\x28\x56\x32\xa8\x03\xaf\xa9\x73\xeb"
769 "\xde\x0f\xf2\x44\x87\x7e\xa6\x0a\x4c\xb0\x43\x2c\xe5\x77\xc3\x1b"
770 "\xeb\x00\x9c\x5c\x2c\x49\xaa\x2e\x4e\xad\xb2\x17\xad\x8c\xc0\x9b";
771 if (memcmp (expected, sum, 64) != 0)
773 printf ("test %d failed\n", cnt);
774 result = 1;
777 for (cnt = 0; cnt < ntests2; ++cnt)
779 char *cp = sha512_crypt (tests2[cnt].input, tests2[cnt].salt);
781 if (strcmp (cp, tests2[cnt].expected) != 0)
783 printf ("test %d: expected \"%s\", got \"%s\"\n",
784 cnt, tests2[cnt].expected, cp);
785 result = 1;
789 if (result == 0)
790 puts ("all tests OK");
792 return result;
794 #endif