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