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