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