Updates to Tomato RAF including NGINX && PHP
[tomato.git] / release / src / router / php / ext / standard / crypt_sha512.c
blob09555321315882d7c90603028321ac048e68833a
1 /* SHA512-based Unix crypt implementation.
2 Released into the Public Domain by Ulrich Drepper <drepper@redhat.com>. */
3 /* Windows VC++ port by Pierre Joye <pierre@php.net> */
5 #include "php.h"
6 #include "php_main.h"
8 #include <errno.h>
9 #include <limits.h>
10 #ifdef PHP_WIN32
11 # include "win32/php_stdint.h"
12 # define __alignof__ __alignof
13 # define alloca _alloca
14 #else
15 # if HAVE_INTTYPES_H
16 # include <inttypes.h>
17 # elif HAVE_STDINT_H
18 # include <stdint.h>
19 # endif
20 # ifndef HAVE_ALIGNOF
21 # include <stddef.h>
22 # define __alignof__(type) offsetof (struct { char c; type member;}, member)
23 # endif
24 # if HAVE_ATTRIBUTE_ALIGNED
25 # define ALIGNED(size) __attribute__ ((__aligned__ (size)))
26 # else
27 # define ALIGNED(size)
28 # endif
29 #endif
31 #include <stdio.h>
32 #include <stdlib.h>
34 #ifdef PHP_WIN32
35 # include <string.h>
36 #else
37 # include <sys/param.h>
38 # include <sys/types.h>
39 # if HAVE_STRING_H
40 # include <string.h>
41 # else
42 # include <strings.h>
43 # endif
44 #endif
46 extern void * __php_mempcpy(void * dst, const void * src, size_t len);
47 extern char * __php_stpncpy(char *dst, const char *src, size_t len);
49 #ifndef MIN
50 # define MIN(a, b) (((a) < (b)) ? (a) : (b))
51 #endif
52 #ifndef MAX
53 # define MAX(a, b) (((a) > (b)) ? (a) : (b))
54 #endif
56 /* See #51582 */
57 #ifndef UINT64_C
58 # define UINT64_C(value) __CONCAT(value, ULL)
59 #endif
61 /* Structure to save state of computation between the single steps. */
62 struct sha512_ctx
64 uint64_t H[8];
66 uint64_t total[2];
67 uint64_t buflen;
68 char buffer[256]; /* NB: always correctly aligned for uint64_t. */
72 #if PHP_WIN32 || (!defined(WORDS_BIGENDIAN))
73 # define SWAP(n) \
74 (((n) << 56) \
75 | (((n) & 0xff00) << 40) \
76 | (((n) & 0xff0000) << 24) \
77 | (((n) & 0xff000000) << 8) \
78 | (((n) >> 8) & 0xff000000) \
79 | (((n) >> 24) & 0xff0000) \
80 | (((n) >> 40) & 0xff00) \
81 | ((n) >> 56))
82 #else
83 # define SWAP(n) (n)
84 #endif
86 /* This array contains the bytes used to pad the buffer to the next
87 64-byte boundary. (FIPS 180-2:5.1.2) */
88 static const unsigned char fillbuf[128] = { 0x80, 0 /* , 0, 0, ... */ };
90 /* Constants for SHA512 from FIPS 180-2:4.2.3. */
91 static const uint64_t K[80] = {
92 UINT64_C (0x428a2f98d728ae22), UINT64_C (0x7137449123ef65cd),
93 UINT64_C (0xb5c0fbcfec4d3b2f), UINT64_C (0xe9b5dba58189dbbc),
94 UINT64_C (0x3956c25bf348b538), UINT64_C (0x59f111f1b605d019),
95 UINT64_C (0x923f82a4af194f9b), UINT64_C (0xab1c5ed5da6d8118),
96 UINT64_C (0xd807aa98a3030242), UINT64_C (0x12835b0145706fbe),
97 UINT64_C (0x243185be4ee4b28c), UINT64_C (0x550c7dc3d5ffb4e2),
98 UINT64_C (0x72be5d74f27b896f), UINT64_C (0x80deb1fe3b1696b1),
99 UINT64_C (0x9bdc06a725c71235), UINT64_C (0xc19bf174cf692694),
100 UINT64_C (0xe49b69c19ef14ad2), UINT64_C (0xefbe4786384f25e3),
101 UINT64_C (0x0fc19dc68b8cd5b5), UINT64_C (0x240ca1cc77ac9c65),
102 UINT64_C (0x2de92c6f592b0275), UINT64_C (0x4a7484aa6ea6e483),
103 UINT64_C (0x5cb0a9dcbd41fbd4), UINT64_C (0x76f988da831153b5),
104 UINT64_C (0x983e5152ee66dfab), UINT64_C (0xa831c66d2db43210),
105 UINT64_C (0xb00327c898fb213f), UINT64_C (0xbf597fc7beef0ee4),
106 UINT64_C (0xc6e00bf33da88fc2), UINT64_C (0xd5a79147930aa725),
107 UINT64_C (0x06ca6351e003826f), UINT64_C (0x142929670a0e6e70),
108 UINT64_C (0x27b70a8546d22ffc), UINT64_C (0x2e1b21385c26c926),
109 UINT64_C (0x4d2c6dfc5ac42aed), UINT64_C (0x53380d139d95b3df),
110 UINT64_C (0x650a73548baf63de), UINT64_C (0x766a0abb3c77b2a8),
111 UINT64_C (0x81c2c92e47edaee6), UINT64_C (0x92722c851482353b),
112 UINT64_C (0xa2bfe8a14cf10364), UINT64_C (0xa81a664bbc423001),
113 UINT64_C (0xc24b8b70d0f89791), UINT64_C (0xc76c51a30654be30),
114 UINT64_C (0xd192e819d6ef5218), UINT64_C (0xd69906245565a910),
115 UINT64_C (0xf40e35855771202a), UINT64_C (0x106aa07032bbd1b8),
116 UINT64_C (0x19a4c116b8d2d0c8), UINT64_C (0x1e376c085141ab53),
117 UINT64_C (0x2748774cdf8eeb99), UINT64_C (0x34b0bcb5e19b48a8),
118 UINT64_C (0x391c0cb3c5c95a63), UINT64_C (0x4ed8aa4ae3418acb),
119 UINT64_C (0x5b9cca4f7763e373), UINT64_C (0x682e6ff3d6b2b8a3),
120 UINT64_C (0x748f82ee5defb2fc), UINT64_C (0x78a5636f43172f60),
121 UINT64_C (0x84c87814a1f0ab72), UINT64_C (0x8cc702081a6439ec),
122 UINT64_C (0x90befffa23631e28), UINT64_C (0xa4506cebde82bde9),
123 UINT64_C (0xbef9a3f7b2c67915), UINT64_C (0xc67178f2e372532b),
124 UINT64_C (0xca273eceea26619c), UINT64_C (0xd186b8c721c0c207),
125 UINT64_C (0xeada7dd6cde0eb1e), UINT64_C (0xf57d4f7fee6ed178),
126 UINT64_C (0x06f067aa72176fba), UINT64_C (0x0a637dc5a2c898a6),
127 UINT64_C (0x113f9804bef90dae), UINT64_C (0x1b710b35131c471b),
128 UINT64_C (0x28db77f523047d84), UINT64_C (0x32caab7b40c72493),
129 UINT64_C (0x3c9ebe0a15c9bebc), UINT64_C (0x431d67c49c100d4c),
130 UINT64_C (0x4cc5d4becb3e42b6), UINT64_C (0x597f299cfc657e2a),
131 UINT64_C (0x5fcb6fab3ad6faec), UINT64_C (0x6c44198c4a475817)
135 /* Process LEN bytes of BUFFER, accumulating context into CTX.
136 It is assumed that LEN % 128 == 0. */
137 static void
138 sha512_process_block(const void *buffer, size_t len, struct sha512_ctx *ctx) {
139 const uint64_t *words = buffer;
140 size_t nwords = len / sizeof(uint64_t);
141 uint64_t a = ctx->H[0];
142 uint64_t b = ctx->H[1];
143 uint64_t c = ctx->H[2];
144 uint64_t d = ctx->H[3];
145 uint64_t e = ctx->H[4];
146 uint64_t f = ctx->H[5];
147 uint64_t g = ctx->H[6];
148 uint64_t h = ctx->H[7];
150 /* First increment the byte count. FIPS 180-2 specifies the possible
151 length of the file up to 2^128 bits. Here we only compute the
152 number of bytes. Do a double word increment. */
153 ctx->total[0] += len;
154 if (ctx->total[0] < len) {
155 ++ctx->total[1];
158 /* Process all bytes in the buffer with 128 bytes in each round of
159 the loop. */
160 while (nwords > 0) {
161 uint64_t W[80];
162 uint64_t a_save = a;
163 uint64_t b_save = b;
164 uint64_t c_save = c;
165 uint64_t d_save = d;
166 uint64_t e_save = e;
167 uint64_t f_save = f;
168 uint64_t g_save = g;
169 uint64_t h_save = h;
170 unsigned int t;
172 /* Operators defined in FIPS 180-2:4.1.2. */
173 #define Ch(x, y, z) ((x & y) ^ (~x & z))
174 #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
175 #define S0(x) (CYCLIC (x, 28) ^ CYCLIC (x, 34) ^ CYCLIC (x, 39))
176 #define S1(x) (CYCLIC (x, 14) ^ CYCLIC (x, 18) ^ CYCLIC (x, 41))
177 #define R0(x) (CYCLIC (x, 1) ^ CYCLIC (x, 8) ^ (x >> 7))
178 #define R1(x) (CYCLIC (x, 19) ^ CYCLIC (x, 61) ^ (x >> 6))
180 /* It is unfortunate that C does not provide an operator for
181 cyclic rotation. Hope the C compiler is smart enough. */
182 #define CYCLIC(w, s) ((w >> s) | (w << (64 - s)))
184 /* Compute the message schedule according to FIPS 180-2:6.3.2 step 2. */
185 for (t = 0; t < 16; ++t) {
186 W[t] = SWAP (*words);
187 ++words;
190 for (t = 16; t < 80; ++t) {
191 W[t] = R1 (W[t - 2]) + W[t - 7] + R0 (W[t - 15]) + W[t - 16];
194 /* The actual computation according to FIPS 180-2:6.3.2 step 3. */
195 for (t = 0; t < 80; ++t) {
196 uint64_t T1 = h + S1 (e) + Ch (e, f, g) + K[t] + W[t];
197 uint64_t T2 = S0 (a) + Maj (a, b, c);
198 h = g;
199 g = f;
200 f = e;
201 e = d + T1;
202 d = c;
203 c = b;
204 b = a;
205 a = T1 + T2;
208 /* Add the starting values of the context according to FIPS 180-2:6.3.2
209 step 4. */
210 a += a_save;
211 b += b_save;
212 c += c_save;
213 d += d_save;
214 e += e_save;
215 f += f_save;
216 g += g_save;
217 h += h_save;
219 /* Prepare for the next round. */
220 nwords -= 16;
223 /* Put checksum in context given as argument. */
224 ctx->H[0] = a;
225 ctx->H[1] = b;
226 ctx->H[2] = c;
227 ctx->H[3] = d;
228 ctx->H[4] = e;
229 ctx->H[5] = f;
230 ctx->H[6] = g;
231 ctx->H[7] = h;
235 /* Initialize structure containing state of computation.
236 (FIPS 180-2:5.3.3) */
237 static void sha512_init_ctx (struct sha512_ctx *ctx) {
238 ctx->H[0] = UINT64_C (0x6a09e667f3bcc908);
239 ctx->H[1] = UINT64_C (0xbb67ae8584caa73b);
240 ctx->H[2] = UINT64_C (0x3c6ef372fe94f82b);
241 ctx->H[3] = UINT64_C (0xa54ff53a5f1d36f1);
242 ctx->H[4] = UINT64_C (0x510e527fade682d1);
243 ctx->H[5] = UINT64_C (0x9b05688c2b3e6c1f);
244 ctx->H[6] = UINT64_C (0x1f83d9abfb41bd6b);
245 ctx->H[7] = UINT64_C (0x5be0cd19137e2179);
247 ctx->total[0] = ctx->total[1] = 0;
248 ctx->buflen = 0;
252 /* Process the remaining bytes in the internal buffer and the usual
253 prolog according to the standard and write the result to RESBUF.
255 IMPORTANT: On some systems it is required that RESBUF is correctly
256 aligned for a 32 bits value. */
257 static void * sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf) {
258 /* Take yet unprocessed bytes into account. */
259 uint64_t bytes = ctx->buflen;
260 size_t pad;
261 unsigned int i;
263 /* Now count remaining bytes. */
264 ctx->total[0] += bytes;
265 if (ctx->total[0] < bytes) {
266 ++ctx->total[1];
269 pad = bytes >= 112 ? 128 + 112 - (size_t)bytes : 112 - (size_t)bytes;
270 memcpy(&ctx->buffer[bytes], fillbuf, pad);
272 /* Put the 128-bit file length in *bits* at the end of the buffer. */
273 *(uint64_t *) &ctx->buffer[bytes + pad + 8] = SWAP(ctx->total[0] << 3);
274 *(uint64_t *) &ctx->buffer[bytes + pad] = SWAP((ctx->total[1] << 3) |
275 (ctx->total[0] >> 61));
277 /* Process last bytes. */
278 sha512_process_block(ctx->buffer, (size_t)(bytes + pad + 16), ctx);
280 /* Put result from CTX in first 64 bytes following RESBUF. */
281 for (i = 0; i < 8; ++i) {
282 ((uint64_t *) resbuf)[i] = SWAP(ctx->H[i]);
285 return resbuf;
288 static void
289 sha512_process_bytes(const void *buffer, size_t len, struct sha512_ctx *ctx) {
290 /* When we already have some bits in our internal buffer concatenate
291 both inputs first. */
292 if (ctx->buflen != 0) {
293 size_t left_over = (size_t)ctx->buflen;
294 size_t add = (size_t)(256 - left_over > len ? len : 256 - left_over);
296 memcpy(&ctx->buffer[left_over], buffer, add);
297 ctx->buflen += add;
299 if (ctx->buflen > 128) {
300 sha512_process_block(ctx->buffer, ctx->buflen & ~127, ctx);
302 ctx->buflen &= 127;
303 /* The regions in the following copy operation cannot overlap. */
304 memcpy(ctx->buffer, &ctx->buffer[(left_over + add) & ~127],
305 (size_t)ctx->buflen);
308 buffer = (const char *) buffer + add;
309 len -= add;
312 /* Process available complete blocks. */
313 if (len >= 128) {
314 #if !_STRING_ARCH_unaligned
315 /* To check alignment gcc has an appropriate operator. Other
316 compilers don't. */
317 # if __GNUC__ >= 2
318 # define UNALIGNED_P(p) (((uintptr_t) p) % __alignof__ (uint64_t) != 0)
319 # else
320 # define UNALIGNED_P(p) (((uintptr_t) p) % sizeof(uint64_t) != 0)
321 # endif
322 if (UNALIGNED_P(buffer))
323 while (len > 128) {
324 sha512_process_block(memcpy(ctx->buffer, buffer, 128), 128, ctx);
325 buffer = (const char *) buffer + 128;
326 len -= 128;
328 else
329 #endif
331 sha512_process_block(buffer, len & ~127, ctx);
332 buffer = (const char *) buffer + (len & ~127);
333 len &= 127;
337 /* Move remaining bytes into internal buffer. */
338 if (len > 0) {
339 size_t left_over = (size_t)ctx->buflen;
341 memcpy(&ctx->buffer[left_over], buffer, len);
342 left_over += len;
343 if (left_over >= 128) {
344 sha512_process_block(ctx->buffer, 128, ctx);
345 left_over -= 128;
346 memcpy(ctx->buffer, &ctx->buffer[128], left_over);
348 ctx->buflen = left_over;
353 /* Define our magic string to mark salt for SHA512 "encryption"
354 replacement. */
355 static const char sha512_salt_prefix[] = "$6$";
357 /* Prefix for optional rounds specification. */
358 static const char sha512_rounds_prefix[] = "rounds=";
360 /* Maximum salt string length. */
361 #define SALT_LEN_MAX 16
362 /* Default number of rounds if not explicitly specified. */
363 #define ROUNDS_DEFAULT 5000
364 /* Minimum number of rounds. */
365 #define ROUNDS_MIN 1000
366 /* Maximum number of rounds. */
367 #define ROUNDS_MAX 999999999
369 /* Table with characters for base64 transformation. */
370 static const char b64t[64] =
371 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
374 char *
375 php_sha512_crypt_r(const char *key, const char *salt, char *buffer, int buflen) {
376 #ifdef PHP_WIN32
377 # if _MSC <= 1300
378 # pragma pack(push, 16)
379 unsigned char alt_result[64];
380 unsigned char temp_result[64];
381 # pragma pack(pop)
382 # else
383 __declspec(align(64)) unsigned char alt_result[64];
384 __declspec(align(64)) unsigned char temp_result[64];
385 # endif
386 #else
387 unsigned char alt_result[64] ALIGNED(__alignof__ (uint64_t));
388 unsigned char temp_result[64] ALIGNED(__alignof__ (uint64_t));
389 #endif
390 struct sha512_ctx ctx;
391 struct sha512_ctx alt_ctx;
392 size_t salt_len;
393 size_t key_len;
394 size_t cnt;
395 char *cp;
396 char *copied_key = NULL;
397 char *copied_salt = NULL;
398 char *p_bytes;
399 char *s_bytes;
400 /* Default number of rounds. */
401 size_t rounds = ROUNDS_DEFAULT;
402 zend_bool rounds_custom = 0;
404 /* Find beginning of salt string. The prefix should normally always
405 be present. Just in case it is not. */
406 if (strncmp(sha512_salt_prefix, salt, sizeof(sha512_salt_prefix) - 1) == 0) {
407 /* Skip salt prefix. */
408 salt += sizeof(sha512_salt_prefix) - 1;
411 if (strncmp(salt, sha512_rounds_prefix, sizeof(sha512_rounds_prefix) - 1) == 0) {
412 const char *num = salt + sizeof(sha512_rounds_prefix) - 1;
413 char *endp;
414 unsigned long int srounds = strtoul(num, &endp, 10);
416 if (*endp == '$') {
417 salt = endp + 1;
418 rounds = MAX(ROUNDS_MIN, MIN(srounds, ROUNDS_MAX));
419 rounds_custom = 1;
423 salt_len = MIN(strcspn(salt, "$"), SALT_LEN_MAX);
424 key_len = strlen(key);
426 if ((key - (char *) 0) % __alignof__ (uint64_t) != 0) {
427 char *tmp = (char *) alloca (key_len + __alignof__ (uint64_t));
428 key = copied_key =
429 memcpy(tmp + __alignof__(uint64_t) - (tmp - (char *) 0) % __alignof__(uint64_t), key, key_len);
432 if ((salt - (char *) 0) % __alignof__ (uint64_t) != 0) {
433 char *tmp = (char *) alloca(salt_len + 1 + __alignof__(uint64_t));
434 salt = copied_salt = memcpy(tmp + __alignof__(uint64_t) - (tmp - (char *) 0) % __alignof__(uint64_t), salt, salt_len);
435 copied_salt[salt_len] = 0;
438 /* Prepare for the real work. */
439 sha512_init_ctx(&ctx);
441 /* Add the key string. */
442 sha512_process_bytes(key, key_len, &ctx);
444 /* The last part is the salt string. This must be at most 16
445 characters and it ends at the first `$' character (for
446 compatibility with existing implementations). */
447 sha512_process_bytes(salt, salt_len, &ctx);
450 /* Compute alternate SHA512 sum with input KEY, SALT, and KEY. The
451 final result will be added to the first context. */
452 sha512_init_ctx(&alt_ctx);
454 /* Add key. */
455 sha512_process_bytes(key, key_len, &alt_ctx);
457 /* Add salt. */
458 sha512_process_bytes(salt, salt_len, &alt_ctx);
460 /* Add key again. */
461 sha512_process_bytes(key, key_len, &alt_ctx);
463 /* Now get result of this (64 bytes) and add it to the other
464 context. */
465 sha512_finish_ctx(&alt_ctx, alt_result);
467 /* Add for any character in the key one byte of the alternate sum. */
468 for (cnt = key_len; cnt > 64; cnt -= 64) {
469 sha512_process_bytes(alt_result, 64, &ctx);
471 sha512_process_bytes(alt_result, cnt, &ctx);
473 /* Take the binary representation of the length of the key and for every
474 1 add the alternate sum, for every 0 the key. */
475 for (cnt = key_len; cnt > 0; cnt >>= 1) {
476 if ((cnt & 1) != 0) {
477 sha512_process_bytes(alt_result, 64, &ctx);
478 } else {
479 sha512_process_bytes(key, key_len, &ctx);
483 /* Create intermediate result. */
484 sha512_finish_ctx(&ctx, alt_result);
486 /* Start computation of P byte sequence. */
487 sha512_init_ctx(&alt_ctx);
489 /* For every character in the password add the entire password. */
490 for (cnt = 0; cnt < key_len; ++cnt) {
491 sha512_process_bytes(key, key_len, &alt_ctx);
494 /* Finish the digest. */
495 sha512_finish_ctx(&alt_ctx, temp_result);
497 /* Create byte sequence P. */
498 cp = p_bytes = alloca(key_len);
499 for (cnt = key_len; cnt >= 64; cnt -= 64) {
500 cp = __php_mempcpy((void *) cp, (const void *)temp_result, 64);
503 memcpy(cp, temp_result, cnt);
505 /* Start computation of S byte sequence. */
506 sha512_init_ctx(&alt_ctx);
508 /* For every character in the password add the entire password. */
509 for (cnt = 0; cnt < (size_t) (16 + alt_result[0]); ++cnt) {
510 sha512_process_bytes(salt, salt_len, &alt_ctx);
513 /* Finish the digest. */
514 sha512_finish_ctx(&alt_ctx, temp_result);
516 /* Create byte sequence S. */
517 cp = s_bytes = alloca(salt_len);
518 for (cnt = salt_len; cnt >= 64; cnt -= 64) {
519 cp = __php_mempcpy(cp, temp_result, 64);
521 memcpy(cp, temp_result, cnt);
523 /* Repeatedly run the collected hash value through SHA512 to burn
524 CPU cycles. */
525 for (cnt = 0; cnt < rounds; ++cnt) {
526 /* New context. */
527 sha512_init_ctx(&ctx);
529 /* Add key or last result. */
530 if ((cnt & 1) != 0) {
531 sha512_process_bytes(p_bytes, key_len, &ctx);
532 } else {
533 sha512_process_bytes(alt_result, 64, &ctx);
536 /* Add salt for numbers not divisible by 3. */
537 if (cnt % 3 != 0) {
538 sha512_process_bytes(s_bytes, salt_len, &ctx);
541 /* Add key for numbers not divisible by 7. */
542 if (cnt % 7 != 0) {
543 sha512_process_bytes(p_bytes, key_len, &ctx);
546 /* Add key or last result. */
547 if ((cnt & 1) != 0) {
548 sha512_process_bytes(alt_result, 64, &ctx);
549 } else {
550 sha512_process_bytes(p_bytes, key_len, &ctx);
553 /* Create intermediate result. */
554 sha512_finish_ctx(&ctx, alt_result);
557 /* Now we can construct the result string. It consists of three
558 parts. */
559 cp = __php_stpncpy(buffer, sha512_salt_prefix, MAX(0, buflen));
560 buflen -= sizeof(sha512_salt_prefix) - 1;
562 if (rounds_custom) {
563 #ifdef PHP_WIN32
564 int n = _snprintf(cp, MAX(0, buflen), "%s%u$", sha512_rounds_prefix, rounds);
565 #else
566 int n = snprintf(cp, MAX(0, buflen), "%s%zu$", sha512_rounds_prefix, rounds);
567 #endif
568 cp += n;
569 buflen -= n;
572 cp = __php_stpncpy(cp, salt, MIN((size_t) MAX(0, buflen), salt_len));
573 buflen -= (int) MIN((size_t) MAX(0, buflen), salt_len);
575 if (buflen > 0) {
576 *cp++ = '$';
577 --buflen;
580 #define b64_from_24bit(B2, B1, B0, N) \
581 do { \
582 unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \
583 int n = (N); \
584 while (n-- > 0 && buflen > 0) \
586 *cp++ = b64t[w & 0x3f]; \
587 --buflen; \
588 w >>= 6; \
590 } while (0)
592 b64_from_24bit(alt_result[0], alt_result[21], alt_result[42], 4);
593 b64_from_24bit(alt_result[22], alt_result[43], alt_result[1], 4);
594 b64_from_24bit(alt_result[44], alt_result[2], alt_result[23], 4);
595 b64_from_24bit(alt_result[3], alt_result[24], alt_result[45], 4);
596 b64_from_24bit(alt_result[25], alt_result[46], alt_result[4], 4);
597 b64_from_24bit(alt_result[47], alt_result[5], alt_result[26], 4);
598 b64_from_24bit(alt_result[6], alt_result[27], alt_result[48], 4);
599 b64_from_24bit(alt_result[28], alt_result[49], alt_result[7], 4);
600 b64_from_24bit(alt_result[50], alt_result[8], alt_result[29], 4);
601 b64_from_24bit(alt_result[9], alt_result[30], alt_result[51], 4);
602 b64_from_24bit(alt_result[31], alt_result[52], alt_result[10], 4);
603 b64_from_24bit(alt_result[53], alt_result[11], alt_result[32], 4);
604 b64_from_24bit(alt_result[12], alt_result[33], alt_result[54], 4);
605 b64_from_24bit(alt_result[34], alt_result[55], alt_result[13], 4);
606 b64_from_24bit(alt_result[56], alt_result[14], alt_result[35], 4);
607 b64_from_24bit(alt_result[15], alt_result[36], alt_result[57], 4);
608 b64_from_24bit(alt_result[37], alt_result[58], alt_result[16], 4);
609 b64_from_24bit(alt_result[59], alt_result[17], alt_result[38], 4);
610 b64_from_24bit(alt_result[18], alt_result[39], alt_result[60], 4);
611 b64_from_24bit(alt_result[40], alt_result[61], alt_result[19], 4);
612 b64_from_24bit(alt_result[62], alt_result[20], alt_result[41], 4);
613 b64_from_24bit(0, 0, alt_result[63], 2);
615 if (buflen <= 0) {
616 errno = ERANGE;
617 buffer = NULL;
618 } else {
619 *cp = '\0'; /* Terminate the string. */
622 /* Clear the buffer for the intermediate result so that people
623 attaching to processes or reading core dumps cannot get any
624 information. We do it in this way to clear correct_words[]
625 inside the SHA512 implementation as well. */
626 sha512_init_ctx(&ctx);
627 sha512_finish_ctx(&ctx, alt_result);
628 memset(temp_result, '\0', sizeof(temp_result));
629 memset(p_bytes, '\0', key_len);
630 memset(s_bytes, '\0', salt_len);
631 memset(&ctx, '\0', sizeof(ctx));
632 memset(&alt_ctx, '\0', sizeof(alt_ctx));
633 if (copied_key != NULL) {
634 memset(copied_key, '\0', key_len);
636 if (copied_salt != NULL) {
637 memset(copied_salt, '\0', salt_len);
640 return buffer;
644 /* This entry point is equivalent to the `crypt' function in Unix
645 libcs. */
646 char *
647 php_sha512_crypt(const char *key, const char *salt) {
648 /* We don't want to have an arbitrary limit in the size of the
649 password. We can compute an upper bound for the size of the
650 result in advance and so we can prepare the buffer we pass to
651 `sha512_crypt_r'. */
652 static char *buffer;
653 static int buflen;
654 int needed = (int)(sizeof(sha512_salt_prefix) - 1
655 + sizeof(sha512_rounds_prefix) + 9 + 1
656 + strlen(salt) + 1 + 86 + 1);
658 if (buflen < needed) {
659 char *new_buffer = (char *) realloc(buffer, needed);
660 if (new_buffer == NULL) {
661 return NULL;
664 buffer = new_buffer;
665 buflen = needed;
668 return php_sha512_crypt_r (key, salt, buffer, buflen);
671 #ifdef TEST
672 static const struct {
673 const char *input;
674 const char result[64];
675 } tests[] =
677 /* Test vectors from FIPS 180-2: appendix C.1. */
678 { "abc",
679 "\xdd\xaf\x35\xa1\x93\x61\x7a\xba\xcc\x41\x73\x49\xae\x20\x41\x31"
680 "\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2\x0a\x9e\xee\xe6\x4b\x55\xd3\x9a"
681 "\x21\x92\x99\x2a\x27\x4f\xc1\xa8\x36\xba\x3c\x23\xa3\xfe\xeb\xbd"
682 "\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a\x9a\xc9\x4f\xa5\x4c\xa4\x9f" },
683 /* Test vectors from FIPS 180-2: appendix C.2. */
684 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
685 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
686 "\x8e\x95\x9b\x75\xda\xe3\x13\xda\x8c\xf4\xf7\x28\x14\xfc\x14\x3f"
687 "\x8f\x77\x79\xc6\xeb\x9f\x7f\xa1\x72\x99\xae\xad\xb6\x88\x90\x18"
688 "\x50\x1d\x28\x9e\x49\x00\xf7\xe4\x33\x1b\x99\xde\xc4\xb5\x43\x3a"
689 "\xc7\xd3\x29\xee\xb6\xdd\x26\x54\x5e\x96\xe5\x5b\x87\x4b\xe9\x09" },
690 /* Test vectors from the NESSIE project. */
691 { "",
692 "\xcf\x83\xe1\x35\x7e\xef\xb8\xbd\xf1\x54\x28\x50\xd6\x6d\x80\x07"
693 "\xd6\x20\xe4\x05\x0b\x57\x15\xdc\x83\xf4\xa9\x21\xd3\x6c\xe9\xce"
694 "\x47\xd0\xd1\x3c\x5d\x85\xf2\xb0\xff\x83\x18\xd2\x87\x7e\xec\x2f"
695 "\x63\xb9\x31\xbd\x47\x41\x7a\x81\xa5\x38\x32\x7a\xf9\x27\xda\x3e" },
696 { "a",
697 "\x1f\x40\xfc\x92\xda\x24\x16\x94\x75\x09\x79\xee\x6c\xf5\x82\xf2"
698 "\xd5\xd7\xd2\x8e\x18\x33\x5d\xe0\x5a\xbc\x54\xd0\x56\x0e\x0f\x53"
699 "\x02\x86\x0c\x65\x2b\xf0\x8d\x56\x02\x52\xaa\x5e\x74\x21\x05\x46"
700 "\xf3\x69\xfb\xbb\xce\x8c\x12\xcf\xc7\x95\x7b\x26\x52\xfe\x9a\x75" },
701 { "message digest",
702 "\x10\x7d\xbf\x38\x9d\x9e\x9f\x71\xa3\xa9\x5f\x6c\x05\x5b\x92\x51"
703 "\xbc\x52\x68\xc2\xbe\x16\xd6\xc1\x34\x92\xea\x45\xb0\x19\x9f\x33"
704 "\x09\xe1\x64\x55\xab\x1e\x96\x11\x8e\x8a\x90\x5d\x55\x97\xb7\x20"
705 "\x38\xdd\xb3\x72\xa8\x98\x26\x04\x6d\xe6\x66\x87\xbb\x42\x0e\x7c" },
706 { "abcdefghijklmnopqrstuvwxyz",
707 "\x4d\xbf\xf8\x6c\xc2\xca\x1b\xae\x1e\x16\x46\x8a\x05\xcb\x98\x81"
708 "\xc9\x7f\x17\x53\xbc\xe3\x61\x90\x34\x89\x8f\xaa\x1a\xab\xe4\x29"
709 "\x95\x5a\x1b\xf8\xec\x48\x3d\x74\x21\xfe\x3c\x16\x46\x61\x3a\x59"
710 "\xed\x54\x41\xfb\x0f\x32\x13\x89\xf7\x7f\x48\xa8\x79\xc7\xb1\xf1" },
711 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
712 "\x20\x4a\x8f\xc6\xdd\xa8\x2f\x0a\x0c\xed\x7b\xeb\x8e\x08\xa4\x16"
713 "\x57\xc1\x6e\xf4\x68\xb2\x28\xa8\x27\x9b\xe3\x31\xa7\x03\xc3\x35"
714 "\x96\xfd\x15\xc1\x3b\x1b\x07\xf9\xaa\x1d\x3b\xea\x57\x78\x9c\xa0"
715 "\x31\xad\x85\xc7\xa7\x1d\xd7\x03\x54\xec\x63\x12\x38\xca\x34\x45" },
716 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
717 "\x1e\x07\xbe\x23\xc2\x6a\x86\xea\x37\xea\x81\x0c\x8e\xc7\x80\x93"
718 "\x52\x51\x5a\x97\x0e\x92\x53\xc2\x6f\x53\x6c\xfc\x7a\x99\x96\xc4"
719 "\x5c\x83\x70\x58\x3e\x0a\x78\xfa\x4a\x90\x04\x1d\x71\xa4\xce\xab"
720 "\x74\x23\xf1\x9c\x71\xb9\xd5\xa3\xe0\x12\x49\xf0\xbe\xbd\x58\x94" },
721 { "123456789012345678901234567890123456789012345678901234567890"
722 "12345678901234567890",
723 "\x72\xec\x1e\xf1\x12\x4a\x45\xb0\x47\xe8\xb7\xc7\x5a\x93\x21\x95"
724 "\x13\x5b\xb6\x1d\xe2\x4e\xc0\xd1\x91\x40\x42\x24\x6e\x0a\xec\x3a"
725 "\x23\x54\xe0\x93\xd7\x6f\x30\x48\xb4\x56\x76\x43\x46\x90\x0c\xb1"
726 "\x30\xd2\xa4\xfd\x5d\xd1\x6a\xbb\x5e\x30\xbc\xb8\x50\xde\xe8\x43" }
728 #define ntests (sizeof (tests) / sizeof (tests[0]))
731 static const struct
733 const char *salt;
734 const char *input;
735 const char *expected;
736 } tests2[] = {
737 { "$6$saltstring", "Hello world!",
738 "$6$saltstring$svn8UoSVapNtMuq1ukKS4tPQd8iKwSMHWjl/O817G3uBnIFNjnQJu"
739 "esI68u4OTLiBFdcbYEdFCoEOfaS35inz1"},
740 { "$6$rounds=10000$saltstringsaltstring", "Hello world!",
741 "$6$rounds=10000$saltstringsaltst$OW1/O6BYHV6BcXZu8QVeXbDWra3Oeqh0sb"
742 "HbbMCVNSnCM/UrjmM0Dp8vOuZeHBy/YTBmSK6H9qs/y3RnOaw5v." },
743 { "$6$rounds=5000$toolongsaltstring", "This is just a test",
744 "$6$rounds=5000$toolongsaltstrin$lQ8jolhgVRVhY4b5pZKaysCLi0QBxGoNeKQ"
745 "zQ3glMhwllF7oGDZxUhx1yxdYcz/e1JSbq3y6JMxxl8audkUEm0" },
746 { "$6$rounds=1400$anotherlongsaltstring",
747 "a very much longer text to encrypt. This one even stretches over more"
748 "than one line.",
749 "$6$rounds=1400$anotherlongsalts$POfYwTEok97VWcjxIiSOjiykti.o/pQs.wP"
750 "vMxQ6Fm7I6IoYN3CmLs66x9t0oSwbtEW7o7UmJEiDwGqd8p4ur1" },
751 { "$6$rounds=77777$short",
752 "we have a short salt string but not a short password",
753 "$6$rounds=77777$short$WuQyW2YR.hBNpjjRhpYD/ifIw05xdfeEyQoMxIXbkvr0g"
754 "ge1a1x3yRULJ5CCaUeOxFmtlcGZelFl5CxtgfiAc0" },
755 { "$6$rounds=123456$asaltof16chars..", "a short string",
756 "$6$rounds=123456$asaltof16chars..$BtCwjqMJGx5hrJhZywWvt0RLE8uZ4oPwc"
757 "elCjmw2kSYu.Ec6ycULevoBK25fs2xXgMNrCzIMVcgEJAstJeonj1" },
758 { "$6$rounds=10$roundstoolow", "the minimum number is still observed",
759 "$6$rounds=1000$roundstoolow$kUMsbe306n21p9R.FRkW3IGn.S9NPN0x50YhH1x"
760 "hLsPuWGsUSklZt58jaTfF4ZEQpyUNGc0dqbpBYYBaHHrsX." },
762 #define ntests2 (sizeof (tests2) / sizeof (tests2[0]))
765 int main (void) {
766 struct sha512_ctx ctx;
767 char sum[64];
768 int result = 0;
769 int cnt;
770 int i;
771 char buf[1000];
772 static const char expected[64] =
773 "\xe7\x18\x48\x3d\x0c\xe7\x69\x64\x4e\x2e\x42\xc7\xbc\x15\xb4\x63"
774 "\x8e\x1f\x98\xb1\x3b\x20\x44\x28\x56\x32\xa8\x03\xaf\xa9\x73\xeb"
775 "\xde\x0f\xf2\x44\x87\x7e\xa6\x0a\x4c\xb0\x43\x2c\xe5\x77\xc3\x1b"
776 "\xeb\x00\x9c\x5c\x2c\x49\xaa\x2e\x4e\xad\xb2\x17\xad\x8c\xc0\x9b";
778 for (cnt = 0; cnt < (int) ntests; ++cnt) {
779 sha512_init_ctx (&ctx);
780 sha512_process_bytes (tests[cnt].input, strlen (tests[cnt].input), &ctx);
781 sha512_finish_ctx (&ctx, sum);
782 if (memcmp (tests[cnt].result, sum, 64) != 0) {
783 printf ("test %d run %d failed\n", cnt, 1);
784 result = 1;
787 sha512_init_ctx (&ctx);
788 for (i = 0; tests[cnt].input[i] != '\0'; ++i) {
789 sha512_process_bytes (&tests[cnt].input[i], 1, &ctx);
791 sha512_finish_ctx (&ctx, sum);
792 if (memcmp (tests[cnt].result, sum, 64) != 0) {
793 printf ("test %d run %d failed\n", cnt, 2);
794 result = 1;
798 /* Test vector from FIPS 180-2: appendix C.3. */
800 memset (buf, 'a', sizeof (buf));
801 sha512_init_ctx (&ctx);
802 for (i = 0; i < 1000; ++i) {
803 sha512_process_bytes (buf, sizeof (buf), &ctx);
806 sha512_finish_ctx (&ctx, sum);
807 if (memcmp (expected, sum, 64) != 0) {
808 printf ("test %d failed\n", cnt);
809 result = 1;
812 for (cnt = 0; cnt < ntests2; ++cnt) {
813 char *cp = php_sha512_crypt(tests2[cnt].input, tests2[cnt].salt);
815 if (strcmp (cp, tests2[cnt].expected) != 0) {
816 printf ("test %d: expected \"%s\", got \"%s\"\n",
817 cnt, tests2[cnt].expected, cp);
818 result = 1;
822 if (result == 0) {
823 puts ("all tests OK");
826 return result;
828 #endif