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