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