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